DSH 每轮固定 30 秒延迟
DeepSeek Harness 每轮固定 30 秒:Tool Call 调度分析
- 作者
- DeepSeekAgent.io 编辑部
- 发布
- 更新
DeepSeek Harness 社区出现了一类很有辨识度的延迟:模型通常在 3~5 秒内已经生成回复,涉及工具调用时,工具却总要等到本轮开始约 30 秒后才执行;即使本轮没有工具,turn/end 也会在接近 30 秒时才出现。延迟集中在每轮的第一个动作,后续工具调用又恢复正常。
这不是普通的“模型慢”。固定时长、稳定复现和首动作集中三个特征,更接近流式响应结束信号、用量结算或调度器兜底计时器之间的同步问题。
事件时间线说明了什么
社区记录中的一个工具轮次具有如下顺序:
- 约 6.04 秒:收到
assistant/message与tool/call; - 约 30.05 秒:出现
job/registered; - 约 30.59 秒:得到
tool/result。
另一个纯文本轮次在约 1.76 秒已经完成文本和 step/end,但 turn/end 仍延迟到约 30.03 秒。两条时间线共同说明,模型输出本身已经到达,等待发生在“本轮何时被视为可继续或可结束”这一层。
如果只是 IM 轮询、网络往返或某个工具启动缓慢,纯文本轮次不应出现同样的固定尾部等待;如果只是模型推理慢,assistant/message 也不会提前二十多秒到达。
为什么固定 30 秒值得优先排查兜底路径
随机延迟通常来自网络拥塞、排队或机器负载。接近常数的 30 秒更像超时配置。可能的路径包括:
- Provider 已发送文本或 Tool Call,却没有及时发送 DSH 期望的最终结束事件;
- 使用量或响应尾部仍在等待,调度器不敢立即提交首个工具任务;
- 某个适配层把“已收到 Tool Call”和“响应流已安全关闭”绑定在一起;
- 30 秒兜底计时器到期后,系统才补发完成信号并推进状态机。
这些仍是由事件序列推导出的诊断方向,不能替代具体版本的调用栈。最有价值的下一步,是把 Provider 原始流事件与 DSH 内部事件放在同一时间轴上,而不是继续笼统测试“网络快不快”。
一套可复现的排查方法
先建立三个最小样本:纯文本回复、一次简单工具调用、连续两次工具调用。每个样本记录以下时间点:
- 请求发出;
- 首个模型 Token;
- Tool Call 块到达;
- Provider 结束原因与用量到达;
step/end、turn/end;job/registered、tool/result。
然后依次对照 Web UI 与 IM、不同 Provider、是否启用插件、是否启用推理输出。只改一个变量。如果所有入口都在第一个动作等待 30 秒,问题更可能位于共用的模型适配或 Turn 调度层;如果只有一个 Provider 触发,应重点检查它的结束事件映射。
社区案例已经排除了若干直觉原因:IM 轮询、Session 日志上传、记忆插件、Anthropic SDK 的简单 drain,以及常见的 streamIdleTimeout 设置都无法解释全部现象。排查应保留这些反证,避免重复绕路。
对用户体验和成本的影响
固定等待不会直接增加模型输出 Token,却会放大整个 Agent 流程的墙钟时间。需要用户确认、文件读取或搜索的短任务,每轮多 30 秒,很快就从十几秒变成几分钟。自动化任务也可能因外层超时提前失败,随后重试并产生额外调用。
在根因修复前,可以减少不必要的轮次:把明确目标、输入文件和验收条件一次给全;允许并行读取时合并工具请求;为自动化设置足够的总时限,同时限制重试次数。不要通过无限增大超时掩盖事件状态机问题。
这篇分析也可与多步工具调用中的 redacted_thinking 中断对照阅读:前者是完成信号推迟,后者是响应块类型未被适配器接受。两者都会表现为 Agent 卡住,但事件时间线完全不同。
参考资料
常见问题
模型很快返回文字,为什么工具仍没有执行?
文字到达不等于本轮响应流已经被适配器确认结束。应检查结束原因、用量事件、turn/end 与 job/registered 的先后关系。
把工具超时调大能解决吗?
通常不能。案例中的等待发生在工具注册之前,工具自身还没有开始运行。
为什么第二个工具调用可能很快?
社区复现显示延迟主要集中在每轮第一个动作,说明首个调度门槛或响应收尾路径比工具执行器本身更可疑。