从最小循环讲清 Agent 的骨架,顺便打掉几个流行误解
这两年"Agent"变成了 AI 圈最被滥用的词。有人把 ChatGPT 串两轮 Prompt 叫 Agent,有人把 RPA 脚本套个 LLM 叫 Agent,有人把一个会调函数的模型也叫 Agent。概念一糊,写的代码就跟着糊——你以为在做 Agent,其实只是把 Function Calling 包了一层;你以为多 Agent 能干大事,其实只是让系统更慢、更贵、更难调。
这个系列从一个朴素的问题开始:Agent 到底是什么,它和已经有的东西有什么区别。
一个干净的定义
Anthropic 在 2024 年底的 "Building effective agents" 里给了一个我很喜欢的定义:
An agent is an LLM dynamically directing its own processes and tool usage.
翻译过来:Agent 是一个自己决定下一步做什么、并能调用工具的 LLM。
关键词两个——自己决定、调用工具。少一个都不成立。只能调工具但由你决定调用顺序,那是 Workflow;能自己决定但没有工具(只是在脑子里推理),那是 Chain of Thought。两件事装进一个循环,才有了 Agent 的最小骨架:
while not done:
response = llm.chat(messages, tools=tools)
if response.tool_calls:
results = [run_tool(tc) for tc in response.tool_calls]
messages.append(response)
messages.extend(results)
else:
done = True
这段代码不到 10 行,但它已经是一个真正的 Agent。剩下所有的复杂性——记忆、规划、反思、多 Agent 协作——都是在这个循环上加东西,而不是另起一个新范式。理解了这一点,后续所有"高级 Agent 架构图"看起来都不会那么吓人。
Workflow 和 Agent 的分界
这是最容易糊的地方,也最值得想清楚。
Workflow 是开发者在代码里写好流程,LLM 只是流程中的一个可调用节点:
summary = llm.summarize(doc)
tags = llm.tag(summary)
result = db.save(summary, tags)
Agent 是开发者只给目标和工具,流程由 LLM 自己生成:
agent.run("帮我整理这份文档,打好标签存到知识库")
# LLM 内部自己决定:先调 summarize,再 tag,再存 db
区别不是"用了多少个 LLM",而是谁在掌控控制流。
这个分界有巨大的工程意义。Workflow 是可预测的——每次运行的路径都一样,好调试、好测试、好监控。Agent 是不可预测的——同一个输入,两次可能走完全不同的路径,某一步跑偏整个任务就偏了。
所以选 Workflow 还是 Agent,本质上是在问一个问题:这个任务的路径能不能事先枚举。能枚举就用 Workflow;不能枚举,或者分支多到枚举起来代码会爆炸,才用 Agent。
很多团队的第一个错误就是:不管任务是什么,上来就要做"多 Agent 系统"。结果是一个本来 20 行代码就能搞定的 Workflow,被做成了一个慢 10 倍、贵 10 倍、还经常跑偏的 Agent。
自主性是一条光谱,不是开关
Workflow 和 Agent 不是非黑即白。Anthropic 把中间划成五档,从左到右自主性递增:
- Prompt chaining:LLM A 的输出喂给 LLM B,顺序固定
- Routing:先让 LLM 判断任务类型,再路由到对应分支
- Parallelization:把任务拆成可并行的子任务,LLM 并发跑,结果聚合
- Orchestrator-Worker:一个 LLM 做协调者,动态分派子任务给 Worker
- Evaluator-Optimizer:一个 LLM 出结果,另一个 LLM 评审,循环到满意
再加上"自由调用工具 + 自主决定何时结束",就到了完整意义上的 Agent。
这个光谱值得记下来,因为大多数真实任务只需要前三档。你以为需要 Agent,其实 Routing + Parallelization 就够了。Anthropic 内部的工程经验也是——先从能解决问题的最简单方案做起,只有在确实需要动态决策时才上 Agent。
Agent 的三要素
把 Agent 拆开看,永远是三件东西:
Model——大脑。决定下一步干什么、解析工具返回的结果、判断任务是否完成。 Tools——手脚。能调用的外部能力:搜索、文件读写、代码执行、API、数据库。 Loop——心跳。一个不断"思考 → 行动 → 观察"的循环,直到任务完成或触发停止条件。
这三件事都离不开,也都是这个系列后续每一篇要深挖的方向。Model 侧讨论 Prompt 设计、推理模型、上下文管理;Tools 侧讨论粒度、命名、错误反馈、工具数量膨胀;Loop 侧讨论最大步数、停止条件、反思与重规划。
为什么 Agent 到 2024 才真正能用
有个有意思的问题:ReAct 这个 Agent 模式 2022 年的论文就提出来了,但大规模能用的 Agent 产品要到 2024 年才看到。中间缺了什么?
缺的不是某一个东西,是一堆能力同时到位:
工具调用能力的成熟。GPT-3.5 时代的 Function Calling 不稳定,经常调错参数、忘记调、重复调。直到 GPT-4 Turbo、Claude 3.5 Sonnet 这一代,工具调用才从"能用"变成"能靠"。
上下文长度的爆炸。Agent 在循环里每一步都往 messages 里堆东西,几步就几千 token。上下文只有 4K 的年代,Agent 跑三轮就爆。到了 100K+、200K 的时代,Agent 才有了做长任务的空间。
推理模型的出现。o 系列、R 系列、Claude 的 extended thinking,让模型在动作前真的能规划,而不是凭直觉瞎跳。多步任务的成功率因此跃了一个数量级。
成本的下降。Agent 很费钱——一次任务可能调 LLM 二十次。当每百万 token 从 60 美元降到 3 美元、0.3 美元,Agent 才从"实验室玩具"变成"敢放上线"。
协议的统一。OpenAI 的 tools、Anthropic 的 tool_use、Hermes 的 XML tool_call,三家格式不同,但"模型能以结构化方式声明要调什么工具"这件事成了行业共识,工具生态才有了基础。
这五件事少一件,Agent 都还停在"demo 能跑、生产没法用"的阶段。
Function Calling 不等于 Agent
这是最常见的混淆。Function Calling 是**模型能以结构化方式说"我想调用这个函数"**的能力。它是 Agent 的一个必要零件,但不是 Agent 本身。
一个只做单次 Function Calling 的系统:
用户:北京天气怎么样?
模型:[tool_call: get_weather(city="北京")]
你:执行函数,拿到 "15 度晴"
模型:北京现在 15 度晴朗。
没有循环,模型调完一次工具就把结果抛给用户了。
一个 Agent 长这样:
用户:整理我上周的日历,把所有会议标签化并存到 Notion
模型:[tool_call: list_calendar(start=..., end=...)]
你:执行,返回 20 个事件
模型:[tool_call: classify_event(event=1)] ... [tool_call: classify_event(event=20)]
你:并行执行,返回 20 个分类
模型:[tool_call: notion_create(...)]
你:执行,创建成功
模型:已经整理完 20 个会议并存入 Notion。
多轮工具调用 + 自己决定调哪个 + 自己决定何时结束。一个简单的识别法:如果你的代码里控制了"下一步调什么",那就是 Workflow 或 Function Calling,不是 Agent。
一个能跑的最小 Agent
把前面的所有概念落到代码上,一个有工具、有循环、有终止条件的 Agent,不依赖任何框架:
import json
from openai import OpenAI
client = OpenAI()
def get_weather(city: str) -> str:
return f"{city} 现在 15 度,晴"
def calculate(expression: str) -> str:
return str(eval(expression))
TOOLS = {"get_weather": get_weather, "calculate": calculate}
TOOL_SCHEMAS = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
},
{
"type": "function",
"function": {
"name": "calculate",
"description": "计算一个数学表达式",
"parameters": {
"type": "object",
"properties": {"expression": {"type": "string"}},
"required": ["expression"],
},
},
},
]
def run_agent(user_input: str, max_steps: int = 10):
messages = [
{"role": "system", "content": "你是一个能用工具的助手。"},
{"role": "user", "content": user_input},
]
for _ in range(max_steps):
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=TOOL_SCHEMAS,
)
msg = resp.choices[0].message
messages.append(msg)
if not msg.tool_calls:
return msg.content
for tc in msg.tool_calls:
fn = TOOLS[tc.function.name]
args = json.loads(tc.function.arguments)
result = fn(**args)
messages.append({
"role": "tool",
"tool_call_id": tc.id,
"content": result,
})
return "达到最大步数限制,任务未完成。"
print(run_agent("北京今天天气怎么样,顺便算一下 (15+20)*3 等于多少"))
不到 60 行,做到了什么:三要素齐全(gpt-4o-mini 是 Model、两个函数是 Tools、for 是 Loop);自主决定(模型看到用户问了两件事,会自己先调 get_weather 再调 calculate,或并行调用);终止条件(模型不再发起 tool_calls 或达到 max_steps 退出);状态累积(messages 列表在循环里追加,保留完整对话和工具历史)。
这就是 Agent 的内核。后面整个系列的复杂机制——ReAct 的思考显式化、Reflection 的自我批评、Plan-Execute 的分层规划、Hermes 协议在开源模型上的落地、Multi-Agent 的分工协作——都是在这 60 行之上加东西,本质上没变。记住这个骨架,后面不会迷路。
不要上来就做"多 Agent"
最后想在第一篇就打掉的流行误解:多 Agent 不是更强,反而经常更弱。
你会看到很多项目一上来就摆七八个 Agent,PM Agent、Coder Agent、Tester Agent、Reviewer Agent 云云。看着像"团队分工",实际上踩两个大坑。
上下文碎片化。Agent A 做了一半,把结果交给 Agent B,中间必然需要压缩上下文。压缩过程必然丢信息,B 经常在 A 已经做过的事情上兜圈子。
错误沿链路放大。A 略微偏了,B 基于 A 的输出继续偏,到 D 那里已经完全跑偏。单 Agent 的错误会被自己在下一步看到并纠正,多 Agent 看不到彼此的思考。
Cognition 的 Devin 团队 2024 年底发了一篇 "Don't Build Multi-Agents",观点非常直接:在你没把单 Agent 做到极限之前,不要碰多 Agent。Anthropic 的立场也类似——先试 Workflow,不行试单 Agent,真不行再考虑 Orchestrator-Worker 这种受控的多 Agent 结构。这个系列会单独有一篇讲多 Agent,但重点不是"怎么做得多"而是"怎么做得对",以及"什么时候根本不该做"。
这个系列会带你走到哪里
从这一篇开始,我会带你把 Agent 这件事从最基础的循环,一步步推到生产可用的程度。不会停在 demo,也不会陷进某个框架的黑盒。每一篇解决一类问题:
怎么让 Agent 思考得更清楚——ReAct、Plan-Execute、Reflection、Tree of Thoughts。怎么设计好的工具——粒度、命名、错误反馈、工具爆炸。怎么管理记忆和上下文,这是 Agent 最难的地方。怎么让本地开源模型也能做 Agent——Hermes 协议、Qwen-Agent、全本地方案。怎么做真正有用的复杂形态——Code Agent、Browser Agent、Multi-Agent。最后怎么把它变成生产系统——评测、监控、成本、安全。
每一篇都会给你可以直接跑的代码,不会用"留给读者练习"这种偷懒写法。
下一篇从 ReAct 开始——手写一个把"思考过程"显式化的 Agent,看看为什么让模型先说出它在想什么,会让整个系统的表现跃一个台阶。
相关阅读
- Building effective agents (Anthropic, 2024) — 这篇文章是本系列的精神底座
- Don't Build Multi-Agents (Cognition) — 打掉多 Agent 崇拜
- ReAct: Synergizing Reasoning and Acting in LLMs (2022) — Agent 最早的范式论文
- Agents (Chip Huyen) — 另一个视角的综述
版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。
(采用 CC BY-NC-SA 4.0 许可协议进行授权)
本文标题:01. Agent 是什么:从一次性 Function Call 到自主循环
本文链接:https://www.sshipanoo.com/blog/ai/ai-agent/01-Agent是什么/
本文最后一次更新为 天前,文章中的某些内容可能已过时!