
做了两年多Agent项目我越来越觉得一个反常识的结论是对的真正让Agent变聪明的关键并不全在模型参数里更多在于你给它看什么。很多人把精力花在调Prompt、换更强模型、堆工具上结果项目还是经常“抽风”要么答着答着就忘了任务要么被一段工具返回带跑偏。这里面的核心短板几乎都是Context Engineering没做到位也就是上下文工程。Context Engineering直译是上下文工程。它管的是Agent在每一步推理时能看到哪些信息、按什么顺序看、哪些噪声被挡在窗外。大型语言模型本身像个超级实习生能力底子由参数决定但具体表现取决于你摆在它工作台上的资料质量。Agent开发里模型要完成规划、工具调用、记忆读写、多轮对话、多Agent协作这些本质上都是上下文读写。谁把上下文组织得干净、完整、有优先级谁的项目可靠性就高。这篇文章适合正在做Agent开发、准备Agent面试题或者已经用LangChain、LlamaIndex等框架但总觉得“差一口气”的人。我会从原理讲到实操再给一套可以直接抄的上下文对象设计、记忆分层方案、工具结果后处理流程以及我在生产环境里踩过的一堆坑。看完你会发现很多Agent框架和编排方案解决的是“流程怎么跑”而上下文工程解决的是“每一轮模型吃进去的东西是不是合格的”。而且“上下文工程”不是一个纯学术概念它就是一门工程手艺。它和Prompt Engineering最本质的区别在于后者调的是“话术”前者调的是“工作台”。话术只占工作台上很小一块真正的重头戏是资料、历史、工具结果、记忆状态和约束条件怎么摆放、怎么更新、怎么隔离。1. 为什么上下文工程是Agent开发的第一工程能力1.1 模型的智商有一半被上下文锁死先说一个很多人不愿意承认的事实语言模型在同一个任务上的表现会因为你给它看的信息组织方式不同产生巨大波动。不是模型变聪明了而是上下文工程让它能把已有能力发挥出来。我在一个项目里做过对比测试。同一个模型、同一个用户问题第一种方案把整本操作手册、全部历史会话、所有工具返回一股脑塞进上下文第二种方案先做信息筛选只放当前任务相关的步骤说明、最近几轮关键对话和工具执行后的摘要。后者的指令遵循率从67%直接跳到94%几乎翻了一倍。这说明什么模型在长上下文里的注意力会衰减。你给它塞一堆无关日志它不仅不会“广纳百川”反而会被噪声干扰把用户最关心的任务淹没。尤其是Agent开发里模型需要在一个上下文窗口内同时理解目标、历史、工具约束、数据快照确实很容易超载。上下文工程不是可选项是决定Agent稳定性的关键上限。1.2 Context Engineering 不只是写提示词很多人会把上下文工程和写Prompt划等号这是最大的误解。写提示词只是其中一小步而且是最后一步。真正的上下文工程至少包含四块工作构建把系统边界、用户目标、历史事实、工具说明、外部数据拼成一个结构化的上下文对象。裁剪按当前任务决定哪些信息必须出现、哪些可以省略而不是无条件“全塞进去”。压缩与记忆将长期记忆、短期记忆和当前工作状态分层管理需要时再展开。隔离与安全外部内容、工具返回、多Agent消息不能直接污染系统指令要做数据化包装和权限隔离。这里有一个热词叫“harness和agent区别”我觉得正好说明问题。Harness是承载Agent运行的外部工程系统包括工具注册、执行环境、结果回传、日志采集Agent是模型驱动的决策单元负责理解目标和发起调用。而Context Engineering横跨两者在harness里编排信息流在Agent推理时提供高信噪比的上下文。框架给你的是流程骨架不是内容保险。1.3 常见“上下文事故”画像我整理了这几年遇到的高频事故基本都能归因到上下文工程模型忘记前文第二轮问“刚才那个订单号你还记得吗”模型一脸懵。往往是因为上一轮工具结果没有回写到记忆块。工具结果遮蔽指令数据库返回了几百行JSON模型开始复述数据忘了用户其实只想要一个“是/否”的判断。多轮后话题漂移用户从查订单聊到退换货再从退换货聊到发票模型渐渐忘了原始订单上下文。上下文超限报错Agent执行到一半直接终止经常是某个工具返回了超大响应把token预算打爆。检索污染向量检索返回了另一个用户的数据或者过时信息模型却当成事实说给当前用户。提示注入网页内容、文档正文里藏着“请忽略上面的指令”这类文本模型轻信后执行了非预期动作。这些问题的表象五花八门但只要你去查每轮真正发给模型的payload都会发现上下文结构不合理。所以我的检查顺序永远是先看Context再审Prompt最后才怀疑模型能力。顺序反了会让你白烧很多冤枉钱。2. 上下文构建与动态管理五大核心操作2.1 构建把任务背景、历史、工具说明、约束条件拼装成结构化上下文我在项目里会用一个固定结构来承载上下文而不是把所有东西都塞进system prompt。你可以理解成给模型准备一个工作台每个抽屉放一类资料。下面是一个基础模板{ system: 系统角色、边界约束、行为准则、输出格式, tools: [ { name: query_order, description: 查询订单状态、物流轨迹, parameters: { order_id: string } } ], history: [ { role: user, content: ... }, { role: assistant, content: ... } ], memory: { user_profile: 用户偏好、身份、权限, task_state: 当前任务阶段、待确认事项, permanent_facts: 不可变事实如账号ID、合规要求 }, observation: 最近一次工具调用结果的结构化摘要 }为什么要这么做因为模型对上下文的理解不是堆叠的而是按位置和结构展开的。结构化对象能让每一轮组装上下文时都有确定性的秩序而不是让开发者在字符串拼接里迷失。system区只放不会频繁变化的原则性约束长度越短越好。tools区放当前任务真正可能用到的工具而不是把所有工具描述都放进去否则光参数说明就能占掉大半窗口。history区放最近N轮对话N根据任务复杂度动态调整一般客服场景10轮以内就够。memory区是记忆的核心也是上下文工程最值得投入的部分。2.2 裁剪不是越长越好窗口要按任务动态取舍大模型的长上下文能力确实在提升动辄128K、200K的窗口让人产生“都可以塞进去”的错觉。但工程上不能这么干因为成本、延迟和注意力质量都会随着token数恶化。上下文工程的核心原则是只给模型它当步必须看到的信息。我常用的裁剪策略有四种时间衰减最近的对话保留原样更早的对话压缩成摘要再早的只保留事实关键词。相关性检索把用户消息向量化从记忆库里的Top-K相关片段注回与当前问题无关的段落不放。实体维度识别当前任务涉及的实体比如订单号、用户名、商品ID只保留与这些实体相关的内容。优先级调度当前目标和工具调用状态放最前面其次是约束条件最后才是补充资料。举一个真实例子。用户问“我昨天买的那个耳机发货了吗”这时候需要的上下文是用户近7天的订单列表、收货地址、物流更新。他三个月前问过的“有没有降噪耳机推荐”属于无关历史可以直接裁掉最多保留一条摘要“用户曾关注降噪耳机”。裁剪不是简单删数据而是把不重要的东西降级存储需要时再通过摘要或检索捞回来。2.3 压缩与记忆分层短期、长期、永久记忆的工程实现Agent记忆是热词里出现频率很高的方向。很多初学者会直接把历史消息全部丢进向量库需要时再查。这样做不是不行但混淆了“记忆”和“检索”的边界。真正生产级的记忆至少要分四层短期记忆当前会话最近几轮的原样内容通常就是messages数组本身无需落到持久化存储。工作记忆当前任务进行到哪一步、已经做出什么决策、等待什么反馈。用task_state对象维护每轮必须放在上下文靠前位置。长期记忆用户偏好、历史结论、项目档案。通过向量检索按需注入但必须附带时间和来源避免“旧信息当新事实”。永久记忆用户身份、账号权限、合规要求等不可变事实直接从数据库确定性读取不走相似度匹配。这四层之间的关系我用一个类比解释短期记忆是桌面上的便签工作记忆是正在填写的主任务表单长期记忆是办公室的文件柜永久记忆是墙上贴的消防条例。上下文工程的任务就是决定哪些便签留在桌面、哪些文件需要临时拿出来、消防条例永远贴在显眼位置。向量检索在长期记忆里很有用但不能过度神话。它适合回答“和这个问题语义相关的历史内容”不适合回答“这个用户的准确身份是什么”。所以我在工程里会同时维护一个关系型实体表和一个向量索引前者保证确定性读取后者提供模糊召回。2.4 工具调用上下文函数定义、结果摘要与状态回传工具调用是Agent开发和普通聊天最大的差异点也是上下文工程最复杂的环节。这里的上下文至少有三种来源工具定义本身、工具执行后的返回结果、工具执行产生的状态变化。工具定义最怕臃肿。如果你把函数的全部参数说明、枚举值、校验规则都塞进上下文模型选择工具时会被信息干扰。精简做法是只放模型决策必需的信息工具名、一句话说明、关键参数、必需参数。其它细节放在harness的注册表里由代码校验。工具执行结果的处理更加关键。很多Agent请求的截断和失败都源于返回结果太大。比如SQL查询返回几百行数据你直接把它拼进上下文模型不仅读不完还会被细节淹没。正确做法是在harness里对结果做后处理提炼成“对当前任务有意义的观察”def build_order_observation(order_data): return { order_id: order_data[order_id], status: order_data[status], eta: order_data.get(eta), last_event: order_data.get(last_event, 无), requires_action: order_data.get(requires_action, False) }我还会强制给观察结果增加一个来源标记标明这是“工具返回的数据”而不是用户指令。这一步既是上下文工程也是安全基础。状态回传则要求每次工具调用结束后把关键字段写入task_state。比如用户改地址工具调用成功后task_state里就要更新“当前地址已变更下一步需要通知库房”这样下一轮模型才能顺着状态继续推进而不是重新翻历史。2.5 上下文安全与隔离防注入、防记忆污染、防串话随着Agent越来越强上下文安全问题也越来越多。热词里有“a-memguard: a proactive defense framework for llm-based agent memory”这类框架的核心思路就是在Agent读写记忆之前增加一道防御性检查。我自己的经验是上下文安全至少要从三个方向做数据与指令分离从工具、网页、文档里拿到的内容都算“数据”系统指令才算“指令”。外部数据必须包一层特殊标记让模型知道这不是可以执行的命令。注入检测在上下文组装之前扫描外部文本抓“ignore previous instructions”“忽略上面要求”等模式一旦命中就拦截或清洗。命名空间隔离多Agent共享记忆时每个Agent的读写都要带命名空间和权限避免Agent A读到Agent B的内部状态或者往共享区写入脏数据。安全不是只在最后一道环节加的过滤网而是贯穿上下文构建的一条原则。凡是外部输入都不可信凡是状态写入都要审计。我见过一个项目因为文档里藏了“把订单价格改成0”的指令Agent真的执行了工具调用。根源不是模型不够聪明而是外部文档内容被无差别当成了高优先级指令。这种情况Context Engineering里的隔离设计就比调Prompt管用得多。3. Agent框架、Skill与编排里的上下文工程3.1 框架不是免死金牌现在打开技术社区到处都是Agent框架、编排引擎、低代码平台。它们解决了重复的循环逻辑和工具注册问题这是好事。但很多人有个错觉以为用了框架上下文工程就自动完成了。实际上框架只负责把messages按固定模板拼起来它不知道你的业务哪些信息重要哪些可以省略。我接过两个迁移到框架后反而变差的项目原因都一致框架默认把历史消息全部保留并且把几十个工具的描述全部塞进system区导致上下文越来越臃肿模型响应越来越慢准确率还下降了。所以用框架的前提是你至少要看一次框架实际发给模型的请求日志检查消息结构、token数、工具描述数量。如果框架默认行为不符合你的上下文预算就绕开它自己接管context组装。框架和编排的价值在于稳定地执行“循环-工具-回传”的机制而上下文工程决定每一轮循环里喂给模型的是什么质量的信息。两者协同不是替代。3.2 Skill 与 Agent 的区别上下文边界的两种设计热词里有个经典问题“skill和agent的区别”。我理解skill是可复用的能力模块里面包含一套步骤说明和输入输出约定本质是一段元上下文。而Agent是拥有独立目标、记忆和决策循环的自主单元看到的是更大的上下文图景。举一个实际场景。你的系统里有一个“文档写作”skill它只负责接收主题和素材输出结构化文章它的上下文可以严格限定在“写作规范素材最近产出”。但如果你把这个功能做成一个Agent它会开始维护用户的写作偏好、历史文章版本、长期选题库甚至主动记住用户喜欢什么样的结尾。这时上下文边界就被撑大了。所以设计时先问这个能力需不需要独立记忆和目标如果不需要用skill即可省上下文、好维护。如果需要在长时间内保持状态或者需要和其他能力协作再用Agent。Skill与Agent的边界本质上就是上下文边界的边界你需要根据任务复杂度理性选择不是所有东西都做成Agent才显得高级。3.3 Multi-Agent 协作消息传递、共享黑板、记忆同步中的上下文一致性多Agent协作是热门方向也是上下文工程最容易失控的地方。我参与过的多Agent项目里三种常见的协作模式各有优劣消息传递Agent之间通过结构化消息通信上下文只包含消息本身。优点是隔离清晰缺点是信息容易丢失或重复。共享黑板多个Agent读写同一块公共状态上下文可以实时看到全局。优点是信息同步快缺点是谁都能改容易冲突和污染。记忆同步多个Agent共享一套长期记忆库按需检索。优点是灵活缺点是需要解决写入冲突和时效性问题。我用一个表格来对比模式优势主要上下文风险适用场景消息传递隔离清晰、易追踪丢消息、上下文碎片化任务边界明确的流水线共享黑板全局状态实时可见并发写入、信息污染需要全局协同的复杂任务记忆同步按需召回、可扩展旧信息误用、越权读取需要长期用户记忆的场景多Agent上下文工程的关键不是让所有Agent都看同样的东西而是建立一套“上下文路由”规则。比如路由Agent只负责理解用户意图和分发任务它不需要看业务数据库执行Agent需要业务数据和工具权限但它不需要关心用户的情感语气。每一条消息都要带topic和target单个Agent可以订阅自己关心的topic避免被无关消息刷屏。这样既保证信息完整又防止上下文膨胀。3.4 观察性与调试从日志还原Agent的“上下文现场”没有观测的上下文工程等于盲人摸象。Agent出现幻觉或者误判的时候你唯一能依靠的证据就是真实发送给模型的那份payload。所以我强烈建议从项目第一天就建立上下文审计日志记录以下内容每一轮实际组装出来的messages完整内容脱敏后。每个上下文区块的来源是检索命中、历史记录、工具结果还是系统注入。token数统计尤其是各区块的占比和总量。工具调用的输入、输出摘要和状态。上下文裁剪规则触发了哪些策略。我之前排查过一个很诡异的Agent问题用户明明问的是A订单模型却总在回答B订单。查日志发现历史消息里有一段很靠前的旧会话里面包含另一个订单的信息系统把两段历史全部保留了。找到原因后我在上下文组装时增加了“实体过滤”规则保留与当前query相关的订单问题瞬间消失。这个项目如果没做上下文日志恐怕要排查好几天。4. 实操案例给一个带记忆的工具调用Agent做上下文工程4.1 场景与需求一个能查询订单、执行SQL、发送通知的客服Agent为了把前面的原理落到地面我们设计一个真实的客服Agent项目。需求是用户可以在对话框里查订单状态、修改收货地址、申请退款Agent需要理解用户意图调用订单库、物流接口和通知接口并在多轮对话中保持状态。这个项目的上下文工程目标非常明确让模型在每一轮都知道当前用户是谁、正在处理哪个订单、已经走到哪一步、下一步有哪些约束。如果做到这几点模型即使面对复杂多轮对话也能稳定执行。4.2 上下文对象设计Messages、SystemBlock、ToolMemory我给的模板可以直接套用{ system_block: { identity: 你是客服助手只处理订单相关问题, constraints: 修改地址前必须经用户确认退款金额不能超过订单实付金额, output_format: 回复不超过5行需要调用工具时先说明意图 }, messages: [ {role: user, content: 你好我昨天买的耳机显示发货了但地址填错了} ], tool_memory: { last_action: query_order, order_id: A12345, order_status: 已发货, shipping_address: 旧地址北京市..., requires_action: true }, user_profile: { user_id: U88, vip_level: normal, contact_preference: 短信通知 } }关键点是把task_state按优先级放在很靠前的位置。我在实际项目里发现模型如果能在生成前直接读到“当前任务状态”它会自然地继续这个状态而不是从十几轮历史里去拼线索。每轮对话结束时我会写一个小的状态更新逻辑如果工具调用成功修改了地址task_state就会从“需要确认新地址”变成“地址已更新等待用户确认通知方式”。这样上下文里的工作记忆永远是最新的不会产生记忆断层。4.3 检索式短期记忆向量库 最近N轮 实体摘要客服场景下用户可能隔几天再来这时近期会话已经不在窗口里但Agent应该记住关键信息。我的做法是同时用三种机制最近N轮对话原样保留保证对话连续性。向量库检索从历史会话中搜索与当前问句语义相关的片段。实体摘要表维护订单号、收货地址、售后状态、用户偏好等结构化字段。用代码表示大概是这样的思路def build_user_context(user_id, query): recent_msgs get_recent_messages(user_id, limit10) entity_keys extract_entities(query) related_docs vector_store.search(user_id, entity_keys, top_k5) profile profile_store.get(user_id) task_state task_store.get(user_id) return assemble_context(recent_msgs, related_docs, profile, task_state)这里有一个容易踩的坑向量检索回来的内容不一定准确。比如用户问“退货”检索可能把几个月前另一个订单的退货流程也捞出来造成混淆。所以我对检索结果会加三个字段timestamp、source、confidence。模型看到这些元信息后会自然区分“这是历史信息”和“这是当前事实”。4.4 工具结果的后处理从原始返回生成“对当前任务有意义的观察”客户Agent的典型工具是查订单。假设工具返回了这样的原始数据{ order_id: A12345, customer_name: 张三, items: [{name: 蓝牙耳机, qty: 1, price: 299}], status: shipped, carrier: 顺丰, tracking_number: SF123456, events: [已揽收, 到达转运中心, 运输中], estimated_delivery: 2025-07-18 }我不会把整段JSON直接扔给模型。harness会先判断用户最关心什么字段。如果用户问“发货了吗”我只保留status、carrier、tracking_number和estimated_delivery。如果用户问“买了什么”我会保留items字段。这个取舍逻辑必须在harness里写死而不是让模型自己挑。工具失败的处理也一样重要。我会把异常转成结构化信息{ tool_name: query_order, success: false, error_code: ORDER_NOT_FOUND, message: 未找到订单请核实订单号, recommended_action: 询问用户提供正确订单号 }模型收到这种结构会自然进入“向用户要正确订单号”的流程而不是对着原始异常日志发呆。Agents执行的稳定感其实就来自这些细节。4.5 多轮状态修正与上下文预算多轮对话里最常见的失败是模型在第三步忘记了第一步的结论。解决方式就是维护task_state对象并把状态更新当作每次工具调用后的强制动作。我还会在每次组装上下文前计算token预算并设一个固定的分配比例system_block不超过500 token。工作记忆与user_profile不超过500 token。最近N轮对话不超过2000 token。工具观察不超过1500 token。给模型生成的预留空间剩余全部。一旦历史或检索内容超过预算就触发摘要。摘要由模型生成还是由抽取规则生成要看你的一致性要求。我的经验是关键字段用规则抽取叙述性内容用模型摘要各干各的活。这里有一个很实用的心得上下文预算不是固定值而是按任务复杂度动态调。比如查物流这种简单任务总预算可以压到3K token而处理退款纠纷这种复杂任务总预算可以放宽到8K。预算的目标是让模型在“信息充分”和“注意力集中”之间找到平衡。4.6 评估上下文工程做得好不好用什么指标很多项目上线后都靠人工肉眼判断Agent表现这不行。上下文工程是可度量的我建议至少跟踪以下指标指令遵循率模型是否按约束执行比如“改地址前必须确认”。关键实体召回率轮次结束时订单号、地址、金额等关键字段是否一直保持准确。无关信息占用率上下文里与当前任务无关的token占比。上下文超限率因为超长而终止或截断的请求比例。工具误用率调用了错误工具或错误参数的比例。注入拦截率外部内容中被检测并拦截的恶意指令数量。这些指标需要一套回归测试集支撑。我会定期从线上日志里抽取100个用户问题标注正确答案和正确工具调用序列跑一遍上下文组装逻辑。只要改动上下文规则就全量回归一次防止修好一个问题、打破一片场景。这个实践让我在迭代上下文工程时心里有底。5. 常见问题与排查技巧实录5.1 Agent执行中途终止/报错上下文截断与工具结果异常热词里有“agent execution terminated due to error.”我想很多人见过类似报错。这类问题七成出在上下文超限三成出在工具返回格式异常。排查顺序我固定为这样看Agent在哪一轮终止读取该轮实际发送的payload。检查token总量是否接近模型上下文上限。检查是历史消息过长还是某个工具返回了超大JSON。如果是历史过长启用滚动摘要。如果是工具返回过大限制返回行数并做后处理摘要。还需要注意框架对超长上下文的默认行为可能是截断而不是报错。截断后模型看不到尾部信息往往会输出一个奇怪的半截答案。所以不要只看错误日志还要看截断日志。我把这个检查项放进日常监控一旦发现截断就立刻告警。5.2 模型“失忆”上下文被清空或未传递模型“失忆”是Agent开发里最烦人的问题。现象通常是第二轮问“刚才说的那个订单号是什么”模型说“我不知道你在说什么”。可能原因有四个框架每次请求从数据库重新拉取历史但拉取逻辑遗漏了工具调用结果。系统提示词里没有把memory区块放进去模型压根看不到历史状态。上一轮的工具调用结果没有回写到task_state。多Agent消息传递时目标Agent只收到了新消息没收到之前的上下文。排查方式是检查相邻两轮请求的messages列表看是否包含上一轮的关键实体。如果缺失就顺着上下文组装代码找断点。我通常会加一个“会话连续性自检”在每轮开始前用规则确认当前task_state里有没有至少一个实体ID没有就说明前面的上下文没传下来。5.3 工具结果淹没主任务没有完成上下文降噪这是把Agent当“搜索引擎”用时常犯的错。工具返回的原始内容一多模型就开始不着边际地复述而不是完成当前任务。我遇到过一个项目给模型塞了整篇维基百科内容结果它滔滔不绝讲历史就是不给用户要的“是/否”判断。解决方案是强制“观察式输出”任何工具结果在进入上下文前必须经过一道精简转换提炼成三到五条事实。如果原始内容确实需要保留全文也要放在一个低优先级的区块里并且明确告诉模型“这是参考资料不是任务主体”。上下文降噪不是丢信息而是改变信息的呈现密度和顺序。5.4 上下文污染的典型症状与清理方案上下文污染比上下文缺失更隐蔽。污染来源多种多样旧版本系统提示词残留在历史里检索结果混入了其他用户的数据工具输出里的特殊字符被模型读成了指令共享记忆没有按Agent隔离。症状也很有识别度模型突然提到当前用户不知道的信息说话风格突变像是被另一段Prompt带走了开始执行与当前任务无关的动作。清理方案是三管齐下给系统提示词加版本号每次请求都从配置中心重建而不是从历史里继承所有外部检索内容包一层“来源标记”共享记忆加命名空间并做越权读取检测。这个防线越早做越省心等线上出了问题再补齐代价会大得多。5.5 多Agent消息风暴与重复推理用上下文路由解决多Agent协作时我见过最夸张的一个项目工作区里同时有12个Agent在跑每个Agent都把所有消息当上下文读结果每个模型都开始重复分析同一件事还互相干扰。这是典型的信息过载型上下文事故。解决思路是上下文路由。我给消息增加topic和target字段只有订阅了该topic的Agent才会收到。共享黑板按领域分区块比如“订单区”“物流区”“退款区”每个Agent只挂在自己负责的区。同一topic的多条消息每隔一段时间合并成一条摘要发布而不是逐条广播。这套机制下来每个Agent的上下文干净很多整体token成本也直接下降了一个量级。5.6 外部预设加载失败与配置隔离问题热词里有一条“无法加载agent预设。client api: agentpresets/list failed: failed to fetch”这句话我在实际开发中也见过类似场景。Agent开发一旦涉及本地配置源、远程预设服务、环境变量就会遇到配置加载失败的报错。它不是模型问题而是上下文工程里的环境隔离问题。排查顺序建议先确认配置文件是否存在、权限是否正确再确认API服务是否可访问、返回结构是否符合预期最后检查环境变量是否注入了正确的部署环境标识。这个报错本身并不难修但它提醒我们Agent的上下文里如果包含配置信息必须区分环境绝不能把本地的调试配置带到生产环境里。我还会让上下文组装器在启动时自动加载一份“环境清单”确保哪些配置该注入、哪些不该注入从一开始就只有一套明确的规则。6. 从面试到生产上下文工程能力的进阶清单6.1 面试题背后的核心考点Agent开发面试题里很多问题表面在问框架、问概念实际都在绕着上下文工程转。比如“Agent是怎么记忆的”考记忆分层与持久化设计。“上下文超限了怎么办”考压缩、摘要、结构化取舍。“多个工具返回结果冲突模型怎么选”考工具的上下文消解。“怎么让Agent记住多轮任务不遗忘”考工作记忆回写。“Agent被提示注入攻击怎么办”考上下文隔离与安全。我的答题框架是先讲上下文组织模型再给一个具体实现最后补评测方式。千万别只背Prompt模板面试官一听就能分辨你是真做过还是看过教程。一个能脱口说出“我在每轮组装前用正则提取实体并校验task_state”的候选人通常比只会说“我调用了LangChain”的候选人更靠谱。6.2 生产环境上下文工程安检清单上生产之前我会用下面这张清单检查所有Agent项目每轮请求是否能在日志里完整还原当时的上下文是否有token预算和超限保护机制系统提示词是否固定并与历史消息隔离工具结果是否做了降噪和结构化摘要多Agent之间是否做了命名空间和topic隔离向量检索结果是否携带时间和来源元信息外部输入是否被当作数据处理而非指令是否有回归测试集能监听上下文改动带来的准确率变化任何一项不满足我都会觉得项目的可靠性是悬着的。上下文工程不是锦上添花它是支撑Agent在生产环境里稳定运行的地基。地基不牢早晚要返工。6.3 后续扩展方向记忆框架、防御框架、评估体系接着你会问这个方向该怎么继续深入。我观察到的趋势有三个第一记忆框架越来越成熟。现在有基于向量库的长期记忆服务也有把记忆拆成实体、事件、时间线的工具。选型时不要只看stars要看它能不能满足你的“确定性读取”要求以及管控写入冲突的能力。第二防御框架开始重视记忆安全。类似A-MemGuard这类主动防御框架会在Agent读写记忆之前做检测拦截注入样本和越权访问。这和传统的输出过滤墙不同它是把安全前置到了上下文入口。第三评估体系开始组件化。你可以把Context Engineering度量嵌入CI每次改动都跑一次回归集量化上下文质量的波动。没有这个闭环优化上下文永远凭感觉。6.4 给新手的一个最实在的建议最后说点我自己的经验。如果你刚开始做Agent开发别急着套高级框架先手写一个最小循环读用户消息、组装上下文、调用模型、解析工具调用、执行工具、回写记忆。手写一遍之后你对Context Engineering每个环节的感知会完全不同。等你跑通了这个最小循环再引入框架你就能分辨哪些活框架替你做得好哪些活必须自己接回来。这个认知会让你在项目里少走很多弯路。我个人做项目时还有一个习惯给上下文工程建一个固定工具箱。里面放一套上下文数据结构、一套组装代码、一套日志模板、一套回归用例和一套预算计算脚本。每次开新Agent项目直接把这套工具箱搬过去改配置效率翻倍。今天你看到的这些方案基本都是从这些工具箱里沉淀出来的。如果对着框架黑盒调来调去你永远不知道Agent到底看到了什么也就永远无法真正掌控它的行为。