Ollama 新增串流工具呼叫支援
TL;DR
Ollama 引入了串流工具呼叫,讓聊天應用程式能夠在接收逐個 token 的模型輸出時,同時呼叫如天氣查詢或數學計算等函數。
串流工具呼叫的功能
串流工具呼叫讓模型可以在不等待整個回應完成的情況下,將一般文字與函數呼叫交錯進行。應用程式可以立即向使用者顯示部分內容,並在模型發出呼叫訊號時立即執行工具(例如 API 呼叫)。
支援工具呼叫的模型
以下由 Ollama 託管的模型與新的串流功能相容:
- Qwen 3
- Devstral
- Qwen2.5 與 Qwen2.5‑coder
- Llama 3.1
- Llama 4
- Ollama 模型庫中「tool calling」篩選器下列出的其他模型。
簡單的工具呼叫範例(天氣)
一個 cURL 請求使用 get_current_weather 函數串流天氣查詢。回應包含增量 JSON 片段,並在模型決定呼叫函數時立即提供 tool_calls 欄位。
{
"model": "qwen3",
"created_at": "2025-05-27T22:54:58.100509Z",
"message": {
"role": "assistant",
"content": "",
"tool_calls": [{
"function": {
"name": "get_current_weather",
"arguments": {"format": "celsius", "location": "Toronto"}
}
}]
},
"done": false
}
串流會在函數結果可用時繼續進行。
Python SDK 使用方式
Python 函式庫(pip install -U ollama)接受原生 Python 可呼叫物件作為工具。在下方的範例中,一個簡單的 add_two_numbers 函數被傳遞給 chat() 並設定 stream=True。客戶端會列印串流文字並在 tool_calls 出現時偵測到它們。
from ollama import chat, ChatResponse
def add_two_numbers(a: int, b: int) -> int:
return a + b
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)
輸出
[ToolCall(function=Function(name='add_two_numbers', arguments={'a': 3, 'b': 1}))]
JavaScript SDK 使用方式
JavaScript 客戶端(npm i ollama)運作方式類似。定義一個工具架構(schema),然後 ollama.chat() 會串流文字與工具呼叫。
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) {
const messages = [{role: 'user', content: 'What is 2 plus 3?'}];
for await (const chunk of await ollama.chat({model, messages, tools: [addTool], stream: true})) {
if (chunk.message.tool_calls) {
console.log('Tool call:', chunk.message.tool_calls);
} else {
process.stdout.write(chunk.message.content);
}
}
}
run('qwen3').catch(console.error);
輸出
Question: What is 2 plus 3?
Tool call: {function: {name: "addTwoNumbers", arguments: {a: 2, b: 3}}}
增量解析器如何運作
背景
早期的 Ollama 版本會緩衝整個模型的輸出,將其解析為 JSON,然後發出工具呼叫。這會阻礙串流,因為工具呼叫可能出現在文字中的任何位置。
增量解析策略
新的解析器會讀取每個模型的模板來識別工具呼叫前綴(例如,特殊 token 或字串)。它可以:
- 在模型串流 token 時偵測部分前綴。
- 將一般內容與待處理的工具呼叫分開。
- 當模型發出不帶預期前綴的原始 JSON 物件時,退回到通用 JSON 偵測。
處理邊緣情況
如果模型重複了先前已進行的工具呼叫,或將呼叫包含在解釋性文字中,解析器的狀態機可以避免重複呼叫。實證測試顯示,格式錯誤或重複的呼叫現在會減少到單次、正確的呼叫。
準確度提升
先前,模型可能會在敘述中重複呼叫時,產生兩個相同的工具呼叫。更新後的解析器會比對前綴並追蹤 JSON 解析狀態,確保只發出一個呼叫。舊版失敗範例:
[TOOL_CALL] [{"name":"get_conditions","arguments":{"city":"Sydney"}}]
... (text) ...
[{"name":"get_conditions","arguments":{"city":"Sydney"}}]
]
現在解析器會回傳單一的 tool_calls 項目。
Model Context Protocol (MCP) 與更大的視窗大小
串流工具呼叫可與 Ollama 的 Model Context Protocol 運作。使用者回報,將上下文視窗(context window)增加到 32k token 或更多,可以同時提升工具偵測的可靠性與生成回答的品質。
透過 cURL 調整上下文視窗
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 版本 – https://ollama.com/download
- 安裝語言特定的 SDKs – Python 使用
pip install -U ollama,JavaScript 使用npm i ollama。 - 使用
stream: true旗標 在 API 呼叫中,並包含一個tools陣列來描述您想要模型呼叫的函數。
參考資料
- 實作串流工具呼叫的 Pull request:https://github.com/ollama/ollama/pull/10415
Sources
相關
- Dispatch
- Dispatch
- Dispatch
- Dispatch
- Dispatch