跳到主要内容

会话记录记住了提交信息遗忘的内容

· 阅读需 11 分钟
Tian Pan
Software Engineer

就在此时,你的笔记本电脑里的某个角落正存放着你的团队有史以来最详尽的工程决策记录,却没有任何人读过其中的一个字。每一个智能体会话 —— 无论是每一次 Claude Code 的运行、每一次 Cursor 对话,还是持续数小时的重构历程 —— 都会被记录成一份转录文本(transcript)。它包含了尝试过又被放弃的三种方案、导致产生这种丑陋临时方案的约束条件,以及你否决模型建议的时刻及其原因。然后会话结束,PR 带着一行 commit message 被合并,所有这些上下文都进入了一个永远不会被打开的 JSONL 文件。

以前,我们丢失这些信息是“理所当然”的。某个设计选择背后的推导过程只存在于某个人的脑子里,随着时间推移而淡忘,并在他们换工作时彻底流失。当时没有什么可以保存的,因为根本没有记录下来。这种借口已经不复存在了。现在的推导过程正被逐字逐句地记录下来,带有时间戳,机器可读 —— 而我们却将其视为随手可弃的废气。

Commit message 是对会话的有损压缩

想想在一个非琐碎的智能体会话中实际发生了什么。你要求进行一项更改。智能体提出了一种方案;你拒绝了它,因为它会破坏智能体不知道的内部消费者。它提出了第二种方案;执行到一半时,一个测试失败揭示了某个依赖项锁死了一个旧版 API。最后,你采用了第三种方案,这种方案你们谁都不会在白纸一张时选中,但它是唯一能同时兼容这两个约束条件的。两个小时的探索,三个死胡同,发现了两个约束。

git 中留下了什么?一个 diff 和一条消息:“重构身份验证中间件以支持令牌轮换”。diff 展示了做了什么更改。消息暗示了为什么。除此之外的所有内容 —— 那些被否决的替代方案、新发现的约束、让 diff 中那些丑陋部分显得合理的推导过程 —— 都被压缩掉了。

软件开发向来如此,这就是为什么会出现架构决策记录(ADR)。但 ADR 的运作粒度是架构级的:为什么我们选择 Postgres 而不是 Mongo,为什么我们拆分了服务。而那些在六个月后引发“为什么这行代码是这样的?”疑问的决策,实际上是实现级别的 —— 为什么这个重试循环有一个特殊情况,为什么这个函数接收一个看似冗余的参数。这些决策的数量是架构决策的十倍,没人会为每一个决策写 ADR,而它们恰恰是智能体转录文本可以免费捕获的内容。

被压缩掉的信息规模也发生了变化。Anthropic 自身对 Claude Code 使用情况的研究发现,典型的用户提示会触发大约 10 个智能体动作和约 2400 个词的输出,其中用户承担了约 70% 的计划决策,而智能体处理了约 80% 的执行决策。把这一数据乘以一个团队每周提交的数十个智能体辅助 PR,你就会得到一个足以让你的维基百科(wiki)相形见绌的决策日志 —— 而目前这些日志正烂在 ~/.claude/ 目录下。

里面到底有什么,以及谁需要它

我们需要具体看看转录文本中包含哪些其他产物所没有的内容,因为“日志”这个词并不能完全体现其价值:

  • 被否决的替代方案。 尝试过又退回的方案,以及每个方案失败的具体原因。这是工程知识中最具价值且最少被记录的类别 —— 标记了雷区分布的地图。
  • 新发现的约束。 “预发布环境没有那个环境变量。”“这个库在 Bun 下会报错。”约束条件在会话中间以错误消息和更正的形式出现,被规避后,便再也不会出现在下一个人会看的地方。
  • 人工干预。 每一个你叫停智能体并说“不,别那样做,因为……”的地方,都是一段被明确表达出来的内部隐性知识(tribal knowledge)—— 往往是第一次被表达,因为你不得不向一个缺乏同事所具备的上下文的机器进行解释。
  • 智能体自身的辩护。 现代的转录文本包含推理痕迹:模型为什么选择一种设计方案而非另一种。当理由错误时,它是调试素材。当理由正确时,它就是没人需要动笔写的文档。

现在考虑一下谁能用到这些。接手代码并想知道为什么重试逻辑如此奇怪的工程师 —— 如今他们运行 git blame,发现了一个解释不了任何问题的 commit message,然后要么去打断别人,要么通过痛苦的方式重新发现那个约束。入职某个子系统的新员工 —— 如今他们得到的是过时的 wiki 页面,而转录文本则保存着该子系统最后五个功能实际构建过程的可回放记录:人们运行了哪些命令、他们信任哪些测试、他们在代码库的哪些部分小心翼翼。

或者是准备尝试某项迁移的工程师,而这项迁移在三个月前已经有人尝试过并放弃了。今天,他们根本无从得知那次尝试曾经发生过,因为放弃的工作在 git 中完全没有留下痕迹。

最后一种情况值得强调:转录文本是未产生 commit 的工作的唯一记录。那些无疾而终的实验、构建了 80% 然后被还原的方案 —— 在以 git 为中心的世界观里,这些从未存在过。而在转录文本中,它们被完整地记录了下来,包括失败分析。

挖掘成本现已降低,工具正在涌现

会话日志在历史上之所以无人问津,原因与日志聚合出现之前的生产日志相同:没有摘要层,且原始数据量巨大。长达数小时的 Agent 会话会产生数 MB 的 JSONL 数据,其中交织着工具调用、文件转储和推理过程。没有人会为了消遣去浏览这些内容。

但我们现在恰好拥有了将海量文本压缩为可搜索摘要的绝佳工具——即最初生成这些对话记录的同类模型。这种模式非常直观:通过流水线摄取每个会话,提取结构化记录(尝试了什么、决定了什么、失败了什么以及原因、发现了哪些约束条件),并为其建立搜索索引。特定时间点的摘要变成了可浏览的工程日志;结构化记录则变成了你可以用自然语言查询的语料库:“有人试过升级支付 SDK 吗?”——你得到的不仅是答案,还有发生该操作的实际会话。

早期工具已经出现。Simon Willison 开发了提取并将 Claude Code 对话记录发布为可分享 HTML 的工具,正是因为(用他的话来说)这些记录捕捉了提问内容、模型建议、决策过程以及模型的辩护理由——这些上下文以前即便存在,也只散落在问题追踪系统中。像 engineering-notebook 这样的开源项目可以摄取 Claude Code 和 Codex 的会话日志,并生成由 LLM 编写的带有全文搜索功能的每日日志。记忆层项目将对话提炼为精选的长期记忆,供未来的 Agent 会话参考。而像 Lore 这样的研究提案则更进一步,认为来自会话的结构化知识应该流回 git 层本身,这样阅读历史的 Agent 在看到代码差异(diff)的同时,也能理解其背后的推理逻辑。

注意最后这个想法中的飞轮效应。挖掘对话记录的第一消费者根本不是人类,而是下一个 Agent 会话。一个能够搜索先前记录的 Agent 在开始工作时,就已经知道预发布环境缺少那个环境变量、知道升级支付 SDK 的尝试及其失败原因、知道团队更倾向于使用这个测试命令。你对 Agent 做的每一次纠正,都会变成以后在任何席位上都不必再做的纠正。团队实际上坐拥一个完全针对自身工作流的私有、特定领域的训练语料库,却从未利用过它。

那个大家都不愿讨论的部分

上述愿景之所以让一些工程师感到不安,其原因并非技术性的。一个可搜索的所有 Agent 会话存档,也是一个可搜索的“每个人实际如何工作”的存档。它记录了谁在挣扎,谁没有;谁的指令清晰,谁的模糊;谁在周四下午陷入了一个队友十分钟就能搞定的 Bug 循环。那些将对话记录视为专业能力信号的研究——专家主导的会话在每条指令下产生的自主工作量是新手主导的两倍以上——换一种读法,其实就是一份根据对话记录对工程师进行排名的蓝图。

假装这种张力不存在,会导致团队背着员工偷偷挖掘对话记录,这既会破坏信任,在越来越多司法管辖区内还会引发合规问题。一个诚实的版本应该具备以下属性:

  • 挖掘决策,而非表现。 流水线提取的是“学到了什么”——约束条件、被否决的方案、结果——而不是针对个人的指标。这是一个你需要写下来的政策选择,而不是默认的假设。
  • 有约束力的保留策略。 原始对话记录是敏感层;提炼后的决策记录是持久层。永久保留提炼内容,并按计划使原始会话过期,就像处理生产日志与衍生分析数据的方式一样。“不用于训练”并不意味着“不保留”,而你的供应商的保留期与你的内部保留期是两个不同的问题——大多数团队从未对两者进行过审计。
  • 贡献应该是可见且边缘自愿的。 你在凌晨两点调试一些令人尴尬的代码的会话,与发现了一个关键约束的会话是不同的。允许人们将会话标记为私有;虽然你会损失一点覆盖率,但能维持那份让存档变得有价值的信任。

做对这一点的团队将拥有真正不公平的优势:能够产生复利效应的制度记忆。做错的团队要么无法建立存档——因为工程师会绕过他们不信任的工具;要么会让存档变成一个监控系统,从而毒害那些能够产出有价值内容的工程文化。

从一个你目前无法回答的问题开始

你不需要一个完整的平台才能开始。找一个你的团队目前通过打断资深工程师来回答的问题——“为什么部署脚本要对那个服务进行特殊处理?”——然后看看答案是否就在某人的会话历史中。通常都在。这个演示足以说服众人。

然后自动化最小的有用循环:运行一个夜间任务,将当天的会话总结为结构化决策记录(尝试过、决定了、失败了、发现的),并将它们存放在可搜索的地方。在构建任何面向人类的 UI 之前,先将这些提炼内容作为上下文喂给你的 Agent;Agent 会比人类更忠实地使用它,而一旦 Agent 开始表现出它们在当前会话中从未被告知过的知识时,人类也会紧随其后。

提交历史记录了我们构建了什么。对话记录则记录了我们在构建过程中的理解——包括我们理解了之后选择不构建的所有内容。在整个软件工程史上,第二种存档从未存在过。现在,它每天都在你团队的每台笔记本电脑上自动生成。剩下的唯一问题是,你是否会在需要它之前去阅读它。

References:Let's stay in touch and Follow me for more thoughts and updates