【大模型Wiki】16 · Agent 与多 Agent 与 Coding Agent
Agent、多 Agent 与 Coding Agent
新增篇目。Agent 是 2025-2026 大模型落地的主战场。
经典综述:Lilian Weng《LLM Powered Autonomous Agents》https://lilianweng.github.io/posts/2023-06-23-agent/
一、Agent 是什么
Agent = LLM(大脑) + 工具(手脚) + 循环(生命) + 记忆(经验)。与"一问一答"的 Chatbot 的本质区别:Agent 在一个循环里自主决策——观察环境、调用工具、根据结果继续行动,直到完成任务。
Lilian Weng 的经典定义:
Agent = LLM + Planning(规划) + Memory(记忆) + Tool Use(工具)
1.1 为什么"循环"是灵魂
普通 Chatbot 是一次性函数调用:input → LLM → output。Agent 则是把 LLM 包在一个 while 循环里:每一次迭代,模型可能决定"我还需要查点东西",于是调用工具、拿到结果、把结果塞回上下文,再让模型决策下一步。这个"自主决断 + 环境交互"的闭环,让模型从"会说话"变成"能办事"。
四个要素缺一不可:
- LLM(大脑):负责推理、规划、生成行动决策;
- 工具(手脚):让模型能影响/读取外部世界(搜索、代码执行、API);
- 循环(生命):把"思考—行动—观察"串成可持续的过程;
- 记忆(经验):让长任务中模型"记得"之前做过什么、学到了什么。
1.2 Agent 与 Chatbot 的能力边界
| 维度 | Chatbot | Agent |
|---|---|---|
| 交互方式 | 一问一答 | 自主多步循环 |
| 能否改外部世界 | 否 | 能(调 API、跑代码、写文件) |
| 是否需要工具 | 不需要 | 核心依赖 |
| 上下文长度 | 单轮/短对话 | 长任务、需记忆管理 |
| 失败处理 | 重问即可 | 需自我修正/回滚 |
二、Agent 循环:ReAct 范式
ReAct(Reasoning + Acting, 2022)是几乎所有 Agent 的骨架:模型交替输出思考与行动,观察行动结果再继续思考:

用户:帮我查北京今天天气,如果下雨提醒我带伞
──────────────────────────────────────────────
Thought: 我需要先查询北京的天气
Action: get_weather(city="北京")
Observation: {temp: 22, condition: "小雨"}
Thought: 今天有小雨,需要带伞。任务完成,回复用户
Final Answer: 北京今天小雨 22°C,出门请带伞。
──────────────────────────────────────────────
落到 API 层面,这就是第 04 篇的 tool calling 外面套一个 while 循环:
messages = [{"role": "user", "content": task}]
while True:
resp = llm.chat(messages, tools=tools)
if resp.tool_calls: # 模型要求调用工具
for tc in resp.tool_calls:
result = execute_tool(tc) # 真正执行
messages.append(tool_result_msg(result))
else: # 模型给出最终答案
return resp.content
工程必备件:最大步数限制(防死循环)、人工确认(危险操作审批)、错误回传(工具报错要把错误信息还给模型让它自我修正)。
2.1 ReAct 的 Prompt 结构拆解
ReAct 之所以有效,是因为它把"推理"和"行动"显式地写在同一个轨迹(trajectory)里,让模型能"边想边做"。一个典型的 ReAct prompt 包含三部分:
- 指令(Instruction):告诉模型"你可以交替使用 Thought / Action / Observation,必要时调用工具,最终用 Final Answer 收尾";
- 少量示例(Few-shot demos):给 2–3 个完整 Thought→Action→Observation→Final Answer 样例,教模型格式;
- 当前轨迹(Trajectory):已发生的
Thought / Action / Observation历史,模型基于它续写下一步。
# 系统指令(示意)
你是一个能用工具的智能体。每一步先写 Thought(你的推理),
再写 Action(调用工具:工具名(参数)),系统会返回 Observation。
循环直到你能在 Final Answer 中给出最终答复。
# 示例
Question: 珠穆朗玛峰比科罗拉多河高多少?
Thought: 我需要先查两座地标高度
Action: search("珠穆朗玛峰 海拔")
Observation: 8848.86 米
Thought: 再查科罗拉多河
Action: search("科罗拉多河 海拔")
Observation: 约 0 米(河流源头海拔不起决定作用,这里仅为示例)
Thought: 两者相减
Action: calculator(8848.86 - 0)
Observation: 8848.86
Final Answer: 约 8848.86 米
# 当前问题
Question: {user_question}
Thought:
注意:现代模型(GPT-4 等)通常不再用纯文本 ReAct 格式,而是改用 API 原生的 tool_calling(结构化输出),由框架把 Observation 回填。但 ReAct 的思想——"思考与行动交错、观察驱动下一步"——仍完整保留在 tool-calling 循环里。
2.2 Function / Tool Calling 实现原理
Tool Calling(也叫 Function Calling)是模型原生能力,让模型以结构化 JSON 表达"我想调哪个函数、传什么参数",而不是靠正则从文本里扒 Action:。
2.2.1 原理
- 你向 API 声明一组工具的 schema(函数名、描述、参数 JSON Schema);
- 模型读用户问题后,若认为需要调用,就返回一个结构化的
tool_calls,含函数名与已填好的参数; - 你(Host)在本地真正执行函数,拿到结果;
- 把"工具名 + 参数 + 结果"作为一条
tool角色消息回填进对话,再请求模型,模型据此继续。
import openai # 以 OpenAI 兼容接口为例,思路通用
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询指定城市当前天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名,如 北京"}
},
"required": ["city"]
}
}
}]
messages = [{"role": "user", "content": "北京今天天气怎么样,要带伞吗?"}]
resp = client.chat.completions.create(
model="gpt-4o", messages=messages, tools=tools
)
# 模型决定调用工具:返回结构化 tool_calls
if resp.choices[0].message.tool_calls:
tc = resp.choices[0].message.tool_calls[0]
print(tc.function.name) # 'get_weather'
print(tc.function.arguments) # '{"city": "北京"}' —— 已是合法 JSON
# 本地执行
result = get_weather(**json.loads(tc.function.arguments))
# 回填工具结果
messages.append(resp.choices[0].message) # 先保留模型的 tool_calls 消息
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": json.dumps(result, ensure_ascii=False)
})
# 再次请求,模型据此给出最终自然语言答复
final = client.chat.completions.create(model="gpt-4o", messages=messages, tools=tools)
print(final.choices[0].message.content)
2.2.2 关键工程细节
- 参数必为合法 JSON:现代模型对 JSON 输出做了微调,基本能稳定产出可解析参数;但仍要
try/except json.loads兜底,解析失败可把错误回传让模型重试。 - tool_call_id 必须对应:回填的
tool消息要带tool_call_id,框架据此把结果拼回对应的那次调用(并行调用时尤其重要)。 - 并行 tool call:模型一次可返回多个
tool_calls,Host 可并发执行再批量回填,提速明显,但注意结果回填顺序与 id 对应。 - schema 写得好坏决定成败:函数
description和参数description是模型"决策是否调用、怎么填参"的主要依据,务必写清楚、写准确,避免歧义。
三、Memory 与上下文工程
上下文窗口有限,长任务必须管理"该让模型看到什么":
- 短期记忆:对话历史,直接放上下文;过长则压缩/摘要(compaction)
- 长期记忆:向量库检索(RAG 式记忆)、结构化事实库("用户偏好 X")
- 工作区记忆:Codex 类 Agent 的
AGENTS.md、任务待办清单文件(todo list 作为持久记忆) - Append-only 日志:DeepSeek Harness 的 session log 是典型——所有"模型所见即所录",可回放可分叉(见 10 篇)
"上下文工程(Context Engineering)"已取代早期"提示工程"成为一门显学:决定每一步把哪些系统提示、工具 schema、历史、检索结果、子 Agent 报告塞进有限窗口。
3.1 记忆系统的三种形态(深入)
3.1.1 短期记忆(Short-term / Working Memory)
就是当前上下文窗口里的内容:系统提示、对话历史、工具调用与结果。问题是窗口有限(哪怕 128K/200K 也有上限),长任务会溢出。
常用压缩策略:
- 截断(Truncation):丢弃最旧的消息——简单但可能丢关键信息;
- 摘要压缩(Compaction):定期对早期消息调用 LLM 做摘要,用摘要替换原文,典型如 Claude Code 的
compact; - 滑动窗口 + 关键保留:保留最近 N 轮 + 始终保留"任务目标、用户偏好、重要结论"。
3.1.2 长期记忆(Long-term Memory)
让 Agent 跨会话记住东西,典型三类:
- 向量库记忆(RAG 式):把历史对话/知识切块 embedding 入库,需要时语义检索回填;
- 结构化事实库:显式存"用户偏好:喜欢简洁回答""项目名称:X"等键值/图结构事实;
- 文件/工作区持久化:直接写文件(笔记、todo、实验记录),模型下次读文件即可恢复。
# 长期记忆最简实现:向量库检索(伪代码)
def recall(memory_db, query, k=5):
q_vec = embed(query)
hits = memory_db.search(q_vec, top_k=k) # 语义检索
return "\n".join(h.text for h in hits)
def remember(memory_db, text):
memory_db.insert(embed(text), text) # 把经历写进长期记忆
3.1.3 工作区记忆(Workspace Memory)
Agent 把"待办清单、约束、发现"持续写进工作区文件,相当于给模型一块"外部大脑"。AGENTS.md(项目级指令)、todo.md(任务清单)、notes.md(调研笔记)是常见形态。好处:不受上下文窗口限制,可审阅、可版本化(进 git)。
3.2 上下文工程(Context Engineering)是什么
Andrej Karpathy 等提出的观点:写好一个固定 prompt 已经不够,每一步"给模型喂什么上下文"本身就是一个需要设计和优化的系统。核心决策:
- 系统提示里放多少"世界观/规则"?
- 暴露多少工具 schema?(schema 越多,模型越容易选错/越占 token)
- 历史保留多少、摘要到什么粒度?
- 检索结果怎么排序、截断?
- 子 Agent 的报告摘要到几行?
好的上下文工程 = 在有限窗口里塞进"恰好够决策的信息",同时剔除噪声。这是 Agent 质量的分水岭,往往比换更强模型收益更大。
四、Planning 与 Self-Reflection
4.1 规划(Planning)技术
| 技术 | 思路 |
|---|---|
| CoT 思维链 | 让模型先写推理再作答 |
| 任务分解 | 把大任务拆成子任务清单(plan-and-execute) |
| Reflection | 执行后自我批评、重试 |
| 长思考(Reasoning 模型) | o1/R1/Qwen3-Thinking 类模型把"规划"内化为测试时计算 |
4.1.1 Plan-and-Execute
把"规划"和"执行"分成两个阶段/两个模型调用:
- 先规划:让模型一次性产出完整子任务清单(plan);
- 再逐条执行:每步执行后把进展写回 plan,执行完一条划掉一条;
- 必要时重规划:遇到意外阻塞,重新调用规划器调整剩余步骤。
优点:plan 在上下文里稳定可见,模型不易"跑偏";适合长任务。
4.2 Reflexion(自我反思)
Reflexion(2023,Shinn et al.)是让 Agent 从失败中学习的关键技术。核心:每轮结束后,让模型基于"轨迹 + 环境反馈"生成一段口头反思(verbal reflection),存进记忆,下一轮决策时读它,避免重复犯错。
第 1 轮:尝试 → 失败(环境回报负值)
↓
反思模块:基于"我做了什么 / 为什么失败"生成反思
"我刚才没先查数据库就直接写 SQL,导致字段名错。
下次应先 DESCRIBE 表结构再写查询。"
↓
反思存入长期记忆
第 2 轮:模型读取反思 → 改变策略 → 成功
实现要点:
- 用一条固定反思 prompt 让模型总结"哪里错了、下次怎么改";
- 反思是文本、可解释、可审计;
- 与 3.1 的长期记忆结合,跨 Episode 积累经验。
4.3 长思考模型对 Agent 的影响
o1 / DeepSeek-R1 / Qwen3-Thinking 这类"推理模型"把规划内化为测试时计算(test-time compute):模型在内部做大量隐式推理后再输出行动。这显著提升了复杂多步任务的规划质量,但代价是延迟和成本更高。实践中常"简单步用快模型、难规划用推理模型",做分层调度。
五、多 Agent(Multi-Agent)
单 Agent 的痛点:上下文装不下一个庞大任务;一个模型既要规划又要执行容易"分心"。多 Agent 把系统组织成分工协作的智能体集合。
5.1 常见拓扑
| 模式 | 结构 | 例子 |
|---|---|---|
| Orchestrator-Worker | 一个主 Agent 拆解任务、派发子 Agent、汇总结果 | Claude Code 子 Agent、DeepSeek Harness 的 subagent |
| 流水线 | A 输出 → B 输入,按序加工 | 需求→编码→测试→评审 |
| 辩论/评审 | 多个 Agent 各持立场互相挑错 | 代码 review 对抗、提升推理质量 |
| 群聊 | 共享消息总线,自由发言 | AutoGen group chat |
5.1.1 各拓扑适用场景
- Orchestrator-Worker:最常用。主 Agent 负责"派活 + 收活 + 兜底",子 Agent 各自专注一块(如一个查文档、一个写代码)。上下文隔离好,主 Agent 不被子任务细节淹没。
- 流水线(Pipeline):任务天然有先后依赖且每一步职责清晰,如"需求分析→编码→测试→评审"。
- 辩论/评审(Debate):用"多视角互相挑错"提升推理/代码质量,代价是多倍调用成本。
- 群聊(Group Chat):角色在共享总线自由发言,灵活但难控制、易发散,多用于探索型协作。
5.2 主流框架角色分工对比
| 框架 | 出品方 | 特点 | 心智模型 |
|---|---|---|---|
| LangGraph | LangChain | 图编排、状态机、checkpoint,工程最成熟 | 把 Agent 画成"有状态的状态图" |
| AutoGen / AgentChat | 微软 | 多 Agent 会话式协作、group chat | 多个 Agent 像人一样聊天协作 |
| CrewAI | 开源 | 角色化团队(CEO/工程师/QA 隐喻),上手快 | 组建一支"有职位的团队" |
| MetaGPT | 开源 | SOP 驱动的软件公司模拟 | 用标准作业流程编排"软件公司" |
| Swarm → Agents SDK | OpenAI | 极简 handoff 模式 | Agent 之间"交接"对话 |
5.2.1 怎么选框架
- 要强可控、可回放、可 checkpoint 的生产系统 → LangGraph(状态机 + 持久化最扎实);
- 要快速搭多 Agent 对话/群聊原型 → AutoGen;
- 要用"角色剧本"讲故事式组队 → CrewAI(CEO/Researcher/Writer 隐喻直观);
- 要模拟软件公司瀑布流(需求→设计→编码→测试) → MetaGPT(内置 SOP);
- 要轻量 handoff、和 OpenAI 生态紧耦合 → Agents SDK。
5.3 多 Agent 的核心难题:状态与上下文隔离
多 Agent 的核心难题不是"怎么对话",而是状态与上下文隔离:子 Agent 之间传什么、主 Agent 记住多少、失败如何回滚——这正是 Harness 层(09 篇)要解决的问题。
具体痛点:
- 上下文污染:子 Agent 的脏输出(报错、冗长日志)直接灌给主 Agent,挤占窗口还带偏决策;
- 信息丢失:子 Agent 该回传"结论摘要"而非"全部过程",否则主 Agent 被淹没;
- 失败传播:一个子 Agent 崩了,要不要整体回滚?还是换一个子 Agent 重试?需要显式错误处理;
- 成本爆炸:N 个 Agent 各自带全量工具 schema + 历史,token 消耗乘倍。
对策:子 Agent 只读必要上下文、只回传结构化摘要;主 Agent 持有全局 plan 与最终裁决;用 Harness 统一管理调度、隔离、回滚。
六、Coding Agent:落地最成功的 Agent
编程是 Agent 的最佳场景:目标可验证(编译/测试)、反馈明确(报错信息)、工具天然存在(文件系统、shell、git)。
6.1 代表产品(2026)
| 产品 | 形态 | 特点 |
|---|---|---|
| Claude Code | 终端 Agent | Anthropic 官方,agentic coding 事实标杆 |
| DeepSeek Harness | 开源运行时 | Everything is a plugin,源码可读(见 10 篇) |
| OpenAI Codex CLI | 终端/云 | 与 GPT-5 协同,沙箱执行 |
| Gemini CLI | 终端 | 超大上下文 |
| Cursor / Windsurf | IDE | 编辑器内多文件编辑 |
| Qwen Code / GLM Coding | 终端 | 国产开源平替 |
6.2 共同的工具集设计
几乎所有 Coding Agent 都收敛到一套最小而完备的工具:
read_file / str_replace_editor # 精确读改文件(diff 式编辑)
bash / shell(持久会话) # 跑构建、测试、git
glob/grep # 代码检索
web_search / fetch # 查文档
subagent / task # 派发子任务
工作流:探索(grep 读代码)→ 计划(todo list)→ 执行(编辑+测试循环)→ 验证(跑测试)→ 汇报。"计划→执行"分离、测试驱动闭环,是从"能改代码"到"可靠改代码"的关键。
6.2.1 工具设计细节
- str_replace_editor(diff 式编辑):模型不是"重写整文件",而是给出
old_string → new_string的精确替换。好处:改动可追溯、失败易定位、不会因一处错毁全文件。是 Coding Agent 比"整文件生成"可靠的核心。 - 持久 shell 会话:多次命令共享同一 shell 状态(环境变量、工作目录、虚拟环境),否则
cd/source activate在下一条命令失效。 - glob/grep 检索:让模型先"看懂仓库结构"再动手,避免凭空编造不存在的文件/函数。
6.2.2 SWE-agent 类工作流(以基准为参照)
SWE-bench 等基准催生的 Coding Agent 范式,可抽象为:
- 复现(Repro):先跑通能触发 bug 的最小测试,确认问题存在;
- 定位(Localize):用 grep/调用图/报错栈定位相关文件与函数;
- 修复(Patch):生成最小 diff;
- 验证(Verify):跑测试套件,失败则把报错回传模型重试;
- 提交(Submit):通过则提 PR。
输入: issue 描述 + 仓库
→ 检索相关代码 (grep / 调用图)
→ 写修复 diff (str_replace_editor)
→ 跑测试 (bash: pytest)
→ 失败? 把报错喂回模型再修 (Reflexion 式循环)
→ 通过? 提 PR
这一范式已被 Claude Code、Codex、DeepSeek Harness 等吸收为"标准姿势"。
6.3 从 Agent 到 Harness
把上面的循环、工具、权限审批、会话日志、子 Agent 调度、上下文管理做成一个可复用、可扩展的运行时,就是 Agent Harness——模型是灵魂,Harness 让它在真实环境里持续工作。
公式:Agent = Model + Harness
09 篇讲 Harness 的完整概念谱系(评估 Harness → Agent Harness),10 篇直接读 DeepSeek Harness 源码。
6.3.1 Harness 的关键子系统
- 权限层:哪些命令需人工确认(如
rm -rf、git push),哪些自动放行; - 沙箱:在隔离环境跑不可信命令,防破坏宿主机;
- 会话日志(Append-only log):记录模型每次决策与环境反馈,可回放、可分叉(试错不留痕地探索);
- 子 Agent 调度器:按拓扑派发/汇总,做上下文隔离;
- 上下文管理器:负责 compaction、检索回填、窗口调度。
七、Agent 的失败模式与对策
落地 Agent 最痛的不是"不会做",而是"做着做着翻车"。常见失败模式:
7.1 循环调用(Loops / Non-termination)
- 现象:模型反复调同一个工具、或 Thought→Action→Observation 打转,永远不 Final Answer。
- 原因:工具结果没给出"终止信号";模型误以为还差一步;或 prompt 没强调"达成即收尾"。
- 对策:
- 设 max_steps(最大步数),超限强制终止并提示用户;
- 工具返回里带明确"已完成/还需 X"的状态;
- 用推理模型或加"反思:你是否已能给出最终答案"的引导。
7.2 上下文污染(Context Pollution)
- 现象:长任务后期,模型被大量工具原始输出(超长日志、错误栈、冗余 JSON)淹没,开始答非所问、调用错误工具。
- 原因:把所有 Observation 原样塞进上下文,噪声盖过信号。
- 对策:
- Observation 截断 + 摘要后再回填(如只留"前 2000 字符 + 错误行");
- 结构化解析工具输出,只提取模型需要的字段;
- 定期 compaction,把长历史压成摘要;
- 子 Agent 只回传结论,细节留在子 Agent 上下文里。
7.3 工具误用 / 参数错误
- 现象:调错工具、参数填错(如 city 填成数字)、漏填 required 字段。
- 对策:
- schema 的
description写清楚"何时用、怎么填"; - 解析失败时把"参数错误原因"回传模型重试;
- 关键调用加 schema 校验(JSON Schema validate)再执行。
- schema 的
7.4 幻觉式行动(Hallucinated Action)
- 现象:模型"编造"一个不存在的工具或文件,或声称已完成实则没执行。
- 对策:
- 严格白名单:只允许调用声明的工具;
- 执行结果以"真实系统返回值"为准,不轻信模型自述;
- 关键操作前让模型先"展示证据"(如先 grep 证明文件存在再编辑)。
7.5 成本与延迟失控
- 现象:多 Agent + 长上下文 + 反复重试,账单爆炸、响应极慢。
- 对策:
- 分层模型(简单步用快廉价模型);
- 限制并行/重试次数;
- 优先用上下文工程减少 token,而非一味加窗口。
7.6 失败模式速查表
| 失败模式 | 信号 | 首选对策 |
|---|---|---|
| 循环调用 | 步数逼近上限还不收尾 | max_steps + 终止信号 |
| 上下文污染 | 后期答非所问 | Observation 摘要 + compaction |
| 工具误用 | 报错"未知工具/参数错" | schema 描述 + 校验 + 重试 |
| 幻觉行动 | 引用不存在的文件/工具 | 工具白名单 + 真实返回值 |
| 成本失控 | 账单/延迟异常 | 分层模型 + 限流 |
八、实践清单(可直接照抄)
- 最小可跑闭环:先实现"tool_calling + while 循环 + max_steps",跑通一个查天气 demo,再叠加记忆/多 Agent。
- 工具 schema 当产品写:每个函数的 name/description/参数描述都精心打磨,这是 Agent 可靠性的第一杠杆。
- Observation 必须被治理:永远不要原样塞大输出,截断/摘要/结构化解析三选一或组合。
- 危险操作人工确认:文件删除、git push、外发请求默认走审批。
- 错误回传模型:工具报错把信息(而非"失败了"三个字)还给模型,它多半能自我修正。
- 长任务上上下文工程:摘要压缩、长期记忆检索、AGENTS.md/todo 工作区记忆组合起来用。
- 可观测:保留 append-only 会话日志,出问题能回放定位,而不是"它又抽风了"。
九、参考
- ReAct:https://arxiv.org/abs/2210.03629
- Reflexion:https://arxiv.org/abs/2303.11366
- Lilian Weng Agent 综述:https://lilianweng.github.io/posts/2023-06-23-agent/
- Anthropic《Building effective agents》:https://www.anthropic.com/research/building-effective-agents
- LangGraph multi-agent:https://langchain-ai.github.io/langgraph/concepts/multi_agent/
十、小结
Agent 的本质,是把 LLM 从"一次性问答函数"升级为"能自主循环、调用工具、管理记忆、从失败中学习"的系统。它的骨架是 ReAct(思考→行动→观察)思想,落地形态是 tool_calling 外套一个 while 循环;它的可靠性来自记忆系统(短期压缩 / 长期检索 / 工作区持久化)与上下文工程;它的上限来自规划(plan-and-execute、Reflexion、长思考模型)与多 Agent 分工。
落地时真正的难点不是"让模型调通一个工具",而是控制失败:循环调用、上下文污染、工具误用、幻觉行动、成本失控,每一步都有成熟对策(步数上限、Observation 治理、schema 打磨、白名单、分层模型)。
Coding Agent 是当前最成功的形态——目标可验证、反馈明确、工具天然。而其背后的 Harness(运行时)才是让模型在真实世界持续工作的真正引擎:Agent = Model + Harness。理解这条主线,就能在 Agent 框架快速更替的浪潮里,抓住不变的内核。

浙公网安备 33010602011771号