Agents 代理
Agents(代理)是 LangChain 最强大的功能之一,它让 LLM 能够自主决定使用哪些工具来完成复杂任务。本章将详细介绍代理系统的原理和使用方法。
什么是 Agent?
Agent(代理) 是一种能够自主决策和执行行动的智能系统。与传统的固定流程 Chain 不同,Agent 可以根据用户输入动态决定下一步操作。
Agent vs Chain
| 特性 | Chain | Agent |
|---|---|---|
| 执行顺序 | 固定顺序 | 动态决定 |
| 工具使用 | 不支持 | 支持 |
| 自主性 | 无 | 有 |
| 适用场景 | 固定流程 | 复杂、开放式任务 |
Agent 工作原理
核心流程:
- 用户输入 → LLM 分析意图
- LLM 决定是否需要使用工具
- 如果需要,选择并调用工具
- 工具返回结果 → LLM 再次分析
- 循环直到任务完成
创建 Agent
基础 Agent
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
from langchain.tools import tool
# 定义工具
@tool
def get_weather(city: str) -> str:
"""获取指定城市的天气信息"""
return f"{city}今天天气晴朗,25°C"
# 初始化模型
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 创建 Agent
agent = create_agent(
model=model,
tools=[get_weather],
system_prompt="你是一个有用的助手,可以查询天气"
)
# 调用 Agent
result = agent.invoke({
"messages": [{"role": "user", "content": "北京今天天气怎么样?"}]
})
print(result["messages"][-1].content)
带思考过程的 Agent
# Agent 会输出思考过程
agent = create_agent(
model=model,
tools=[get_weather],
system_prompt="你是一个有帮助的助手",
prompt={"user": "{input}"}
)
# invoke 返回完整消息,包括思考
result = agent.invoke({"messages": [{"role": "user", "content": "上海天气"}]})
# 查看所有消息
for msg in result["messages"]:
if hasattr(msg, "type"):
print(f"[{msg.type}]: {msg.content[:100]}...")
工具(Tools)
工具是 Agent 执行具体操作的函数。
定义工具
from langchain.tools import tool
@tool
def calculate(expression: str) -> str:
"""执行数学计算"""
try:
result = eval(expression)
return str(result)
except Exception as e:
return f"计算错误: {e}"
@tool
def search_web(query: str) -> str:
"""搜索网络信息"""
# 这里可以接入真实的搜索API
return f"搜索结果: {query} 相关信息..."
@tool
def get_current_time() -> str:
"""获取当前时间"""
from datetime import datetime
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
工具装饰器
from langchain.tools import tool
# 方式1:使用装饰器(推荐)
@tool
def multiply(a: int, b: int) -> int:
"""计算两个数的乘积"""
return a * b
# 方式2:使用 Tool 类
from langchain.tools import Tool
def divide(a: float, b: float) -> str:
if b == 0:
return "错误:除数不能为零"
return str(a / b)
divide_tool = Tool(
name="divide",
func=divide,
description="用于计算两个数的除法,参数为被除数和除数"
)
多个工具组合
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 定义多个工具
@tool
def get_weather(city: str) -> str:
"""获取城市天气"""
return f"{city}:晴,25°C"
@tool
def search_restaurant(cuisine: str, location: str) -> str:
"""搜索餐厅"""
return f"在{location}找到的{cuisine}餐厅:xxx"
@tool
def get_directions(from_loc: str, to_loc: str) -> str:
"""获取路线"""
return f"从{from_loc}到{to_loc}的路线..."
# 创建 Agent
agent = create_agent(
model=model,
tools=[get_weather, search_restaurant, get_directions],
system_prompt="你是一个乐于助人的助手"
)
# 测试
result = agent.invoke({
"messages": [{"role": "user", "content": "我想找一家北京的川菜馆"}]
})
Agent 类型
1. OpenAI Functions Agent
适合需要调用函数的场景:
from langchain.agents import create_openai_functions_agent
agent = create_openai_functions_agent(
llm=model,
tools=tools,
prompt=prompt
)
2. JSON Agent
输出 JSON 格式的工具调用:
from langchain.agents import create_json_agent
agent = create_json_agent(
llm=model,
tools=tools,
prompt=prompt
)
3. Tool Agent
通用工具代理:
from langchain.agents import create_tool_calling_agent
agent = create_tool_calling_agent(
llm=model,
tools=tools,
prompt=prompt
)
4. XML Agent
适合 Anthropic 模型:
from langchain.agents import create_xml_agent
agent = create_xml_agent(
llm=model,
tools=tools,
prompt=prompt
)
Agent 工具选择机制
Tool 定义要点
工具的选择依赖于名称和描述:
from langchain.tools import tool
# ✅ 好的工具定义
@tool
def get_weather(city: str) -> str:
"""获取指定城市的当前天气情况,包括温度和天气状况"""
return "..."
# ❌ 不好的工具定义
@tool
def gw(c: str) -> str:
"""天气"""
return "..."
为什么?
- LLM 根据
description选择合适的工具 - 描述越详细准确,LLM 越能做出正确选择
工具选择示例
@tool
def get_weather(city: str) -> str:
"""获取指定城市的天气信息。输入参数为城市名称(中文或英文)。"""
...
@tool
def search_hotels(city: str, price_level: str) -> str:
"""搜索指定城市的酒店。输入参数为城市名称和价格等级(budget/mid-range/luxury)。"""
...
@tool
def book_hotel(hotel_id: str, checkin: str, checkout: str) -> str:
"""预订酒店。需要酒店ID、入住日期、退房日期。"""
...
# Agent 会根据用户意图自动选择合适的工具
# "北京天气如何" → get_weather
# "北京便宜酒店" → search_hotels
# "我要预订xxx酒店" → book_hotel
Agent 与 Memory
对话式 Agent
from langchain.agents import create_agent
from langchain.memory import ConversationBufferMemory
from langchain.memory.chat_message_histories.in_memory import ChatMessageHistory
# 创建记忆
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
# 创建带记忆的 Agent
agent = create_agent(
model=model,
tools=tools,
system_prompt="你是对话助手",
prompt={"chat_history": "{chat_history}", "input": "{input}"}
)
# 第一次对话
result1 = agent.invoke({
"messages": [{"role": "user", "content": "我叫张三"}]
})
print(result1["messages"][-1].content)
# 第二次对话(Agent 记得之前的内容)
result2 = agent.invoke({
"messages": [{"role": "user", "content": "你还记得我叫什么吗?"}]
})
print(result2["messages"][-1].content)
保存对话历史
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(
memory_key="history",
return_messages=True
)
# 添加历史
memory.chat_memory.add_user_message("我想了解Python")
memory.chat_memory.add_ai_message("Python是一种高级编程语言...")
# 创建 Agent 时传入
agent = create_agent(
model=model,
tools=tools,
prompt={"history": "{history}", "input": "{input}"}
)
实际应用示例
1. 研究助手 Agent
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
from langchain.tools import tool
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
@tool
def search_academic(query: str) -> str:
"""搜索学术论文"""
return f"关于{query}的学术论文..."
@tool
def summarize_text(text: str) -> str:
"""总结文本"""
return f"文本摘要:{text[:100]}..."
@tool
def translate_text(text: str, target_lang: str) -> str:
"""翻译文本"""
return f"翻译成{target_lang}:{text}"
agent = create_agent(
model=model,
tools=[search_academic, summarize_text, translate_text],
system_prompt="你是一个研究助手,帮助用户查找和整理学术资料"
)
# 使用
result = agent.invoke({
"messages": [{"role": "user", "content": "帮我找一些关于Transformer的论文并总结"}]
})
2. 客服 Agent
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
@tool
def get_order_status(order_id: str) -> str:
"""查询订单状态"""
return f"订单{order_id}已发货,预计明天到达"
@tool
def initiate_refund(order_id: str) -> str:
"""发起退款"""
return f"订单{order_id}的退款已发起,3-5个工作日到账"
agent = create_agent(
model=model,
tools=[get_order_status, initiate_refund],
system_prompt="""你是一个客服助手。
用户来询时,先了解问题,然后使用相应工具帮助用户。
如果需要用户提供信息,请礼貌地请求。"""
)
result = agent.invoke({
"messages": [{"role": "user", "content": "我的订单号是12345,请问发货了吗?"}]
})
3. 数据分析 Agent
@tool
def load_csv_data(file_path: str) -> str:
"""加载CSV数据"""
return "数据加载成功..."
@tool
def analyze_data(data: str, analysis_type: str) -> str:
"""分析数据"""
return f"分析完成,结果:..."
@tool
def create_chart(data: str, chart_type: str) -> str:
"""创建图表"""
return f"创建了{chart_type}类型的图表"
agent = create_agent(
model=model,
tools=[load_csv_data, analyze_data, create_chart],
system_prompt="你是一个数据分析助手"
)
Agent 调试
开启详细输出
agent = create_agent(
model=model,
tools=tools,
verbose=True # 打印思考过程
)
result = agent.invoke({"messages": [{"role": "user", "content": "..."}]})
使用 LangSmith 追踪
import os
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = "ls-..."
# 所有执行都会被记录
result = agent.invoke({"messages": [{"role": "user", "content": "..."}]})
常见问题
1. Agent 不调用工具
# 可能的解决方案:
# 1. 检查工具描述是否足够清晰
# 2. 增加 system_prompt 说明需要使用工具
# 3. 明确告诉 Agent 在什么时候需要调用工具
agent = create_agent(
model=model,
tools=tools,
system_prompt="""你是助手。当你需要获取信息时,使用提供的工具。
可用工具:{tools}"""
)
2. Agent 选择错误的工具
# 解决方案:优化工具描述
@tool
def get_weather(city: str) -> str:
"""获取城市天气。用于回答关于特定城市天气状况的问题。
参数:city - 城市名称(必须)
返回:天气描述"""
3. 工具返回格式问题
# 确保工具返回字符串格式
@tool
def calculate(expression: str) -> str:
result = eval(expression)
return str(result) # 转换为字符串
下一步
现在你已经掌握了 Agents 的核心概念,接下来学习: