从多智能体翻车到稳定落地:上下文工程实战指南 1. 从多智能体“翻车现场”说起上下文工程到底是什么先讲一个我亲眼见过的场景。某个系统里跑了三个智能体分别负责问答、推荐和订单查询。单看任何一个表现都还行。但只要丢进来一个稍微复杂的用户问题比如“我想买个适合跑步用的耳机顺便查一下昨天那单什么时候到”三个智能体就开始互相打架问答Agent把耳机推荐给做了推荐Agent又把订单信息答错了订单Agent因为拿到了一堆不相关的上下文直接返回了一串不知所云的默认话术。这个问题的根源不在模型能力而在上下文。你给每个Agent喂了什么上下文它就基于什么做判断。喂错了喂多了喂串了Agent就会一本正经地胡说八道。传统的Prompt Engineering解决的是“怎么把指令写清楚”但当你有多个Agent、多轮任务、多个信息源的时候真正要解决的是另一件事在每一轮交互中只把当前任务需要的信息以正确的结构和顺序放到模型的上下文窗口里。这就是上下文工程Context Engineering。上下文工程不是某个具体技术而是一整套关于“如何设计、构造、管理、审计模型上下文”的方法论。它包含三个核心能力预算管理控制上下文窗口的使用、规划结构决定信息的层次和优先级、动态装配在正确的时间注入正确的信息。它解决的是多智能体协作中三个最致命的问题上下文污染、Token浪费、跨Agent信息错乱。这篇文章不打算讲太多理论。我会从实际项目出发先解释上下文工程和多智能体之间的关系再给出可以直接落地的操作步骤、参数建议和踩坑记录。适合正在做多智能体系统的开发者、算法工程师也适合那些已经发现“模型能力够了但系统总是不稳定”的团队参考。先记住一个判断标准如果你的多智能体系统经常出现答非所问、上下文串台、日志里Token消耗高得离谱那大概率不是模型的问题而是上下文工程没做到位。1.1 一个典型的失败案例拆解上面提到的那个三Agent系统我用了一次完整的请求链路来做诊断。用户问的是跑步耳机和订单状态这两个问题分属两个垂直业务域。原始方案把所有历史对话、用户画像、商品库摘要、订单库摘要全部拼在一个长上下文里同时喂给三个Agent。从日志看一次请求消耗了近8000个Token其中真正和这次问题相关的有效上下文不到1200个。更麻烦的是信息干扰。订单Agent读到了耳机相关的商品描述就把“骨传导”“降噪”这些词当成了订单特征开始一本正经地编造物流信息。推荐Agent读到了订单数据里的发货地址就开始猜测用户所在城市的跑步路线。这些错误又被下一个环节当成“事实”继续使用错误就像滚雪球一样在Agent之间传递。这个问题就是典型的上下文规划缺失所有信息无差别供给所有Agent共享同一份上下文没有隔离没有优先级没有淘汰机制。后面我重构这个系统时做的第一件事就是把“一份上下文喂给所有人”改成“每个Agent单独装配自己的上下文”。效果立竿见影上下文消耗下降了60%错误率大幅降低。1.2 上下文工程和Prompt Engineering到底有什么不同很多人把上下文工程当成Prompt Engineering的进阶版这个理解不够准确。我把两者的区别用一个表格说清楚对比维度Prompt EngineeringContext Engineering核心目标把指令表达清楚把信息组织正确关注对象提示词本身进入模型的所有信息解决问题输出格式、语气、风格信息隔离、优先级、记忆、干扰工作单元单次Prompt多轮、多Agent、多信息源的上下文生命周期典型技术角色设定、Few-shot示例、输出约束Token预算、上下文规划、动态装配、记忆分层失败模式输出不符合预期上下文污染、Token爆炸、跨Agent误导这么说吧Prompt Engineering解决的是“让模型听懂人话”Context Engineering解决的是“让模型在复杂场景下一直听到对的、有用的、没有干扰的话”。在多智能体系统里Prompt写的漂亮只是基本功真正决定系统上限的是你怎么管理每个Agent看到的上下文。2. 上下文工程的核心要素预算、结构与动态装配上下文工程听起来玄乎落到实操层面就三件事先算账再立规矩最后按需装配。2.1 Token预算先算账再开工很多开发者在做多智能体系统时对上下文开销完全没有概念。我见过一个系统每个Agent的Prompt里塞了8轮历史对话、20条Few-shot示例、一份完整的产品手册再加一个实时检索结果。单次请求Token数轻松过万。更严重的是上下文窗口是有限资源一旦超出系统就只能做截断。而多数截断策略都是“砍掉中间保留头和尾”这会导致Agent丢失关键任务信息输出质量直线下降。我的建议是在每个Agent上线前先做一张Token预算表。以我常用的文本模型为例上下文窗口如果是32K Token那我会按以下比例分配用途预算占比参考Token数说明系统指令与角色定义8%约2560固定不变的部分当前任务输入30%约9600用户问题、当前请求参数动态检索结果35%约11200需要实时注入的知识/上下文历史对话摘要15%约4800不是全文是压缩后的结构化摘要输出预留10%约3200确保模型有足够空间生成回复冗余缓冲2%约640防止超限截断这只是一个参考模板不同场景要按实际情况调整。但核心原则是通用的每个Agent必须有明确的Token预算上限预算分配要固定防止某个环节无限制吞噬上下文。如果某个环节要用更多Token就必须从其他环节挪预算而不是无脑扩容。2.2 上下文规划明确“谁看什么”预算定完之后下一步是规划信息结构。多智能体系统里常见的错误是把所有Agent当成“全知全能”的节点让每个Agent都接触所有信息。正确做法是给每个Agent定义它的“信息边界”。我在实际项目中把上下文规划分成三个层次全局白板存放所有Agent都可能需要的基础信息比如用户ID、会话ID、当前业务阶段、全局约束。这部分上下文对所有人可见但必须严格控制长度一般建议不超过500个Token。任务卡存放当前任务专属的信息。比如订单查询任务任务卡只包含订单号、订单状态、物流轨迹。任务卡绑定到具体Agent其他Agent不会读取。角色档案存放某个Agent的专属知识、行为准则、输出格式约束。这部分信息和业务数据分离保证Agent的角色设定不被动态内容干扰。这套分层设计最直接的好处是信息隔离。订单Agent只看订单数据推荐Agent只看商品和用户偏好数据谁都不会拿到自己不该看到的信息。我改造上面的三Agent系统时就是用这个结构重新规划了每个Agent的上下文。订单Agent的上下文从8000Token降到了2000Token左右而且错误率明显下降因为它不再被无关的商品描述干扰。2.3 动态装配按需拼接上下文静态规划解决的是“什么信息归谁”动态装配解决的是“每个时刻注入什么信息”。这里的关键是时序和条件判断。我在实操中总结了一套“三段式装配法”第一段是基础段。包含系统指令、角色档案、全局白板。这段内容在会话开始时一次性加载通常保持不变。第二段是检索段。系统根据当前输入动态检索相关信息并注入。这个环节最核心的是检索质量上下文工程不只是“检索到相关内容”还要对检索结果做排序、过滤、去重。我经常看到很多团队直接把向量检索结果全部塞进上下文结果相关度低的内容占了大片Token反而把真正关键的信息挤掉了。我的做法是设置相似度阈值低于阈值的检索结果直接丢弃同时限制最多返回数量。第三段是任务段。包含当前轮次用户输入、任务执行状态、上一步Agent的输出摘要。任务段是最容易失控的部分因为多智能体系统里每轮交互都会产生大量中间结果。如果全部保留上下文很快会被撑爆。我的做法是只保留“上一步的结论摘要”不保留“上一步的全部推理过程”。3. 实操案例模拟项目X的多Agent客服系统上下文装配流程这个案例来自一个内部项目代号模拟项目X。它不是一个理论模型而是一个真实上线、真实跑了几个月的客服系统业务场景就是前文提到的那个翻车系统。我拿这个项目说明上下文工程的具体落地过程。3.1 系统架构与历史问题模拟项目X共部署了四个Agent意图识别Agent、售后客服Agent、物流查询Agent、质检Agent。用户发言先经过意图识别Agent再分发到对应业务Agent。如下图所示意的交互链路这里不用流程图我用文字描述用户输入 → 意图识别Agent判断意图 → 路由到售后或物流Agent → 业务Agent生成回复 → 质检Agent检查回复是否合规 → 返回给用户。这个链路看似清晰但上线初期问题非常多。最典型的是用户连续追问导致上下文爆炸比如用户先问“耳机怎么样”再问“那我的耳机订单呢”又追问“物流到哪了”最后加一句“顺便推荐个充电宝”。每一步都会把历史对话完整传给下一个Agent并且每个Agent都会重跑一次检索Token消耗迅速翻倍。3.2 可复用的上下文装配流程重构后的系统遵循五步装配流程每一步都有明确目的第一步初始化基础上下文。每个Agent构建自己的角色档案注入全局白板信息比如用户ID、会话ID、业务线标识、可用工具列表。这一步在会话建立时执行一次不随用户输入变化。第二步意图识别与任务拆分。意图识别Agent先判断用户本次输入涉及几个业务意图。上面的例子会被拆成“耳机咨询”“订单查询”“充电宝推荐”三个子任务每个子任务维护独立的上下文片段。第三步按意图检索边界信息。每个子任务只检索自己的业务域。耳机咨询只检索商品知识库订单查询只检索订单接口充电宝推荐只检索商品池。检索结果按相似度排序后取Top-K注入且K值由预算决定。第四步压缩历史上下文。系统不用原始历史对话而是用历史摘要替换。摘要由一个独立的“总结Agent”在每轮结束时生成格式是结构化JSON{已解决问题: ..., 当前任务: ..., 用户偏好: ..., 未解决问题: ...}。下一轮Agent读到的不是原始对话而是这份摘要。第五步输出后校验。质检Agent负责检查最终回复。这个Agent的上下文设计很特别它不看完整上下文只看三种信息——用户原始问题摘要、业务Agent的最终输出、质检规则清单。上下文越精简质检Agent反而越专注不会因为读到太多背景信息而被干扰。3.3 参数配置和实测数据重构前后的上下文Token用量和数据表现对比如下指标重构前重构后平均单会话上下文Token数约12000约3800平均响应时间3.5秒1.8秒回复无效率17.2%4.9%上下文超限触发率8.3%0.2%Agent串台错误率13.6%2.1%另外我给每个Agent单独配置了检索参数。意图识别Agent的相似度阈值设为0.65返回Top-3售后客服Agent的阈值设为0.72返回Top-5物流查询Agent比较特殊因为订单号是强结构化信息所以不走向量检索直接用精确匹配。很多人容易忽略这一点不是所有信息都该走语义检索。结构化信息用结构化查询准确率和效率都更高。这里还要强调一个容易忽略的细节动态装配完成后要对最终上下文做一次“完整性校验”。常见的做法是检查关键字段是否存在比如订单查询上下文里必须有order_id如果没有就直接终止处理而不是让模型硬猜。这个校验能拦截掉很多看似聪明、实则瞎编的回答。4. 多Agent场景下的记忆设计为什么“记忆”不等于“上下文”做多智能体系统时你会发现“记忆”和“上下文”这两个概念经常被混着说。但正式设计时它们必须分开。上下文是“当前窗口里模型能看到的所有内容”记忆是“跨会话、跨任务需要保留并能够被检索的结构化信息”。上下文是记忆的“投影”记忆本身存在外部存储里只有被检索出来并注入窗口时才成为上下文。4.1 三层记忆架构我在模拟项目X里把记忆分成了三层工作记忆只存在于当前会话内保存本轮任务的状态信息。比如“用户刚才问了耳机降噪效果正在挑选两款耳机”放在Redis里会话结束或超时后清空。它的特点是生命周期短、访问频繁。长期记忆跨会话保存使用向量数据库存储。保存的是用户偏好、历史投诉记录、历史购买行为等。它的检索方式是语义相似度检索和当前用户输入的嵌入向量做比对返回相似度最高的若干条记忆片段。超长期记忆保存业务规则、产品知识、合规约束。这部分内容通常更新频率低、权威性高不适合用向量检索更适合用规则引擎或知识图谱来查询。这套三层架构的核心逻辑是不同生命周期、不同检索方式的信息必须分开存储、分开管理。如果全部塞进一个向量数据库会导致“用户随口说的一句话”和“官方业务规则”被当成同等级的记忆来检索权重完全失衡。4.2 记忆的读写接口设计记忆层不能只是“存进去、查出来”还需要设计清晰的接口语义。我在项目中定义了四个基本操作write_memory(key, content, ttl, importance)写入记忆设置过期时间和重要性权重。read_memory(query, filters, top_k)读取记忆支持按业务域过滤。update_memory(key, content)更新已有记忆通常用于修正错误信息。delete_memory(key)删除记忆一般用于移除过时或错误的内容。这里有一个被很多人忽略的设计点记忆写入前要做“重要性校验”。不是所有对话内容都值得写入长期记忆。比如用户说“嗯”“好的”“谢谢”这些闭环话术没有任何记忆价值。我在项目里给每轮对话计算一个“记忆价值分数”分数低于阈值就直接丢弃。这个机制大大减少了向量数据库的无效写入和检索噪声。4.3 记忆淘汰与冲突解决记忆系统最容易犯的错是“只进不出”。时间久了向量库里塞满了过时信息检索结果越来越不准确。我必须定期做两件事第一是过期清除。给记忆打上创建时间戳和过期时间戳到期自动归档到冷存储不再参与常规检索。第二是冲突消解。当用户新说的话和历史记忆冲突时系统要以新信息为准。比如用户半年内多次咨询耳机但最近一次说“我又不跑步了想换个办公耳机”那系统就不能再把“跑步爱好者”这个标签当作用户偏好。我的做法是给每条用户偏好记忆附带一个“置信度”字段新信息覆盖旧信息时旧记录的置信度自动衰减。记忆层做完之后上下文工程的数据供给就闭环了不是找一堆数据堆给模型看而是从三层记忆里精准检索出“当前真正需要的那几条”带着明确的时效性和优先级注入到Agent的上下文窗口中。5. 多Agent上下文工程中的常见坑问题与排查实录上下文工程做起来踩坑是必然的。这里我整理了几个高频问题附上排查思路和解决办法都是可以直接抄作业的。5.1 Agent之间上下文污染这是多智能体系统第一大坑。表现形式是Agent A的输出被错误地当成Agent B的输入或者共享上下文里混入了本不该出现的业务数据。问题现象可能原因排查方法解决方案售后Agent回复了物流内容共享上下文混入物流信息查看日志中Agent输入快照强制拆分为独立上下文物理隔离推荐Agent引用用户订单号全局白板中字段未隔离检查全局白板的可见范围按Agent最小权限分配白板字段意图识别结果被后续Agent误读中间结果格式不明确检查是否有结构化字段标记中间结果必须使用JSON Schema强约束Agent之间互相“学”对方的错误某Agent的错误输出被另一切Agent当作事实引用查找日志中错误传播链路给每个Agent输出增加置信度标记低置信度结果不传递我的经验是排查上下文污染最有效的手段是“输入快照记录”。每次调用模型前把组装好的上下文完整写入日志出问题时直接检查快照内容一眼就能看出是哪个环节混入了不该有的信息。这个机制虽然会额外消耗存储但比猜测高效得多。5.2 Token被无效内容占满一个常见场景是上下文窗口明明很大但模型表现却很笨。打开日志一看几千个Token里全是重复的检索结果、冗余的历史对话、互相矛盾的旧信息。这个问题的根源通常有两个。一是检索环节没有过滤把所有相似结果一股脑塞进上下文。二是历史对话没有压缩原始对话越长占用的Token越多真正用于任务分析的空间越少。我的建议很直接给每个上下文环节设硬上限超了就截断或丢弃而不是“尽可能多塞一点”。另外对历史对话一定要用“摘要替代法”。我之前测试过5轮原始对话大约占用1500个Token换成结构化摘要后只需要400个Token而且模型对摘要的利用效果反而更好因为信息密度更高、噪声更少。5.3 幻觉被多级放大在单Agent场景幻觉只影响一个输出。在多Agent场景幻觉会被逐级传递。比如物流Agent猜测了一个不存在的发货时间质检Agent基于这个错误时间生成了“预计明天到达”的回复用户收到错误信息后投诉售后Agent在复盘时又把“物流承诺明天到达”当成了事实记录。这个问题的核心是中间环节的输出既没有被验证也没有被标记信任度。解决的思路有三个。第一关键事实必须经过工具调用验证不允许Agent“凭记忆回答”。比如查询发货时间必须调用物流接口拿到数据模型不能自己编。第二Agent输出必须附带置信度字段低于阈值的输出需要二次验证或人工介入。第三链路中的下游Agent只接受结构化任务结果不接受自由文本推测。5.4 上下文窗口截断导致行为突变很多团队上线后才发现同一个Agent短对话时表现正常长对话后突然变得“像个傻子”。大概率是因为上下文超过了窗口限制自动截断把关键信息给截掉了。排查方法是在日志里记录每次请求的Token数和截断策略。如果发现“截断位置恰好位于检索结果附近”那说明预算分配不合理。我的做法是给系统指令和高优先级信息设置“保护区间”即组装上下文时把最重要的内容放在窗口头部或尾部中间位置留给可牺牲的辅助信息。这利用了主流模型对头和尾的记忆更强、对中间注意力较弱的特点。5.5 工具选型和排查建议上下文工程对基础设施的依赖比一般人想象中高。我整理过一个最小工具清单供参考可观测性必须能记录每次模型调用的完整上下文快照和Token用量否则无法排查问题。向量检索需要一个支持过滤条件和相似度阈值的向量数据库。缓存层高频使用的上下文片段比如系统指令、角色档案可以做缓存减少重复消耗。摘要服务独立的历史对话摘要任务建议单独部署避免影响主链路响应速度。6. 上下文工程继续深化的方向评估与迭代到这里上下文工程的基本方法已经完整了预算管理、结构规划、动态装配、记忆分层、问题排查。但最后我想再聊一个常被忽略的环节——上下文评估。没有评估就没有迭代。大部分团队做上下文工程是靠“感觉”模型回答变好了就继续变差了就调一调。但多智能体系统涉及多跳任务评价“好和坏”很难凭直觉判断。我给一套轻量级的评估思路上下文精简率重构前后Token用量的对比衡量信息密度是否提升。单Agent任务完成率每个Agent独立完成其目标任务的比率。跨Agent一致性上下游Agent之间传递的信息是否一致是否有错误信息传播。用户侧无效回复率最终输出的回复中被用户认为“文不对题”的比例。这些指标不需要一次性全部上线先选一两个核心指标跑几周再根据数据调整上下文结构效果远好过无依据的频繁改动。最后分享一个我在实践中的小技巧每次修改上下文结构后保留一份旧版本的完整快照。不要只在线上改完就跑因为你很可能需要回头对比“到底是哪个改动让效果变好了”。上下文工程是一个持续迭代的过程不是一锤子买卖。把每次改动当作一次实验来对待系统才会越来越稳。