AI Agent 和普通 LLM 到底差在哪:从订机票的七步拆解说起
AIAI Summary (BLUF)
AI Agent 是能自主感知、决策和行动的智能系统,与普通 LLM 不同,它可以通过工具调用、记忆和规划来完成复杂任务。本文用通俗语言和代码示例,带你理解 Agent 的核心架构与 Function Calling 机制。
核心洞察
这篇文章把 Agent 和普通 LLM 的区别讲得很直白:一个是给你答案,一个是给你结果。我特别喜欢里面订机票那个例子,七步拆解下来,你立刻就能明白 Agent 到底在干什么。不过有一点得提醒:文章把 Agent 的能力说得比较理想化,实际落地时工具调用的稳定性和错误处理才是真正的坑。
你可能已经习惯了这样的交互:你问一个问题,AI 给出一个答案。
你让它写一篇文章,它写一篇文章。你让它翻译一句话,它翻译一句话。
这种模式下,AI 更像一个顾问。它给你建议,但不直接做事。
但如果任务稍微复杂一点呢?比如:帮我查一下明天北京的天气,如果温度超过 25 度,就给我推荐一件短袖衬衫,预算 300 元以内,然后把结果整理成邮件发给我老板。
用普通的对话 AI,你得分成好几步:
第一步,查明天北京天气。第二步,如果超过 25 度,推荐 300 元以内的短袖衬衫。第三步,帮我写一封邮件给老板,内容是……
每一步都需要你手动推进。
而 AI Agent(智能体)的思路是:你只需要说一遍帮我做这件事,它自己会把剩下的都做完。
它会自动判断需要做什么、调用什么工具、按什么顺序执行、遇到问题怎么调整,直到任务完成。
简单理解:普通 LLM 是军师,帮你出谋划策;AI Agent 是执行者,拿到目标后自己就去把事办了。
核心结论
AI Agent 与普通 LLM 的本质区别在于交付物不同:普通 LLM 提供答案(如写代码或告知查询网站),而 Agent 直接交付结果(如实际查询航班并生成订单链接)。
Agent 具备三大核心能力:感知(获取环境信息和反馈)、决策(判断下一步做什么)、行动(执行具体操作),分别类比为人的眼睛耳朵、大脑和手脚。
Agent 的标准架构由四部分组成:LLM 大脑(推理核心)、工具(扩展能力边界)、记忆(短期+长期)、规划(任务分解),其中 LLM 是核心但非全部。
Function Calling 的工作机制是"LLM 负责想,执行方负责做":LLM 输出结构化 JSON 表明想调用的函数及参数,实际执行由外部系统完成,结果再回传给 LLM 生成自然语言回答。
工具定义中 description 字段至关重要:LLM 完全依赖该描述来理解工具用途和调用时机,参数需明确类型、enum 约束和 required 必填项。
什么是 AI Agent
AI Agent 是一个能感知环境、做出决策、采取行动的自主系统。
学术一点的定义是:Agent 是一个位于某环境中的实体,它能通过传感器感知环境,并通过执行器作用于环境,以实现一系列目标。
这个定义听起来有点抽象,让我们用大白话拆解。
Agent vs 普通 LLM
先看一张对比表:
| 特性 | 普通 LLM | AI Agent |
|---|---|---|
| 交互模式 | 一问一答,用户驱动 | 自主执行,目标驱动 |
| 能力边界 | 只有模型内置能力 | 可通过工具扩展能力 |
| 记忆 | 会话上下文(有限) | 短期 + 长期记忆 |
| 规划 | 无(或需用户引导) | 自主任务分解与规划 |
| 反馈循环 | 无(单次生成) | 观察-思考-行动 循环 |
举个具体例子:帮我订一张明天从上海去北京的机票,价格 1500 元以内。
普通 LLM 可能会这样回答:好的,我可以帮你写一段查询机票的代码,或者告诉你应该去哪个网站查询。但它不会真的去查机票,更不会帮你下单。
而一个合格的 Agent 会:
- 理解目标:订明天上海到北京,1500 元以内的机票。
- 决定行动:我需要调用机票查询 API。
- 执行行动:调用 API,获取航班列表。
- 观察结果:获取到 10 个航班,其中 3 个在 1500 元以内。
- 再次思考:选哪个?可能需要再查一下起降时间,或者询问用户偏好。
- 继续行动:可能调用另一个 API 查准点率,或者直接给用户推荐选项。
- 完成任务:帮用户锁定座位,生成订单链接。
看到区别了吗?普通 LLM 给你答案,Agent 给你结果。
Agent 的核心能力
一个完整的 Agent 通常具备以下三大核心能力:
| 能力 | 说明 | 类比 |
|---|---|---|
| 感知(Perception) | 获取环境信息和反馈 | 眼睛、耳朵 |
| 决策(Decision) | 思考做什么、怎么做 | 大脑 |
| 行动(Action) | 执行具体操作 | 手、脚 |
感知,就是 Agent 能看到发生了什么。比如用户发了一条消息、API 返回了一个结果、文件系统里新增了一个文件,这些都是感知的输入。
决策,就是 Agent 基于感知到的信息,决定下一步做什么。是直接回答用户?还是需要调用工具?还是需要把大任务拆成小任务?这都是决策。
行动,就是 Agent 真的去执行决策。调用搜索 API、读取文件、发送邮件、操作数据库,这些都是行动。
Agent 的基本架构
现在我们来看 Agent 的标准四块拼图:大脑、工具、记忆、规划。
先看一张架构图:
大脑:LLM 作为推理核心
Agent 的大脑通常是一个大语言模型,比如 GPT-4、Claude、Llama 等。
这个 LLM 负责:
- 理解用户的意图:用户说帮我订票,他真正想要的是什么?
- 做决策:下一步我应该做什么?
- 生成工具调用参数:要调用机票查询 API,需要哪些参数?
- 整理最终答案:现在信息收集够了,怎么给用户一个清晰的总结?
LLM 是 Agent 的核心,但不是全部。就像人脑很重要,但也需要手脚才能做事。
工具:扩展 AI 的能力边界
原生 LLM 有两个明显的局限:
- 知识截止:它不知道训练结束之后发生的事。
- 无法交互:它不能直接读文件、查数据库、调用 API。
工具(Tools)就是用来解决这些问题的。
常见的工具类型:
| 工具类型 | 作用 | 示例 |
|---|---|---|
| 搜索工具 | 获取最新信息 | Google Search、Bing Search |
| 计算工具 | 做数学运算 | 计算器、Wolfram Alpha |
| 文件操作 | 读写本地文件 | 读取 PDF、写入 CSV |
| API 调用 | 与外部系统交互 | 订机票、发邮件、查天气 |
| 数据库查询 | 存取结构化数据 | SQL 查询、向量检索 |
| 代码执行 | 运行代码解决问题 | Python REPL、Jupyter |
给 Agent 工具,就像给人配了一台电脑,瞬间从只能想变成可以做。
记忆:短期 vs 长期记忆
LLM 原生是失忆的。每一次对话都是全新的,除非你把上下文塞进去。
而 Agent 需要记住很多东西:
短期记忆:刚才用户说了什么?我上一步调用了什么工具?得到了什么结果?
长期记忆:用户的偏好是什么?过去类似任务是怎么处理的?有哪些经验教训?
记忆系统的常见实现方式:
| 记忆类型 | 存储内容 | 实现方式 |
|---|---|---|
| 短期记忆 | 当前会话的对话历史、中间步骤 | 直接放 LLM 上下文窗口 |
| 长期记忆 | 用户偏好、历史任务、知识文档 | 向量数据库 + 相似度检索 |
| 摘要记忆 | 压缩后的历史总结 | 让 LLM 定期生成摘要 |
一个好的记忆系统,能让 Agent 看起来记得你,而不是每次都像第一次见面。
规划:任务分解
复杂任务不会一步完成,Agent 需要能把大目标拆成小步骤。
比如:帮我策划一场 10 人的生日派对。
Agent 可能会这样规划:
- 先问清楚:预算多少?什么时候?在哪里?主角有什么偏好?
- 然后:查一下附近的场地。
- 接着:设计菜单。
- 再接着:列出采购清单。
- 最后:生成日程安排表。
规划的常见策略:
链式思考(Chain-of-Thought):一步一步想清楚,先做什么、后做什么。
树状规划(Tree-of-Thought):同时考虑多个可能的路径,选最优的。
反思(Reflection):做完一步后回头看看,有没有问题,需不需要调整。
工具调用:Tool Use / Function Calling
工具调用是 Agent 最基础也是最重要的能力。
让我们从是什么开始讲。
什么是 Function Calling
简单说:Function Calling 就是 LLM 输出一个结构化的 JSON,告诉你它想调用哪个函数、传什么参数。
不是 LLM 真的去执行这个函数。它只是告诉你它想调用,执行的事还得由你来做。
整个流程通常是这样的:
- 你告诉 LLM:这里有一些函数可以调用,每个函数的名字、参数、用途是……
- 用户发消息:帮我查一下明天北京的天气。
- LLM 回复:我要调用 get_weather 函数,参数是 city='北京', date='明天'。
- 你去调用这个函数(真的去查天气 API),得到结果。
- 你把结果塞回给 LLM:刚才的函数调用返回了:温度 25 度,晴天。
- LLM 基于这个结果,给用户一个自然语言回答:明天北京晴天,温度 25 度,很舒适。
看到了吗?LLM 负责想,你负责执行。
定义工具的 JSON Schema
要让 LLM 调用工具,你得先告诉它有哪些工具可用。
这个告诉的过程,就是用 JSON Schema 描述函数。
来看一个标准的函数定义格式:
# 这是一个典型的工具定义(用 Python 字典表示,最终会转成 JSON)
tool_definition = {
"type": "function",
"function": {
"name": "get_weather", # 函数名
"description": "查询指定城市指定日期的天气", # 函数用途描述,LLM 会看这个
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,比如'北京'、'上海'、'深圳'",
},
"date": {
"type": "string",
"description": "日期,格式为 YYYY-MM-DD,比如'2024-06-18'",
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位,摄氏度或华氏度,默认摄氏度",
},
},
"required": ["city", "date"], # 必填参数
},
},
}
# 另一个工具:搜索
search_tool = {
"type": "function",
"function": {
"name": "web_search",
"description": "在互联网上搜索最新信息,适合查新闻、实时数据、未知知识",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词或问题",
},
"num_results": {
"type": "integer",
"description": "返回多少条结果,默认 5",
"default": 5,
},
},
"required": ["query"],
},
},
}
另一个工具:计算器
calculator_tool = {
"type": "function",
"function": {
"name": "calculate",
"description": "执行数学计算,支持加减乘除、幂运算等",
"parameters": {
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "数学表达式,比如'25 * 4 + 10'、'sqrt(16)'",
},
},
"required": ["expression"],
},
},
}
print(f"已定义 {len([tool_definition, search_tool, calculator_tool])} 个工具:get_weather, web_search, calculate")
# 输出:已定义 3 个工具:get_weather, web_search, calculate
关键点:
- description 非常重要。LLM 就是靠这个描述来理解这个工具是干什么的、什么时候该用。
- 参数也要描述清楚。比如 unit 有 enum 约束,LLM 就知道只能从这两个值里选。
- required 标出必填项,LLM 会确保这些参数一定有值。
代码实战:给 AI 添加搜索、计算工具
现在写一个完整的、可运行的例子。
为了演示,我们用 Python 模拟 Function Calling 的完整流程。
# ============================================
# 一个简化版的 Agent 工具调用演示
# 不需要真实的 API Key,用模拟数据演示
# ============================================
import json
import random
from typing import Dict, Any, List, Optional
class SimpleAgent:
"""一个简单的 Agent 演示类"""
def __init__(self):
# 注册可用的工具
self.tools = self._define_tools()
# 对话历史(记忆)
self.messages: List[Dict] = []
def _define_tools(self) -> List[Dict]:
"""定义所有可用的工具"""
return [
{
"name": "web_search",
"description": "搜索互联网获取最新信息",
"parameters": {
"query": {"type": "string", "description": "搜索关键词"},
},
"required": ["query"],
},
{
"name": "calculate",
"description": "执行数学计算",
"parameters": {
"expression": {"type": "string", "description": "数学表达式"},
},
"required": ["expression"],
},
{
"name": "get_weather",
"description": "查询天气",
"parameters": {
"city": {"type": "string", "description": "城市名"},
"date": {"type": "string", "description": "日期"},
},
"required": ["city", "date"],
},
]
def _call_tool(self, tool_name: str, parameters: Dict[str, Any]) -> str:
"""(模拟)调用工具并返回结果"""
print(f" [工具调用] {tool_name}({parameters})")
if tool_name == "web_search":
query = parameters["query"]
# 模拟搜索结果
results = {
"runoob": "菜鸟教程(runoob)是一个编程学习网站,提供大量编程教程和实例。",
"2024年6月18日北京天气": "北京 2024-06-18:晴天,25°C,湿度 45%。",
"上海人口": "上海 2024 年常住人口约 2489 万。",
}
return results.get(query, f"搜索结果:未找到'{query}'的精确信息,这是一个模拟结果。")
elif tool_name == "calculate":
expr = parameters["expression"]
try:
# 注意:生产环境不要用 eval,这里只是演示
result = eval(expr, {"__builtins__": None}, {
"sqrt": lambda x: x**0.5,
"pow": pow,
})
return f"计算结果:{expr} = {result}"
except Exception as e:
return f"计算错误:{e}"
elif tool_name == "get_weather":
city = parameters["city"]
date = parameters["date"]
# 模拟天气数据
weathers = ["晴天", "多云", "小雨", "阴天"]
temp = random.randint(15, 35)
return f"{city} {date}:{random.choice(weathers)},{temp}°C"
else:
return f"未知工具:{tool_name}"
def _decide_action(self, user_input: str) -> Dict[str, Any]:
"""
(模拟)LLM 决策过程
实际项目中这里会调用真实的 LLM API
"""
# 这里用简单的规则模拟,真实场景应该用 LLM
if "搜索" in user_input or "查一下" in user_input or "什么是" in user_input:
# 提取搜索词(简单模拟)
query = user_input.replace("搜索", "").replace("查一下", "").replace("什么是", "").strip()
if not query:
query = "runoob"
return {
"action": "call_tool",
"tool": "web_search",
"parameters": {"query": query},
}
elif "计算" in user_input or "等于" in user_input:
# 提取表达式(简单模拟)
return {
"action": "call_tool",
"tool": "calculate",
"parameters": {"expression": "25 * 4 + 10"}, # 示例固定值
}
elif "天气" in user_input:
return {
"action": "call_tool",
"tool": "get_weather",
"parameters": {"city": "北京", "date": "2024-06-18"},
}
else:
return {
"action": "respond",
"content": "好的,我来帮你处理这个问题。" + user_input,
}
def run(self, user_input: str) -> str:
"""运行 Agent 处理用户输入"""
print(f"[用户输入] {user_input}")
self.messages.append({"role": "user", "content": user_input})
# 第一步:决定做什么
decision = self._decide_action(user_input)
if decision["action"] == "call_tool":
# 第二步:调用工具
tool_result = self._call_tool(decision["tool"], decision["parameters"])
self.messages.append({"role": "tool", "content": tool_result})
# 第三步:基于工具结果生成最终回答
# (这里简单拼接,实际应该让 LLM 生成)
final_response = f"根据我的查询:{tool_result}\n\n希望这个信息对你有帮助!"
self.messages.append({"role": "assistant", "content": final_response})
return final_response
else:
# 直接回答
self.messages.append({"role": "assistant", "content": decision["content"]})
return decision["content"]
# ============================================
# 测试这个 Agent
# ============================================
agent = SimpleAgent()
print("=" * 60)
response1 = agent.run("搜索一下 runoob 是什么")
print(f"[Agent 回复]\n{response1}")
print("\n" + "=" * 60)
response2 = agent.run("帮我查 2024-06-18 北京的天气")
print(f"[Agent 回复]\n{response2}")
print("\n" + "=" * 60)
response3 = agent.run("计算一下 25 * 4 + 10 等于多少")
print(f"[Agent 回复]\n{response3}")




