真正决定 AI 智能体效果的,不只是大模型:上下文工程为何成为关键变量
在使用 AI、搭建智能体(Agent)时,容易会陷入一个典型误区:
一味追逐更强、更贵、更新的大模型,默认模型选得越好,AI 的实际效果就一定越好。
但真正做过复杂 AI 应用后往往会发现:
即便接入能力很强的前沿大模型,一旦上下文组织混乱、信息缺失、状态管理失控,AI 依然可能出现记忆断层、回答跑偏、答非所问、重复执行、任务中断等问题,甚至增加错误和幻觉发生的概率。
很多时候,问题并不只是“模型能力不足”。
更值得追问的是:
模型在当前这一次推理中,究竟看到了什么?
进一步说:
这些信息是否完整、准确、相关、最新,并且以适合当前任务的方式组织起来?
这也是当下 AI Agent 工程中越来越重要的一项能力:
上下文工程(Context Engineering)。
如果用一句话概括:
模型能力决定 Agent 能够完成什么类型的认知与推理任务,而上下文工程决定这些能力在当前任务中能否被有效调用。
顶级模型如果长期接收混乱、冗余、缺失甚至相互冲突的信息,也很难稳定承接复杂业务任务。
反过来,在固定业务场景中,即使模型并非行业最强,只要上下文组织、工具配置、状态管理和工作流设计合理,也可能获得远超“裸模型调用”的实际效果。
01 先搞清楚:模型、Context、Memory 和 State,到底有什么区别?
理解 Agent,首先要解决一个最常见的问题:
“AI 到底有没有记忆?”
这个问题之所以容易混乱,是因为大家经常把 Context、Memory、State、Conversation History 混在一起。
实际上,它们承担的是不同职责。
1. 大模型:推理与生成引擎
大模型本身最核心的职责,是根据当前可用的信息进行推理和生成,例如:
- 理解用户输入
- 进行逻辑推理
- 生成文本或结构化数据
- 根据工具定义生成工具调用请求
- 处理代码、文本、图像等输入
但需要注意:
大模型本身并不天然负责业务级的持久化记忆、任务状态和完整生命周期管理。
在典型的无状态模型调用模式下,每次推理所需的信息,都需要由 Agent Runtime 或上层系统组织并提供。
即使某些模型平台提供了会话、线程或历史上下文能力,真正的业务系统依然需要决定:
- 哪些历史信息应该保留?
- 哪些信息应该压缩?
- 哪些信息已经过期?
- 哪些信息应该写入 Memory?
- 当前任务处于什么 State?
- 下一次模型调用究竟应该看到什么?
因此可以把模型理解成:
模型负责“算”,Agent 系统负责“组织信息、管理状态、驱动任务”。
2. Context:模型当前这一次推理能够直接访问的信息集合
Context 上下文,是理解 Context Engineering 最关键的概念。
可以简单定义为:
为当前这一次模型推理而组织出来的、模型能够直接访问的信息集合。
它可能包括:
- System Instructions 系统指令
- 用户当前需求
- 对话历史
- 用户偏好
- Memory 召回内容
- 知识库检索结果
- 工具定义
- 工具执行结果
- 当前任务状态
- 业务规则
- 历史决策
- 当前项目代码与文档
- 外部系统返回的数据
因此:
Context 不等于系统里的全部数据。
数据库里有 100 万条数据,并不意味着这 100 万条数据都是模型当前的 Context。
真正进入当前推理过程的,只是经过筛选、检索、转换和组装之后的那部分信息。
可以把 Context 理解成:
模型当前这一刻能够“看到”的世界。
3. Memory:为了未来复用而沉淀的信息
Memory 是系统为了让信息能够跨推理步骤、会话或任务继续复用,而建立的一类持久化或半持久化信息机制。
例如:
用户偏好:
默认使用 Markdown 输出
项目约束:
项目统一使用 Go + Redis
业务规则:
订单创建后不能直接删除,只允许关闭
这些信息并不一定需要每次都完整塞进 Context。
系统可以将它们保存下来,在后续任务需要时进行召回。
因此 Memory 的核心不是:
“一直放在 Context 里面。”
而是:
“需要的时候能够被准确召回,并重新进入当前 Context。”
典型过程:
Memory
↓
按任务需要召回
↓
筛选 / 转换 / 压缩
↓
进入当前 Context
↓
供模型推理使用
所以:
Memory 是信息储备,Context 是当前推理实际使用的信息。
二者不能混为一谈。
4. State:Agent 当前正在做什么
State 更关注:
任务现在进行到了哪里?
例如一个代码迁移 Agent:
需求分析
↓
扫描代码
↓
修改代码
↓
运行测试
↓
发现失败
↓
修复问题
↓
重新测试
系统可能维护:
current_step = 4
migration_completed = true
last_test_result = failed
retry_count = 2
这些就是任务运行状态。
典型 State 可以包含:
- 当前任务执行节点
- 已完成的步骤
- 未完成的步骤
- 已失败的步骤
- 工具调用结果
- 当前重试次数
- 中间结果
- 下一步目标
- 当前任务的 checkpoint
但有一个非常重要的工程原则:
并非所有 State 都需要暴露给模型。
例如:
数据库事务 ID
分布式锁状态
任务队列 ID
权限校验信息
内部重试计数
这些信息可能只需要系统自己维护。
只有真正影响模型决策的信息,才需要经过筛选后进入 Context。
02 Context、Memory、State,到底是什么关系?
如果把整个 Agent 系统抽象成一张图,核心关系其实非常简单:
┌─────────────────────┐
│ Model │
│ 推理 / 生成能力 │
└──────────▲──────────┘
│
│ Context
│
┌──────────┴──────────┐
│ Context Builder │
│ │
│ 筛选 / 排序 / 压缩 │
│ 召回 / 更新 / 淘汰 │
└──────────▲──────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
│ │ │
Conversation Memory State
History 信息储备 任务状态
│ │ │
└────────────────────────┼────────────────────────┘
│
┌──────────┴──────────┐
│ Retrieval │
│ 知识 / 数据检索 │
└──────────▲──────────┘
│
┌──────────┴──────────┐
│ Tools │
│ API / DB / Browser │
│ Code / External Sys │
└──────────▲──────────┘
│
┌──────────┴──────────┐
│ Workflow │
│ 任务拆解 / 执行循环 │
└─────────────────────┘
Evaluation
│
↓
持续验证 Agent 是否真的变好
这张图基本就是整篇文章的核心。
可以进一步浓缩成一句话:
Memory 和 State 是系统的信息资产与运行状态;Context Builder 负责从这些信息中挑选当前真正需要的内容;Context 最终成为模型当前推理可以直接访问的信息集合。
而 Agent 并不是:
一次 Prompt
↓
一次回答
↓
任务结束
真正复杂的 Agent 更接近:
用户需求
↓
构建 Context
↓
模型推理
↓
调用工具
↓
获得结果
↓
更新 State / Memory
↓
重新构建 Context
↓
再次推理
↓
再次调用工具
↓
……
这就是 Agent 的核心循环。
03 为什么上下文工程,正在成为 Agent 落地的重要分水岭?
可以用一个简单的工程模型理解:
Agent 实际效果 ≈ 模型能力 × Context 工程 × 工具能力 × 工作流与状态管理
这不是严格数学公式,而是一个帮助工程团队定位问题的分析框架。
其中:
模型能力
决定模型本身具备怎样的:
- 推理能力
- 代码能力
- 指令遵循能力
- 工具调用能力
- 多模态理解能力
- 长文本处理能力
Context 工程
解决:
- 当前应该给模型看什么?
- 哪些信息必须保留?
- 哪些信息需要压缩?
- 哪些信息应该检索?
- 哪些信息已经过期?
- 新旧信息冲突时谁优先?
工具能力
解决:
模型能不能真正操作外部世界。
例如:
- 数据库
- API
- 浏览器
- 文件系统
- Git
- 搜索
- 企业内部系统
Workflow 与 State
解决:
复杂任务能不能持续、可控、可恢复地执行。
例如:
- 任务拆解
- 步骤编排
- 状态管理
- 失败重试
- 断点恢复
- 权限控制
- 幂等性
因此,一个 Agent 的问题出现时,不能简单地归结成:
“模型不够强。”
很多时候真正的问题可能发生在 Context、Tool、State 或 Workflow。
04 Agent 为什么经常“失忆”或者“跑偏”?
Agent 翻车,很多时候不是因为没有信息,而是因为:
信息虽然存在,但没有以正确的形式出现在当前 Context 中。
常见问题主要有三类。
① Context 无限堆叠,有效信息密度下降
多轮任务持续执行之后,Context 可能变成:
早期需求
↓
大量闲聊
↓
中间讨论
↓
多轮工具调用
↓
失败尝试
↓
调试日志
↓
重复沟通
↓
需求变更
↓
当前问题
如果系统只是简单地把所有内容不断追加:
History += New Message
History += Tool Result
History += New Message
History += Tool Result
……
最终 Context 会越来越臃肿。
真正的问题不是:
信息多。
而是:
相关信息、无关信息、过期信息、重复信息和冲突信息全部混在了一起。
因此需要主动进行:
压缩
摘要
裁剪
检索
重排
淘汰
而不是等上下文窗口达到上限之后才被动处理。
② 核心约束被噪声淹没
例如项目真正重要的规则只有:
项目必须使用 PostgreSQL
接口必须兼容旧版本
禁止修改公共 API
但 Context 里同时存在:
旧方案
废弃方案
失败尝试
调试日志
无关讨论
历史错误
重复工具结果
这时模型面对的并不是“信息不足”。
恰恰相反:
信息太多,但有效信息密度太低。
所以 Context Engineering 的一个核心目标,就是:
提高有效信息在当前 Context 中的信号密度。
③ 新旧信息冲突
这是复杂长期任务中特别常见的问题。
例如:
历史信息:
数据库使用 MySQL
当前项目状态:
已经完成 PostgreSQL 迁移
如果两条信息同时进入 Context,却没有明确说明:
MySQL = 历史状态
PostgreSQL = 当前状态
模型就可能根据错误的信息进行推理。
因此 Context Engineering 不只是:
“把信息放进去。”
还必须解决:
信息的优先级、时效性和有效性。
05 Context Engineering 到底在做什么?
真正成熟的 Context Engineering,不是写一个更长的 Prompt。
它实际上是在持续回答四个问题。
1. 什么信息必须保留?
例如:
- 当前用户核心需求
- 当前任务目标
- 核心业务规则
- 已确认的决策
- 当前任务 State
- 必要的工具结果
- 当前任务真正相关的代码和文档
这些信息通常应该优先保留。
2. 什么信息需要压缩?
已经完成闭环的讨论,没有必要永远保留完整原文。
例如原本有几十轮讨论:
方案 A
↓
讨论
↓
方案 B
↓
反复比较
↓
最终决定使用方案 C
最终 Context 可能只需要:
已确认:
1. 项目数据库使用 PostgreSQL
2. 保留现有 API,不进行破坏性修改
3. Redis 负责缓存
4. 当前迭代聚焦订单模块
这就是:
从完整过程压缩成可复用结论。
3. 什么信息需要按需检索?
不要把整个知识库、整个代码仓库、所有历史资料全部塞给模型。
而应该:
当前任务
↓
判断需要什么信息
↓
检索知识库 / Memory / 数据库 / 代码
↓
过滤无关内容
↓
重新排序
↓
只把相关内容放进 Context
这就是:
Just-in-Time Context。
不是提前把所有东西都装进模型,而是在真正需要的时候取。
4. 什么信息应该主动丢弃?
例如:
- 无关历史
- 重复信息
- 已经失效的方案
- 临时日志
- 失败尝试
- 已经完成的中间过程
- 与当前任务无关的工具结果
Context Engineering 并不是:
尽可能保存所有信息。
而是:
尽可能让当前 Context 只保留对当前任务真正有价值的信息。
因此可以把它总结成:
筛选
↓
排序
↓
压缩
↓
召回
↓
更新
↓
淘汰
↓
重新组装 Context
06 为什么聊天记录还在,AI 却像“失忆”?
这是很多 Agent 产品中非常常见的现象。
例如用户明明可以看到:
“我们已经完成数据库迁移。”
但 Agent 下一步却又问:
“现在数据库是 MySQL 还是 PostgreSQL?”
为什么?
因为:
聊天记录存在,不等于当前任务状态正确存在。
聊天历史主要描述:
过去发生了什么。
State 更关注:
现在进行到了哪里。
例如:
Conversation History
────────────────────
“我们已经完成数据库迁移。”
State
────────────────────
migration_completed = true
current_step = 4
last_test_result = failed
两者职责不同。
而且在工程实现上:
它们可以独立存储,也可以从同一套事件日志中派生。
例如:
Event Log
↓
┌───────────────┐
│ Conversation │
│ History │
└───────────────┘
Event Log
↓
┌───────────────┐
│ State Reducer │
└───────┬───────┘
↓
Current State
因此真正的问题不是:
“聊天记录有没有保存?”
而是:
当前任务所需要的 State,是否被正确持久化、恢复,并在需要的时候进入 Context?
如果 State 只存在进程内存中,那么进程重启后确实可能丢失。
但如果 State 已经通过数据库、Checkpoint、事件日志或其他持久化机制保存,那么 Agent 完全可以在新会话中恢复任务。
所以:
聊天记录 ≠ Memory ≠ State ≠ Context。
它们可以相互关联,但职责不同。
07 Context Engineering 早已不只是 Prompt Engineering
早期 AI 应用相对简单:
User
↓
Prompt
↓
LLM
↓
Answer
这个阶段,优化 Prompt 往往能够获得非常明显的收益。
但复杂 Agent 已经变成:
User Request
↓
Context Builder
↓
Model
↓
Tool Call
↓
Tool Result
↓
State Update
↓
Memory Update
↓
Context Builder
↓
Model
↓
……
这时 Prompt 只是整个系统中的一个组成部分。
Prompt Engineering 解决什么?
可以粗略理解为:
告诉模型“应该怎么做”。
例如:
你是一名资深 Go 工程师。
请分析以下代码并找出潜在的并发问题。
Context Engineering 解决什么?
则更接近:
决定模型“这一次究竟应该看到什么”。
例如:
System Instructions
+
当前需求
+
相关代码
+
相关业务规则
+
最近一次测试结果
+
历史关键决策
+
必要工具结果
因此可以用一句话概括:
Prompt Engineering 关注“怎么告诉模型”,Context Engineering 关注“这一次让模型看到什么”。
而当 Agent 进入复杂任务之后,Context 还必须持续变化。
08 Agent 的 Context,不是一次性构建的
这是理解 Context Engineering 最关键的一步。
传统 LLM 调用更像:
Prompt
↓
Model
↓
Answer
而 Agent 更像:
┌──────────────┐
│ Model │
└──────┬───────┘
│
Tool Call
│
▼
┌──────────────┐
│ Tool │
└──────┬───────┘
│
Tool Result
│
▼
┌──────────────────┐
│ Context Update │
└────────┬─────────┘
│
▼
Model
│
...
每执行一步:
- State 可能发生变化
- Memory 可能发生变化
- 工具结果会增加
- 某些旧信息可能失效
- 当前任务目标可能变化
因此:
Agent 的 Context 是动态的。
真正成熟的 Agent,不应该只是:
Context = History + New Message + Tool Result
而应该是:
Context(t)
=
当前任务所需的
最相关、最新、最可靠的信息集合
每一步重新计算。
这就是 Context Engineering 的核心。
09 一套完整的 Context Engineering 体系,需要管理什么?
如果把前面的内容进一步工程化,可以把 Context 看成由多个信息源共同组成:
Context
├── System Instructions 系统指令
├── User Request 当前需求
├── Conversation History 对话历史
├── Memory 长期 / 持久化信息
├── Retrieved Knowledge 检索知识
├── Tool Definitions 工具定义
├── Tool Results 工具结果
├── Task State 当前任务状态
├── Business Rules 业务规则
└── Previous Decisions 已确认决策
这里尤其容易忽略:
Tool Definitions 本身也是 Context 的一部分。
模型不仅需要看到工具执行结果,还需要知道:
有哪些工具?
工具做什么?
参数是什么?
什么情况下应该调用?
返回什么?
工具定义太多,同样会消耗 Context,并可能增加模型选择工具时的认知负担。
因此:
工具也需要 Context Engineering。
不是工具越多越好,而是:
当前任务真正需要哪些工具?
10 Context Engineering 的完整闭环
最终,整个过程可以抽象成:
信息源
│
├── Conversation
├── Memory
├── State
├── Knowledge
├── Tools
└── Business Data
│
▼
┌─────────────────────┐
│ Context Builder │
│ │
│ 筛选 → 排序 → 压缩 │
│ 召回 → 更新 → 淘汰 │
└──────────┬──────────┘
│
▼
Context
│
▼
Model
│
▼
Tool / Action
│
▼
Tool Result
│
▼
State / Memory
更新
│
└──────────────┐
│
▼
Context Builder
这其实就是一个完整的 Agent Loop。
11 为什么“大模型换得更强”,有时候效果还是不好?
因为如果问题发生在 Context 层:
错误信息
+
过期信息
+
冲突信息
+
大量噪声
+
缺失关键状态
那么换模型并不能从根本上解决信息问题。
例如:
历史状态:
MySQL
当前状态:
PostgreSQL
Context:
MySQL + PostgreSQL
如果没有明确的状态优先级,那么即使换成更强的模型,也不能保证每次都正确判断。
真正应该优化的是:
历史信息
↓
识别为旧状态
↓
当前 State
↓
识别为最新状态
↓
构建 Context
↓
模型推理
因此,当 Agent 表现不好时:
不要第一时间就换模型。
先检查:
Context
Memory
State
Tools
Workflow
Evaluation
12 AI 效果不佳,应该检查哪几个维度?
可以建立一套实际工程排查清单。
① Context 是否准确?
检查:
- 是否存在错误信息?
- 是否存在过期信息?
- 是否存在相互冲突的约束?
- 是否存在已经失效的业务规则?
② Context 是否完整?
检查:
- 当前任务的关键条件是否存在?
- 业务规则是否缺失?
- 当前 State 是否完整?
- 关键历史决策是否丢失?
③ Context 是否纯净?
检查:
- 是否存在大量无关历史?
- 是否存在重复信息?
- 是否存在废弃方案?
- 是否存在大量无关日志?
④ 外部信息是否可信?
Agent 很多信息并不是模型自己生成的,而是来自:
RAG
Database
API
Search
Tool
External Service
因此需要验证:
模型看到的信息是否真的可靠。
否则模型可能只是:
很认真地基于错误数据得出了错误结论。
⑤ Memory 是否真正可用?
Memory 不是:
存得越多越好。
真正重要的是:
召得准
+
召得及时
+
内容有效
+
能够正确进入 Context
⑥ State 是否可靠?
检查:
- 当前任务节点是否正确?
- 已完成步骤是否正确?
- 失败步骤是否记录?
- 下一步目标是否明确?
- State 是否持久化?
- 会话重启后能否恢复?
⑦ 工具是否设计合理?
检查:
- 工具入参是否清晰?
- 出参是否结构化?
- 错误是否可识别?
- 是否支持幂等?
- 权限是否正确?
- 是否存在危险操作?
- 工具数量是否过多?
⑧ Workflow 是否清晰?
复杂任务不能全部依赖模型临场发挥。
需要合理设计:
任务拆解
↓
步骤执行
↓
状态更新
↓
错误处理
↓
重试 / 回滚
↓
下一步骤
⑨ 是否有 Evaluation?
这是很多 Agent 项目最容易忽略的一环。
如果没有 Evaluation,你甚至不知道:
Context 改了之后,到底有没有真的变好。
一个基本闭环应该是:
修改 Context
↓
运行测试任务集
↓
采集 Agent Trace
↓
评估结果
↓
分析失败案例
↓
继续优化 Context
↓
回归测试
真正成熟的 Agent 工程,不应该依赖:
“我感觉这个 Prompt 好像更好了。”
而应该逐渐走向:
可观测、可评估、可回归。
13 大模型到底重不重要?
当然重要。
甚至可以说:
上下文工程无法替代模型本身的核心能力。
模型的:
- 推理能力
- 代码能力
- 指令遵循
- 工具调用
- 多模态理解
- 长文本处理
都会直接影响 Agent 的表现。
因此,真正合理的认知并不是:
“模型不重要了。”
而应该是:
模型是 Agent 的认知引擎,但模型并不是整个 Agent。
可以把两者关系理解成:
模型能力
↓
决定模型本身能完成什么认知任务
Context Engineering
↓
决定当前任务给模型提供了什么信息
Tools
↓
决定模型能够操作什么外部资源
State
↓
决定任务当前进行到了哪里
Workflow
↓
决定复杂任务如何持续执行
Evaluation
↓
决定我们能否知道系统到底有没有变好
因此:
真正的 Agent 工程,不是“模型 vs 上下文”的二选一。
而是:
模型能力 × Context × Tools × State × Workflow × Evaluation
共同决定最终的工程表现。
14 Context Engineering 的本质:管理“模型当下看到的世界”
如果把全文浓缩到一个核心问题:
Agent 每一次推理,到底应该让模型看到什么?
那么很多工程问题都会变得清晰。
模型不应该看到:
整个数据库
整个知识库
整个代码仓库
全部聊天记录
所有历史工具调用
所有运行日志
而应该看到:
当前任务
+
必要约束
+
相关历史
+
相关知识
+
当前 State
+
必要工具
+
最新工具结果
+
已经确认的关键结论
因此 Context Engineering 的最终目标并不是:
让模型看到更多。
而是:
让模型在正确的时间,看到正确的信息。
15 最终总结:AI Agent 的真正工程分水岭
我们可以把前面的内容收敛成一个完整模型:
┌─────────────────────┐
│ Model │
│ 推理 / 生成能力 │
└──────────▲──────────┘
│
│ Context
│
┌──────────┴──────────┐
│ Context Builder │
│ │
│ 筛选 / 排序 / 压缩 │
│ 召回 / 更新 / 淘汰 │
└──────────▲──────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
│ │ │
Conversation Memory State
History 信息储备 任务状态
│ │ │
└─────────────────────────┼─────────────────────────┘
│
┌──────────┴──────────┐
│ Knowledge / Data │
│ RAG / DB / APIs │
└──────────▲──────────┘
│
┌──────────┴──────────┐
│ Tools │
│ API / DB / Code │
│ Browser / External │
└──────────▲──────────┘
│
┌──────────┴──────────┐
│ Workflow │
│ 任务拆解 / 执行循环 │
└─────────────────────┘
Evaluation
│
▼
评估 → 追踪 → 发现问题
│
▼
持续优化
最终可以把这套关系概括成六句话:
大模型 → 决定 AI「能做什么」
Context → 决定 AI「当前知道什么」
Memory → 决定 AI「过去的信息能否被重新利用」
State → 决定 AI「知道任务进行到了哪里」
Tools → 决定 AI「能够操作什么外部资源」
Workflow → 决定 AI「如何持续完成复杂任务」
而 Evaluation 则负责回答:
“我们怎么证明它真的变好了?”
真正成熟的 AI 工程思维
已经不是:
“哪个模型最强?”
而是逐渐变成:
“当前这个任务,应该让模型看到什么?”
进一步变成:
什么信息必须保留?
↓
什么信息应该压缩?
↓
什么信息需要检索?
↓
什么信息已经过期?
↓
什么 State 必须持久化?
↓
什么工具应该暴露给模型?
↓
如何组织 Workflow?
↓
如何通过 Evaluation 验证结果?
这也是为什么:
Agent 工程正在从 Prompt Engineering,逐渐走向 Context Engineering。
Prompt 只是告诉模型:
“你应该怎么做。”
而 Context Engineering 更关注:
“你这一次究竟应该看到什么。”
最终,一个成熟的 AI Agent,不应该只是一个接入大模型的聊天机器人。
它应该是一套能够:
在正确的时间,获取正确的信息,构建正确的上下文,调用正确的工具,维护正确的状态,并通过持续评估稳定完成复杂任务的系统。
这才是 AI Agent 真正的工程化方向。
专注 AI 落地实践,拆解智能体核心逻辑,持续分享可复用的 AI 工程认知。
浙公网安备 33010602011771号