文档工程:记忆与知识如何进入 Agent 的 Context
本文是「企业级应用中 Harness Engineering 的实践与思考」系列的第 3 篇。
Context Window 不是项目记忆
AI Agent 每一次工作,都是从当前 context window 开始的。它能看到什么,就基于什么理解任务;它看不到什么,就只能猜测、重复探索,或者在错误假设上继续推进。
但真实项目不是一次 session。一个企业级应用可能有长期目标、历史决策、已完成和未完成的 story、技术约定、业务边界、review 结论、踩过的坑,以及很多只在过去某次 conversation 中被解释过的背景。
session 一旦重启,这些内容不会自动留在 Agent 的上下文里。即使它们曾经在某次 conversation 中出现过,也不意味着下一次 Agent 还能继续使用。于是,一个很现实的问题出现了:每次重新开始时,Agent 都可能重新问一遍已经解释过的问题,重新探索已经走过的路径,甚至重新犯已经修正过的错误。
当然,这个问题看起来正在被缓解。现在的大模型能力越来越强,context window 越来越大,很多工具也提供了 compact、summarize、resume 之类的能力。对于个人项目、小型 demo,甚至一个较短周期的功能实验来说,把大部分上下文放进一个 window 里,让 Agent 从头做到尾,已经越来越可行。
但在企业级应用中,这仍然不够。
企业级应用不是一个短期 demo。它的生命周期通常以年为单位,而不是以一次 session 或一个 sprint 为单位。它有多年的业务沉淀、历史决策、架构演进、权限边界、异常规则、团队约定、review 结论和线上问题。很多决定背后都有前因后果:为什么当时没有选择另一种方案,为什么某个看起来奇怪的实现不能轻易改,为什么某条业务规则只在特定场景下成立。
这些东西不是单个 context window 能真正承载的。即使 window 越来越大,也只是缓解了“能放多少内容”的问题,并没有解决“哪些内容应该出现、什么时候出现、如何被理解、如何被团队共享”的问题。
甚至可以想象一个极端情况:如果真的存在无限大的 context window,把项目多年的文档、所有历史对话、所有 review、所有代码约定全部塞进去,也不等于 Agent 就能保持足够的专注。把一座图书馆放进上下文,并不意味着它能在正确时刻找到正确书架上的正确一页。
更重要的是,企业级应用不是一个 Agent 的个人工作区。它往往涉及多人协作,甚至跨团队协作。一个 session 里的 window 不能成为团队共享的项目记忆,也不能承担长期治理、交接和复盘的职责。
所以,Harness 需要解决的不是简单地给 Agent 更大的 window,也不是把所有内容都塞进 context。真正的问题是:如何让项目在长期演进中积累下来的记忆和知识,跨 session、跨任务、跨团队地被保存、组织,并在正确时机进入 Agent 当前的 context。
记忆是什么,知识是什么
在讨论如何管理之前,需要先区分两个经常混在一起的概念:记忆和知识。
记忆更接近“发生过什么”。它通常和时间、过程、具体任务绑定在一起,也变化得更频繁。某个 story 是什么时候开始分析的,为什么暂停过,review 中发现了什么问题,某次实现为什么被退回,某个方案为什么被放弃,某个线上问题后来是怎么处理的,这些都属于记忆。
这些内容不一定能直接变成规则,但它们保留了项目的上下文和因果关系。没有记忆,Agent 只能看到当前任务的表面,而看不到这个任务是如何走到这里的。
知识更接近“以后应该怎么做”。它通常比记忆更稳定,是从多次经验中提炼出来的规则、约定、方法和判断。比如 workflow 如何流转,某类页面应该如何迁移,某个组件应该如何使用,某种状态转换需要什么条件,某个技术栈应该如何测试。
记忆和知识并不是完全分开的。记忆经过整理、归纳和验证,会沉淀为知识;而知识一旦被固定下来,也会成为项目长期经验的一部分。
还有一层容易被忽略:知识本身不一定需要一直留在 Agent 的 context 里,但 Agent 需要知道它存在、在哪里、什么时候应该读取。也就是说,知识的内容可以被放在外部,但触达知识的路径和时机,本身也需要被保存下来。
所以,在 AI Harness 中,记忆和知识更像是一组连续的项目经验。记忆保存过程,知识提炼规律。前者让 Agent 知道“为什么会这样”,后者让 Agent 知道“以后应该怎样”。
人类如何管理记忆和知识
人类很早就面对过类似的问题。
一个人的大脑容量是有限的,工作记忆尤其有限。长期记忆虽然可以保存很多经验,但它会被压缩、遗忘、重构,也会随着时间变得模糊。即使是经验丰富的人,也不可能记住一个项目、一个组织、一个领域里的所有细节。
更重要的是,知识并不只服务于一个人。它需要跨人、跨团队、跨时间传递。一个项目的经验需要交给后来者,一个团队的约定需要被新人理解,一个领域的知识甚至可以跨越数十个世纪继续被继承。这些都不可能只依赖某个人的大脑。
所以,人类一直在把记忆和知识外化。
更接近记忆的内容,会被写成日记、手札、会议纪要、工作日志、问题记录和复盘材料。它们保存的是发生过什么、当时怎么想、为什么做出某个决定、后来出现了什么结果。
更接近知识的内容,会被写成书籍、手册、规范、教程、档案和操作指南。它们不只是记录某一次具体经历,而是把经验整理成可以被别人学习、引用和复用的形式。
这些外化出来的内容不会全部留在人的当前注意力里。没有人需要记住一座图书馆中每一本书的每一页。真正有效的方式,是把记忆和知识放进合适的载体和位置,比如手册、档案这样的载体,书架和图书馆这样的位置;再通过目录、索引、标签和分类系统,让人在需要的时候找到对应内容。
这给 Harness Engineering 的启发是:记忆和知识需要被保存,但不需要一次性全部进入当前注意力。它们应该在合适的位置被保存,并在需要时被按需触达。
用文档承载记忆和知识
在 Harness Engineering 的实践中,对记忆和知识的管理,很自然地借鉴了人类管理记忆和知识的方式:不把所有内容都留在当前注意力里,而是把它们放进稳定的载体,再通过位置、结构和触达规则,在需要时进入 Agent 的 context。
这个载体就是文档。
这里的文档不只是传统意义上的说明书。它可以是 workflow guide、story file、conversation record、review report、spec、rule、handbook、schema、配置文件、状态记录,也可以是某种结构化数据。只要它承载了项目记忆或项目知识,并且会影响后续开发判断,它就是文档工程需要管理的对象。
但文档本身也需要工程化。没有被工程化管理的文档,很快就会变成另一种噪音:写过,但 Agent 不知道它存在;知道存在,但找不到;找到了,但不知道是不是最新;读到了,但不知道应该在什么时候使用。
可以用日记这个简单例子,来理解什么是工程化良好的文档。
如果一个人想知道自己 16 岁生日那天的天气,他可能并不记得当天的天气,但他知道这件事可以通过自己的日记本找到。前提是:日记本在一个他知道的位置,比如书柜;日记本按照固定格式记录内容,比如每篇开头都有日期和天气;他也知道查找路径:先找到日记本,再找到 16 岁生日那天的记录,最后读取天气。
这个例子之所以有效,是因为它回答了文档工程的三个核心问题。
第一个问题是:文档放在哪里。
项目关键记忆和知识不应该只散落在 repo 外部。外部文档当然可以存在,但如果关键知识只存在于外部系统里,Agent 的触达就会依赖权限、连接器、搜索入口和工具可用性。更重要的是,Agent 未必知道什么时候应该去哪里找。
它们也不应该只存在于某个工具提供的 agent memory 里。企业级应用不是某一个 Agent 的个人工作区。项目记忆和知识需要被团队共享、审查、版本化、迁移和交接,不能只属于某个 session、某个工具,或者某个私有记忆系统。
更一般地说,项目关键记忆和知识不应该放在只对某个人、某台设备或某个私有 session 可见的位置,也不应该放在默认不会被版本化、同步或共享的区域。被忽略的本地草稿目录、个人机器上的临时文件、某个工具私有的 memory store,都不适合作为项目长期记忆和知识的唯一载体。
位置也不只是“放进项目里”这么简单。不同类型的记忆和知识应该有不同的位置:任务记忆应该靠近 plan 和 story,长期知识应该进入稳定的文档区域,工具规则应该放在对应工具能够加载的位置,临时分析材料应该放在当前任务可以追溯的位置。位置本身就是一种索引,它让人和 Agent 在进入某个阶段时,知道应该去哪里寻找对应内容。
第二个问题是:文档写成什么结构。
不同类型的记忆和知识,适合不同的承载方式。有些内容适合 Markdown,因为它需要解释和叙述;有些内容适合 JSON 或 YAML,因为它需要被程序读取和更新;有些内容适合表格,因为它需要比较和追踪;有些关系适合用图表达,因为它需要展示流程或依赖。
格式之外,还需要 schema。不同用途的文档应该有自己的结构规范:story 应该承载哪些字段,status history 应该如何记录,review report 应该包含哪些结论,workflow guide 应该如何组织步骤,handbook 应该如何说明触发条件。没有结构的文档很难被稳定读取,也很难被 Agent 正确解释。
第三个问题是:文档如何被触达。
文档不是写了就会自动进入 Agent 的 context。Agent 需要知道文档存在,知道什么时候应该读取,知道读哪一层,知道读完之后如何用于当前任务。否则,文档即使存在,也只是静态文件,不是可用的 context。
所以,文档工程不是“多写文档”,而是把项目记忆和知识用合适的位置、格式、结构和触达规则组织起来,让它们能够被人和 Agent 在正确时机使用。位置解决“能不能找到”,结构解决“能不能读懂”,触达规则解决“能不能在正确时机进入 context”。
文档工程的核心原则:渐进式披露
文档工程的三个核心问题,最终都会指向同一个原则:渐进式披露。
还是回到日记的例子。一个人想知道 16 岁生日那天的天气,并不会先把所有日记全部读一遍。他会先知道“这件事可能被记录在日记里”,再知道“日记本放在书柜里”,然后打开日记本,通过日期找到具体的一篇,最后读取开头的天气记录。
这个过程是一层一层展开的。先触达入口,再进入载体;先定位范围,再读取细节。
放到 AI Harness 中,渐进式披露的意思是:不要把所有记忆和知识一次性暴露给 Agent,而是在 workflow 的不同阶段,只暴露当前阶段需要的那一层信息,同时保留继续向下追溯的路径。
这样做有两个意义。
第一个意义是,Agent 能在合适的时候找到合适的文档。进入 plan 时,它应该看到 plan 相关的目标、状态和 stories;进入 story 时,它应该看到 story 本身、依赖、历史 conversation 和必要 spec;进入实现时,它应该看到代码约定、测试方式和相关模块;进入 review 时,它应该看到验收标准、实现报告和质量检查结果。
第二个意义是,当前 context window 不会被过多内容干扰。长期知识、历史记录、工具规则、项目约定都很重要,但它们不应该在任何时候都完整进入当前 context。过多的内容会让 Agent 失去焦点,也会让真正重要的信息被噪音淹没。
所以,渐进式披露不是为了隐藏知识,而是为了让知识在正确的时候出现。它让 Agent 既不会失忆,也不会被整个项目的记忆和知识压垮。
实践一:记忆的分层与沉淀
在 Harness Engineering 的实践中,记忆不能只是一条不断变长的 conversation。它必须被放到合适的层级。
记忆至少可以分成四层:跨项目记忆、项目记忆、plan 记忆和 story 记忆。
跨项目记忆保存多个项目都能复用的经验;项目记忆保存当前项目的长期背景;plan 记忆保存一条工作线的目标、进展和关键决策;story 记忆保存具体任务的分析、实现、review 和 QA 结论。
这种分层的意义,是让 Agent 在不同层级工作时加载不同层级的记忆。进入项目时,不需要读取所有 story 的细节;进入 story 时,也不应该只看项目级原则而忽略当前任务的历史。
记忆还需要被及时记录。每当发生重要 decision、scope change、质量问题、测试发现、review 结论、暂停恢复、session 交接时,都应该把值得未来再次使用的内容写到合适层级的文档里。任何值得未来少解释一次、少踩一次坑、少重新探索一次的内容,都应该被记录。
但记忆也不能无限增长。已经完成的 plan 中,很多开发过程的细节在当时很重要,但长期来看会变成 context 负担。完成之后,plan 记忆需要被压缩和归档:保留关键节点、重要决策、风险和结论;原始过程细节可以留在 git history、归档记录或历史记录中,只有需要追溯时再读取。
如果某类记忆被反复提及,它就不应该永远停留在记忆层。反复出现的操作步骤可以沉淀为 handbook,反复出现的 review 问题可以沉淀为 checklist,多个项目共同遇到的问题可以沉淀为 guide。记忆经过整理、归纳和验证,就会变成知识。
所以,记忆管理不是把所有事情永远保存下来,而是让记忆在合适层级被记录,在合适时机被读取,在完成后被压缩归档,并在反复出现时沉淀为知识。
实践二:知识的分层
记忆经过反复验证之后,会沉淀为知识。但知识如果只以一篇长文档存在,仍然很难被 Agent 使用。Agent 不应该在每次工作时读完所有知识,也不可能在完全不知道某份知识存在的情况下凭空想起它。
所以,在 Harness Engineering 的实践中,知识需要被分层。
最外层是 description。它通常以 YAML front matter 的形式存在,用来说明这份知识应该在什么时候被触发。description 不是完整知识,而是入口。它让 Agent 先知道:在当前场景下,可能有一份知识需要被考虑。
第二层是 handbook。handbook 把知识整理成 step-by-step 的行动步骤。它不试图解释所有背景,而是告诉 Agent:当这份知识被触发时,应该按照什么顺序做。
第三层是 signpost。handbook 的步骤中会出现指向其他 handbook 或详细 document 的 signpost。当某一步需要更多背景、另一套流程或更完整规则时,Agent 可以顺着 signpost 继续深入。
最深层是详细 document。它保存完整解释、背景、设计理由、边界条件和例外情况。它不应该在每次任务开始时全部进入 context,但当 Agent 真的需要理解原因或处理复杂情况时,它必须能够被找到。
这种分层让知识可以按照需要一层层展开。主 Agent 可以通过 agent hook 在合适时机自动获得可能相关知识的 description;subagent 在被 spawn 时,也可以获得与自己职责相关的 description。Agent 不需要一开始读完所有知识,但它知道哪些知识存在,以及什么时候应该继续向下读取。
这正是渐进式披露在知识管理中的体现:先知道存在,再在合适时机展开;先读取行动步骤,再在需要时进入更深层的解释。
这种结构还有一个额外好处:稳定下来的 handbook 很容易进一步转换成 agent skill。description 可以成为触发条件,step-by-step 的内容可以成为执行流程,signpost 可以成为按需加载的知识入口。换句话说,良好的知识分层不仅服务于当前的文档阅读,也为未来的自动化和工具化留下了路径。
回到 Harness:文档工程最终服务于人
从表面看,文档工程是在服务 Agent:让它知道哪些记忆和知识存在,在哪里,什么时候读取,如何进入当前 context。
但这不是文档工程的最终目的。
真正重要的是,文档工程降低了人的心智负担。人不需要记住所有项目细节,不需要每次重新解释背景,不需要手动回忆每个 workflow 步骤,也不需要把所有规范、约定、历史决策和踩过的坑都放在脑子里。
这些记忆和知识被放进 harness,由 Agent 在正确时机读取、整理、执行和检查。人则可以把注意力更多放在方向、判断、取舍、授权和验证上。
文档工程将繁重的记忆和知识强行压在 Agent 身上,不是为了让 Agent 取代人。恰恰相反,它是为了把人从重复解释、反复检索和细节记忆中解放出来,让人更专注于决定系统应该往哪里走。
所以,文档工程的最终目的,是给人减负。记忆与知识进入 Agent context 的真正意义,不是让 Agent 拥有一切,而是让人可以通过 harness 更轻松、稳定地驾驭 Agent。