Context Window:Harness Engineering 如何管理 Agent 的注意力
本文是「企业级应用中 Harness Engineering 的实践与思考」系列的第 8 篇。
为什么不能一个 Window 跑完整个项目
模型的 context window 越来越大,工具也开始提供 compact 能力。看起来,只要开一个足够长的 window,把需求、代码、文档、历史讨论和执行过程都放进去,就能让 Agent 从头做到尾。
这个想法背后有一个隐含假设:只要内容进入了 context,Agent 就会在之后的任何时候都记得它、理解它,并且在需要时正确使用它。
这个假设并不是凭空来的。很多人最早接触生成式 AI,是从 ChatGPT 这样的对话式产品开始的。对话式产品刻意隐藏了 context window 的复杂性,让用户可以像聊天一样自然使用 AI。对于问答、写作、总结和轻量任务来说,这是很好的体验。
但这里有一个很重要的差别:ChatGPT 是在聊天,而 agentic 开发工具是通过聊天在工作。
前者的核心体验是对话本身。用户提出问题,模型给出回答,很多时候一次对话就是一个完整的使用闭环。后者虽然也以聊天作为交互界面,但聊天只是工作入口。Agent 会阅读项目、修改文件、调用工具、运行命令、生成报告、推动 workflow。它不是在完成一次回答,而是在参与一个持续演进的工程过程。
因此,基于 ChatGPT 形成的使用习惯,不能直接迁移到 agentic 开发里。对于普通聊天来说,用户不需要理解 context window;但在企业级应用开发中,context window 就是 Agent 当前工作的注意力空间,必须被有意识地管理。
问题恰恰出在这里。
Context Window 不是数据库,也不是硬盘。它更像 Agent 当前这一次工作的注意力空间。一个信息出现在 window 里,只说明它可能被模型看到,并不意味着它会在后续所有步骤中被同等重视、准确引用、持续保持优先级。
人也是类似的。会议上听过一句话,不等于三小时后还能在复杂讨论中正确想起它;桌上摊开十份文件,也不等于每一份文件里的每一个细节都会在当前判断中被同等关注。信息存在,和信息在正确时刻发挥作用,是两回事。
Agent 也是一样。越长的 conversation,越多的文档片段,越复杂的历史记录,越容易让当前任务的重点被稀释。最近出现的内容、反复出现的指令、结构更清晰的信息、和当前任务更显著相关的片段,往往会更容易影响 Agent 的判断;而早期、隐含、零散、没有被显式整理的信息,即使仍然在 window 中,也可能在实际工作中被弱化、遗漏或误用。
所以,真正的问题不是 context window 能不能装下所有东西,而是 Agent 能不能在正确时刻关注正确内容。Harness Engineering 之所以要管理 Context Window,不是因为窗口不够大,而是因为 Agent 的注意力需要被管理。
Context Window 承载不了项目记忆和知识
项目的知识和记忆,不能只存在于某一次 conversation 的 context window 里。从这个角度回头看文档工程,就会更清楚它为什么必要。
Context Window 只是 Agent 当前 session 的工作空间,不是项目记忆。它有容量限制,会随着 session 结束而消失,也可能在 compact 之后丢失细节和语境。更重要的是,它无法天然共享。一个 Agent 当前 window 里的内容,不能自动成为另一个 Agent、另一个人,或者下一次 session 可以稳定依赖的项目知识。
但企业级应用需要的恰恰是跨 session、跨 Agent、跨人、跨时间的记忆和知识。为什么当时做了这个决定,某个接口有哪些约束,某个流程为什么不能改,某个 story 现在处于什么状态,某次 review 发现了什么风险,这些都不能只存在于一次 conversation 里。
所以,项目记忆必须由文档工程来承接。Spec、report、status、handbook、project knowledge、history,这些文档化产物让知识离开某一个 window,变成可以被共享、交接、追溯和复用的工程资产。
但这并不意味着要把所有文档一股脑塞进 Context Window。那只会让 Agent 失去焦点。文档工程真正要做的,是通过渐进式披露,让 Agent 先知道哪些知识存在,再在合适的阶段、合适的任务中,展开合适的内容。
这样,Context Window 里保留的是当前任务真正需要的内容,而项目的长期记忆仍然稳定存在于 window 之外。Agent 可以保持专注和高效,项目也可以在不同 session、不同 Agent、不同人之间持续协作、交接和追溯。
Context 隔离是 Agent 分工的基础
既然项目的长期记忆和知识不能全部放在 Context Window 里,接下来的问题就是:能不能在需要工作的时候,把相关的知识和记忆一次性都塞进去?
答案仍然是否定的。
企业级应用里的职责太多,对应的 context 也太多。业务规则、架构约束、接口文档、设计稿、测试策略、review 规则、发布流程、历史决策、当前状态,它们都可能是有用信息,但并不都应该在同一个时刻进入同一个 Agent 的 Context。
如果全部放在一起,不同职责需要的知识会互相干扰。Dev Agent 需要的是实现相关的代码、架构、接口和约束;QA Agent 需要的是验收路径、测试数据、边界条件和验证工具;Code Reviewer Agent 需要的是代码质量、架构边界、团队规范和风险模式;BA Agent 和 TL Agent 需要的是业务规则、技术约束和分析材料;PM Agent 需要的是 workflow、plan/story、status 和 Agent 协作信息。
这些 Context 并不是谁多谁少的问题,而是谁和当前职责相关的问题。一个 Agent 如果拿到了大量和当前职责无关的信息,它并不会因此变得更可靠,反而更容易失去焦点。它可能被其他职责的知识牵引,顺手做了不该做的事,也可能在本该专注的任务上遗漏关键细节。
所以,Agent 分工本质上也是 Context 分工。职责边界决定了 Agent 应该拥有哪些知识、工具和输入输出,也决定了哪些内容不应该进入它当前的 Context。
这也从 Context 的角度解释了为什么 Agent 要各司其职,不能随意逾越。QA Agent 不应该顺手改代码,不只是因为职责上不该做,也因为它的 Context 并不是为了实现代码而组织的;Dev Agent 不应该替人做业务取舍,也不是因为它“能力不够”,而是因为它的 Context 没有承载那些判断所需的完整业务、风险和责任信息。
Context 隔离不是为了制造墙,而是为了让每个 Agent 在自己的职责范围内保持专注。该看的内容进入当前 window,不该看的内容留在外面,必要时通过文档、report、status 和 human gate 进行交接。
Workflow 让 Context 按阶段进入
从职责上看,不同 Agent 需要不同 Context;从流程上看,同一个 plan 或 story 在不同阶段,也不应该使用同一份完整 Context。
一个 story 的完整上下文可能包括需求、讨论、设计、代码、历史决策、分析结果、实现过程、review 记录、测试结果和 human gate 判断。如果这些内容全部堆进一个 window,Agent 仍然会失去焦点。
所以,从 Context 的角度回看 workflow,它不仅是在管理状态流转,也是在对 Context 做阶段性分割。每个阶段都有自己的输入、处理方式和输出,而这些输入输出本质上都是对 Context 的选择、压缩和交接。
在 analyzing 阶段,Agent 需要更多原始材料和背景知识,目标是形成 Spec。Spec 把分散的原始 Context 压缩成 implementing 阶段可以依赖的 Context。
在 implementing 阶段,Agent 不应该重新沉入所有原始材料,而应该主要依赖已经确认的 Spec、相关代码和实现约束。这里的 implementing 并不只是 Dev Agent 写代码,也包括 Code Reviewer Agent 的 review 和 QA Agent 的测试验证。开发、review、测试都围绕同一个 Spec 展开,只是从不同职责和不同 Context 去理解它。
Dev Agent 从 Spec 中看到实现要求,Code Reviewer Agent 从 Spec 中看到代码审查标准,QA Agent 从 Spec 中看到验证路径和验收依据。它们需要的 Context 不同,但都不应该脱离已经确认的 Spec。开发报告、review report 和 test report,则把 implementing 阶段的执行、审查和验证结果压缩成 human gate 可以使用的 Context。
所以,Spec 和 report 不是额外文档负担,而是 workflow 在不同阶段生成的 Context 交接物。workflow 的价值不只是让任务有状态,更是让 Context 按阶段进入:当前阶段需要什么,就展开什么;下一阶段需要什么,就产出什么。
人必须主动管理 Agent 的注意力
按职责隔离 Context,按 workflow 切分 Context,并不意味着 Context Window 越小越好。它真正需要落在注意力的甜点区间。
太少,Agent 会猜;太多,Agent 会失焦;太散,职责会混乱;太杂,阶段会互相干扰;太久,早期内容会被弱化;太依赖 compact,细节、语境和决策过程会丢失。
一个好的 Context Window,应该足够多,让 Agent 不必凭空猜测;也应该足够少,让 Agent 不被无关内容拖走;更应该足够相关,让 Agent 始终围绕当前职责和当前阶段工作,并尽量避免依赖 compact 来维持长期工作。
这正是 Context Engineering 需要解决的问题。它不是自动发生的事情。人必须主动管理 Agent 的注意力:及时记录值得保存的记忆,不把临时 conversation 当项目记忆,在合适阶段结束 session,而不是无限拖长 conversation,避免依赖 compact,防止 Agent 职责越界,判断当前任务真正需要哪些文档、Spec、report 和工具结果。
当 Agent 开始重复、失焦、幻觉、偏离任务时,人要意识到,这不一定只是模型能力问题,也可能是 Context 已经坏了。此时继续 prompt 它,往往只是在混乱的 Context 上叠加更多混乱。更好的做法可能是停下来,记录必要记忆,切断当前 session,重新构造一个干净、聚焦的 Context。
这也是 Human in the Loop 的一部分。人不只是判断结果,也要管理 Agent 产生结果时所处的注意力空间。
回到 Harness:Context Window 的管理是在管理注意力
回到 Harness,Context Window 不是一个越大越好的容器,也不是一个可以无限依赖 compact 维持下去的工作空间。它是 Agent 当前工作的注意力空间。
Harness 要做的,不是把所有项目知识都塞进这个空间,而是让正确且恰当的内容,在正确的时间,进入正确 Agent 的 Context Window。正确,意味着它和当前任务、职责、阶段相关;恰当,意味着它不多不少,足够支撑 Agent 工作,又不会让 Agent 失去焦点。
而人要做的,是通过 Harness 主动管理这个空间:哪些内容应该被记录,哪些内容应该被展开,哪些内容应该留在外面,什么时候应该结束 session,什么时候应该切断并重建 Context,什么时候应该阻止 Agent 在错误的 Context 中继续前进。
所以,Context Window 的管理,最终管理的不是 token,也不是文件数量,而是 Agent 的注意力。一个好的 Harness,不是让 Agent 看到一切,而是让 Agent 在当前阶段、当前职责、当前任务中,看到正确且恰当的内容。