小白程序员轻松掌握Context Engineering,让你的AI Agent智能翻倍!
本文深入浅出地介绍了2025年AI工程圈最热的概念——Context Engineering,通过实战代码和五个实用技巧,帮助程序员解决AI Agent在运行中出现的“失忆”和答非所问等问题。文章强调了上下文质量对Agent性能的重要性,并提出了结构化Prompt、对话历史压缩、记忆注入、工具输出格式化和上下文预算管理等关键策略,旨在提升AI Agent的智能化水平。
一、那些年,Agent 给我整的笑话
说个真实场景。
你花了两周搭了一个客服 Agent,测试的时候表现完美——回答准确、有条理、语气友好。
上线第一天,用户问了一个稍微复杂点的问题,Agent 开始正常回答。
然后用户追问了三四轮……
Agent 的回答开始变味了。
先是忘了自己是"客服助手"的身份,开始自由发挥。
然后忘了用户前面说过的信息,开始重复问。
最后干脆给出了一个跟实际产品文档完全矛盾的答案。
你盯着日志,百思不得其解——Prompt 我没动啊,怎么就翻车了?
“RAG 80% 的问题,出在切文档那一步。Agent 80% 的问题,出在上下文管理那一步。”
哎,这就是 Context Engineering 要解决的核心问题。
二、Context Engineering 是什么?跟 Prompt Engineering 有什么区别?
先说清楚这两个概念,很多人混着用,其实差得远。
💡 一句话定义:Prompt Engineering 是"如何问一个好问题",Context Engineering 是"如何把整个对话现场布置好,让 AI 一直保持最佳状态"。
用装修来类比——
Prompt Engineering 像是"怎么跟装修工人沟通需求",你要说清楚风格、预算、要求。
Context Engineering 像是"设计整个施工现场":工人在哪、图纸放哪、工具摆哪、今天干什么、昨天干了啥、下一步计划是什么。

现场设计好了,工人自然干得好;现场一团乱,沟通再清楚也没用。
这个概念在 2025 年被 AI 圈广泛采用,Andrej Karpathy(前 OpenAI 研究员、特斯拉 AI 负责人)明确表达过这个观点:
“The bottleneck is not the model. The bottleneck is context.”
(瓶颈不是模型,瓶颈是上下文。)
上下文窗口里,到底装了什么?
很多人以为"上下文"就是聊天记录。其实,一个 Agent 运行时,上下文窗口里塞满了各种东西:

| 内容类型 | 说明 | 举例 |
|---|---|---|
| System Prompt | Agent 的身份、规则、行为约束 | “你是一个客服助手,不得讨论竞品” |
| 对话历史 | 用户和 AI 的来回 | 前 N 轮问答 |
| 检索结果 | RAG 拉回来的文档片段 | 产品手册第 3-5 页 |
| 工具调用记录 | 调用了什么工具、返回了什么 | 查了数据库,结果是 xxx |
| 记忆注入 | 从长期记忆里提取的相关历史 | 这个用户上次说他是 VIP |
| 用户当前输入 | 这一轮的问题 | “我的订单在哪里?” |
这些东西加在一起,很容易就把上下文窗口撑满。
而模型处理上下文的能力,跟"塞了多少有用信息"直接相关。

三、为什么现在特别重要?选型前先搞清楚这件事
你品你细品——同样是 Claude 3.6 Sonnet,为什么有人用得飞起,有人用得一塌糊涂?
差别就在 Context 的质量。
3.1 Agent 把 Context 问题放大了 10 倍
单轮问答时代,Context Engineering 还不紧迫——一个问题进去,一个答案出来,上下文本来就简单。
但 Agent 不一样:
- 它要多轮对话,历史越来越长
- 它要调用工具,工具返回值也要塞进去
- 它要自主规划,中间的推理步骤也占位置
- 它可能要并行处理多个任务,上下文更复杂
不管好 Context,Agent 跑几步就"失忆",跑更多步就"人格分裂"。
3.2 三种典型失败模式
我总结了工程实践中最常见的三种 Context 翻车场景:
| 失败模式 | 表现 | 根本原因 |
|---|---|---|
| 上下文溢出 | Agent 突然忘记了早期的关键指令 | 对话太长,早期内容被"挤出"窗口 |
| 上下文污染 | Agent 被不相关的工具输出或检索结果带偏 | 往上下文里塞了太多低质量信息 |
| 上下文割裂 | Agent 无法把多轮信息联系起来 | 缺乏有效的记忆管理和信息压缩 |
3.3 Context Engineering 的四个核心维度
说白了,Context Engineering 就是回答四个问题:
1. 放什么进去? → 内容选择(相关性过滤)
2. 怎么组织? → 结构设计(格式、顺序、标记)
3. 放多少? → 预算管理(Token 分配)
4. 什么时候更新? → 动态维护(压缩、遗忘、注入)

决策流程动图
四、实战:五个让 Agent 不再失忆的 Context 管理技巧
好,原理讲完,进入实战环节。
下面这五个技巧,是我认为性价比最高的 Context Engineering 手段。代码用 Python + LangChain / 原生 API,你可以直接跑。
技巧一:结构化 System Prompt,用 XML 标签分区
很多人的 System Prompt 是一大坨纯文本。模型理解起来其实挺费劲的——它得自己猜哪段是规则、哪段是背景、哪段是约束。
给它分好区,效果立竿见影。
# -----------------------------------------------
# 🔧 【按你的环境修改这里】
# -----------------------------------------------
# 把 YOUR_API_KEY 换成你的 Anthropic API Key
# 在 https://console.anthropic.com 获取
API_KEY = "YOUR_ANTHROPIC_API_KEY"
# -----------------------------------------------
import anthropic
client = anthropic.Anthropic(api_key=API_KEY)
# ✅ 用 XML 标签结构化 System Prompt
# 为什么用 XML?Claude 的训练数据里大量使用 XML,识别效果最好
SYSTEM_PROMPT = """
<role>
你是一个专业的 RAG 技术顾问,帮助开发者解决检索增强生成相关问题。
</role>
<rules>
- 只回答 RAG、向量数据库、LLM 应用相关的技术问题
- 代码示例必须可以直接运行,不允许使用占位符
- 如果不确定,明确说"我不确定",不要编造答案
</rules>
<context>
当前用户是一名有 Python 基础的 AI 应用开发工程师,正在学习 RAG 技术。
</context>
<output_format>
回答分三部分:核心答案(1-2句)→ 原理解释 → 代码示例
</output_format>
"""
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=SYSTEM_PROMPT, # 结构化的 System Prompt
messages=[{"role": "user", "content": "FAISS 和 Milvus 该选哪个?"}]
)
print(response.content[0].text)
# 运行结果示例
核心答案:本地开发用 FAISS,生产环境用 Milvus。
原理解释:FAISS 是内存索引库,轻量快速但无法持久化和水平扩展;
Milvus 是完整的向量数据库,支持分布式部署、数据持久化和实时更新...
技巧二:对话历史压缩,防止上下文溢出
Agent 跑多轮之后,历史记录越来越长,Token 消耗爆炸。
解法是:定期把历史总结成摘要,替换掉原始记录。
from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
# -----------------------------------------------
# 🔧 【按你的环境修改这里】
# -----------------------------------------------
# Anthropic API Key
API_KEY = "YOUR_ANTHROPIC_API_KEY"
# 触发压缩的消息轮数阈值,超过这个就压缩
COMPRESS_THRESHOLD = 10
# -----------------------------------------------
llm = ChatAnthropic(model="claude-sonnet-4-6", api_key=API_KEY)
def compress_history(messages: list, llm) -> list:
"""
把历史消息压缩成摘要,保留最近 2 轮原始对话。
为什么保留最近 2 轮?保证模型能看到最新的上下文,
同时用摘要覆盖早期对话,大幅减少 Token 消耗。
"""
if len(messages) <= COMPRESS_THRESHOLD:
return messages # 还没到阈值,不用压缩
# 把早期消息(除最近 4 条)发给模型,让它总结
old_messages = messages[:-4]
recent_messages = messages[-4:] # 保留最近 2 轮(4 条消息)
# 构造压缩请求
summary_prompt = f"""请将以下对话历史压缩成一段简洁的摘要(200字以内),
保留所有关键信息、决策和结论:
{chr(10).join([f'{m.type}: {m.content}' for m in old_messages])}"""
summary_response = llm.invoke([HumanMessage(content=summary_prompt)])
# 用摘要替换早期消息,插回对话历史
compressed = [
SystemMessage(content=f"[对话历史摘要]/n{summary_response.content}")
] + recent_messages
print(f"✅ 压缩完成:{len(messages)} 条 → {len(compressed)} 条")
return compressed
# 模拟一个多轮对话
conversation_history = []
questions = [
"RAG 是什么?",
"向量数据库怎么选?",
"FAISS 怎么安装?",
"chunk_size 设多少合适?",
"怎么评估 RAG 效果?",
]
for question in questions:
conversation_history.append(HumanMessage(content=question))
# 每次对话前检查是否需要压缩
conversation_history = compress_history(conversation_history, llm)
response = llm.invoke(conversation_history)
conversation_history.append(AIMessage(content=response.content))
print(f"Q: {question}")
print(f"A: {response.content[:100]}.../n")
# 运行结果
Q: RAG 是什么?
A: RAG(检索增强生成)是一种将外部知识库与大语言模型结合的技术框架...
Q: 向量数据库怎么选?
A: 根据规模选择:本地开发用 FAISS,中等规模用 Chroma,生产环境用 Milvus...
✅ 压缩完成:12 条 → 5 条 ← 触发压缩,历史从 12 条压到 5 条
Q: 怎么评估 RAG 效果?
A: 推荐用 RAGAS 框架,核心指标包括 faithfulness、answer_relevancy...
技巧三:动态记忆注入,让 Agent 记住"重要的事"
不是所有信息都值得永远留在上下文里。
重要的是:在需要的时候,把相关的记忆注入进来。
# -----------------------------------------------
# 🔧 【按你的环境修改这里】
# -----------------------------------------------
# 向量库保存路径,改成你本地的目录
MEMORY_STORE_PATH = "./agent_memory"
# 嵌入模型,不用改,用免费的本地模型
EMBED_MODEL = "BAAI/bge-small-zh-v1.5"
# 检索记忆时返回最相关的 K 条
MEMORY_TOP_K = 3
# -----------------------------------------------
from langchain_community.vectorstores import FAISS
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_core.documents import Document
embeddings = HuggingFaceEmbeddings(model_name=EMBED_MODEL)
def save_memory(content: str, metadata: dict = None):
"""把重要信息存进记忆向量库"""
doc = Document(page_content=content, metadata=metadata or {})
try:
# 已有记忆库则追加
store = FAISS.load_local(
MEMORY_STORE_PATH, embeddings,
allow_dangerous_deserialization=True # 本地文件,安全
)
store.add_documents([doc])
except Exception:
# 第一次运行,创建新的记忆库
store = FAISS.from_documents([doc], embeddings)
store.save_local(MEMORY_STORE_PATH)
print(f"✅ 记忆已保存:{content[:50]}...")
def retrieve_memory(query: str) -> str:
"""根据当前问题,检索最相关的历史记忆"""
try:
store = FAISS.load_local(
MEMORY_STORE_PATH, embeddings,
allow_dangerous_deserialization=True
)
docs = store.similarity_search(query, k=MEMORY_TOP_K)
if not docs:
return ""
# 把检索到的记忆拼成字符串,注入到 System Prompt
memories = "/n".join([f"- {d.page_content}" for d in docs])
return f"<relevant_memory>/n{memories}/n</relevant_memory>"
except Exception:
return "" # 没有记忆库时静默返回空
# 使用示例:保存用户偏好
save_memory("用户偏好使用 FAISS 而不是 Milvus,因为他的项目是单机部署")
save_memory("用户的技术栈:Python 3.11 + LangChain 0.3 + FastAPI")
save_memory("用户正在做一个内部知识库 RAG 系统,文档量约 1000 篇")
# 下次对话时,动态注入相关记忆
query = "向量库应该用哪个?"
memory_context = retrieve_memory(query) # 自动检索相关记忆
print(f"注入的记忆:/n{memory_context}")
# 运行结果
✅ 记忆已保存:用户偏好使用 FAISS 而不是 Milvus,因为他的项目是单...
✅ 记忆已保存:用户的技术栈:Python 3.11 + LangChain 0.3 + FastAPI
✅ 记忆已保存:用户正在做一个内部知识库 RAG 系统,文档量约 1000 篇
注入的记忆:
<relevant_memory>
- 用户偏好使用 FAISS 而不是 Milvus,因为他的项目是单机部署
- 用户正在做一个内部知识库 RAG 系统,文档量约 1000 篇
</relevant_memory>
技巧四:工具输出格式化,别把"垃圾"喂给模型
Agent 调用工具之后,返回值可能又长又乱——SQL 查询返回了几百行数据、API 返回了一大堆嵌套 JSON。
直接塞进上下文,模型会被"噎住"。
现在想想,当时我们组有个系统,工具返回值直接原样传给模型——一次工具调用产生 3000 个 Token 的返回值,调三次工具上下文就撑爆了。踩过才知道这个坑有多深。
正确做法:工具结果先提炼再注入。
import json
from typing import Any
def format_tool_output(tool_name: str, raw_output: Any, max_tokens: int = 500) -> str:
"""
把工具返回值格式化成上下文友好的格式。
核心思路:只保留模型决策所需的信息,其余截断或摘要。
"""
if tool_name == "database_query":
# 数据库查询结果:只保留前 N 行,附上总行数
rows = raw_output.get("rows", [])
total = raw_output.get("total_count", len(rows))
preview = rows[:5] # 只给模型看前 5 行
return (
f"<tool_result name='database_query'>/n"
f"查询成功,共 {total} 条结果,展示前 {len(preview)} 条:/n"
f"{json.dumps(preview, ensure_ascii=False, indent=2)}/n"
f"{'(已截断,仅展示前5条)' if total > 5 else ''}/n"
f"</tool_result>"
)
elif tool_name == "web_search":
# 网页搜索结果:每条结果只保留标题 + 摘要,去掉正文
results = raw_output.get("results", [])
formatted = []
for i, r in enumerate(results[:3]): # 最多用前 3 条结果
formatted.append(f"{i+1}. 【{r['title']}】/n {r['snippet']}")
return (
f"<tool_result name='web_search'>/n"
+ "/n".join(formatted)
ool_result>"
)
else:
# 其他工具:把结果转成字符串,硬截断
result_str = str(raw_output)
if len(result_str) > max_tokens * 4: # 粗略估算 Token 数
result_str = result_str[:max_tokens * 4] + "/n...[已截断]"
return f"<tool_result name='{tool_name}'>/n{result_str}/n</tool_result>"
# 使用示例
raw_db_result = {
"rows": [{"id": i, "content": f"文档{i}的内容..."} for i in range(100)],
"total_count": 100
}
formatted = format_tool_output("database_query", raw_db_result)
print(formatted)
print(f"/n原始长度:{len(str(raw_db_result))} 字符")
print(f"格式化后:{len(formatted)} 字符")
# 运行结果
<tool_result name='database_query'>
查询成功,共 100 条结果,展示前 5 条:
[
{"id": 0, "content": "文档0的内容..."},
{"id": 1, "content": "文档1的内容..."},
...
]
(已截断,仅展示前5条)
</tool_result>
原始长度:2847 字符
格式化后:312 字符 ← 压缩了 89%,且保留了所有关键信息
技巧五:上下文预算管理,给不同内容分配 Token 配额
这是稍微进阶一点的技巧。说白了,就是事先规划好上下文窗口里各部分的 Token 占比,防止某一部分无限膨胀把其他部分挤掉。
# -----------------------------------------------
# 🔧 【按你的环境修改这里】
# -----------------------------------------------
# 模型的总上下文窗口大小(Token 数)
# claude-sonnet-4-6 最大 200k,这里保守设 32k 用于实验
TOTAL_CONTEXT_BUDGET = 32000
# -----------------------------------------------
# 上下文预算分配方案(比例之和为 1.0)
CONTEXT_BUDGET = {
"system_prompt": 0.10, # 10% 给系统提示词(约 3200 tokens)
"memory": 0.15, # 15% 给长期记忆注入(约 4800 tokens)
"retrieved_docs": 0.35, # 35% 给 RAG 检索结果(约 11200 tokens,最大头)
"tool_outputs": 0.20, # 20% 给工具调用返回值(约 6400 tokens)
"chat_history": 0.15, # 15% 给对话历史(约 4800 tokens)
"user_input": 0.05, # 5% 给用户当前输入(约 1600 tokens)
}
def check_budget(content: str, budget_key: str) -> tuple[bool, int, int]:
"""
检查某部分内容是否超出预算。
返回:(是否超标, 实际token数估算, 预算token数)
"""
# 用字符数 / 4 粗略估算 Token 数(英文约 4字符/token,中文约 2字符/token)
estimated_tokens = len(content) // 3
budget_tokens = int(TOTAL_CONTEXT_BUDGET * CONTEXT_BUDGET[budget_key])
over_budget = estimated_tokens > budget_tokens
if over_budget:
print(f"⚠️ [{budget_key}] 超出预算!"
f"估算 {estimated_tokens} tokens,预算 {budget_tokens} tokens")
return over_budget, estimated_tokens, budget_tokens
def truncate_to_budget(content: str, budget_key: str) -> str:
"""把内容截断到预算以内"""
_, estimated, budget = check_budget(content, budget_key)
if estimated <= budget:
return content
# 按预算比例截断(token * 3 还原成大约的字符数)
max_chars = budget * 3
return content[:max_chars] + f"/n...[已截断,超出 {budget_key} 预算]"
# 使用示例
retrieved_docs = "这是从向量库里检索出来的超长文档内容..." * 200 # 模拟超长检索结果
truncated = truncate_to_budget(retrieved_docs, "retrieved_docs")
print(f"原始:{len(retrieved_docs)} 字符 → 截断后:{len(truncated)} 字符")
# 运行结果
⚠️ [retrieved_docs] 超出预算!估算 14000 tokens,预算 11200 tokens
原始:42000 字符 → 截断后:33605 字符
五、总结:Context Engineering 的三条铁律
说到这里,核心就一句话:
上下文的质量,决定了 Agent 的上限。
三条铁律:
- ✅ 放什么:宁缺毋滥,只放跟当前任务直接相关的内容
- ✅ 怎么放:结构化优先,用 XML 标签告诉模型每段是什么
- ✅ 管多少:预算意识,给每部分分配合理的 Token 配额
技术选型快速参考
| 你的场景 | 推荐方案 |
|---|---|
| 单轮问答,上下文简单 | 不用专门做 CE,把 Prompt 写清楚就够 |
| 多轮对话 Agent | 对话历史压缩 + 记忆注入(技巧二 + 三) |
| 调用多个外部工具 | 工具输出格式化(技巧四) |
| 复杂 RAG 系统 | 上下文预算管理 + 结构化 System Prompt(技巧一 + 五) |
| 生产级 Agent | 以上全部,配合 Prompt Caching 降成本 |
现在就可以做的三件事
-
1. 检查你的 System Prompt:加上 XML 标签分区,5 分钟的改动,效果立竿见影
-
2. 加一个压缩机制:超过 10 轮对话触发摘要压缩,防止上下文溢出
-
3. 格式化工具输出:别把原始返回值直接喂给模型,先提炼关键信息
进阶学习路线
| 阶段 | 掌握内容 | 参考资料 |
|---|---|---|
| 入门 | 结构化 Prompt + 对话历史管理 | 本文代码 |
| 进阶 | 记忆系统设计 + Token 预算管理 | mem0 文档、LangChain Memory |
| 高级 | Multi-Agent 上下文共享 + Prompt Caching | Anthropic API 文档 |
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线科技企业深耕十二载,见证过太多因技术卡位而跃迁的案例。那些率先拥抱 AI 的同事,早已在效率与薪资上形成代际优势,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在大模型的学习中的很多困惑。我们整理出这套 AI 大模型突围资料包:
- ✅ 从零到一的 AI 学习路径图
- ✅ 大模型调优实战手册(附医疗/金融等大厂真实案例)
- ✅ 百度/阿里专家闭门录播课
- ✅ 大模型当下最新行业报告
- ✅ 真实大厂面试真题
- ✅ 2026 最新岗位需求图谱
所有资料 ⚡️ ,朋友们如果有需要 《AI大模型入门+进阶学习资源包》,下方扫码获取~
① 全套AI大模型应用开发视频教程
(包含提示工程、RAG、LangChain、Agent、模型微调与部署、DeepSeek等技术点)
② 大模型系统化学习路线
作为学习AI大模型技术的新手,方向至关重要。 正确的学习路线可以为你节省时间,少走弯路;方向不对,努力白费。这里我给大家准备了一份最科学最系统的学习成长路线图和学习规划,带你从零基础入门到精通!
③ 大模型学习书籍&文档
学习AI大模型离不开书籍文档,我精选了一系列大模型技术的书籍和学习文档(电子版),它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。
④ AI大模型最新行业报告
2025最新行业报告,针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。
⑤ 大模型项目实战&配套源码
学以致用,在项目实战中检验和巩固你所学到的知识,同时为你找工作就业和职业发展打下坚实的基础。
⑥ 大模型大厂面试真题
面试不仅是技术的较量,更需要充分的准备。在你已经掌握了大模型技术之后,就需要开始准备面试,我精心整理了一份大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

以上资料如何领取?

为什么大家都在学大模型?
最近科技巨头英特尔宣布裁员2万人,传统岗位不断缩减,但AI相关技术岗疯狂扩招,有3-5年经验,大厂薪资就能给到50K*20薪!

不出1年,“有AI项目经验”将成为投递简历的门槛。
风口之下,与其像“温水煮青蛙”一样坐等被行业淘汰,不如先人一步,掌握AI大模型原理+应用技术+项目实操经验,“顺风”翻盘!

这些资料真的有用吗?
这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。
资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。

以上全套大模型资料如何领取?

更多推荐

所有评论(0)