智能体面试准备(六十一):智能体上下文工程 Context Engineering------上下文预算、压缩、优先级与多轮演进
引言
前面(五十九)长期记忆、(四十一)记忆架构讲了"记忆怎么存"。本文讲"每次推理把什么放进上下文窗口"------这正是 2025-2026 最热的 Context Engineering。同样的模型,上下文编排好坏,agent 表现能差一个量级。它和提示工程(Prompt Engineering)的区别在于:提示工程雕"一句话",上下文工程雕"整个窗口的信息结构与取舍"。
一、上下文工程是什么
原始信号(记忆 / 工具结果 / 历史 / 环境观测)
|
v
选择 + 压缩 + 排序 + 裁剪
|
v
Context Window <-- 预算有限
|
v
模型推理 -> 动作
核心矛盾:窗口有限 vs 信息无限。上下文工程的目标,是在预算内把"此刻最该被模型看到的信息"排到最前面。
二、上下文预算与分层
| 层 | 内容 | 是否可压缩 | 占比建议 |
|---|---|---|---|
| System | 角色 / 规则 / 工具 schema | 否 | 10%~15% |
| Tools | 可用工具列表 | 部分(按需展开) | ~10% |
| Memory | 长期记忆检索结果 | 是(摘要) | 20%~30% |
| Working | 当前任务 / 计划 / 中间结果 | 部分 | ~20% |
| History | 多轮对话 / 工具调用轨迹 | 是(滚动 / 摘要) | 剩余 |
经验:System 与 Tools 是"骨架"尽量稳定;Memory 与 History 是"血肉"需要动态取舍。
三、压缩与裁剪
常用策略:
-
摘要压缩:把旧的工具调用轨迹用模型摘要成一段。
-
截断:保留最近 K 轮,更早的进"冷记忆"。
-
重要性排序:按 recency + relevance + 任务相关性打分,预算内优先保留高分。
python
def pack_context(items, budget_tokens):
items = sorted(items, key=lambda it: it.score, reverse=True)
packed, used = [], 0
for it in items:
if used + it.tokens <= budget_tokens:
packed.append(it); used += it.tokens
else:
packed.append(it.summarize(remaining=budget_tokens - used))
break
return packed
四、优先级与记忆选择
- recency:最近的交互更可能相关。
- relevance:用 query 对记忆做向量检索(接(五十九)的检索增强记忆)。
- importance:用户显式标记 / 被多次引用。
- 三者加权融合排序,取 top-N 填入 Memory 层。
注意:relevance 高不代表该进窗口------一条和当前任务无关但高度相似的旧记忆可能只是噪声。优先级函数要带"任务相关性"这一强信号。
五、多轮演进与漂移
- 滚动窗口:固定窗口滑过历史,超出部分摘要归档。
- 上下文漂移:任务中途转向,旧上下文变成噪声 -> 用"任务 checkpoint"在转向点截断并重写 working 层。
- 重放 vs 摘要:关键决策(如选中的工具、确认的参数)保留原文防摘要失真;琐碎步骤可摘要。
六、失败模式与评测
常见坑:
-
Context Overflow:重要工具结果被挤出窗口 -> 动作基于缺失信息。
-
噪声淹没:低质记忆占满预算 -> 模型被带偏。
-
摘要失真:关键数值(ID、坐标、金额)在摘要中丢失。
评测:在长程任务上跑"带 / 不带上下文工程"的完成率对比,监控"关键信息命中率"(关键字段是否仍在窗口内)。
七、面试速答
Q:上下文工程和 RAG 什么关系?
A:RAG 解决"从外部知识取什么",上下文工程解决"取来后 + 历史 + 工具结果一起怎么排布进窗口"。RAG 是上下文工程在 Memory 层的具体手段之一。
Q:长对话怎么不爆窗口?
A:分层 + 滚动摘要 + 关键原文保留;把可重算的信息(如完整工具输出)外置,窗口只留指针 / 摘要。
八、高频追问清单
- 预算分配比例怎么定?不同任务是否动态?
- 摘要失真怎么缓解(保留结构化字段)?
- 工具结果很大(如长 JSON)怎么塞进窗口?
- 多智能体间上下文如何共享 vs 隔离(接(五十八))?
- 上下文工程能否用模型自动优化(meta-prompt)?
- 流式 / 实时场景下上下文如何增量更新?
- 如何评测上下文工程对最终成功率的影响?
- 与"提示缓存 / prefix cache"如何配合降本?