你接入了最强的模型写了一个 Agent结果它表现得像个实习生答非所问、乱调工具、忘了前面说过什么。你第一反应是模型不行于是换更贵的模型——然后发现没什么改善。问题大概率不在模型而在上下文。这篇文章讲清楚什么是上下文工程Context Engineering以及怎么系统化地把正确的信息、用正确的格式、在正确的时机喂给模型。一、90% 的 Agent 失败都不是模型的锅打个比方。你请来一位顶尖维修专家对他说帮我修好这台机器。他失败了——不是因为他不行而是因为你没告诉他机器型号、故障现象、维修手册、可用工具。换种说法“帮我修好这台机器。型号 X-200故障是异常噪音这是维修手册第 3 章可用工具有扳手、螺丝刀、万用表。”同一个专家立刻解决问题。差别不在能力在上下文。Agent 也一样。一个被广泛认同的经验法则是Agent 失败的原因 ❌ 10% 因为底层 LLM 能力不足 ✅ 90% 因为没有传给 LLM 正确的上下文所以Context Engineering上下文工程的定义就是以正确的格式为 LLM 提供正确的信息和工具让它能完成任务。这是 AI 工程师的首要工作。它不等于提示词工程很多人把上下文工程简化成怎么把提示词写好这远远不够Prompt EngineeringContext Engineering关注单次提示词怎么写更好整个上下文系统怎么设计范围一句提示词的内容和结构给什么、为什么给、给多少、何时给、如何压缩与维护提示词工程 ⊂ 上下文工程。提示词只是上下文的一部分上下文工程还要管对话历史、工具、记忆、状态、检索……它是这些技术的编排者而不是其中任何一个。二、一个贯穿全文的比喻上下文工程 给决策者备简报的幕僚长把模型想成一个日理万机的决策者高管而你上下文工程师是他的幕僚长决定什么材料送到他桌上、什么被过滤掉、调哪份档案、哪些当下要看、哪些只是背景参考。整篇文章你只需记住这个比喻后面所有概念都能对号入座——而且每一项的核心动作都是为决策者筛选并适时递送信息概念幕僚长比喻作用模型本身做决策的高管它的本职就是决定调工具还是直接答Context Engineering幕僚长的工作策展/筛选——决定什么上桌、什么拦下Model Context今天这场会的简报本单次调用的输入开完即作废Tool Context助理去调档、更新档案工具读写的数据改了后面一直生效Life-cycle Context幕僚长的把关流程控制执行流程不替高管做决定Middleware各环节的幕后人员钩入流程的每个环节三、Agent 的核心循环上下文在哪里被喂进去理解上下文工程先看 Agent 怎么转用户输入 → 【模型调用】传入提示词工具→ 需要调工具 ├─ 是 → 【工具执行】→ 工具结果 → 回到模型调用 └─ 否 → 输出答案上下文工程就是在这个循环的每一步决定传入什么、何时传入、如何更新。下面三大维度正是对这个循环不同环节的控制。四、三大控制维度瞬态 vs 持久这是整套体系的骨架。关键区分是瞬态只影响这一次还是持久跨步骤保留。维度一Model Context模型上下文—— 瞬态只影响单次模型调用演完就结束。包括系统提示词模型的角色“你是客服助手”消息历史当前对话可用工具这次能调哪些工具模型选择用哪个 LLM响应格式结构化输出的 Schema比喻今天这场会的简报本。每次内容不同开完即作废不影响下一场会。维度二Tool Context工具上下文—— 持久工具对数据源的读写效果会留下来影响后续工具执行时 读取查数据库、取用户偏好、读配置 写入更新会话状态、改长期记忆、记日志比喻助理去调档、更新档案。一旦改了某条记录后续所有人看到的都是新状态。维度三Life-cycle Context生命周期上下文—— 持久控制模型调用与工具执行之间的逻辑——对话摘要、护栏检查、日志、动态提示词、模型切换。比喻幕僚长的把关流程。不替高管做决定但决定什么先递、什么拦下、何时提醒、何时收尾。五、三大数据源信息从哪来活多久控制维度是怎么管数据源是管的东西从哪来。三者生命周期不同数据源生命周期作用域装什么Runtime Context单次调用会话内用户 ID、API Key、环境标志静态配置State会话期间会话内消息历史、上传文件、认证状态短期记忆Store永久跨会话用户偏好、历史画像长期记忆对应代码大致长这样# Runtime Context调用时传入的静态配置dataclassclassAppContext:user_id:strenvironment:str# dev / prodrole:str# admin / viewerresultagent.invoke({messages:[...]},contextAppContext(user_idu1,...))# State会话内的短期记忆会话结束即消失state{messages:[...],uploaded_files:[...],auth_status:True}# Store跨会话的长期记忆runtime.store.put((users,u1),preferences,{language:zh,theme:dark})prefsruntime.store.get((users,u1),preferences)# 下次会话还在一句话记忆Runtime Context 是这次的配置State 是这场对话的记忆Store 是永久的档案。六、落地机制中间件Middleware前面都是该做什么Middleware 是怎么做——它能钩入 Agent 生命周期的任何一步用户输入 → before_agent 会话级钩子 → before_model 模型调用前 → wrap_model_call 包裹模型调用 → 【模型调用】 → after_model 模型调用后 → wrap_tool_call 包裹工具调用 → 【工具执行】 → after_agent 会话级钩子 → 输出 / 回到循环很多常见需求官方已有内置中间件别自己造轮子。比如对话超长时自动压缩历史fromlangchain.agents.middlewareimportSummarizationMiddleware summarizerSummarizationMiddleware(modelgpt-4-mini,trigger(tokens,4000),# 超过 4000 token 触发keep(messages,20),# 保留最近 20 条)agentcreate_agent(modelgpt-4,middleware[summarizer])或者根据用户角色动态过滤工具非管理员看不到危险工具before_modeldeffilter_tools_by_role(state,runtime):ifruntime.context.role!admin:request.override(tools[tfortinrequest.toolsift.namenotin[delete_record,admin_tool]])returnrequest七、最容易踩的坑瞬态 vs 持久更新这是上下文工程里最常见的误解单独拎出来讲。同样是往消息里加一条指令用不同钩子效果完全不同# 瞬态只影响本次调用State 历史不变wrap_model_calldeftransient_change(state,request,handler):request.messages[SystemMessage(额外指令)]request.messagesreturnhandler(request)# State 没动# 持久永久改变 Statebefore_modeldefpersistent_change(state):return{messages:[SystemMessage(额外指令)]state[messages]}# State 被更新典型翻车现场在wrap_model_call里改消息以为改了对话历史结果只有这一次调用看得到下一轮就没了。记住想只这一次生效如临时注入一条约束→瞬态wrap_model_call想永久留在历史里 →持久before_model返回 dict 更新 State八、几条高价值实践1. 从简开始。先用静态提示词 固定工具跑通验证确实需要后再加动态逻辑。不要一上来就上一堆中间件。2. 增量测试。一次只加一个特性静态 → 动态提示词 → 工具过滤 → Store 记忆方便定位问题。3. 工具定义就是给 LLM 的说明书。名称、描述、参数说明不是元数据而是引导模型推理的关键# ✅ 好说清做什么、何时用、不适合什么tooldefsearch_web(query:str,max_results:int5)-str:搜索互联网获取最新信息。当你需要实时数据、新闻或事实时使用。 不适合用于本地数据库查询或计算。 Args: query: 搜索关键词2-10 个词 max_results: 最大返回结果数 # ❌ 差模型不知道何时该用tooldefsearch(query:str)-str:搜索。4. 工具数量要适中5~10 个为佳。太多50→ 上下文过载、模型混淆、乱调太少只给 1 个→ 能力受限、模型用文本硬编替代工具。需要时动态过滤工具集。5. 别把所有信息一次性塞进去。10 万字文档全文、500 条历史、50 个工具——这是上下文过载的标准姿势。正确做法RAG 检索相关片段、Summarization 压缩历史、动态过滤工具。九、总结上下文工程的本质是围绕模型每次调用的输入做系统化的设计与治理。它回答的不是提示词怎么写这一个点而是一整套问题给模型什么上下文、为什么给、给多少、什么时候给、如何压缩和维护。把它拆解开就是这张图三大维度怎么控制Model瞬态/ Tool持久/ Life-cycle持久三大数据源信息从哪来Runtime Context配置/ State短期/ Store长期一个机制怎么落地Middleware钩入生命周期每一步当你下次觉得模型不行想换更贵的模型时先停一下问自己我是不是没把正确的上下文喂给它九成情况下答案在这里而不在模型。
上下文工程:为什么你的 Agent 不是模型不够强,而是“没喂对“
你接入了最强的模型写了一个 Agent结果它表现得像个实习生答非所问、乱调工具、忘了前面说过什么。你第一反应是模型不行于是换更贵的模型——然后发现没什么改善。问题大概率不在模型而在上下文。这篇文章讲清楚什么是上下文工程Context Engineering以及怎么系统化地把正确的信息、用正确的格式、在正确的时机喂给模型。一、90% 的 Agent 失败都不是模型的锅打个比方。你请来一位顶尖维修专家对他说帮我修好这台机器。他失败了——不是因为他不行而是因为你没告诉他机器型号、故障现象、维修手册、可用工具。换种说法“帮我修好这台机器。型号 X-200故障是异常噪音这是维修手册第 3 章可用工具有扳手、螺丝刀、万用表。”同一个专家立刻解决问题。差别不在能力在上下文。Agent 也一样。一个被广泛认同的经验法则是Agent 失败的原因 ❌ 10% 因为底层 LLM 能力不足 ✅ 90% 因为没有传给 LLM 正确的上下文所以Context Engineering上下文工程的定义就是以正确的格式为 LLM 提供正确的信息和工具让它能完成任务。这是 AI 工程师的首要工作。它不等于提示词工程很多人把上下文工程简化成怎么把提示词写好这远远不够Prompt EngineeringContext Engineering关注单次提示词怎么写更好整个上下文系统怎么设计范围一句提示词的内容和结构给什么、为什么给、给多少、何时给、如何压缩与维护提示词工程 ⊂ 上下文工程。提示词只是上下文的一部分上下文工程还要管对话历史、工具、记忆、状态、检索……它是这些技术的编排者而不是其中任何一个。二、一个贯穿全文的比喻上下文工程 给决策者备简报的幕僚长把模型想成一个日理万机的决策者高管而你上下文工程师是他的幕僚长决定什么材料送到他桌上、什么被过滤掉、调哪份档案、哪些当下要看、哪些只是背景参考。整篇文章你只需记住这个比喻后面所有概念都能对号入座——而且每一项的核心动作都是为决策者筛选并适时递送信息概念幕僚长比喻作用模型本身做决策的高管它的本职就是决定调工具还是直接答Context Engineering幕僚长的工作策展/筛选——决定什么上桌、什么拦下Model Context今天这场会的简报本单次调用的输入开完即作废Tool Context助理去调档、更新档案工具读写的数据改了后面一直生效Life-cycle Context幕僚长的把关流程控制执行流程不替高管做决定Middleware各环节的幕后人员钩入流程的每个环节三、Agent 的核心循环上下文在哪里被喂进去理解上下文工程先看 Agent 怎么转用户输入 → 【模型调用】传入提示词工具→ 需要调工具 ├─ 是 → 【工具执行】→ 工具结果 → 回到模型调用 └─ 否 → 输出答案上下文工程就是在这个循环的每一步决定传入什么、何时传入、如何更新。下面三大维度正是对这个循环不同环节的控制。四、三大控制维度瞬态 vs 持久这是整套体系的骨架。关键区分是瞬态只影响这一次还是持久跨步骤保留。维度一Model Context模型上下文—— 瞬态只影响单次模型调用演完就结束。包括系统提示词模型的角色“你是客服助手”消息历史当前对话可用工具这次能调哪些工具模型选择用哪个 LLM响应格式结构化输出的 Schema比喻今天这场会的简报本。每次内容不同开完即作废不影响下一场会。维度二Tool Context工具上下文—— 持久工具对数据源的读写效果会留下来影响后续工具执行时 读取查数据库、取用户偏好、读配置 写入更新会话状态、改长期记忆、记日志比喻助理去调档、更新档案。一旦改了某条记录后续所有人看到的都是新状态。维度三Life-cycle Context生命周期上下文—— 持久控制模型调用与工具执行之间的逻辑——对话摘要、护栏检查、日志、动态提示词、模型切换。比喻幕僚长的把关流程。不替高管做决定但决定什么先递、什么拦下、何时提醒、何时收尾。五、三大数据源信息从哪来活多久控制维度是怎么管数据源是管的东西从哪来。三者生命周期不同数据源生命周期作用域装什么Runtime Context单次调用会话内用户 ID、API Key、环境标志静态配置State会话期间会话内消息历史、上传文件、认证状态短期记忆Store永久跨会话用户偏好、历史画像长期记忆对应代码大致长这样# Runtime Context调用时传入的静态配置dataclassclassAppContext:user_id:strenvironment:str# dev / prodrole:str# admin / viewerresultagent.invoke({messages:[...]},contextAppContext(user_idu1,...))# State会话内的短期记忆会话结束即消失state{messages:[...],uploaded_files:[...],auth_status:True}# Store跨会话的长期记忆runtime.store.put((users,u1),preferences,{language:zh,theme:dark})prefsruntime.store.get((users,u1),preferences)# 下次会话还在一句话记忆Runtime Context 是这次的配置State 是这场对话的记忆Store 是永久的档案。六、落地机制中间件Middleware前面都是该做什么Middleware 是怎么做——它能钩入 Agent 生命周期的任何一步用户输入 → before_agent 会话级钩子 → before_model 模型调用前 → wrap_model_call 包裹模型调用 → 【模型调用】 → after_model 模型调用后 → wrap_tool_call 包裹工具调用 → 【工具执行】 → after_agent 会话级钩子 → 输出 / 回到循环很多常见需求官方已有内置中间件别自己造轮子。比如对话超长时自动压缩历史fromlangchain.agents.middlewareimportSummarizationMiddleware summarizerSummarizationMiddleware(modelgpt-4-mini,trigger(tokens,4000),# 超过 4000 token 触发keep(messages,20),# 保留最近 20 条)agentcreate_agent(modelgpt-4,middleware[summarizer])或者根据用户角色动态过滤工具非管理员看不到危险工具before_modeldeffilter_tools_by_role(state,runtime):ifruntime.context.role!admin:request.override(tools[tfortinrequest.toolsift.namenotin[delete_record,admin_tool]])returnrequest七、最容易踩的坑瞬态 vs 持久更新这是上下文工程里最常见的误解单独拎出来讲。同样是往消息里加一条指令用不同钩子效果完全不同# 瞬态只影响本次调用State 历史不变wrap_model_calldeftransient_change(state,request,handler):request.messages[SystemMessage(额外指令)]request.messagesreturnhandler(request)# State 没动# 持久永久改变 Statebefore_modeldefpersistent_change(state):return{messages:[SystemMessage(额外指令)]state[messages]}# State 被更新典型翻车现场在wrap_model_call里改消息以为改了对话历史结果只有这一次调用看得到下一轮就没了。记住想只这一次生效如临时注入一条约束→瞬态wrap_model_call想永久留在历史里 →持久before_model返回 dict 更新 State八、几条高价值实践1. 从简开始。先用静态提示词 固定工具跑通验证确实需要后再加动态逻辑。不要一上来就上一堆中间件。2. 增量测试。一次只加一个特性静态 → 动态提示词 → 工具过滤 → Store 记忆方便定位问题。3. 工具定义就是给 LLM 的说明书。名称、描述、参数说明不是元数据而是引导模型推理的关键# ✅ 好说清做什么、何时用、不适合什么tooldefsearch_web(query:str,max_results:int5)-str:搜索互联网获取最新信息。当你需要实时数据、新闻或事实时使用。 不适合用于本地数据库查询或计算。 Args: query: 搜索关键词2-10 个词 max_results: 最大返回结果数 # ❌ 差模型不知道何时该用tooldefsearch(query:str)-str:搜索。4. 工具数量要适中5~10 个为佳。太多50→ 上下文过载、模型混淆、乱调太少只给 1 个→ 能力受限、模型用文本硬编替代工具。需要时动态过滤工具集。5. 别把所有信息一次性塞进去。10 万字文档全文、500 条历史、50 个工具——这是上下文过载的标准姿势。正确做法RAG 检索相关片段、Summarization 压缩历史、动态过滤工具。九、总结上下文工程的本质是围绕模型每次调用的输入做系统化的设计与治理。它回答的不是提示词怎么写这一个点而是一整套问题给模型什么上下文、为什么给、给多少、什么时候给、如何压缩和维护。把它拆解开就是这张图三大维度怎么控制Model瞬态/ Tool持久/ Life-cycle持久三大数据源信息从哪来Runtime Context配置/ State短期/ Store长期一个机制怎么落地Middleware钩入生命周期每一步当你下次觉得模型不行想换更贵的模型时先停一下问自己我是不是没把正确的上下文喂给它九成情况下答案在这里而不在模型。