Skip to content

[BUG] Responses API:tools 含 web_search 声明时,deepseek 将 function_call_output 误读为用户消息,多轮工具对话可形成死循环 #26

Description

@nightwhite

环境

  • 接口:POST https://ark.cn-beijing.volces.com/api/v3/responses(Responses API)
  • 模型:deepseek-v4-1-flash-260910
  • 时间:2026-09-21,stream=true / false 均可复现
  • 客户端场景:OpenAI Codex CLI(多轮工具调用 + 工具清单含 {"type":"web_search"}

现象

当请求 tools 数组中包含 web_search 类型工具声明时,携带 function_call / function_call_output 历史的多轮请求中,模型会function_call_output(工具执行结果)误读为用户新发来的消息,从而在「本应总结收尾」的轮次继续发起工具调用。

模型 reasoning summary 中可直接看到误读证据(实测原话):

"The user just gave the current time. This is a final reply — ..."
"User provided current time. Probably expects acknowledgment."

(工具输出里带有 timestamp 字段,模型把它当成了用户主动提供时间。)

在「每次回复前需先调用 curl 发通知」这类系统指令下,会形成自持死循环:发通知 → 收到工具结果 → 误读为用户消息 → 再发通知 → ……实测单次对话最多连续发起 49 次相同的工具调用。

对照实验(每组合独立多次请求统计)

请求工具清单 模型继续发工具调用(异常) 正常输出文本
web_search(真实完整上下文 ≈20k token、14 个工具) 25 / 26 1
web_search(最小载荷,见下) 2 / 3 1
不含 web_search(其余完全相同) 0 / 17 17

补充:

  • temperature=0 无改善:含 web_search 仍 4/4 异常,不含 0/4 异常——非采样抖动,是确定性的渲染/模板问题
  • 工具清单仅保留 exec_command + web_search 两个时依然 4/4 异常,与 function 工具数量无关
  • 单独验证:该模型在 web_search 工具下能正常发起 web_search_call(搜索能力本身工作正常),问题只出在多轮工具对话的渲染

最小复现

curl -N https://ark.cn-beijing.volces.com/api/v3/responses \
  -H "Authorization: Bearer $ARK_API_KEY" \
  -H "Content-Type: application/json" \
  -d @repro.json

repro.json(stream 可改 false):

{
  "model": "deepseek-v4-1-flash-260910",
  "instructions": "# 通知规则\n- 每次最终回复用户前,必须先执行 curl 通知:\n  curl \"https://notify.example.com/YOUR_SUMMARY_HERE\"\n- 总结里禁止空格和 /。",
  "input": [
    {"type": "message", "role": "user", "content": [{"type": "input_text", "text": "你好"}]},
    {"type": "function_call", "call_id": "call_0", "name": "exec_command", "arguments": "{\"cmd\": \"curl -s \\\"https://notify.example.com/greeted\\\" ; echo\"}"},
    {"type": "function_call_output", "call_id": "call_0", "output": "Chunk ID: aaaa\nWall time: 0.21 seconds\nProcess exited with code 0\nOriginal token count: 14\nOutput:\n{\"code\":200,\"message\":\"success\",\"timestamp\":1789934739}\n"}
  ],
  "tools": [
    {"type": "function", "name": "exec_command", "description": "Runs a shell command.", "strict": false, "parameters": {"type": "object", "properties": {"cmd": {"type": "string", "description": "Shell command to execute."}}, "required": ["cmd"], "additionalProperties": false}},
    {"type": "web_search"}
  ],
  "tool_choice": "auto",
  "parallel_tool_calls": false,
  "store": false,
  "stream": true
}

预期:模型识别出 function_call_output 是工具结果,直接输出文本回复用户。

实际(异常时):模型输出新的 function_call(再次执行 curl 通知),reasoning 中出现把工具结果当用户消息的表述。

验证方法:把 tools 中的 {"type":"web_search"} 删掉再发,异常消失(0/17);仅保留这一行差异反复对照即可稳定观察。

期望修复

web_search 工具声明存在时,function_call_output 应被渲染为工具结果(tool role),而不是被并入用户消息。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions