~/tools / 在自己的伺服器上執行本機 LLM / Ollama Stream Reader

Ollama Stream Reader — 組合 Ollama 串流,查看速度與停止原因

貼上 Ollama 的串流回應(來自 /api/chat、/api/generate,或相容 OpenAI 的 /v1/chat/completions),工具會把零散的片段重新組合成完整的文字、thinking 與 tool calls。它會顯示模型停止的原因、生成與提示詞的速度、串流是否被截斷,並提供可加入下一個請求的 assistant 訊息。資料不會離開你的瀏覽器。

如何用 curl 儲存串流

-N 會關閉 curl 的緩衝,> stream.txt 會把串流存成檔案。請把模型與訊息換成你自己的。

curl -sN http://localhost:11434/api/chat -d '{"model":"qwen2.5:7b","messages":[{"role":"user","content":"Hello"}]}' > stream.txt

curl -sN http://localhost:11434/v1/chat/completions -H "Content-Type: application/json" -d '{"model":"qwen2.5:7b","stream":true,"stream_options":{"include_usage":true},"messages":[{"role":"user","content":"Hello"}]}' > stream.txt

已當作/api/chat 串流(每行一個 JSON 物件)讀取。

摘要

模型
qwen2.5:7b
停止原因
stop
區塊數
7
生成的 token
7
生成速度
10.4 token/秒
提示詞 token
35
提示詞速度(不在快取中的 token)
64.1 token/秒
模型載入時間
4.923 秒
總時間
6.310 秒
第一個到最後一個區塊
0.675 秒

文字

Hello, nice to meet.

供下一個請求使用的 assistant 訊息

把這則訊息加入 messages,如果有 tool calls,再接上它們的結果。

{
  "role": "assistant",
  "content": "Hello, nice to meet."
}

eval_count 也包含不以文字串流的 tool calls 的 token。在我們的測試中,一次 tool call 以 eval_count 20 在單一區塊中送達。

Ollama 的文件說明 prompt_eval_duration 只涵蓋不在快取中的提示詞 token。這裡的提示詞速度只去除這些 token。所有耗時的單位都是奈秒;在 OpenAI 形式中,timings 是整數毫秒。

在相容 OpenAI 的形式中,token 數只有在設定 stream_options.include_usage 時才會送出,放在 data: [DONE] 之前的額外區塊中。如果串流被截斷,這個區塊就不會送達。

格式依據 Ollama 的串流與用量文件及其原始碼(v0.40.15),並於 2026-11-07 以 Ollama 0.40.11 的真實串流檢驗。 Ollama: Streaming

所有處理都在你的瀏覽器中完成。工具不會連線到任何地方。

Ollama 預設以串流方式送出回答。/api/chat 與 /api/generate 每行送出一個 JSON 物件(newline-delimited JSON):每一行帶有回答的幾個字元,最後一行的 done 為 true,並帶有 token 數與耗時(單位為奈秒)。相容 OpenAI 的 /v1/chat/completions 只有在 stream 為 true 時才會串流。此時它送出 server-sent events:以 data: 開頭的行、一個帶有空 delta 與 finish_reason 的獨立區塊,以及結尾的 data: [DONE]。只有在請求設定 stream_options.include_usage 時才會有 token 數,它放在一個 choices 清單為空的額外區塊中,Ollama 還會在其中加入 timings 物件。這個工具能讀取這三種形式,包括帶有 HTTP 標頭的 curl -i 輸出,會組合 content、thinking(OpenAI 形式為 reasoning)與 tool calls,並列出哪裡有問題:沒有 done 行或沒有 [DONE] 的串流被截斷了;{"error": …} 這一行表示 Ollama 在開始送出之後因錯誤而停止;done_reason 為 length 表示已達到 num_predict 或 max_tokens。生成速度是 eval_count 除以 eval_duration。至於提示詞,Ollama 的文件說明 prompt_eval_duration 只涵蓋不在快取中的提示詞 token,所以工具只用這段時間去除這些 token。在 OpenAI 形式中,Ollama 自己的 timings.prompt_per_second 則是用這段時間去除所有提示詞 token,包括來自快取的。在我們的測試中,一個 35 個 token 的提示詞有 34 個來自快取,剩下的 1 個 token 花了 97 ms,它回報了 360.8 token/秒。OpenAI 形式中的 tool calls 可能分成共用同一個 index 的片段送達,所以工具會依 index 組合 arguments;Ollama 本身則是把每個 tool call 完整地放在一個區塊中送出。我們以 Ollama 0.40.11 搭配 qwen2.5:7b 的真實串流檢驗了這個工具,並以 Ollama 的文件與原始碼檢驗了各種格式。

這個工具的核心邏輯以 MIT 授權開放原始碼。 github.com/seigo5555/toolkitbox-lib/src/ollama-stream.ts

使用情境

  • 看到用 curl 發出的串流請求的完整回答,而不是一行一行地讀片段
  • 找出串流是被截斷、停在 length 上限,還是以錯誤結束
  • 測量模型在你的電腦或伺服器上的生成速度與提示詞速度

使用方法

  1. 用 curl -sN 執行你的請求並把輸出存成檔案,或複製你的程式收到的內容。
  2. 貼上整個串流。工具會判斷它來自 /api/chat、/api/generate 還是 /v1/chat/completions。
  3. 閱讀問題與數字,並複製文字或供下一個請求使用的 assistant 訊息。

FAQ

為什麼我的 /v1/chat/completions 串流沒有 token 數?

在相容 OpenAI 的形式中,只有在請求把 stream_options 設為 {"include_usage": true} 時才會送出計數。它們會放在 data: [DONE] 之前、choices 清單為空的額外區塊中。/api/chat 與 /api/generate 則一律放在最後一行。

為什麼提示詞速度與 timings.prompt_per_second 差這麼多?

Ollama 的文件說明 prompt_eval_duration 只涵蓋不在快取中的提示詞 token。Ollama 的 timings.prompt_per_second 是用這段時間去除所有提示詞 token,包括來自快取的,所以在用到快取時看起來快很多。工具只去除不在快取中的 token。

模型呼叫了工具,但 eval_count 是 20。那些 token 在哪裡?

tool call 的文字不會以 content 的形式串流;Ollama 會把它轉成 tool_calls,並在一個區塊中送出。這些 token 仍然會被生成並計入。在我們的測試中,一次帶有一個參數的 tool call 以 eval_count 20 在單一區塊中送達。

為什麼模型呼叫了工具,/api/chat 卻顯示 stop?

/api/chat 會讓 done_reason 維持為 stop。相容 OpenAI 的端點則會在送出 tool call 時,把 finish_reason 中的 stop 改成 tool_calls。

我該如何處理 assistant 訊息?

Ollama 的文件指出,要保留對話歷程,需要把串流的片段組合起來,這對 tool calls 最為重要。把訊息加入 messages,把每個 tool call 的結果以 role 為 tool 的訊息加入,然後送出下一個請求。

我的資料會被傳送到任何地方嗎?

不會。串流是在你的瀏覽器中讀取的。curl 指令只是供你自行執行的文字。

相關文章

相關工具