机制分析
从保存请求,到送达反馈
任务是查询杭州天气,判断是否需要带伞。第一次调用时,模型尚无天气数据,先提出 get_weather(杭州)。Harness 把这份输出追加为 assistant 消息,原有规则和用户任务继续保留。天气服务返回后,结果通过调用编号与请求对应,再追加为 tool 消息。
装配第二次输入时,程序按顺序取出规则、用户任务、工具请求和工具反馈,另外附上 tools 定义。这里 tools 是独立字段,不是消息列表中的第五条消息;角色也可以多次出现,阶梯只是本例的时间顺序。
调用编号的作用是关联。请求写着 call_1,回执却指向另一个编号时,宿主不能把它随意接到当前请求。这个判断不依赖返回文字是否“看起来像天气”,而依赖结构化身份是否配对。
为什么要同时检查历史与输入快照?
演示里有一个更隐蔽的故障:消息架上已经保存四条消息,复制台却只装入前三条。日志里的天气结果确实存在,但这一轮副本没有它。若只检查“历史条数为4”,就会误以为模型已经拥有天气证据。
| 检查对象 | 能够证明什么 |
|---|---|
| 工具原始结果 | 执行器返回了什么,还不能证明结果已送给模型 |
| 宿主消息历史 | 请求与回执是否保存、关联是否正确 |
| 本轮输入快照 | 这次调用实际组织了哪些消息和工具定义 |
| 模型后续输出 | 模型生成了什么,还需与输入证据对照 |
工程取舍
把上下文组织当作可检查的程序行为
每次携带历史,还是让服务端维护会话?
显式组织消息便于记录请求快照,也便于定位某条反馈是否遗漏,但宿主要负责截断、压缩和顺序管理。服务端会话能减少客户端的组织工作,却仍需弄清哪些历史会进入当前有效上下文。无论采用哪条路线,“完整逻辑上下文”都不意味着网络上必须每次重复传输全部历史。
遇到编号错配,补写还是停止?
静默替换编号可能把另一项任务的结果接进来。本例选择阻止追加,要求明确恢复正确回执。生产系统可以将异常结果隔离,保留来源和失败原因,再重试或人工核对;自动修复也应依赖可靠映射,不能按返回内容相似就猜测归属。
为了省输入,能删掉哪些消息?
历史整理必须考虑当前接口的消息约束,以及请求、结果之间的依赖。保留工具反馈却删掉关联请求,或者留下请求却省略必要结果,都可能破坏输入结构。更稳妥的做法是把一组调用关系作为整体处理,并在发送前检查结构完整性,再判断还需保留哪些任务背景。
落到实现
记录“已保存”之外的状态
排障记录最好能够区分原始返回、历史追加、输入装配和调用送达。涉及敏感信息时,需要按权限保存必要内容或摘要,避免为了调试无差别留存所有原文。关键是能够回答“模型这一轮有机会看到什么”,而不是只得到一个笼统的成功标志。
本页的消息形状对应特定 API 风格,不能直接当作所有模型接口的统一报文。文件架和复制台表达宿主的组织行为;天气、请求和答复采用固定样例,不代表真实模型必然遵从。
当历史记录与模型表现不一致,先核对本轮输入。数据存在于系统里,与数据进入这次推理,是两份不同的证据。