https://ollama.com/blog/streaming-tool
(かわいい、、、、)
目次
Part 1: Ollamaツール呼び出し機能の全体像
- Chapter 1.1: 新機能の詳細とエンジニアにとってのメリット
- Chapter 1.2: 対応モデルと技術仕様
Part 2: 実装方法と具体的コード例
- Chapter 2.1: cURLによる基本実装とAPI設計
- Chapter 2.2: Pythonでの高度な実装パターン
- Chapter 2.3: JavaScriptでのフロントエンド統合
Part 3: 技術的メカニズムの深掘り
- Chapter 3.1: パーサーアーキテクチャの革新
- Chapter 3.2: インクリメンタルパーシングの実装戦略
- Chapter 3.3: 精度向上とエラーハンドリング
Part 4: Model Context Protocolとの統合活用
- Chapter 4.1: MCPとの連携による開発効率向上
- Chapter 4.2: パフォーマンス最適化とメモリ管理
Part 1: Ollamaツール呼び出し機能の全体像
Chapter 1.1: 新機能の詳細とエンジニアにとってのメリット 💡
Ollamaの最新アップデートにより、ストリーミングレスポンスとツール呼び出しの同時実行が可能となった。この機能強化は、AI駆動アプリケーション開発において重要な転換点となる可能性がある。
エンジニアにとってのGains(利益) ✅
リアルタイム応答性の向上
従来のツール呼び出しでは、完全なレスポンス生成を待つ必要があったが、新機能により部分的なレスポンスを即座に表示できるようになった。これにより、ユーザーエクスペリエンスが大幅に改善される。
開発効率の向上
ストリーミングとツール呼び出しを同時に処理できることで、複雑なワークフローを単一のAPIコールで実現できる。これは開発時間の短縮と、システム設計の簡素化をもたらす。
スケーラビリティの改善
リアルタイム処理により、大量のリクエストを効率的に処理できるため、システムの応答性とスループットが向上する。
潜在的なPains(課題) ⚠️
複雑性の増加
ストリーミングとツール呼び出しの同時処理は、エラーハンドリングとデバッグの複雑さを増す可能性がある。
メモリ使用量の増加
コンテキストウィンドウの拡張により、メモリ消費量が増加する傾向がある。
Chapter 1.2: 対応モデルと技術仕様 🔧
対応モデル一覧
現在、以下のモデルがツール呼び出し機能をサポートしている:
- Qwen 3: 最新の多言語対応モデル
- Devstral: 開発特化型モデル
- Qwen2.5 & Qwen2.5-coder: コーディング支援モデル
- Llama 3.1: Meta社の高性能モデル
- Llama 4: 次世代言語モデル
技術仕様
APIエンドポイント: http://localhost:11434/api/chat
ストリーミング: "stream": true
パラメータで有効化
ツール定義: OpenAI Function Calling互換の仕様
Part 2: 実装方法と具体的コード例
Chapter 2.1: cURLによる基本実装とAPI設計 🌐
cURLを使用した基本的な実装例では、天気情報取得ツールを定義している。この実装パターンは、RESTful APIの設計原則に従い、直感的で拡張可能な構造となっている。
APIリクエスト構造
curl http://localhost:11434/api/chat -d '{
"model": "qwen3",
"messages": [
{
"role": "user",
"content": "What is the weather today in Toronto?"
}
],
"stream": true,
"tools": [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The location to get the weather for, e.g. San Francisco, CA"
},
"format": {
"type": "string",
"description": "The format to return the weather in, e.g. 'celsius' or 'fahrenheit'",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location", "format"]
}
}
}
]
}'
レスポンス処理フロー
Chapter 2.2: Pythonでの高度な実装パターン 🐍
Python実装では、関数定義とドキュメント文字列を活用した、より直感的なAPIが提供されている。これにより、開発者はPythonの標準的なコーディングパターンを維持しながら、AI機能を統合できる。
関数定義とツール統合
def add_two_numbers(a: int, b: int) -> int:
"""
Add two numbers
Args:
a (int): The first number as an int
b (int): The second number as an int
Returns:
int: The sum of the two numbers
"""
return a + b
from ollama import chat, ChatResponse
messages = [{'role': 'user', 'content': 'what is three minus one?'}]
response: ChatResponse = chat(
model='qwen3',
messages=messages,
tools=[add_two_numbers], # 関数を直接渡すことが可能
stream=True
)
for chunk in response:
print(chunk.message.content, end='', flush=True)
if chunk.message.tool_calls:
print(chunk.message.tool_calls)
Pythonの利点
タイプヒンティング対応: 関数の型情報が自動的にツール定義に反映される
ドキュメント自動生成: docstringからツールの説明が自動生成される
IDE統合: 既存のPython開発環境との完全な互換性
Chapter 2.3: JavaScriptでのフロントエンド統合 ⚡
JavaScript実装では、非同期処理とモダンなES6+構文を活用したクリーンなAPIが提供されている。これにより、フロントエンドアプリケーションでのリアルタイムAI機能統合が容易になる。
非同期ストリーミング処理
import ollama from 'ollama';
const addTool = {
type: 'function',
function: {
name: 'addTwoNumbers',
description: 'Add two numbers together',
parameters: {
type: 'object',
required: ['a', 'b'],
properties: {
a: { type: 'number', description: 'The first number' },
b: { type: 'number', description: 'The second number' }
}
}
}
};
async function run(model: string) {
const messages = [{ role: 'user', content: 'What is 2 plus 3?' }];
for await (const chunk of await ollama.chat({
model: model,
messages: messages,
tools: [addTool],
stream: true
})) {
if (chunk.message.tool_calls) {
for (const tool of chunk.message.tool_calls) {
console.log('Tool call:', tool);
}
} else {
process.stdout.write(chunk.message.content);
}
}
}
Part 3: 技術的メカニズムの深掘り
Chapter 3.1: パーサーアーキテクチャの革新 🔍
新しいパーサーは、単純なJSON解析から構造理解ベースのアプローチへと進化している。この変更により、ストリーミング中でもツール呼び出しを正確に検出できるようになった。
従来のアプローチとの比較
従来の方式:
- 完全な出力生成後にJSON解析
- ストリーミングのブロッキング
- 構造的な理解の欠如
新しい方式:
- 構造ベースの理解
- リアルタイム検出
- モデル固有のテンプレート活用
Chapter 3.2: インクリメンタルパーシングの実装戦略 ⚙️
インクリメンタルパーサーは、各モデルのテンプレートを直接参照することで、ツール呼び出しのプレフィックスを理解している。これにより、ツール呼び出しとコンテンツを適切に分離できる。
処理ステップ
- プレフィックス検出: モデル固有のツール呼び出しプレフィックスを識別
- 状態管理: パーシング状態を追跡して適切な処理を実行
- フォールバック処理: プレフィックスなしのJSONも適切に処理
特殊ケースの処理
プレフィックスなしツール呼び出し: 一部のモデルは訓練データと異なる出力パターンを示すことがある
JSON検出: 出力開始時のJSON構造を認識してツール呼び出しとして処理
Chapter 3.3: 精度向上とエラーハンドリング 🎯
新しいパーサーは、モデルが以前のツール呼び出しを参照する際の重複検出問題を解決している。プレフィックスマッチングと状態管理により、信頼性が大幅に向上している。
問題例と解決策
従来の問題:
[TOOL_CALL] [{"name":"get_conditions","arguments":{"city":"Sydney"}}]
To get the current weather conditions for Sydney, we can use the function `get_conditions`.
However, I don't have real-time data access. Let's assume that the API will return the information:
[{"name":"get_conditions","arguments":{"city":"Sydney"}}]
この例では、2つのツール呼び出しが検出されていたが、実際には1つのみが意図されている。
解決アプローチ:
- プレフィックスマッチングによる正確な境界検出
- 状態管理による重複防止
- JSON構造の文脈的解析
精度向上により、プロダクション環境での信頼性が大幅に改善されている。特に、複雑なツール呼び出しシーケンスでの安定性が向上している。
Part 4: Model Context Protocolとの統合活用
Chapter 4.1: MCPとの連携による開発効率向上 🔗
Model Context Protocol (MCP) との統合により、開発者はストリーミングとツール呼び出しの両方を活用したより高度なアプリケーションを構築できるようになった。
MCPの利点
標準化されたプロトコル: 異なるAIモデル間での一貫したインターフェース
ツール管理の簡素化: 中央集権的なツール定義と管理
開発者体験の向上: 統一されたAPIによる学習コストの削減
Chapter 4.2: パフォーマンス最適化とメモリ管理 📊
コンテキストウィンドウの最適化は、ツール呼び出しの性能とツール実行結果の品質に直接的な影響を与える。32k以上のコンテキストウィンドウ使用が推奨されているが、メモリ使用量とのバランスを考慮する必要がある。
コンテキストウィンドウ設定例
curl -X POST "http://localhost:11434/api/chat" -d '{
"model": "llama3.2",
"messages": [
{
"role": "user",
"content": "why is the sky blue?"
}
],
"options": {
"num_ctx": 32000
}
}'
パフォーマンス考慮事項
メモリ使用量: コンテキストウィンドウサイズに比例して増加
処理速度: 大きなコンテキストは処理時間の増加を伴う
品質向上: 十分なコンテキストにより、ツール呼び出しの精度が向上
コンテキストウィンドウを大きく設定する際は、利用可能なメモリ量を事前に確認することが重要である。特に、本番環境では適切なリソース監視が必要となる。
まとめ
Ollamaの新しいストリーミング対応ツール呼び出し機能は、AI駆動アプリケーション開発において重要な進歩を表している。リアルタイム応答性の向上、開発効率の改善、そして Model Context Protocol との統合により、より洗練されたAIアプリケーションの構築が可能となった。
主要なポイント
- ストリーミングレスポンスとツール呼び出しの同時実行
- 複数プログラミング言語での統一されたAPI
- 構造理解ベースの新しいパーサーアーキテクチャ
- MCP統合による開発効率向上
- 実装複雑性とリソース管理のバランス
この機能強化により、開発者はより応答性が高く、機能豊富なAIアプリケーションを構築できるようになり、エンドユーザーエクスペリエンスの大幅な改善が期待される。ただし、実装時には適切なエラーハンドリングとリソース管理を考慮することが重要である。