news 2026/6/25 18:58:08

上下文工程:为什么你的 Agent 不是模型不够强,而是“没喂对“

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
上下文工程:为什么你的 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 / viewerresult=agent.invoke({"messages":[...]},context=AppContext(user_id="u1",...))# State:会话内的短期记忆,会话结束即消失state={"messages":[...],"uploaded_files":[...],"auth_status":True}# Store:跨会话的长期记忆runtime.store.put(("users","u1"),"preferences",{"language":"zh","theme":"dark"})prefs=runtime.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 summarizer=SummarizationMiddleware(model="gpt-4-mini",trigger=("tokens",4000),# 超过 4000 token 触发keep=("messages",20),# 保留最近 20 条)agent=create_agent(model="gpt-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 没动# 持久:永久改变 State@before_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:int=5)->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,钩入生命周期每一步

当你下次觉得"模型不行"想换更贵的模型时,先停一下问自己:我是不是没把正确的上下文喂给它?九成情况下,答案在这里,而不在模型。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/25 18:51:18

Kimi K2.5+ChatPPT:AI驱动的PPT工作流重构方法论

1. 项目概述:这不是又一个PPT插件,而是一次工作流重构“告别低效做 PPT!Kimi K2.5ChatPPT 让创作效率翻 10 倍”——这个标题里藏着三个被多数人忽略的关键信号:“告别”是结果,“低效”是现状,“翻 10 倍”…

作者头像 李华
网站建设 2026/6/25 18:49:51

Vue 3 setup语法糖用错,数据不更新!

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 Vue 3 setup语法糖用错?数据不更新的真相! 目录昨天改需求,setup语法糖写得飞起。点按钮&…

作者头像 李华
网站建设 2026/6/25 18:49:41

线性回归四大假设的实战诊断与业务修复指南

1. 这不是教科书里的“背诵清单”,而是数据科学家每天都在踩的坑“线性回归的假设”这八个字,几乎出现在每一份数据科学面试题库、每一门统计学入门课的PPT第12页、每一篇机器学习综述的“基础模型”小节里。但现实是:我带过的7个实习数据工程…

作者头像 李华
网站建设 2026/6/25 18:47:54

从代码逻辑到大模型心智:个人微信机器人接口的“对齐”之路

在深度开发 个人微信机器人接口 的实际业务场景中,技术团队常常会遭遇一个诡异的“技术断层”:研发人员写好了健壮的代码逻辑,配置好了高防服务器,也将接口对接到了业界最先进的大模型上。但在实际运行中,当用户在微信…

作者头像 李华
网站建设 2026/6/25 18:47:15

13-Vue2 渲染函数与 JSX

Vue2 渲染函数与 JSX Vue 的模板语法在绝大多数场景下足够使用,但在某些复杂场景下,渲染函数(Render Functions)提供了更灵活的编程能力。配合 JSX 语法,可以像写 React 一样编写 Vue 组件。 一、前言 Vue 推荐在绝大…

作者头像 李华
网站建设 2026/6/25 18:41:37

计算机毕业设计之基于SSM的大学生兴趣组管理系统

系统根据现有的管理模块进行开发和扩展,采用面向对象的开发的思想和结构化的开发方法对大学生兴趣组管理的现状进行系统调查。采用结构化的分析设计,该方法要求结合一定的图表,在模块化的基础上进行系统的开发工作。在设计中采用“自下而上”…

作者头像 李华