协议观察台
协议观察台把同一个提示词,通过三种不同的服务协议并行发送给你本地的 Ollama 守护进程,并清楚地展示每种协议是如何组织同一段对话的。
侧边栏位置: 协议观察台(在代码补全下方) 路由: /protocols加入版本: v0.4.7(2026 年 5 月)
这有什么意义?
Ollama 并不只说一种协议。它实际上通过三种不同的传输格式暴露同一个本地模型:
| 接口 | 格式 | 流式封装 |
|---|---|---|
/api/chat | Ollama 原生 | NDJSON(每行一个 JSON) |
/v1/chat/completions | OpenAI 兼容 | SSE(data: …) |
/v1/messages | Anthropic 兼容 | 带 event: 标签的 SSE |
不同的生态通过不同的协议与大模型通信。如果你在做集成、调试客户端库,或者只是好奇同一个模型在不同封装下表现如何,这个页面会把差异直观地呈现出来 —— 全部针对同一个本地模型,无云端、无 API key、无需注册。
使用这个页面
- 从下拉框选择一个模型。
- 输入提示词(已提供默认值)。
- 按需调整最大 token 数。
- 点击运行全部 3 种协议。
三列会并行流式输出。每一列显示:
- 协议名称与接口路径
- 实时状态标识(空闲 → 流式中 → 已完成)
- 流式回复文本
- 指标网格:TTFT、总耗时、token 数、token/秒、结束原因
- 可展开的报文检查面板,显示原始的首个与最后一个数据块 / 事件
报文差异标签页
三次运行全部完成后,下方会出现一个分标签区域。切换到报文差异,可以并排比较每种协议如何组织自己的响应:
| 方面 | 原生 | OpenAI 兼容 | Anthropic 兼容 |
|---|---|---|---|
| 流式封装 | NDJSON | SSE | 带 event: 标签的 SSE |
| 结束原因所在字段 | done + done_reason | choices[].finish_reason | message_stop 事件 |
| token 计数所在字段 | eval_count + prompt_eval_count | usage.{prompt,completion,total}_tokens | usage.{input,output}_tokens |
| 提示词缓存所在字段 | prompt_eval_cached_count | usage.prompt_tokens_details.cached_tokens | usage.cache_read_input_tokens |
| 预填充时间所在字段 | prompt_eval_duration(纳秒) | timings.prompt_ms | — |
| 推理所在字段 | message.thinking | choices[].delta.reasoning | thinking_delta 事件 |
| 错误报文结构 | {"error": "string"} | {"error": {"message", "type", "code"}} | {"type": "error", "error": {...}, "request_id"} |
标着「本次运行」的行会填入你这次运行中实际观察到的值 —— 于是你可以看到,比如原生协议返回了 done_reason: "stop",而 Anthropic 协议把同一个结果称为 stop_reason: "end_turn"。
使用推理模型时,推理这一行最值得留意。原生路径只在请求要求时才思考;两条兼容路径默认让模型思考,而思考与回答共用输出预算。在相同提示和相同 max_tokens 下,兼容列可能把全部 token 花在推理上,一个字的回答也没有。每一列都会显示模型的思考内容,并在预算于第一个字之前耗尽时明确说明。
两个预填充速率
自 Ollama 0.35.1 起,OpenAI 兼容端点会附带一个 timings 块,其中有现成的 prompt_per_second。表格把它显示为**「预填充速率(守护进程自报)」,旁边是「预填充速率(按实际评估的 token)」**,后者由 LLMxRay 根据同一个 chunk 计算:(prompt_tokens − cached_tokens) / prompt_ms。
只要缓存是热的,两者就会不一致。守护进程的数字用提示词总 token 数除以仅处理未缓存 token 的时间,因此会按缓存命中率被放大;同一提示词运行两次,自报那一格就会变成琥珀色。在 0.40.3 上实测,31 个 token 中 30 个命中缓存:自报 3875 tok/s,按评估 token 计算为 125 tok/s。只有后者描述了模型真正做的工作。原生协议从不自报速率,Anthropic 兼容协议则完全不报告预填充时间,所以那些格子显示为破折号。
为什么是三种协议?
这并非纸上谈兵 —— 很多真实工具都依赖这些兼容层:
- OpenAI 兼容是 IDE 插件、Cursor、Continue.dev,以及大多数「面向 OpenAI API」的 Python 库与本地模型通信的方式。
- Anthropic 兼容是 Claude Code、Claude Cowork、OpenClaw 这类工具与 Ollama 通信的方式(Ollama v0.23 / 2026 年 1 月加入)。
- 原生协议给出的指标最丰富 —— 包括各项耗时、评估计数和
done_reason字段。
如果某个第三方工具在你的本地 Ollama 上表现异常,协议观察台能让你透过那种协议的视角,看清传输层到底长什么样。