Agent 的 Context Engineering 应该怎么做?¶
- ID:Q005
- 难度:进阶 / 系统设计
- 标签:Context Window、压缩、检索、状态、长任务、Coding Agent
同义问法¶
- Agent 上下文太长怎么解决?
- 长对话如何动态压缩和遗忘?
- 为什么上下文窗口很大,Agent 仍会丢失信息?
- Coding Agent 如何理解大型代码仓库?
- Memory 能不能解决 Prompt 过长?
来源¶
真实面试来源¶
- 阿里 AI Agent 应用开发二面:
长对话中如何实现上下文的动态压缩和遗忘? - 查看原文
- 美团大模型工程一面:
记忆能解决 Prompt 过长吗? - 查看原文
- 阿里淘天 Agent 面经:
是否尝试过 Prompt 压缩? - 查看原文
面试官真正考察什么¶
不是看你会不会说“摘要、向量库、滑动窗口”,而是看你是否理解:
Context Engineering 的目标不是塞进更多内容,而是在当前决策点提供最少但足够、可信且结构清晰的信息。
它涉及信息选择、状态建模、证据保真、成本和错误恢复,是 Agent 工程的核心问题。
可视化图解¶
flowchart LR
S[完整 Runtime State] --> F[相关性过滤]
M[长期 Memory] --> F
K[检索知识与工具结果] --> F
F --> B[Token Budget 分配]
B --> C[压缩与摘要]
C --> A[Context Assembly]
A --> L[LLM]
L --> T[决策或工具调用]
T --> S
先建立直觉¶
上下文窗口像工作台,不是仓库。
把所有聊天、日志、代码、工具输出都堆上工作台,会出现:
- 关键指令被淹没;
- 旧信息和新信息冲突;
- 模型重复分析;
- Token 成本和延迟上涨;
- 截断时随机丢失重要内容。
正确方式是:原始数据放在外部存储,工作台只保留当前步骤真正需要的内容。
Context 不等于聊天记录¶
生产级 Agent 的上下文通常至少分为:
- 目标与约束:用户要什么、不能做什么。
- 当前状态:任务处于哪个阶段,哪些步骤完成。
- 工作记忆:当前推理需要的少量事实和假设。
- 工具目录:当前阶段可使用的相关工具。
- 检索证据:按需取回的代码、文档、日志和历史经验。
- 最近交互:保持局部连续性的消息。
- 产物引用:文件、日志、Diff、测试结果的地址和摘要。
关键是把“状态”从自然语言历史中抽出来,结构化保存。
为什么大窗口不能自动解决问题¶
更大的 Context Window 主要提高容量,但不能保证:
- 模型能正确注意到中间的重要信息;
- 冲突信息自动消解;
- 工具结果可信;
- 历史噪声不会影响决策;
- 成本和延迟可接受;
- 长任务中目标不会漂移。
容量问题只是 Context Engineering 的一部分,选择和组织通常更重要。
推荐的分层架构¶
对应流程使用 Mermaid 图解展示。
原始层¶
必须保留可追溯的完整数据,避免摘要丢失后无法恢复。
状态层¶
结构化保存:
{
"goal": "定位发布失败根因",
"constraints": ["只读", "不得重启生产服务"],
"stage": "dependency_analysis",
"completed_steps": ["fetch_build_log"],
"hypotheses": [
{"name": "依赖仓库不可用", "confidence": 0.7}
],
"open_questions": ["其他项目是否同时失败"]
}
摘要层¶
摘要不是简单缩写聊天,而应保留:
- 已确认事实;
- 尚未确认的假设;
- 决策及原因;
- 用户明确约束;
- 关键产物引用;
- 未完成事项。
检索层¶
根据当前任务检索,而不是把所有历史做一次向量相似度查询。
可以结合:
- 关键词检索;
- 语义检索;
- 文件路径和代码符号;
- 时间范围;
- 任务阶段;
- 最近修改;
- 权限和数据来源。
压缩策略¶
1. 滑动窗口¶
保留最近消息,适合局部对话连续性。
缺点:可能丢失早期目标和约束,所以必须将关键内容提升到状态层。
2. 阶段摘要¶
每完成一个阶段生成摘要,再进入下一阶段。
比每轮都重新总结更稳定,也便于中断恢复。
3. 事件压缩¶
把多条低价值事件合并,例如连续 20 次日志分页读取,最终只保留关键错误、时间范围和原始引用。
4. 语义去重¶
不同工具可能返回重复信息,应按实体、时间和事实去重。
5. 按需展开¶
上下文先放摘要和引用,模型确实需要细节时再读取原文。
这类似操作系统的分页,而不是一次把全部数据装进内存。
“遗忘”应该怎么做¶
遗忘不是删除一切旧内容,而是降低不再相关信息进入当前上下文的优先级。
不能遗忘:
- 用户目标和硬约束;
- 已执行的有副作用动作;
- 关键证据和结论来源;
- 安全和权限信息;
- 未完成承诺。
可以衰减:
- 已失效的中间猜测;
- 重复工具输出;
- 已解决阶段的细节;
- 与当前任务无关的闲聊。
Coding Agent 的特殊处理¶
大型代码库不能靠把仓库全部塞进 Prompt。
更合理的路径是:
- 解析仓库结构和构建入口;
- 通过文件名、符号、调用关系、搜索结果定位候选范围;
- 读取相关文件和必要邻接代码;
- 修改后通过 Diff、编译和测试反馈继续迭代;
- 将生成产物保存在工作区,Context 中只保留摘要和引用。
代码检索也不能只用 Embedding:精确符号、路径、grep、语言服务器和依赖图通常更可靠。
摘要的风险¶
摘要会产生信息损失甚至错误归纳。
防护方法:
- 摘要中的事实附原始引用;
- 区分 confirmed fact 与 hypothesis;
- 关键数字、错误码、文件路径尽量原样保留;
- 重要决策可由规则校验;
- 允许从原始层重新构建摘要;
- 不让摘要覆盖原始记录。
Context 污染与 Prompt Injection¶
外部网页、日志、代码注释都可能包含类似指令的文本。
系统应明确:
- System / Developer 指令;
- 用户目标;
- 外部不可信数据;
- 工具结果。
外部内容只能作为数据,不应自动改变权限和系统规则。
如何评估 Context Engineering¶
不能只看 Token 是否减少。至少关注:
- 任务成功率;
- 关键约束保留率;
- 证据召回率;
- 摘要事实错误率;
- 平均输入 Token;
- P95 延迟;
- 重复工具调用率;
- 长任务目标漂移率;
- 中断恢复成功率。
压缩 80% Token 但成功率下降,不能算优化。
常见低质量回答¶
回答 1¶
超长后做摘要。
问题:没有说明摘要什么、保留什么、如何追溯和何时触发。
回答 2¶
使用向量数据库做长期记忆。
问题:向量库是检索工具,不等于状态管理,也无法保证召回关键约束。
回答 3¶
换一个更大上下文的模型。
问题:只缓解容量,不解决噪声、冲突、成本和目标漂移。
可直接口述的回答¶
Context Engineering 的目标不是尽量把信息塞满,而是让模型在当前决策点看到最少但足够、可信且结构清晰的信息。我通常把完整对话、日志和代码保存在外部原始层,把目标、约束、计划、进度和假设抽成结构化状态;阶段完成后生成带引用的摘要;本轮根据任务阶段按需检索原文。最近消息用滑动窗口维持局部连续性,但关键目标和约束不能依赖窗口保留。对于 Coding Agent,还要结合文件路径、符号搜索、调用关系和测试反馈,而不是只靠向量检索。评估时不仅看 Token,还要看任务成功率、约束保留、证据召回、摘要错误和目标漂移。
结合个人项目怎么回答¶
我们在 CI/CD Agent 中遇到过把流程说明、源码和大量日志一次性塞给模型,最终 Prompt 超长且模型反复关注次要错误。更合理的做法是先用脚本提取时间线、异常链和关键错误,把完整日志放在文件中;Agent 根据假设按需读取前后文。任务状态单独记录已确认事实和待验证项,阶段结束后压缩上下文,但保留原始日志引用。这样上下文变小的同时,证据链仍可追溯。
可能追问¶
什么时候触发压缩?¶
可以结合 Token 水位、阶段边界、工具结果体积和任务停滞触发,不建议仅按固定轮次。
Memory 和 Context 有什么区别?¶
Memory 是跨轮或跨任务保存的信息;Context 是本轮实际提供给模型的信息。Memory 必须经过选择才能进入 Context。
如何处理新信息与旧记忆冲突?¶
记录来源、时间和可信度,优先使用更新且权威的数据;不要静默覆盖,必要时把冲突暴露给模型或用户。