第1章:什么是AI Agent
概述
如果你正在读这本书,你很可能已经听说过"AI Agent"这个词。它出现在技术博客的标题里,出现在产品发布会的PPT上,出现在风投的投资主题中。但当你试图精确定义它时,可能会发现每个人说的"Agent"似乎不是同一个东西。
本章的目标很明确:给AI Agent一个清晰的、可操作的定义。我们不会止步于抽象概念——你会看到代码,看到架构,看到真实的判断标准。读完本章,你应该能够:
- 准确判断一个系统是否是Agent
- 理解Agent与Chatbot、传统软件的本质区别
- 选择合适的Agent类型来解决实际问题
- 对Agent的能力和局限有清醒的认知
让我们开始。
1.1 Agent的定义
1.1.1 一个直观的定义
先给一个最直观的定义:
AI Agent(智能体)是一个能够感知环境、进行推理决策、执行动作以实现目标的自治系统。
这个定义里有五个关键词,每一个都值得展开:
| 关键词 | 含义 | 例子 |
|---|---|---|
| 感知(Perception) | 从环境中获取信息 | 读取用户消息、查询数据库、调用API |
| 推理(Reasoning) | 基于感知到的信息进行分析和决策 | 分析意图、制定计划、评估选项 |
| 执行(Action) | 在环境中产生实际影响 | 发送邮件、修改文件、调用工具 |
| 目标(Goal) | 有明确的预期结果 | "帮用户订机票"、"完成代码审查" |
| 自治(Autonomy) | 在一定范围内自主决策,不需要每步都由人指定 | Agent自己决定先查数据库还是先问用户 |
这五个要素构成了Agent的"灵魂"。缺少任何一个,系统就会退化成其他东西:
- 缺少执行 → 变成分析系统(Analytics System)
- 缺少推理 → 变成自动化脚本(RPA Script)
- 缺少感知 → 变成定时任务(Cron Job)
- 缺少目标 → 变成随机行为系统
- 缺少自治 → 变成命令行工具(CLI Tool)
1.1.2 学术视角的定义
在学术界,Stuart Russell 和 Peter Norvig 在《人工智能:一种现代方法》中将智能体定义为:
"An agent is anything that can be viewed as perceiving its environment through sensors and acting upon that environment through actuators."
翻译过来就是:Agent是通过传感器感知环境、通过执行器作用于环境的任何实体。
这个定义更加宽泛,它甚至可以涵盖恒温器这样的简单系统。但在本书的语境中,当我们说"AI Agent"时,通常指的是基于大语言模型(LLM)的、具有较强推理能力的智能体。
1.1.3 实践中的定义
在实际工程中,我倾向于使用一个更务实的工作定义:
AI Agent = LLM + 工具(Tools)+ 记忆(Memory)+ 规划(Planning)
这个公式虽然简化了很多细节,但它抓住了当前Agent系统的核心技术栈:
# 一个最小Agent的抽象模型
class MinimalAgent:
def __init__(self, llm, tools, memory):
self.llm = llm # 大脑:推理引擎
self.tools = tools # 手:执行能力
self.memory = memory # 记忆:上下文和经验
self.goal = None # 目标:待完成任务
def perceive(self, input_data):
"""感知:接收环境信息"""
self.memory.add("user_input", input_data)
def reason(self):
"""推理:基于LLM进行思考和规划"""
context = self.memory.get_relevant()
plan = self.llm.generate(
system="你是一个有帮助的AI Agent。",
context=context,
goal=self.goal,
available_tools=self.tools.list()
)
return plan
def act(self, plan):
"""执行:按照计划调用工具"""
for step in plan.steps:
if step.is_tool_call:
result = self.tools.call(step.tool_name, step.args)
self.memory.add("tool_result", result)
else:
self.memory.add("thought", step.content)
def run(self, goal, input_data):
"""Agent的主循环"""
self.goal = goal
self.perceive(input_data)
while not self.is_goal_achieved():
plan = self.reason()
self.act(plan)
return self.get_result()这个代码框架虽然简单,但它揭示了Agent编程的核心循环:感知 → 推理 → 执行 → 再感知 → ...,直到目标达成。
1.2 Agent的核心特征
1.2.1 四大核心能力
基于前面的定义,我们可以提炼出Agent的四大核心能力:
(1)自主决策能力(Autonomy)
传统软件是"指令-执行"模式:你告诉它做什么,它就做什么。Agent则不同——你告诉它目标,它自己决定怎么做。
# 传统软件:指定每一步
def traditional_approach():
emails = fetch_emails() # 第一步
important = filter(emails) # 第二步
summaries = summarize(important) # 第三步
send_report(summaries) # 第四步
# Agent方式:只指定目标
agent.run(
goal="帮我整理今天的重要邮件并发送摘要报告",
input_data={"user": "zhangsan"}
)
# Agent会自己决定:
# 1. 先查看哪些邮件是重要的
# 2. 是否需要查看日历来判断"重要"的标准
# 3. 报告的格式和详细程度
# 4. 发送给谁这种自主性的程度是可调的。你可以给Agent很大自由度,也可以通过约束来限制它的决策空间。
(2)工具使用能力(Tool Use)
Agent最强大的能力之一是调用外部工具。纯LLM只能在文本世界里工作,而Agent可以:
- 查询数据库
- 调用API
- 执行代码
- 操作文件系统
- 发送网络请求
- 控制浏览器
# Agent可以调用的工具示例
tools = [
Tool(
name="search_web",
description="搜索互联网获取最新信息",
parameters={
"query": {"type": "string", "description": "搜索关键词"}
}
),
Tool(
name="execute_python",
description="执行Python代码并返回结果",
parameters={
"code": {"type": "string", "description": "要执行的Python代码"}
}
),
Tool(
name="query_database",
description="查询公司内部数据库",
parameters={
"sql": {"type": "string", "description": "SQL查询语句"},
"database": {"type": "string", "description": "数据库名称"}
}
)
]
# Agent会根据任务需要,自主选择和组合使用这些工具工具使用将Agent从"能说不能做"的聊天机器人变成了"既说又做"的数字员工。
(3)记忆能力(Memory)
没有记忆的Agent就像金鱼——每次对话都从零开始。真正的Agent需要不同层级的记忆:
┌─────────────────────────────────────────┐
│ 长期记忆 (Long-term Memory) │
│ 用户偏好、历史知识、学到的经验 │
│ 存储:向量数据库 / 知识图谱 │
├─────────────────────────────────────────┤
│ 工作记忆 (Working Memory) │
│ 当前任务的上下文、中间状态 │
│ 存储:对话历史 / 状态变量 │
├─────────────────────────────────────────┤
│ 短期记忆 (Short-term Memory) │
│ 当前轮次的输入 │
│ 存储:当前消息 / 函数返回值 │
└─────────────────────────────────────────┘# 三层记忆的实现示例
class AgentMemory:
def __init__(self):
self.short_term = [] # 当前对话的最近N轮
self.working = {} # 当前任务的上下文
self.long_term = VectorStore() # 持久化知识
def remember_user_preference(self, key, value):
"""记住用户偏好(长期记忆)"""
self.long_term.upsert(
id=f"pref_{key}",
content=f"用户偏好: {key} = {value}",
metadata={"type": "preference", "key": key}
)
def recall_relevant(self, query, top_k=5):
"""回忆与当前场景相关的信息"""
return self.long_term.search(query, top_k=top_k)
def update_working_state(self, key, value):
"""更新工作状态"""
self.working[key] = value
def add_exchange(self, role, content):
"""添加对话交换到短期记忆"""
self.short_term.append({"role": role, "content": content})
# 保持短期记忆窗口
if len(self.short_term) > 20:
self.short_term = self.short_term[-20:](4)学习能力(Learning)
最前沿的Agent不仅仅是执行预设任务,它们还能从经验中学习:
- 从反馈中学习:根据用户的肯定/否定调整行为
- 从错误中学习:记住失败的尝试,避免重复犯错
- 从模式中学习:总结规律,形成更好的策略
class LearningAgent(MinimalAgent):
def __init__(self, llm, tools, memory):
super().__init__(llm, tools, memory)
self.experience_log = [] # 经验日志
def learn_from_feedback(self, feedback):
"""从用户反馈中学习"""
experience = {
"task": self.goal,
"actions_taken": self.get_action_history(),
"outcome": feedback,
"timestamp": datetime.now()
}
self.experience_log.append(experience)
# 将经验转化为长期记忆
if feedback == "positive":
self.memory.long_term.upsert(
id=f"success_{self.goal}",
content=f"任务 '{self.goal}' 的成功策略: {self.summarize_strategy()}",
metadata={"type": "success_strategy"}
)
else:
self.memory.long_term.upsert(
id=f"failure_{self.goal}",
content=f"任务 '{self.goal}' 的失败教训: {feedback}",
metadata={"type": "failure_lesson"}
)
def plan_with_experience(self):
"""规划时参考历史经验"""
relevant_experiences = self.memory.recall_relevant(self.goal)
enhanced_context = f"""
历史相关经验:
{format_experiences(relevant_experiences)}
当前任务: {self.goal}
"""
return self.llm.generate(context=enhanced_context)1.2.2 一个关键区分:Agent vs. 自动化
很多人容易把Agent和自动化混淆。它们的核心区别在于:
| 维度 | 自动化(Automation) | Agent |
|---|---|---|
| 决策方式 | 预定义的规则/流程 | 基于推理的动态决策 |
| 适应性 | 输入变化时可能失败 | 能处理预期之外的情况 |
| 工具选择 | 硬编码的工具链 | 根据需要动态选择工具 |
| 错误处理 | 预定义的异常处理 | 能推理出新的处理方式 |
| 上限 | 设计者预设的所有场景 | 受限于LLM的能力边界 |
# 自动化:硬编码的邮件处理流程
def automated_email_handler(email):
if email.subject.contains("urgent"):
send_sms(email.content)
elif email.subject.contains("invoice"):
save_to_accounting(email)
else:
archive(email)
# 遇到"稍微紧急但不是urgent"的邮件?无法处理
# Agent:基于理解的邮件处理
agent.run(
goal="处理收到的邮件",
input={"email": email}
)
# Agent能理解:
# - "ASAP" 和 "urgent" 是类似的意思
# - 这封发票可能是诈骗邮件
# - 用户之前说过不关心某类通知1.3 Agent与传统软件的区别
1.3.1 范式转换
Agent编程代表着一次根本性的范式转换。理解这种转换,是掌握Agent编程的前提。
传统软件开发的范式是确定性的:
输入 → [确定性的处理逻辑] → 输出同样的输入永远产生同样的输出。你可以精确预测程序的每一步行为。
Agent开发的范式是概率性的:
输入 + 目标 → [LLM推理] → 可能的行动方案 → [执行] → 结果(可能需要迭代)同样的输入可能产生不同的行动方案。你只能约束Agent的行为范围,但不能精确预测每一步。
1.3.2 一个对比示例
让我们通过一个具体任务来感受这种差异——"帮用户预订明天从北京到上海的机票"。
传统软件开发方式:
def book_flight(user_id, departure, destination, date):
# 1. 查询用户偏好
preferences = db.query("SELECT * FROM user_prefs WHERE user_id = ?", user_id)
# 2. 查询可用航班
flights = flight_api.search(departure, destination, date)
# 3. 按偏好筛选
if preferences.prefer_morning:
flights = [f for f in flights if f.departure_hour < 12]
# 4. 按价格排序
flights.sort(key=lambda f: f.price)
# 5. 选择最便宜的
selected = flights[0]
# 6. 预订
booking = flight_api.book(selected.id, user_id)
return booking
# 问题:如果用户没有设置偏好怎么办?
# 如果没有早班机怎么办?
# 如果最便宜的是红眼航班怎么办?
# 需要为每种边界情况写代码...Agent方式:
agent.run(
goal="帮用户预订明天从北京到上海的机票",
input={"user_id": "zhangsan"}
)
# Agent的推理过程可能是:
# 1. 查询用户过去的出行记录 → 发现他经常选国航
# 2. 查询明天的航班 → 发现早上8点和下午3点各有航班
# 3. 检查用户的日历 → 发现下午2点有会议
# 4. 推理:下午的航班时间太紧,选择早上8点
# 5. 检查价格 → 发现在预算范围内
# 6. 预订,并发送确认消息给用户关键区别在于:传统软件中,每一个if-else都需要开发者预先想到;而Agent能够根据当前情况自主推理出合理的处理方式。
1.3.3 设计哲学的差异
| 维度 | 传统软件 | Agent |
|---|---|---|
| 核心问题 | "如何做"(How) | "做什么"(What) |
| 开发者角色 | 实现每一步逻辑 | 定义目标和约束 |
| 错误处理 | 预定义所有错误场景 | 自适应处理异常 |
| 测试方式 | 确定性测试(断言精确输出) | 评估性测试(判断结果质量) |
| 可预测性 | 高(相同输入→相同输出) | 低(但可通过约束提高) |
| 适应性 | 需要修改代码 | 可以通过调整提示词 |
1.3.4 何时用传统软件,何时用Agent
不是所有问题都适合用Agent解决。以下是一些判断标准:
适合用Agent的场景:
- 任务涉及多步骤的复杂推理
- 需要根据上下文灵活调整策略
- 输入格式不固定或需要自然语言理解
- 边界情况太多,无法穷举
- 需要"理解"语义而非简单匹配
适合用传统软件的场景:
- 性能要求极高(如高频交易)
- 需要确定性保证(如金融计算)
- 逻辑规则清晰且稳定
- 对延迟极其敏感
- 涉及安全关键决策(需人工兜底)
最佳实践:混合架构
大多数生产级系统不是纯Agent或纯传统软件,而是混合架构:
class HybridFlightBookingSystem:
def __init__(self):
self.agent = BookingAgent() # 处理复杂决策
self.db = FlightDatabase() # 处理数据存储
self.payment = PaymentService() # 处理支付(确定性逻辑)
def book(self, user_id, request):
# 第一步:Agent理解用户意图并收集信息
booking_params = self.agent.process_request(request)
# 第二步:传统软件处理确定性操作
available_flights = self.db.search_flights(booking_params)
# 第三步:Agent帮助用户选择
selected_flight = self.agent.recommend_flight(
available_flights,
user_preferences=self.db.get_prefs(user_id)
)
# 第四步:传统软件处理支付(需要确定性保证)
payment_result = self.payment.process(
amount=selected_flight.price,
method=booking_params.payment_method
)
# 第五步:Agent生成确认消息
confirmation = self.agent.generate_confirmation(
flight=selected_flight,
payment=payment_result
)
return confirmation1.4 Agent与Chatbot的区别
这是最常见的一个混淆。很多人把加了几条工具的Chatbot叫做Agent,但实际上它们有本质区别。
1.4.1 核心区别
| 维度 | Chatbot | Agent |
|---|---|---|
| 交互模式 | 对话式,你来我往 | 目标驱动,持续工作 |
| 主动性 | 被动等待输入 | 主动规划和执行 |
| 持久性 | 对话结束即终止 | 可以长时间运行、跨会话 |
| 工具使用 | 可能调用少量工具 | 深度集成多种工具 |
| 状态管理 | 无状态或简单状态 | 复杂状态追踪 |
| 输出类型 | 文本回复为主 | 可以执行任意操作 |
1.4.2 一个直观的比喻
- Chatbot像一个坐在柜台后的咨询员——你问一个问题,他回答一个问题。你走了,他就休息了。
- Agent像一个项目经理——你给他一个目标,他自己规划、协调资源、解决问题,直到完成目标。
1.4.3 代码对比
# ============ Chatbot 的典型实现 ============
class Chatbot:
def __init__(self, llm):
self.llm = llm
def chat(self, user_message, history=None):
"""收到一条消息,回复一条消息"""
response = self.llm.chat(
messages=[
{"role": "system", "content": "你是一个有帮助的助手。"},
*history,
{"role": "user", "content": user_message}
]
)
return response
# 交互模式:
# User: "帮我查一下明天的天气"
# Bot: "明天北京晴,温度15-25度"
# [对话结束]
# ============ Agent 的典型实现 ============
class WeatherAgent:
def __init__(self, llm, tools):
self.llm = llm
self.tools = tools
self.planner = TaskPlanner()
def execute(self, goal):
"""接收目标,持续执行直到完成"""
plan = self.planner.create_plan(goal, self.tools)
while not plan.is_complete():
current_step = plan.next_step()
if current_step.needs_tool:
result = self.tools.call(
current_step.tool,
current_step.arguments
)
plan.record_result(result)
else:
thought = self.llm.think(current_step, plan.context())
plan.update(thought)
# 如果遇到问题,重新规划
if plan.is_blocked():
plan = self.planner.replan(plan, self.tools)
return plan.get_result()
# 交互模式:
# User: "帮我规划明天的出行"
# Agent内部:
# 1. 调用天气API → 明天下午有雨
# 2. 调用日历API → 明天下午有会议
# 3. 推理 → 建议上午出行,带伞
# 4. 调用地图API → 推荐路线
# 5. 生成完整出行方案
# Agent: "根据天气和您的日程安排,我建议..."1.4.4 演化路径
值得注意的是,Chatbot和Agent不是非此即彼的关系。很多系统是逐步从Chatbot演化成Agent的:
Stage 1: 纯对话 Chatbot
↓ 添加FAQ知识库
Stage 2: 知识增强 Chatbot
↓ 添加工具调用
Stage 3: 工具增强 Chatbot
↓ 添加多步推理
Stage 4: 简单 Agent
↓ 添加规划和记忆
Stage 5: 完整 Agent
↓ 添加多Agent协作
Stage 6: Agent 系统理解这个演化路径很重要,因为它告诉我们:不需要一步到位地构建完整Agent,可以渐进式地增强现有系统。
1.5 Agent的分类体系
Agent是一个很大的概念,不同类型的Agent适用于不同的场景。建立清晰的分类体系有助于我们选择合适的方案。
1.5.1 按自主程度分类
反应式Agent(Reactive Agent)
最简单的Agent,直接根据输入做出反应,没有内部状态和复杂的推理。
class ReactiveAgent:
"""反应式Agent:刺激-反应模式"""
def __init__(self, rules):
self.rules = rules # 预定义的规则集
def act(self, perception):
for rule in self.rules:
if rule.matches(perception):
return rule.action
return self.default_action()适用场景:简单的分类、路由、格式转换。
慎思式Agent(Deliberative Agent)
具有内部状态和推理能力的Agent,会在行动前进行"思考"。
class DeliberativeAgent:
"""慎思式Agent:先思考再行动"""
def __init__(self, llm, world_model):
self.llm = llm
self.world_model = world_model # 对世界的内部模型
def act(self, perception):
# 1. 更新对世界的认知
self.world_model.update(perception)
# 2. 生成多个候选方案
candidates = self.llm.generate_options(
state=self.world_model.current_state()
)
# 3. 评估每个方案
evaluations = []
for candidate in candidates:
predicted_outcome = self.world_model.predict(candidate)
score = self.evaluate(predicted_outcome)
evaluations.append((candidate, score))
# 4. 选择最优方案
best = max(evaluations, key=lambda x: x[1])
return best[0]适用场景:需要多步推理的复杂任务。
混合式Agent(Hybrid Agent)
结合反应式和慎思式的优点——对简单情况快速反应,对复杂情况深入思考。
class HybridAgent:
"""混合式Agent:快思考 + 慢思考"""
def __init__(self, llm, reactive_rules):
self.llm = llm
self.reactive_rules = reactive_rules
def act(self, perception):
# 快速路径:简单情况直接反应
for rule in self.reactive_rules:
if rule.matches(perception) and rule.confidence > 0.95:
return rule.action
# 慢速路径:复杂情况深入推理
return self.deliberate(perception)
def deliberate(self, perception):
"""复杂情况下的深度推理"""
return self.llm.reason(
perception=perception,
available_tools=self.tools.list(),
goal=self.current_goal
)这是目前生产环境中最常用的Agent架构。
1.5.2 按功能类型分类
| 类型 | 描述 | 典型例子 |
|---|---|---|
| 信息获取型 | 搜索、检索、汇总信息 | 搜索助手、研究助手 |
| 内容生成型 | 创建文本、图像、代码 | 写作助手、代码助手 |
| 决策支持型 | 分析数据、提供建议 | 数据分析Agent、投资顾问 |
| 操作执行型 | 执行具体操作 | 邮件管理Agent、文件管理Agent |
| 协调管理型 | 协调多个Agent或人 | 项目管理Agent、工作流编排Agent |
1.5.3 按部署形态分类
| 形态 | 特点 | 适用场景 |
|---|---|---|
| 独立Agent | 单个Agent独立工作 | 简单任务、个人助手 |
| 嵌入式Agent | 集成到现有应用中 | 增强现有产品功能 |
| 多Agent系统 | 多个Agent协作完成复杂任务 | 复杂工作流、企业级系统 |
| Agent平台 | 提供Agent创建和管理能力 | Agent开发平台、SaaS |
1.5.4 按LLM依赖程度分类
这个分类在工程实践中特别重要,因为它直接影响到系统的成本、延迟和可靠性:
| 类型 | LLM依赖 | 特点 | 适用场景 |
|---|---|---|---|
| LLM-Heavy | 高 | 推理、规划都依赖LLM | 创意任务、开放域任务 |
| LLM-Light | 低 | LLM只做意图识别,执行用传统代码 | 结构化任务、高频任务 |
| LLM-Free | 无 | 纯规则驱动 | 超低延迟、确定性要求高 |
# LLM-Heavy Agent:几乎所有决策都经过LLM
class HeavyAgent:
def process(self, task):
plan = self.llm.plan(task) # LLM规划
for step in plan:
tool_choice = self.llm.choose_tool(step) # LLM选工具
args = self.llm.generate_args(step) # LLM生成参数
result = self.tools.call(tool_choice, args)
next_step = self.llm.decide_next(result) # LLM决定下一步
return self.llm.summarize(results)
# LLM-Light Agent:LLM只做意图路由
class LightAgent:
def process(self, task):
intent = self.llm.classify_intent(task) # 只调一次LLM
# 后续全部用确定性代码
if intent == "book_flight":
return self.flight_booking_handler.handle(task)
elif intent == "check_weather":
return self.weather_handler.handle(task)
else:
return self.fallback_handler.handle(task)工程建议:在生产环境中,尽可能降低对LLM的依赖。LLM调用是系统中成本最高、延迟最大、可靠性最低的部分。能用传统代码解决的,就不要用LLM。
1.6 典型应用场景
1.6.1 客服自动化
这是目前Agent应用最广泛的场景之一。
class CustomerServiceAgent:
"""智能客服Agent"""
def __init__(self):
self.tools = [
Tool("search_faq", "搜索常见问题库"),
Tool("query_order", "查询订单状态"),
Tool("process_refund", "处理退款申请"),
Tool("transfer_to_human", "转接人工客服"),
Tool("create_ticket", "创建工单"),
]
self.memory = CustomerMemory() # 记住客户的投诉历史
self.llm = LLM(model="gpt-4")
def handle_customer(self, customer_message, customer_id):
# 加载客户历史(记忆)
history = self.memory.get_customer_history(customer_id)
# 理解客户意图
intent = self.llm.analyze_intent(customer_message, history)
# 根据意图执行操作
if intent.type == "complaint":
# 查看客户历史投诉
past_issues = self.tools.search_faq(customer_message)
similar_cases = self.memory.find_similar(customer_id, intent)
# 尝试自动解决
if self.can_auto_resolve(intent, similar_cases):
resolution = self.resolve_automatically(intent)
return self.generate_response(resolution)
else:
# 转人工
self.tools.create_ticket(customer_id, intent)
return "您的问题比较复杂,已为您转接人工客服..."1.6.2 代码开发助手
程序员可能是最早也是最活跃的Agent用户群体。
class CodeAgent:
"""代码开发Agent"""
def __init__(self):
self.tools = [
Tool("read_file", "读取文件内容"),
Tool("write_file", "写入文件"),
Tool("run_tests", "运行测试"),
Tool("search_codebase", "搜索代码库"),
Tool("execute_shell", "执行Shell命令"),
Tool("install_package", "安装依赖包"),
]
def implement_feature(self, feature_description, project_path):
# 1. 理解需求
requirements = self.llm.analyze_requirements(
feature_description,
existing_code=self.tools.search_codebase(project_path)
)
# 2. 制定实现计划
plan = self.llm.create_implementation_plan(requirements)
# 3. 逐步实现
for step in plan:
self.tools.write_file(step.file_path, step.code)
# 实现后立即验证
test_result = self.tools.run_tests(step.related_tests)
if not test_result.passed:
fix = self.llm.fix_error(test_result.error, step.code)
self.tools.write_file(step.file_path, fix)
# 4. 运行完整测试
final_result = self.tools.run_tests("all")
return final_result1.6.3 数据分析
Agent特别擅长处理探索性的数据分析任务——因为这类任务需要根据中间结果不断调整分析方向。
class DataAnalysisAgent:
"""数据分析Agent"""
def analyze(self, question, data_source):
# 1. 加载和初步理解数据
data = self.load_data(data_source)
data_profile = self.profile_data(data)
# 2. 理解分析目标
analysis_plan = self.llm.create_analysis_plan(
question=question,
data_profile=data_profile
)
# 3. 迭代式分析
results = []
for step in analysis_plan:
code = self.llm.generate_analysis_code(
step, data_profile, previous_results=results
)
result = self.execute_python(code)
results.append(result)
# 根据结果调整后续计划
if self.needs_more_analysis(result):
additional_steps = self.llm.suggest_followup(result)
analysis_plan.extend(additional_steps)
# 4. 生成报告
report = self.llm.generate_report(question, results)
return report1.6.4 工作流自动化
class WorkflowAgent:
"""工作流自动化Agent"""
def automate(self, trigger, workflow_description):
# 理解工作流
steps = self.llm.parse_workflow(workflow_description)
# 监听触发条件
while True:
if self.check_trigger(trigger):
# 执行工作流
context = {}
for step in steps:
# 动态适配每个步骤
if step.type == "api_call":
context[step.name] = self.call_api(
step.config, context
)
elif step.type == "decision":
decision = self.llm.decide(
step.criteria, context
)
context[step.name] = decision
elif step.type == "notification":
self.send_notification(
step.recipient,
self.llm.format_message(step.template, context)
)
# 记录执行结果
self.log_execution(trigger, steps, context)1.7 Agent的局限性与挑战
在热情拥抱Agent技术的同时,我们也必须清醒地认识到它当前面临的局限。
1.7.1 幻觉问题(Hallucination)
LLM会"一本正经地胡说八道",Agent也不例外。当Agent基于错误的信息做出决策时,后果可能比Chatbot更严重——因为它不仅仅是说错话,还可能执行错误的操作。
# 危险场景:Agent基于幻觉做出操作
# User: "把最近的发票全部标记为已支付"
# Agent幻觉:认为某笔大额支出是发票
# Agent执行:将一笔实际是贷款的记录标记为已支付
# 结果:财务数据出错缓解策略:
- 关键操作前要求人工确认
- 对Agent的输出进行交叉验证
- 限制Agent在安全沙箱中执行操作
1.7.2 成本问题
每次LLM调用都是有成本的。一个复杂的Agent任务可能需要多次LLM调用(推理、规划、工具选择、参数生成、结果总结),成本可能快速累积。
# 一次完整的Agent任务可能涉及的LLM调用
class CostAwareAgent:
def estimate_cost(self, task):
return {
"intent_understanding": 1, # 1次调用
"planning": 1, # 1次调用
"tool_selection_per_step": 3, # 假设3步,每步1次
"argument_generation": 3, # 每步1次
"result_interpretation": 3, # 每步1次
"error_recovery": 1, # 可能需要1次
"final_summary": 1, # 1次调用
}
# 总计:~12次LLM调用1.7.3 可靠性和可预测性
Agent的行为是概率性的,这意味着:
- 同样的输入可能产生不同的输出
- 某些操作可能偶尔失败
- 行为模式可能随着模型更新而变化
1.7.4 安全性
Agent具有执行能力,这意味着如果被恶意利用,后果可能很严重。需要特别注意:
- 提示注入攻击:通过精心构造的输入控制Agent行为
- 权限控制:限制Agent能执行的操作范围
- 审计追踪:记录Agent的所有操作
class SecureAgent(MinimalAgent):
def __init__(self, llm, tools, memory, permission_manager):
super().__init__(llm, tools, memory)
self.permissions = permission_manager
def safe_act(self, plan):
"""安全执行:每次操作前检查权限"""
for step in plan.steps:
if not self.permissions.is_allowed(step):
# 敏感操作需要人工确认
approval = self.request_human_approval(step)
if not approval.approved:
self.log_blocked_action(step)
continue
# 执行并审计
result = self.tools.call(step.tool_name, step.args)
self.audit_log.record(step, result)最佳实践
1. 从小处开始
不要一上来就试图构建一个全能的Agent。从一个功能明确、范围有限的小Agent开始:
# ❌ 不好的做法:一上来就搞大而全
class SuperAgent:
"""能做所有事情的超级Agent""" # 几乎不可能做好
# ✅ 好的做法:从特定功能开始
class EmailTriagingAgent:
"""只做邮件分类的小Agent""" # 范围明确,容易做好2. 明确定义Agent的边界
Agent不是万能的。明确它能做什么、不能做什么,比让它"尽量做到最好"更重要:
class WellBoundedAgent:
def __init__(self):
self.capabilities = [
"搜索公司内部文档",
"总结会议记录",
"创建简单的日历事件"
]
self.not_capabilities = [
"发送邮件", # 需要人工确认
"删除任何数据", # 安全边界
"访问外部网站", # 安全边界
]
def handle(self, request):
if not self.can_handle(request):
return self.handoff_to_human(request)
return self.execute(request)3. 设计好"人的回路"(Human-in-the-Loop)
让Agent在关键决策节点请人确认,而不是完全自主:
class HumanInTheLoopAgent:
CONFIRMATION_REQUIRED = [
"send_email", # 发送邮件
"delete_data", # 删除数据
"financial_transaction", # 金融交易
"external_api_call", # 调用外部API
]
def act(self, plan):
for step in plan:
if step.tool in self.CONFIRMATION_REQUIRED:
approval = self.ask_human(
f"Agent想要执行: {step.tool}({step.args})\n"
f"原因: {step.reasoning}\n"
f"是否批准?"
)
if not approval:
continue
self.tools.call(step.tool, step.args)4. 为Agent设计完善的可观测性
你无法优化你看不见的东西。Agent的决策过程必须可追踪:
class ObservableAgent(MinimalAgent):
def __init__(self, llm, tools, memory):
super().__init__(llm, tools, memory)
self.traces = [] # 执行追踪
def reason(self):
thought = self.llm.think(...)
self.traces.append({
"timestamp": datetime.now(),
"type": "reasoning",
"input": self.memory.get_context(),
"output": thought,
"token_usage": self.llm.last_token_usage,
"latency_ms": self.llm.last_latency,
})
return thought5. 选择合适的自主程度
不是所有Agent都需要高度自治。根据场景选择合适的自主程度:
# 场景1:高自主度(研究助手)
research_agent = Agent(
autonomy_level="high", # 可以自行搜索、分析、总结
confirmation_required=[], # 不需要人工确认
fallback="ask_human" # 无法完成时才问人
)
# 场景2:中等自主度(客服Agent)
service_agent = Agent(
autonomy_level="medium", # 可以回答常见问题
confirmation_required=["refund", "escalate"], # 退款和升级需确认
fallback="transfer_to_human"
)
# 场景3:低自主度(代码审查助手)
review_agent = Agent(
autonomy_level="low", # 只提供建议
confirmation_required=["all_changes"], # 所有修改需确认
fallback="skip_review" # 不确定就跳过
)常见陷阱
陷阱1:把Chatbot包装成Agent
很多人在Chatbot上加了几个API调用就宣称它是Agent。真正的Agent需要持续的、目标驱动的工作能力,而不是一问一答。
判断标准:如果去掉LLM后,你的系统退化为一个简单的API路由器,那它可能还不是一个Agent。
陷阱2:过度依赖LLM
把所有逻辑都塞给LLM,导致成本高、延迟大、不可控。
# ❌ 过度依赖LLM
class OverReliantAgent:
def process(self, data):
# 简单的JSON解析也用LLM
parsed = self.llm.parse_json(data)
# 简单的条件判断也用LLM
category = self.llm.classify(parsed, categories)
# 简单的格式化也用LLM
return self.llm.format_response(parsed, category)
# ✅ 合理使用LLM
class BalancedAgent:
def process(self, data):
parsed = json.loads(data) # 用传统代码
category = self.classify(parsed) # 用传统代码(规则/ML)
if category == "complex":
return self.llm.handle_complex(parsed) # 只在必要时用LLM
return self.format_response(parsed, category) # 用传统代码陷阱3:忽视边界情况
Agent的"创造力"是一把双刃剑——它可能在边界情况下做出意想不到的事情。
建议:
- 为Agent设计明确的操作白名单
- 在沙箱环境中充分测试
- 实现操作审计和回滚机制
陷阱4:忽视上下文窗口限制
LLM有上下文窗口大小的限制。如果你的Agent需要处理大量信息,需要设计好上下文管理策略:
# ❌ 无限累积上下文
class NaiveAgent:
def chat(self, messages):
self.history.extend(messages) # 一直增长...
return self.llm.chat(self.history) # 终究会超出窗口限制
# ✅ 主动管理上下文
class SmartAgent:
def chat(self, message):
self.history.append(message)
# 当上下文接近窗口限制时,进行压缩
if self.estimate_tokens(self.history) > self.window_limit * 0.8:
self.history = self.compress_context(self.history)
return self.llm.chat(self.history)
def compress_context(self, history):
"""保留最近N轮 + 早期摘要"""
recent = history[-10:]
early_summary = self.llm.summarize(history[:-10])
return [{"role": "system", "content": f"历史摘要: {early_summary}"}] + recent陷阱5:缺乏评估体系
Agent的行为是概率性的,如果没有系统化的评估方法,你无法知道它到底做得好不好。
建议:
- 建立评测数据集
- 定义明确的评估指标
- 实现自动化评测流水线
- 持续跟踪Agent的表现
小结
让我们回顾一下本章的核心内容:
Agent的定义:能够感知环境、推理决策、执行动作以实现目标的自治系统。在实践中,Agent = LLM + 工具 + 记忆 + 规划。
四大核心能力:自主决策、工具使用、记忆、学习。这四项能力的组合程度决定了Agent的复杂度。
与传统软件的区别:从"如何做"到"做什么"的范式转换。Agent不是替代传统软件,而是与之互补。
与Chatbot的区别:Chatbot是对话式的,Agent是目标驱动的。但两者之间存在演化路径。
分类体系:按自主程度(反应式/慎思式/混合式)、功能类型、部署形态、LLM依赖程度进行分类。
应用场景:客服自动化、代码开发、数据分析、工作流自动化是目前最成熟的场景。
局限性:幻觉、成本、可靠性、安全性是当前Agent技术面临的核心挑战。
理解这些概念是后续深入学习和实践的基础。在接下来的章节中,我们将回顾Agent技术是如何一步步走到今天的,然后深入探讨Agent编程的具体范式。
延伸阅读
经典文献
- Russell, S. & Norvig, P. (2020). Artificial Intelligence: A Modern Methods (4th ed.) — 第2章对Agent有深入讨论
- Wooldridge, M. (2009). An Introduction to MultiAgent Systems — 多Agent系统入门经典
大语言模型时代的Agent
- Wang, L. et al. (2024). A Survey on Large Language Model Based Autonomous Agents — LLM Agent的全面综述
- Schick, T. et al. (2024). Toolformer: Language Models Can Teach Themselves to Use Tools — 工具增强LLM的开创性工作
实践资源
- OpenAI Cookbook (github.com/openai/openai-cookbook) — 包含大量Agent实现的示例代码
- LangChain Documentation (python.langchain.com) — 主流Agent框架的文档
值得关注的Agent项目
- AutoGPT — 最早的自主Agent实验之一
- BabyAGI — 展示Agent任务分解能力的最小实现
- CrewAI — 多Agent协作框架
- Microsoft AutoGen — 微软的多Agent框架
上一篇 → 卷索引 | 下一篇 → 第2章:Agent技术演进史