Files
deepseek-harness/.agents/notes/implemented/simplification/2026-06-20-collapse-trace-only-session-events.zh.md
T

4.5 KiB
Raw Blame History

Agent Note: 将仅用于追踪的会话事实折叠进承载实际功能的事件

Status: implemented

English | 中文

问题

会话事件词汇中包含一些一等事件,它们不属于可回放的对话历史,在生产环境中几乎没有消费方。usage 已经作为模型流分片存在,之后循环又追加了一个独立的 usage 事件。error 与 turn/end { kind: 'error', message, code } 中的循环失败原因重复;ACP(Agent Client Protocol)结算读取轮次结束原因,而消息投影和 UI 投影都会跳过独立的 error 事件。

这些事件让规范的 transcript(文本记录)看起来比实际更适合作为遥测数据。它们增加了事件变体、不变式、测试、快照和持久化用例,但作为独立记录并不承载实际功能。它们携带的事实仍然有用:token 用量应当保留以供计费,错误的步骤编号也不应悄然消失。简化的方式是将这些事实折叠进消费方本已必须理解的邻近事件,而非减少记录的信息量。

决策

仅在信息已被保留、无需并行记录的情况下,移除独立的、仅用于追踪的事件:

  • 成功步骤的 usage 折叠进匹配的 assistant/message(assistant/message { turn, step, content, usage? }),使组装好的模型输出与其计费信息一同传递。
  • 失败或中止的步骤如果有 usage 但没有 assistant 内容,则将 usage 放在一个空内容的 assistant/message 上(下方实现说明给出了无信息丢失的证明)——不会有已持久化的 usage 分片无处安放。
  • 独立 error 事件中的步骤编号折叠进 turn/end.reason(当 kind: 'error' 时:{ kind: 'error', step, message, code? })——turn/end 是 ACP 和恢复机制已经消费的持久轮次结果。
  • agent/error 与日志保留用于实时诊断;turn/end 之后不再有第二条会话日志错误记录。

用户对话日志包含渲染、恢复、审计和计费所需的全部信息,消费方无需协调重复的追踪行。

曾考虑的替代方案

保留独立行作为遥测——这些事件让规范 transcript 看起来比实际更适合作为遥测数据,代价是增加了事件变体、不变式、测试、快照和持久化用例,却没有任何消费方使用。如果分析需求真正出现,正确的形态是投影辅助工具或带有独立保留策略的专用遥测存储,而非对话日志中的重复追踪行。

验证

SessionEventMap 不再包含独立的 usage 或 error;agent loop(智能体循环)不再追加独立的 usage 事件,并通过 turn/end { kind: 'error', step, message, code? } 持久记录失败;ACP 快照和持久化测试断言不存在仅用于追踪的行;已录制的 fixture(测试前置数据)使用新事件形状,会话格式版本固定为 0(后端按预发布格式策略拒绝任何版本非 0 的已存储日志);文档说明了 token 用量和运行时错误的观测位置。

后果

消费方不能再从规范日志中筛选独立的 usage 或步骤级 error 行,而必须从承载这些信息的助手消息或失败事件中读取这些事实。只有在实现 PR(Pull Request)证明相同事实仍然存在的前提下,这才是合理的简化;否则独立事件应予保留。

实现说明

按提案落地,但有一处范围细化(遵循 AGENTS.md 所述「Agent Note 是提案,而非绝对真理」):

  • 空内容 assistant/message 承载 usage,无数据丢失。 提案要求的证明(不会有已持久化的 usage 分片无处安放)落在 max-tokens 路径上:一个被截断的步骤有 usage 但内容为空(例如只有一个被丢弃的工具调用),以前会发出独立的 usage。现在它记录一个空内容的 assistant/message { content: [], usage }。为防止这向提供方 transcript 注入一个多余的无内容 assistant 轮次,deriveMessages() 跳过空内容的 assistant/message 事件。回归测试断言 usage 仍有记录,且派生历史未被破坏。

格式版本。 此变更影响已持久化的事件,但预发布会话格式仍固定为 0,拒绝任何其他版本且不做迁移。dsh-session 拥有写入方和加载校验使用的常量。单调递增的格式版本从首次正式发布开始。

Usage 现在通过 assistant/message.usage 观测;运行时错误的步骤编号通过 turn/end.reason(当 kind: 'error' 时)观测。agent/error 与日志用于实时诊断,保持不变。