Misc. bug: Anthropic /v1/messages drops output_config.effort

当客户端通过 Anthropic 兼容的 /v1/messages 接口传入 output_config.effort (例如 Claude Code 的 thinking.type=adaptive 请求)时,llama-server 在转换为内部 OpenAI 格式时会丢弃该字段,导致请求级 e

快速结论:当客户端通过 Anthropic 兼容的 /v1/messages 接口传入 output_config.effort(例如 Claude Code 的 thinking.type=adaptive 请求)时,llama-server 在转换为内部 OpenAI 格式时会丢弃该字段,导致请求级 effort 不生效、模板只拿到服务端 --reasoning-effort 的默认值。优先检查走的是哪条接口,以及转换后的请求里是否还存在 reasoning_effort。

适用环境:Issue 已确认:llama.cpp 版本 0.6.0-dev(build 11457,commit 5ad1c5da0),Linux x86_64,GNU 13.3.0 编译;复现者在 macOS 当前 master(61dbf4922)上同样复现。受影响模块为 llama-server。Python、CUDA 版本及显卡信息 Issue 未提供。

最快修复方案:暂无确认的一步修复方案,Issue 讨论时尚未合并修复。临时规避:在请求中改用 /v1/chat/completions 并直接传顶层 reasoning_effort(该路径已支持,请求级值优先于 chat_template_kwargs.reasoning_effort)。

注意事项:上述规避只绕开 Anthropic 转换路径,不等于修复 /v1/messages。即使转换器补上映射,Anthropic 的 effort 等级与模板可接受值也可能不一致(如模板接受 high 而遇到 max 会报错),需要额外定义映射或回退策略。

问题场景

以 MiniCPM5-2B(Q4_K_M)加载 llama-server,开启 --jinja 并使用自定义 effort.jinja 模板。客户端(如 Claude Code)通过 Anthropic 兼容的 /v1/messages 端点发送请求,结构中包含 thinking: {type: "adaptive"} 与 output_config: {effort: "low"}。期望模板中 reasoning_effort 为 low,实际渲染为服务端启动参数 --reasoning-effort medium 的值(EFFORT=medium)。同样的 effort 通过 /v1/chat/completions 传 reasoning_effort 时则正常生效。

报错原文

converted request: {"messages":[{"role":"user","content":"hello"}],"max_tokens":1}
"prompt":"<s> [user] EFFORT=medium :: hello\n[assistant] "   <- /v1/messages, output_config.effort=low
"prompt":"<s> [user] EFFORT=low :: hello\n[assistant] "      <- /v1/chat/completions, reasoning_effort=low

核心报错标题:Misc. bug: Anthropic /v1/messages drops output_config.effort。转换后请求中已不含 output_config,也不含 reasoning_effort。

原因分析

已确认的根因在转换函数 server_chat_convert_anthropic_to_oai()(tools/server/server-chat.cpp):它只传递 temperature、top_p、top_k、stream、chat_template_kwargs 等字段;对 thinking 仅在 type == "enabled" 时处理,而 Claude Code 发的是 adaptive,该分支不会触发;对 output_config 则完全不读取。同文件中的 Responses 转换器已把 reasoning.effort 映射为 reasoning_effort(约第 304 行),OpenAI 路径本身也支持请求级 reasoning_effort,说明机制存在,只是 Anthropic 转换路径缺失。

可能的影响面:任何依赖 output_config.effort 控制推理强度的 Anthropic 兼容客户端都会受影响,且不会报错,只会静默回落到服务端默认 effort,较难发现。

环境排查

  • 确认使用的是 /v1/messages 还是 /v1/chat/completions,并对比两者转换后的请求体。
  • 确认 llama.cpp 版本与 commit(Issue 中为 0.6.0-dev build 11457、commit 5ad1c5da0;复现环境为 master 61dbf4922)。
  • 确认启动参数:--jinja、--chat-template-file、--reasoning-effort 的取值。
  • 开启日志级别 -lv 5,观察转换后的请求是否含 reasoning_effort。
  • 确认所用 chat 模板接受哪些 effort 值(例如有的模板接受 high 并在 max 时报错)。
  • Issue 未涉及 Python、PyTorch、CUDA 或显卡版本,这些不是本问题的必要条件。

解决步骤

  1. 先做最小化对比:用同一模板发送 POST /v1/messages(带 thinking.type=adaptive 与 output_config.effort=low)和 POST /v1/chat/completions(带顶层 reasoning_effort=low),都以 -lv 5 运行,比较两者转换后请求与渲染 prompt 中的 EFFORT= 值。
  2. 若 /v1/messages 渲染为服务端默认值而 chat/completions 为 low,即确认命中本 Issue。
  3. 临时规避(可优先尝试):客户端或中间层改为调用 /v1/chat/completions 并显式传顶层 reasoning_effort;即需同时传 chat_template_kwargs.reasoning_effort 时,以顶层值为准。
  4. 根治方向:在 server_chat_convert_anthropic_to_oai() 中读取 output_config.effort 并写入 oai_body["reasoning_effort"],使其优先级与 OpenAI 路径一致(请求级覆盖 chat_template_kwargs),并补一个回归测试。此为 Issue 提出的方案,讨论中尚未合并修复。
  5. 修改后需额外考虑兼容性:定义 Anthropic effort 等级到模板可接受值的映射或回退策略,避免客户端传 max 等值时被模板拒绝。
  6. 升级到包含该修复的 llama.cpp 版本前,持续使用 chat/completions 路径作为变通。

验证方法

保持 effort.jinja 模板不变,重新发送 /v1/messages 请求(output_config.effort=low),在 -lv 5 日志中确认转换后的请求包含 "reasoning_effort":"low",且渲染 prompt 中显示 EFFORT=low 而非服务端默认的 medium。再同时传 chat_template_kwargs.reasoning_effort=high,确认顶层值仍优先为 low。

参考来源

ggml-org/llama.cpp #30564

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 35208

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注