Skip to content
kefan.life
Go back

给仓库装上记忆:当人不再拥有全部上下文

这一周折腾 AI coding,我不断撞上同一个问题:每次 Agent 接手新任务,我都要重新解释这个项目为什么会变成今天这样。

代码、测试和提交记录都在仓库里,它还是会缺掉最影响判断的那部分信息。某个边界为什么划在这里,上次为什么放弃另一条路,哪些做法看着合理却踩过坑,哪些技术债暂时不能动。这些事情散落在聊天记录、PR 讨论、外部文档和我的脑子里。Agent 只看得到结果,但不知道 Why,只好从几句口头交代猜我的想法。等它猜错了,我再愤怒纠正“你在干什么.jpg”。

我累,AI 也贵。

我想要的效果其实很朴素:让 Agent 替我编程,而不是只是完成编程。后来读到 OpenAI 的 Harness engineering 和 yage 的 Context Infrastructure,我才发现大家处理的是同一类问题。模型已经能完成不少复杂任务,实际效果却越来越依赖它进入任务时拿到了什么上下文,以及这些上下文能否指导后续行动。

于是我开始给仓库加一套结构化记忆,最后做成了 doc-flow

Git 记得改住变更,仓库还要记得为什么

Git 可以回看代码如何变化,却很少保存一次选择背后的完整理由。commit message 会说明改了什么,偶尔也会解释为什么改,但项目里的约束、放弃方案、现实 trade-off 和经验判断,通常没有稳定的去处。

这些信息全塞进 AGENTS.md 也解决不了问题。入口文件越写越长,Agent 每次进入仓库都要先吞下一整套规则。真正和当前任务有关的内容反而被埋住了。上下文窗口容量再大,也不等于每一段内容都能被同样有效地利用。

我希望项目记忆满足几个条件。它应该跟仓库一起存活,可以被 Codex、Claude Code 等不同工具读取;新项目和已有项目都能接入;Agent 做事时会留下现场记录,任务结束后再把少量长期有效的结论沉淀下来。以后换一个人或一个 Agent 接手,先读仓库就能理解项目,而不是等待原作者重新口述一遍历史。

麻烦在于,记录得越积极,仓库越容易变成我家的储藏室:什么都有,什么都找不到。doc-flow 最重要的约束因此落在“什么不要长期保存”上。

两层文档,把任务现场和长期判断分开

doc-flow 只保留两层内容。

这两层分开以后,中间过程不必急着写进长期文档。任务现场允许杂乱,durable docs 则需要证据和筛选。只有那些经过验证、以后还会改变选择的结论,才从 worklog 进入长期记忆。

我最初以为一个 bootstrap 就够了,做下去才发现 fresh repo 和 existing repo 面临的风险完全不同。空仓库可以直接搭脚手架,已有历史的仓库往往已经有自己的文档、约定和事实来源,接入时最怕新系统篡位。最后我把入口收敛成四个 mode:

另一个容易失控的地方是 AGENTS.md。我一开始想把自动化规则都放进去,后来发现这会同时制造重复和上下文污染。最后只留下一个 pointer:去看 docs/index.yaml,需要维护项目记忆时使用 doc-flow。具体怎么 work,由 skill 自己说明。

入口负责路由,文档索引负责指路,skill 负责行为。每一层只保存自己必须知道的内容。

另外,这背后还有一个技术前提:使用的模型经过后训练,具备主动、渐进式检索的能力。

Trellis 让我看清了另一种控制强度

后来我发现了 Trellis。第一眼看过去,它和 doc-flow 很像:同样使用很短的 AGENTS.md 做路由,同样强调 repo-local context,也都希望 Agent 的工作能留下可复用的记录。

我当时查看它的实现时,真正的控制面在 .trellis/ 里。里面有 spec、tasks、workspace journal 和 workflow,还会为不同工具生成 commands、skills 与 hooks。以 Claude 为例,/trellis:* 命令按需调用,session-start hook 则会在固定阶段注入 workflow、spec index、当前任务状态和 start 指令。

我起初看到十几个命令文件,下意识地觉得这套系统开始变重了。仔细看完才发现,它们没有在每次会话里一起进入上下文。高频注入主要由 session-start hook 完成,其余命令只在需要时加载。它建立的是一个范围明确的反馈回路:会话开始时读取 workflow、spec 和任务状态,后续再通过对应命令维护这些记录。固定事件提高了触发的确定性,比单靠 instruction 要求 Agent 自觉执行更可靠。

不过目前为止我没有发现什么 benchmark 能证明“注入更多指令、拆出更多命令”,模型效果一定更好。能支持它的主要还是更广义的 harness 经验。OpenAI 的 Harness engineering 和 Anthropic 的 Effective Harnesses for Long-Running Agents 都在强调外部脚手架、任务状态和 repo-local context 的价值;但另一方面,像 Lost in the Middle 这类长上下文研究也在提醒我们,更多上下文不等于更有效的上下文。上下文窗口不是无限垃圾桶,这点和人脑其实没什么本质区别。

到这里,doc-flow 和 Trellis 的边界也清楚了。doc-flow 更接近 memory substrate,回答什么进入长期记忆、什么停留在任务现场、下一个 Agent 从哪里开始。Trellis 更接近 workflow controller,还要决定什么时候读写、哪些事件由 hook 捕捉、任务怎样切分、检查、归档和迁移。

两者处理的是同一个母问题,承担的自动化成本不同。跨工具、长周期、多任务、多 Agent 的开发 harness,需要 commands、hooks、状态管理以及模板升级和用户修改冲突处理。这些组件有明确用途,也会带来对应的维护成本。

我现在只需要一个轻量闭环

Trellis 没有促使我把 doc-flow 扩成一套 workflow OS。它反而帮我确认了当前边界:我需要项目记忆能够持续运转,但暂时不想让流程接管整个开发现场。

这套轻量闭环有四个选择:

这样做会牺牲一部分强制性。Agent 可能漏掉,某些工具也没有合适的 hook。好处是系统容易理解,接入已有仓库时改动有限,我也不必长期维护一整套迁移和命令体系。等任务规模真的需要更强控制,再为那部分确定的需求付成本。

说白了,我不想让 Agent 每次进仓库都先读一遍四书五经。我们做这些,只是为了让它更像一个能持续记住上下文的工作伙伴。

当仓库比人记得更完整

这次折腾也改变了我对文档的理解。README、方案设计和接口说明偏向描述某个稳定结果。在 agentic workflow 里,文档还承担工作记忆:它把边界、理由、任务现场和验证结果留给未来的协作者,无论后来接手的是人还是 Agent。

一套项目记忆至少要回答三件事:

  1. 哪些信息、原则和标准会长期影响这个项目?
  2. 哪些内容只属于当前任务的进度追溯?
  3. 系统应该在多大程度上自动维护这条分界?

如果这三件事能够持续运转,人需要反复补充的上下文会减少。与此同时,一个更远的问题也会出现: 假如人不再拥有全部的上下文,是否还拥有跟 AI 协作的基础条件? 我们现在仍在努力给 AI 提供更完整的上下文。假如某一天,仓库和 Agent 比任何一个人都更了解项目,人还要审核什么、补充什么,又该在哪些地方授权?

我也没有答案。

至少眼前,我希望 Agent 有办法获取项目里的隐性上下文。这样下次开工时,我就不必再给 AI 交代这个项目的病历了 ;)


Share this post on:

Previous Post
Agent架构重构的心路历程:从造轮子到选轮子
Next Post
AI 拟人化是存在危机?是低摩擦的 UX!