Skip to content

Anthropic(Messages API)响应不回传 thinking 思考内容 —— Claude Code 看不到思考 #4

Description

@6Kmfi6HP

问题概述

通过 Anthropic Messages API/v1/messages)调用推理模型时,思考过程(thinking block)完全不会回传到客户端。Claude Code / 任意 Anthropic SDK 只能看到最终正文,看不到模型推理内容。

注意:这不是模型不支持思考——通过 OpenAI 端点/v1/chat/completions)调用同一模型可以正常收到推理内容(见下方证据)。问题出在本代理的 Anthropic 响应转换路径。

根因(两处)

1. 响应方向:Anthropic 流式转换丢弃推理事件(直接原因)

createAnthropicSseTranslatorproxy.mjs:1387)对上游的推理事件直接丢弃,从不生成 Anthropic 的 thinking block:

case 'reasoning-start':   // :1383 也仅计事件,不产出 content block
    break;
case 'reasoning-delta':
    // Anthropic Messages API default mode doesn't expose thinking blocks
    break;                       // ← 思考内容在此被丢弃

流式响应因此只输出 text / tool_use 两种 content block,永远没有 {type:"thinking"}

2. 响应方向:非流式响应也不含 thinking block

buildAnthropicResponseproxy.mjs:1138)只组装 texttool_use 两类 content block:

const content = [];
if (fullText) content.push({ type: 'text', text: fullText });
if (toolCalls) { /* push tool_use */ }

没有任何 { type: 'thinking', thinking: ... } 的输出分支。


对照:OpenAI 端(/v1/chat/completions)已正确回传推理——流式 proxy.mjs:553reasoning-delta 转成 reasoning_content,非流式 proxy.mjs:1010/:1076 累积后合并。这证实了上游确实会产出 reasoning 事件,Anthropic 端只是没有回传。

复现与证据

证据 A:本地 mock 上游端到端复现(代理指向返回 reasoning-delta 的 mock 上游)

上游返回含 reasoning-start / reasoning-delta / reasoning-end 的事件流,代理转成 Anthropic 响应后:

  • 流式 仅收到 content_block_start(text)content_block_delta(text_delta)content_block_stop无任何 thinking block
  • 非流式 返回 content:[{"type":"text","text":"..."}],同样无 thinking。

即:即使模型明确在思考并输出推理事件,Anthropic 端也全部丢掉了。

证据 B:真实 API key 验证(deepseek/deepseek-v4-pro/v1/chat/completionsmax_tokens=32

真实调用返回了推理内容,证明模型确实会思考、且 OpenAI 端能正确回传:

"content": null,
"reasoning_content": "The user is asking \"1加1等于几?\" ...",
"finish_reason": "length"

prompt_tokens:7577,其中 cached_tokens:7424 已被缓存,未额外消耗大量 token。)

两个证据相互印证:模型确实思考,但 Anthropic 端从不同步思考内容

影响

  • Claude Code 以及所有通过 Anthropic SDK 使用该代理的客户端,看不到模型的思考过程。
  • 对依赖 visible thinking 的推理模型(如 deepseek-v4-pro 等带 reasoning 的模型)体验不完整。

建议修复

  1. 流式 createAnthropicSseTranslator:为 reasoning-start / reasoning-delta / reasoning-end 各事件增加 thinking block 输出——
    • reasoning-startcontent_block_start { type:"thinking", thinking:"" }
    • reasoning-deltacontent_block_delta { delta: { type:"thinking_delta", thinking } }
    • reasoning-endcontent_block_stop
    • 复用现有 nextBlockIndex 编号器,与 text/tool block 正确编排索引。
  2. 非流式 buildAnthropicResponse 及对应非流式解析处:累积推理内容,追加 { type:"thinking", thinking },并按 Anthropic 规范映射 stop_reason

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions