AI: AI Agent
最后更新:2026-08-26
1. 你将学到
| 编号 | 内容 |
|---|---|
| ❶ | Agent vs 普通 Chatbot 的区别 |
| ❷ | ReAct 模式(推理 + 行动) |
| ❸ | 工具调用(Function Calling) |
| ❹ | Agent 规划与记忆 |
| ❺ | 用 Python 实现简单 Agent |
2. 故事
Bob 想让 AI 帮他"查一下苹果公司最新股价并分析是否值得投资"。普通 ChatGPT 只能说"我无法联网,截至我的训练数据截止日期……"——信息过时,毫无用处。
Alice 用 Agent 框架搭建了一个 AI Agent,同样的提问,Agent 自己决定:
- 调用 搜索工具 → 查到 AAPL 当前股价 $195.27,PE 比率 31.2
- 调用 计算工具 → 算出预期年化回报率约 6.8%
- 综合以上结果 → 输出投资建议
Bob 惊叹:"这不就是 AI 自己在思考和工作吗?"
核心区别:Chatbot 只会"说",Agent 会"做"。
3. 什么是 AI Agent?
(1) Agent 的定义
AI Agent = LLM + 工具 + 记忆 + 规划
| 组件 | 作用 | 类比 |
|---|---|---|
| LLM(大语言模型) | 理解、推理、决策 | 大脑 |
| 工具(Tools) | 执行动作(搜索、计算、代码执行等) | 双手 |
| 记忆(Memory) | 保存对话历史和长期知识 | 笔记本 |
| 规划(Planning) | 分解任务、制定步骤 | 计划表 |
一个普通 Chatbot 只有 LLM,像一个"只能说话不能动手"的顾问。而 Agent 有了工具、记忆和规划能力后,就像一个能自己上网查资料、做计算、写报告的助手。
(2) Chatbot vs Agent vs Workflow
| 维度 | Chatbot | Agent | Workflow |
|---|---|---|---|
| 决策方式 | 无决策,直接回答 | LLM 自主决定下一步 | 人工预定义流程 |
| 工具使用 | 无 | 动态选择和调用 | 固定节点调用 |
| 灵活性 | 低 | 高 | 中 |
| 可控性 | 高 | 中 | 高 |
| 典型场景 | 问答、闲聊 | 研究、分析、自主探索 | 流水线、审批流 |
4. ReAct 模式——推理 + 行动
(1) ReAct 核心思想
ReAct(Reasoning + Acting)是 Agent 最经典的决策模式:
- 观察(Observation):接收用户输入或工具返回的结果
- 思考(Thought):LLM 分析当前情况,决定下一步
- 行动(Action):调用工具执行操作
- 循环往复,直到得出最终答案
(2) ReAct 各步骤说明
| 步骤 | 说明 | 示例 |
|---|---|---|
| Observation | 接收输入/工具结果 | "用户问:Apple 最新股价?" |
| Thought | LLM 推理当前该做什么 | "我需要调用搜索工具查股价" |
| Action | 执行工具调用 | search_stock("AAPL") |
| Observation | 工具返回结果 | "AAPL = $195.27" |
| Thought | 继续推理 | "有了股价,可以算 PE 了" |
| Action | 调用下一个工具 | calculate_pe(195.27, 6.26) |
| ... | 重复直到有最终答案 | ... |
| Final Answer | 输出最终回复 | "AAPL 当前 $195.27,PE 31.2..." |
(3) ReAct 流程图
graph TB
A[User Input] --> B[Observation]
B --> C[Thought]
C --> D{Need Action?}
D -- Yes --> E[Action / Tool Call]
E --> F[Tool Result]
F --> B
D -- No --> G[Final Answer]
G --> H[User]
5. 工具调用——Function Calling
(1) 什么是 Function Calling
Function Calling 是 OpenAI 等模型提供的能力:你告诉模型"有哪些工具可用",模型在回答时可以选择调用某个工具,而不是直接给出文字回答。
关键区别:模型不直接执行代码,而是输出一个结构化的工具调用请求(函数名 + 参数),由你的代码负责执行。
(2) 工具类型对比
| 工具类型 | 用途 | 典型 API | 示例 |
|---|---|---|---|
| 搜索 | 获取实时信息 | SerpAPI / Tavily | get_stock_price("AAPL") |
| 计算器 | 数学运算 | Python eval / Wolfram | calculate("31.2 / 6.26") |
| 代码执行 | 运行程序 | Python REPL / Docker | run_code("print(2**10)") |
| API 调用 | 对接外部服务 | HTTP / SDK | send_email(to, subject) |
▶ 示例:定义一个函数工具(难度⭐)
import json
def get_weather(city: str) -> str:
"""Get current weather for a city."""
weather_data = {
"Beijing": '{"temp": 22, "condition": "Sunny"}',
"Tokyo": '{"temp": 18, "condition": "Cloudy"}',
"New York": '{"temp": 15, "condition": "Rainy"}',
}
return weather_data.get(city, '{"temp": null, "condition": "Unknown"}')
tool_definition = {
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a given city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name, e.g. Beijing, Tokyo"
}
},
"required": ["city"]
}
}
}
print(get_weather("Beijing"))
{"temp": 22, "condition": "Sunny"}
▶ 示例:OpenAI Function Calling 调用(难度⭐⭐)
from openai import OpenAI
client = OpenAI()
tools = [tool_definition]
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "What is the weather in Beijing?"}
],
tools=tools,
tool_choice="auto"
)
message = response.choices[0].message
if message.tool_calls:
tool_call = message.tool_calls[0]
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
print(f"Model wants to call: {func_name}")
print(f"Arguments: {func_args}")
result = get_weather(**func_args)
print(f"Tool result: {result}")
Model wants to call: get_weather
Arguments: {'city': 'Beijing'}
Tool result: {"temp": 22, "condition": "Sunny"}
6. Agent 规划与记忆
(1) 规划(Planning)
复杂任务需要分步完成。Agent 的规划能力体现在:
- 任务分解:将"分析是否值得投资"拆分为"查股价→算 PE→比较行业平均→给出建议"
- 步骤排序:确定先做什么、后做什么
- 动态调整:如果搜索工具失败,换一个工具或策略
(2) 记忆(Memory)
| 类型 | 说明 | 实现 |
|---|---|---|
| 短期记忆 | 当前对话上下文 | 对话历史列表 |
| 长期记忆 | 跨会话的知识 | 向量数据库 / 文件存储 |
| 工作记忆 | 当前任务的中间结果 | Scratchpad / 变量 |
短期记忆就是对话历史——每次调用 LLM 时把之前的消息都传进去。长期记忆需要额外的存储机制。
7. 用 Python 实现简单 Agent
▶ 示例:Agent 循环(while loop 实现)(难度⭐⭐)
import json
from openai import OpenAI
client = OpenAI()
def get_weather(city: str) -> str:
"""Get current weather for a city."""
data = {
"Beijing": '{"temp": 22, "condition": "Sunny"}',
"Tokyo": '{"temp": 18, "condition": "Cloudy"}',
}
return data.get(city, '{"temp": null, "condition": "Unknown"}')
available_tools = {
"get_weather": get_weather,
}
tool_schemas = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a given city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
}
}]
def run_agent(user_query: str, max_steps: int = 5) -> str:
messages = [{"role": "user", "content": user_query}]
for step in range(max_steps):
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=tool_schemas,
tool_choice="auto"
)
msg = response.choices[0].message
messages.append(msg)
if not msg.tool_calls:
return msg.content
for tool_call in msg.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
print(f"[Step {step+1}] Calling {func_name}({func_args})")
result = available_tools[func_name](**func_args)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
return "Agent reached max steps without final answer."
answer = run_agent("What is the weather in Beijing and Tokyo?")
print(answer)
[Step 1] Calling get_weather({'city': 'Beijing'})
[Step 2] Calling get_weather({'city': 'Tokyo'})
The weather in Beijing is 22°C and Sunny, while Tokyo is 18°C and Cloudy.
▶ 示例:多工具 Agent(搜索 + 计算器)(难度⭐⭐⭐)
import json
from openai import OpenAI
client = OpenAI()
def search_web(query: str) -> str:
"""Simulate web search."""
mock_results = {
"Tesla 2024 revenue": "Tesla 2024 total revenue: $97.69 billion",
"Tesla 2023 revenue": "Tesla 2023 total revenue: $96.77 billion",
"AAPL stock price": "AAPL current price: $195.27, PE ratio: 31.2",
}
for key, val in mock_results.items():
if key.lower() in query.lower():
return val
return "No results found for: " + query
def calculate(expression: str) -> str:
"""Evaluate a math expression safely."""
allowed = set("0123456789+-*/.() ")
if all(c in allowed for c in expression):
try:
result = eval(expression)
return str(result)
except Exception as e:
return f"Calculation error: {e}"
return "Invalid expression"
available_tools = {
"search_web": search_web,
"calculate": calculate,
}
tool_schemas = [
{
"type": "function",
"function": {
"name": "search_web",
"description": "Search the web for information",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search query"}
},
"required": ["query"]
}
}
},
{
"type": "function",
"function": {
"name": "calculate",
"description": "Evaluate a mathematical expression",
"parameters": {
"type": "object",
"properties": {
"expression": {"type": "string", "description": "Math expression to evaluate"}
},
"required": ["expression"]
}
}
}
]
def run_multi_tool_agent(user_query: str, max_steps: int = 10) -> str:
messages = [{"role": "user", "content": user_query}]
for step in range(max_steps):
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=tool_schemas,
tool_choice="auto"
)
msg = response.choices[0].message
messages.append(msg)
if not msg.tool_calls:
return msg.content
for tool_call in msg.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
print(f"[Step {step+1}] {func_name}({func_args})")
result = available_tools[func_name](**func_args)
print(f" -> {result}")
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
return "Agent reached max steps."
answer = run_multi_tool_agent("What was Tesla's 2024 revenue and how much did it grow YoY?")
print(f"\nFinal Answer:\n{answer}")
[Step 1] search_web({'query': 'Tesla 2024 revenue'})
-> Tesla 2024 total revenue: $97.69 billion
[Step 2] search_web({'query': 'Tesla 2023 revenue'})
-> Tesla 2023 total revenue: $96.77 billion
[Step 3] calculate({'expression': '(97.69 - 96.77) / 96.77 * 100'})
-> 0.9508080206700424
Final Answer:
Tesla's 2024 revenue was $97.69 billion, compared to $96.77 billion in 2023.
This represents a year-over-year growth of approximately 0.95%.
▶ 示例:带记忆的 Agent(难度⭐⭐⭐)
import json
from openai import OpenAI
client = OpenAI()
class MemoryAgent:
def __init__(self, system_prompt: str = "You are a helpful assistant."):
self.system_prompt = system_prompt
self.short_term_memory: list = []
self.long_term_memory: list = []
def add_to_long_term(self, fact: str):
self.long_term_memory.append(fact)
print(f"[Memory Saved] {fact}")
def get_context(self) -> list:
context = [{"role": "system", "content": self.system_prompt}]
if self.long_term_memory:
mem_str = "\n".join(f"- {m}" for m in self.long_term_memory)
context.append({
"role": "system",
"content": f"Long-term memory:\n{mem_str}"
})
context.extend(self.short_term_memory)
return context
def chat(self, user_input: str) -> str:
self.short_term_memory.append({"role": "user", "content": user_input})
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=self.get_context()
)
reply = response.choices[0].message.content
self.short_term_memory.append({"role": "assistant", "content": reply})
return reply
def remember(self, fact: str):
self.add_to_long_term(fact)
agent = MemoryAgent(system_prompt="You are a research assistant.")
r1 = agent.chat("My name is Bob and I work at Apple Inc.")
print(f"Agent: {r1}")
agent.remember("User name: Bob, works at Apple Inc.")
r2 = agent.chat("What is my name and where do I work?")
print(f"Agent: {r2}")
Agent: Nice to meet you, Bob! How can I help you today?
[Memory Saved] User name: Bob, works at Apple Inc.
Agent: Your name is Bob, and you work at Apple Inc.
8. Agent 框架
(1) Agent 框架对比
| 框架 | 特点 | 适合场景 | 语言 |
|---|---|---|---|
| LangChain / LangGraph | 生态丰富、社区大、灵活但复杂 | 通用 Agent 开发 | Python / JS |
| OpenAI Assistants API | 官方托管、简单易用、黑箱 | 快速原型、OpenAI 生态 | REST / Python |
| AutoGen (Microsoft) | 多 Agent 协作、对话式 | 多 Agent 讨论与协作 | Python |
| CrewAI | 角色扮演、团队协作 | 模拟团队工作流 | Python |
(2) 如何选择
- 入门练习:自己用 while loop 写(本课的方法),理解原理
- 快速原型:OpenAI Assistants API,几行代码搞定
- 生产项目:LangGraph,可控性好
- 多 Agent:AutoGen 或 CrewAI
9. 综合示例:研究助理 Agent
▶ 示例:构建一个"研究助理 Agent"(难度⭐⭐⭐)
import json
from openai import OpenAI
client = OpenAI()
# --- Tool Definitions ---
def search_web(query: str) -> str:
"""Simulate web search for real-time information."""
mock_db = {
"Tesla 2024 revenue": "Tesla 2024 total revenue: $97.69 billion, net income: $7.09 billion",
"Tesla 2023 revenue": "Tesla 2023 total revenue: $96.77 billion, net income: $14.99 billion",
"Tesla stock price": "TSLA current price: $352.00, market cap: $1.13 trillion",
}
for key, val in mock_db.items():
if key.lower() in query.lower():
return val
return f"No specific results for: {query}"
def calculate(expression: str) -> str:
"""Evaluate a mathematical expression."""
allowed = set("0123456789+-*/.() ")
if all(c in allowed for c in expression):
try:
return str(eval(expression))
except Exception as e:
return f"Error: {e}"
return "Invalid expression"
def run_code(code: str) -> str:
"""Execute Python code and return output."""
import io
import contextlib
output = io.StringIO()
try:
with contextlib.redirect_stdout(output):
exec(code, {"__builtins__": {}})
return output.getvalue() or "Code executed with no output."
except Exception as e:
return f"Execution error: {e}"
# --- Agent Setup ---
available_tools = {
"search_web": search_web,
"calculate": calculate,
"run_code": run_code,
}
tool_schemas = [
{
"type": "function",
"function": {
"name": "search_web",
"description": "Search the web for real-time information like stock prices, revenue, news",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search query"}
},
"required": ["query"]
}
}
},
{
"type": "function",
"function": {
"name": "calculate",
"description": "Evaluate a mathematical expression, e.g. (100-90)/90*100",
"parameters": {
"type": "object",
"properties": {
"expression": {"type": "string", "description": "Math expression"}
},
"required": ["expression"]
}
}
},
{
"type": "function",
"function": {
"name": "run_code",
"description": "Execute Python code for complex analysis, charting, or data processing",
"parameters": {
"type": "object",
"properties": {
"code": {"type": "string", "description": "Python code to execute"}
},
"required": ["code"]
}
}
}
]
SYSTEM_PROMPT = """You are a research assistant agent. When answering questions:
1. Use search_web to find real-time data
2. Use calculate for math operations
3. Use run_code for complex analysis
Always show your reasoning step by step."""
def research_agent(user_query: str, max_steps: int = 10) -> str:
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_query}
]
for step in range(max_steps):
print(f"\n--- Step {step + 1} ---")
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=tool_schemas,
tool_choice="auto"
)
msg = response.choices[0].message
messages.append(msg)
if msg.content:
print(f"Thought: {msg.content[:200]}")
if not msg.tool_calls:
return msg.content
for tool_call in msg.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
print(f"Action: {func_name}({json.dumps(func_args)})")
result = available_tools[func_name](**func_args)
print(f"Observation: {result[:200]}")
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
return "Agent reached maximum steps."
# --- Run the Agent ---
answer = research_agent(
"What was Tesla's 2024 revenue? How much did it grow year-over-year? "
"Calculate the growth rate as a percentage."
)
print(f"\n{'='*50}\nFinal Answer:\n{answer}")
--- Step 1 ---
Thought: I need to find Tesla's 2024 and 2023 revenue first.
Action: search_web({"query": "Tesla 2024 revenue"})
Observation: Tesla 2024 total revenue: $97.69 billion, net income: $7.09 billion
--- Step 2 ---
Action: search_web({"query": "Tesla 2023 revenue"})
Observation: Tesla 2023 total revenue: $96.77 billion, net income: $14.99 billion
--- Step 3 ---
Action: calculate({"expression": "(97.69 - 96.77) / 96.77 * 100"})
Observation: 0.9508080206700424
==================================================
Final Answer:
Tesla's 2024 total revenue was $97.69 billion, compared to $96.77 billion in 2023.
The year-over-year growth rate is approximately 0.95%.
❓ 常见问题
📖 小节
| 概念 | 一句话总结 |
|---|---|
| AI Agent | LLM + 工具 + 记忆 + 规划 = 能自主行动的 AI |
| ReAct | 观察→思考→行动的循环,Agent 的核心决策模式 |
| Function Calling | 模型输出工具调用请求,代码负责执行 |
| 规划 | Agent 将复杂任务分解为可执行的步骤 |
| 记忆 | 短期(对话历史)+ 长期(向量数据库)= Agent 的知识基础 |
| Agent 框架 | LangChain / OpenAI Assistants / AutoGen 等,简化 Agent 开发 |
📝 作业
基础(⭐)
定义 2 个自定义工具(如 get_population 和 get_gdp),按照 Function Calling 的 JSON Schema 格式编写工具定义,并注册到 available_tools 字典中。
进阶(⭐⭐)
实现一个单工具 Agent 循环:定义一个 get_exchange_rate 工具,用户输入"100 USD 能换多少 CNY?",Agent 自动调用工具并返回结果。
挑战(⭐⭐⭐)
让 Agent 回答一个需要搜索 + 计算的问题:如"东京的人口是多少?如果每人每天需要 2 kg 水,东京每天需要多少吨水?" Agent 需要自主决定先搜索人口数据,再调用计算工具得出答案。