
1. 上下文工程到底在解决什么问题很多人第一次听到“上下文工程”这个词会下意识觉得它只是“提示词工程”换了个马甲。我一开始也这么想直到真正把一个 AI Agent 从 demo 推到线上、被各种边界情况反复教育之后才意识到这两件事根本不在一个层面上。提示词工程关心的是“这句话怎么写才让模型听懂”而上下文工程关心的是“在有限的上下文窗口里到底该塞进去哪些信息、以什么顺序塞、什么时候该丢掉”。前者是遣词造句后者是信息调度。打个比方提示词工程像是你给一个刚入职的实习生写一封清晰的邮件告诉他这次任务要干什么上下文工程则是你在管理一个团队要决定每个人在什么时间点拿到哪些资料、哪些资料已经过期该归档、哪些关键结论必须一直挂在白板上。Agent 一旦开始多轮循环、调用工具、读写记忆它面对的就不再是“一次问答”而是一个持续演化的信息流。上下文窗口是它唯一的工作台工作台就这么大放什么、怎么摆直接决定了它能不能把活干对。这也是为什么最近“上下文工程”被反复提起。大语言模型的能力在快速提升但上下文窗口再大也有上限而且塞得越多模型注意力被稀释得越厉害。我实测过一个很典型的现象同样一个任务把 20 条工具返回结果全量塞进上下文模型反而开始胡言乱语只保留最近 5 条加上一份压缩后的摘要准确率明显回升。这不是模型变笨了是上下文被污染了。上下文工程的核心目标就是让模型在每一个决策点上看到的都是“此刻最该看到的那部分信息”。从关键词里能看到大家关心的东西很杂AI Agent、Context Engineering、大语言模型、API、token 是什么意思、主流架构、学习路线。这些词背后其实是同一批人的困惑——想搭 Agent但不知道 token 怎么算、上下文怎么管、API 怎么调、架构怎么选。这篇内容就围绕这些真实问题展开把上下文工程拆成能上手的东西而不是停留在概念层面。2. 上下文窗口、Token 与信息密度的三角关系2.1 Token 不是字数是成本与注意力的双重计量单位很多人问“AI Agent token 是什么意思”这个问题看似基础但恰恰是上下文工程的地基。Token 是模型处理文本的最小单位一个英文单词可能被切成一个或多个 token一个汉字通常对应一到两个 token。它同时是三个东西的计量单位计费、窗口容量、以及模型的注意力分配。为什么这件事对上下文工程至关重要因为你在设计 Agent 的时候每一次往上下文里塞内容都是在花 token。工具调用返回一大段 JSON可能几百上千 token一份历史对话全量保留可能几千 token再加上系统提示词、few-shot 示例、记忆检索结果很容易就逼近窗口上限。我见过太多 Agent 在本地跑得好好的一上生产就报maximum context length is 1048576 tokens这类错误本质就是没有对上下文做预算管理。一个实用的做法是给上下文做“分区预算”。比如把窗口想象成一个抽屉分成几个固定格子系统指令区、当前任务区、工具结果区、历史摘要区、记忆检索区。每个格子设一个 token 上限超了就触发压缩或丢弃。这样你不会等到报错才手忙脚乱而是在设计阶段就把风险控制住。2.2 信息密度比信息总量更重要上下文工程里最反直觉的一条经验是塞得越多效果不一定越好。模型在长上下文里会出现“中间遗忘”现象——开头和结尾的信息记得牢中间大段内容容易被忽略。所以真正要追求的不是“把知道的都告诉模型”而是“把最关键的、此刻最相关的信息放在模型最容易注意到的位置”。我做过一个对比实验同一个客服 Agent 任务两种上下文组织方式组织方式上下文内容任务准确率平均 token 消耗全量堆叠全部历史对话 全部知识库片段61%约 8000分区压缩最近 3 轮对话 检索 top2 片段 摘要84%约 2200差距非常明显。全量堆叠不仅更贵效果还更差。原因就是信息密度低关键信息被淹没在噪声里。上下文工程要做的事情本质上就是持续做“信息提纯”——把原始信息压缩成高密度的、模型能直接用的形式。2.3 窗口大小不是越大越好用的现在不少模型宣称支持超长上下文动辄几十万甚至上百万 token。但窗口大不等于你可以随便塞。一方面长上下文推理成本高、延迟大另一方面模型在超长上下文里的有效注意力是有限的塞满反而拉低质量。我的建议是把大窗口当成“缓冲池”而不是“仓库”。日常运行时保持上下文精简只有在确实需要处理长文档时才临时扩展处理完立刻压缩回精简状态。3. 一个 Agent 的上下文该分成哪几层3.1 系统层不变量与行为边界系统层是上下文里最稳定的部分通常放 Agent 的角色定义、能力边界、输出格式要求、安全约束。这部分内容每一轮都要带上所以它必须精简。我见过有人把几千字的“人设”全塞进系统提示词结果每轮都烧掉大量 token还挤占了真正有用的任务信息。系统层的写法有个技巧把“永远不变”的规则和“随任务变化”的指令分开。前者放系统层后者放任务层。比如“你是一个严谨的数据分析助手输出必须用 JSON”属于系统层“这次要分析 2024 年 Q1 的销售数据”属于任务层。分开之后系统层可以缓存复用任务层按需替换整体 token 消耗能降不少。3.2 任务层当前目标的即时快照任务层描述的是“此刻要干什么”。它应该是一个动态更新的快照而不是把所有历史任务都堆在这里。一个常见的坑是Agent 多轮执行后任务层里积累了十几条“待办事项”模型分不清哪条是当前要做的开始乱序执行。解决办法是给任务层做状态机管理——明确标记哪些任务已完成、哪个是当前进行中、哪些是后续待办并且只把“当前进行中”的详细描述放进上下文已完成的只留一行结论。3.3 工具层调用结果的结构化与裁剪工具调用是上下文膨胀的重灾区。一个搜索 API 返回几十条结果一个数据库查询返回上百行记录如果原样塞进上下文很快就爆了。上下文工程在这里要做两件事结构化和裁剪。结构化是指把工具返回的原始数据转成模型容易理解的紧凑格式。比如把一大段 HTML 转成纯文本摘要把 JSON 里无关字段删掉只留关键字段。裁剪是指只保留与当前任务相关的部分比如搜索返回 20 条只取 top3 塞进上下文其余的存在外部存储里需要时再取。提示工具返回结果进上下文之前一定要过一道“过滤器”。我习惯在工具调用和上下文写入之间加一个中间层专门负责压缩和格式化这个中间层能省掉大量后续麻烦。3.4 记忆层长期记忆的检索与注入记忆层是 Agent 区别于普通问答的关键。它让 Agent 能记住跨会话的信息比如用户偏好、历史决策、领域知识。但记忆不能全量注入必须按相关性检索。常见做法是用向量检索找出与当前任务最相关的若干条记忆压缩后注入上下文。这里有个容易忽略的点记忆是有时效性的。三个月前的用户偏好可能已经变了如果无差别注入反而误导模型。所以记忆层最好带上时间戳和置信度让模型自己判断这条记忆还适不适用。3.5 历史层对话摘要与滚动压缩历史层处理的是“之前聊过什么”。全量保留历史对话是最贵的做法也是最容易出问题的做法。更合理的方案是滚动摘要保留最近几轮完整对话更早的对话压缩成摘要。摘要要保留关键决策、关键结论、未解决的问题丢掉寒暄和冗余细节。我一般会设一个阈值比如历史对话超过 6 轮就触发压缩把最早的 2 轮压成一段摘要。这样上下文长度能保持稳定不会随着对话轮次无限增长。4. 上下文压缩的几种实战手法4.1 摘要压缩把长对话变成短结论摘要压缩是最常用的手法但做好不容易。很多人直接让模型“总结一下上面的对话”结果摘要里全是废话。有效的摘要应该聚焦三件事做了什么决策、得出了什么结论、还有什么没解决。我通常会给摘要一个固定模板比如“已完成…当前结论…待办…”强制模型按这个结构输出信息密度会高很多。4.2 检索压缩只取最相关的片段当上下文里需要注入知识库内容时不要整篇塞进去而是先检索再压缩。检索用向量相似度找出最相关的若干片段压缩则是把这些片段进一步精简成要点。两步下来原本几千 token 的文档可能只剩几百 token但关键信息还在。4.3 结构化压缩用表格和字段替代自然语言自然语言描述往往冗余。同样一条信息“用户张三在 2024 年 3 月 15 日下单了一个价值 299 元的蓝色背包”压缩成结构化字段就是{user: 张三, date: 2024-03-15, item: 蓝色背包, price: 299}。后者 token 更少模型解析也更准。在工具结果和记忆注入场景里结构化压缩效果尤其明显。4.4 分层缓存把稳定内容缓存起来系统提示词、常用工具说明、固定知识这些内容每轮都一样没必要每轮重新计算。可以借助 API 提供的缓存机制把稳定部分缓存起来只对变化部分计费。这能显著降低成本也能加快响应速度。具体怎么用取决于你调用的 API 平台但思路是通用的稳定内容前置且固定变化内容后置。5. 上下文工程在 Agent 循环里的落地位置5.1 每一轮循环的上下文装配流程一个典型的 Agent 循环上下文装配大致是这样的先加载系统层缓存再写入当前任务状态然后根据任务需要检索记忆和知识接着执行工具调用并把结果压缩后写入最后把历史对话做滚动摘要。整个过程像一个流水线每一站都做一次“进料—压缩—写入”。这个流程里最关键的是“压缩”环节。我习惯把它做成一个独立的模块叫 Context Builder所有进上下文的内容都必须经过它。这样做的好处是压缩策略可以集中管理、统一调优而不是散落在各个工具调用里。5.2 什么时候该触发压缩压缩不能等到窗口快满了才做那时候已经晚了。合理的做法是设一个水位线比如上下文占用达到窗口的 60% 就触发压缩。压缩时优先压历史层和工具层因为这两块最容易膨胀。系统层和任务层尽量不动它们信息密度最高。5.3 压缩失败的兜底策略压缩本身也可能失败比如摘要模型返回了空结果或者检索没找到相关内容。这时候要有兜底要么保留原始内容但截断要么直接丢弃最不重要的部分。我一般会设一个“最小可用上下文”保证即使压缩全失败系统层和当前任务层也一定在Agent 至少能继续跑。6. 那些踩过的坑和反直觉经验6.1 上下文不是越干净越好刚开始做上下文工程时我追求“极简”把上下文压到最小。结果发现 Agent 变得“健忘”经常重复问已经问过的问题。后来才明白上下文里需要保留一定的“连续性信息”让模型知道事情进展到哪了。过度压缩会破坏这种连续性。所以压缩要有度关键状态必须保留。6.2 工具描述也会吃掉大量 token很多人只关注工具返回结果忽略了工具本身的描述。一个 Agent 挂载十几个工具每个工具的说明、参数、示例加起来可能上千 token而且每轮都要带上。优化方法是只挂载当前任务可能用到的工具其余的工具动态加载。这样能省下不少上下文空间。6.3 顺序影响效果同样一组信息放在上下文开头和放在结尾模型的使用效果不一样。一般来说最重要的指令放开头最新的任务信息放结尾中间放支撑材料。这是利用了模型对首尾信息更敏感的特性。我调整过几次信息顺序任务成功率有明显变化这个细节值得花时间调。6.4 别忽视 API 层面的限制调用大模型 API 时除了上下文长度还有速率限制、并发限制、超时限制。这些都会影响上下文策略。比如速率限制紧的时候你就不能频繁调用摘要模型做压缩得改用规则压缩。所以上下文工程不是孤立的要和 API 使用策略一起考虑。7. 从零搭一个上下文管理模块的思路7.1 先定义上下文的“数据模型”动手写代码之前先把上下文抽象成一个数据结构。我一般会定义一个 Context 对象里面分几个字段system、task、tools、memory、history。每个字段有自己的 token 预算和压缩策略。这样后续所有操作都围绕这个对象进行逻辑清晰。7.2 压缩策略的可插拔设计压缩策略不要写死做成可插拔的。摘要压缩、检索压缩、结构化压缩各是一个策略类根据内容类型自动选择。这样以后想加新策略不用改主流程。我吃过写死的亏后来重构了一次才把这块理顺。7.3 监控与调优上线之后一定要监控上下文的 token 占用、压缩触发频率、压缩前后效果对比。我一般会记录每轮循环的上下文快照出问题时能回溯。调优是个持续过程没有一劳永逸的参数得根据实际流量不断调整水位线和压缩比例。8. 关于学习路线的一点个人建议如果你刚开始接触 AI Agent 和上下文工程我的建议是别一上来就啃架构图。先动手跑一个最小的 Agent让它调用一两个工具然后观察它的上下文是怎么增长的。你会亲眼看到 token 怎么被吃掉、上下文怎么变乱。有了这个体感再去学压缩、检索、记忆这些概念会顺畅很多。至于主流架构不用急着全学。先把“单 Agent 工具调用 上下文管理”这条线走通这是最核心的。多 Agent 协作、复杂规划这些等基础打牢了再上。我见过不少人一上来就搞多 Agent结果连单个 Agent 的上下文都没管好最后调试到崩溃。API 这块选一个稳定的平台先跑通调用流程理解 token 计费、上下文限制、缓存机制这些基础概念。不同平台的 API 细节有差异但核心逻辑是相通的。把一家的用熟换平台时迁移成本很低。上下文工程这件事说到底是在资源受限的条件下做信息调度。它没有标准答案只有不断权衡。窗口、成本、延迟、准确率这几个变量永远在互相拉扯。你要做的是找到适合自己场景的那个平衡点然后持续调优。我在实际项目里最大的体会是与其追求一次设计完美不如把上下文管理做成一个可观测、可调整的系统让它在运行中自己暴露问题你再针对性优化。这样比闭门造车靠谱得多。