JianFeeeee
4ab888ce06
fix(agent): 发送前自检 tool_call 配对 —— 止损并定位上游 400
## 为什么还要修(前面两个修复都不够)
今天已经修了两处:
263b651 并发批次 stepToolBatch 漏记 ToolCalls
0ed3c89 L1 预算截断切开 tool 配对
并用生产 context.json 验证历史已干净:
53 个事件,0 个"结果多于调用"的帧
但 A2A **新会话**(a2a_1793778753015670668)仍然报同一个 400:
An assistant message with 'tool_calls' must be followed by tool messages
responding to each 'tool_call_id'. (insufficient tool messages following...)
同时日志显示 `ratio=0.28`(远低于 1.25 阈值)、`skip oversized frame` 计数 0
⇒ 既不是裁剪,也不是预算截断。
## 定位:问题在 f.Msgs,不在 L1 历史
`f.Msgs` 是**多条路径**拼出来的:
prepare 重建 buildMessages
中断恢复 rebaseFramePrefix(重建 prefix + 接回 tail)
批末附加 flushBatchAttachments
占位补全 dropContinuationPlaceholders / continuation
任何一条漏掉配对,最终都表现为同一个 400,而协议**不告诉你是哪条 call**。
所以把自检放在唯一一次组装 provider 请求的位置(stepLLM,task.go:750),
而不是散在各条路径上。
## 为什么剔 call 而不是补占位
补一条 "tool result: (missing)" 会让模型看到它**从未调用过**的结果,
可能据此继续推理 —— 那是编造事实。剔掉 call 只是少了一次尝试,
模型可以重来,语义安全。
被剔的 call 记录工具名与数量,日志里能看出是哪一轮出的问题。
## 判据(5 条,3 次变异全部实测变红)
DropsCallWithoutResult 主方向:没有结果的 call 必须剔
变异:直接 return msgs ⇒ "★ 未配对的 call c2 仍在消息里 —— 上游必然 400"
DropsOrphanToolResult 反方向:找不到 call 的孤立 tool 必须删
变异:删掉第二遍循环 ⇒ 红
DropsEmptyAssistantShell call 全剔且正文为空 ⇒ 整条删
变异:去掉该分支 ⇒ 红
KeepsContentWhenAllCallsDropped
call 全剔但**有正文**时保留正文(那是模型说的话,不能丢)
LeavesValidSequenceUntouched
合法序列必须逐条不变 —— 修正逻辑不能引入新问题
只测一个方向会放过另一半失配,所以两个方向都钉。
## 验证
go build ./... PASS
go vet ./... PASS
gofmt -l 干净
go test ./... -count=1 62 包全过,0 FAIL
干净检出(worktree) build + TestDropUnpaired 全绿
## 下一步
这条是**止损 + 定位**,不是根因修复。部署后如果日志里出现
"dropped N unpaired tool message(s)",那 N 与工具名就指向真正漏配对的
那条路径,据此再修上游。
2026-11-04 15:58:22 +08:00
..
2026-11-04 08:35:23 +08:00
2026-10-29 23:53:48 +08:00
2026-10-29 23:53:48 +08:00
2026-10-29 23:53:48 +08:00
2026-11-04 11:57:48 +08:00
2026-10-29 23:53:48 +08:00
2026-10-22 20:49:44 +08:00
2026-10-29 23:53:48 +08:00
2026-10-29 23:53:48 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 08:56:47 +08:00
2026-10-21 12:17:19 +08:00
2026-10-17 19:18:24 +08:00
2026-11-04 08:21:15 +08:00
2026-10-29 23:53:48 +08:00
2026-10-21 12:17:19 +08:00
2026-11-04 11:57:48 +08:00
2026-10-27 15:53:49 +08:00
2026-10-29 23:53:48 +08:00
2026-10-29 23:53:48 +08:00
2026-10-26 20:55:25 +08:00
2026-10-26 20:55:25 +08:00
2026-11-04 11:57:48 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-11-04 11:57:48 +08:00
2026-11-04 11:57:48 +08:00
2026-11-03 08:46:46 +08:00
2026-11-04 11:57:48 +08:00
2026-10-21 12:17:19 +08:00
2026-10-29 23:53:48 +08:00
2026-10-29 23:53:48 +08:00
2026-11-04 11:57:48 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 08:21:15 +08:00
2026-10-29 23:53:48 +08:00
2026-10-25 13:37:29 +08:00
2026-10-25 21:39:12 +08:00
2026-10-30 17:00:47 +08:00
2026-10-25 13:48:35 +08:00
2026-11-03 14:37:53 +08:00
2026-11-04 11:57:48 +08:00
2026-10-29 23:53:48 +08:00
2026-11-04 11:57:48 +08:00
2026-11-04 11:57:48 +08:00
2026-10-29 23:53:48 +08:00
2026-10-25 15:55:26 +08:00
2026-10-25 15:55:26 +08:00
2026-10-29 23:53:48 +08:00
2026-10-25 15:55:26 +08:00
2026-11-04 11:57:48 +08:00
2026-10-29 23:53:48 +08:00
2026-10-21 12:17:19 +08:00
2026-10-29 23:53:48 +08:00
2026-10-29 23:53:48 +08:00
2026-10-26 20:55:25 +08:00
2026-10-27 12:16:06 +08:00
2026-11-04 15:58:22 +08:00
2026-11-04 15:58:22 +08:00
2026-10-21 12:17:19 +08:00
2026-10-27 15:40:43 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 08:21:15 +08:00
2026-10-21 12:17:19 +08:00
2026-10-25 17:03:09 +08:00
2026-10-26 20:55:25 +08:00
2026-11-04 11:57:48 +08:00
2026-10-22 22:42:02 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 08:21:15 +08:00
2026-11-02 21:54:35 +08:00
2026-11-02 21:54:35 +08:00
2026-11-03 14:37:53 +08:00
2026-10-21 12:17:19 +08:00
2026-11-04 11:57:48 +08:00
2026-10-26 20:55:25 +08:00
2026-10-21 12:17:19 +08:00
2026-09-19 16:49:16 +08:00
2026-10-29 23:53:48 +08:00
2026-10-30 17:00:47 +08:00
2026-10-21 12:17:19 +08:00
2026-11-04 14:15:33 +08:00
2026-10-29 23:53:48 +08:00
2026-10-26 20:55:25 +08:00
2026-10-29 23:53:48 +08:00
2026-11-04 11:23:05 +08:00
2026-11-04 11:23:05 +08:00
2026-10-23 15:51:02 +08:00
2026-10-27 11:49:26 +08:00
2026-11-04 08:21:15 +08:00
2026-10-23 15:51:02 +08:00
2026-10-21 12:17:19 +08:00
2026-10-06 09:22:12 +08:00
2026-10-29 23:53:48 +08:00
2026-10-31 11:39:13 +08:00
2026-10-23 15:51:02 +08:00
2026-11-04 14:15:33 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 11:57:48 +08:00
2026-10-31 06:35:32 +08:00
2026-11-04 11:23:05 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 08:21:15 +08:00
2026-10-30 17:00:47 +08:00
2026-10-30 17:00:47 +08:00
2026-10-31 19:16:58 +08:00
2026-10-30 17:00:47 +08:00
2026-10-30 17:00:47 +08:00
2026-11-04 08:21:15 +08:00
2026-10-31 10:03:43 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 11:23:05 +08:00
2026-10-25 18:25:37 +08:00
2026-10-29 23:53:48 +08:00
2026-10-21 12:17:19 +08:00
2026-10-23 15:51:02 +08:00
2026-09-13 08:59:15 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-26 20:55:25 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-09-13 07:00:51 +08:00
2026-10-24 14:34:24 +08:00
2026-10-21 12:17:19 +08:00
2026-10-27 15:58:55 +08:00
2026-11-04 11:57:48 +08:00
2026-11-04 11:57:48 +08:00
2026-11-04 11:57:48 +08:00
2026-11-03 09:20:04 +08:00
2026-10-31 07:14:09 +08:00
2026-11-04 11:57:48 +08:00
2026-10-29 23:53:48 +08:00
2026-10-29 23:53:48 +08:00
2026-10-29 23:53:48 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-11-04 08:35:23 +08:00
2026-10-26 20:55:25 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-11-04 11:57:48 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-29 23:53:48 +08:00
2026-11-03 08:46:46 +08:00
2026-10-21 12:17:19 +08:00
2026-10-25 10:10:21 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-11-04 15:58:22 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-18 06:38:51 +08:00
2026-10-29 23:53:48 +08:00
2026-11-04 14:02:58 +08:00
2026-11-04 08:21:15 +08:00
2026-10-23 15:51:02 +08:00
2026-10-29 23:53:48 +08:00
2026-10-26 20:55:25 +08:00
2026-11-04 11:57:48 +08:00
2026-11-04 11:57:48 +08:00
2026-11-04 11:57:48 +08:00
2026-10-21 12:17:19 +08:00
2026-10-29 23:53:48 +08:00
2026-10-29 23:53:48 +08:00
2026-10-23 15:51:02 +08:00
2026-10-21 12:17:19 +08:00
2026-10-05 11:25:20 +08:00
2026-11-04 11:57:48 +08:00
2026-10-25 20:16:16 +08:00
2026-10-25 20:16:16 +08:00
2026-11-04 08:21:15 +08:00
2026-10-26 20:55:25 +08:00
2026-10-29 23:53:48 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-10-21 12:17:19 +08:00
2026-11-04 08:21:15 +08:00
2026-11-04 08:35:23 +08:00
2026-10-21 12:17:19 +08:00