LangChain Agents(智能体)¶
概述¶
Agents(代理)将语言模型与工具相结合,创建能够推理任务、决定使用哪些工具并迭代工作以找到解决方案的系统。
核心概念¶
- 推理引擎:语言模型负责思考和决策
- 工具调用:代理可以调用外部工具执行操作
- 迭代过程:代理在循环中工作直到达到停止条件
- 状态管理:代理维护对话历史和自定义状态
基础 Agent 创建¶
1. 简单 Agent¶
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search_web(query: str) -> str:
"""在网络上搜索信息。"""
return f"关于 '{query}' 的搜索结果:相关文章、新闻和信息"
@tool
def get_weather(location: str) -> str:
"""获取指定位置的天气信息。"""
return f"{location}的天气:晴朗,25°C"
# 创建基础 Agent
agent = create_agent(
model="openai:gpt-4o",
tools=[search_web, get_weather]
)
2. 调用 Agent¶
# 基础调用
result = agent.invoke(
{"messages": [{"role": "user", "content": "北京今天天气怎么样?"}]}
)
print(result["messages"][-1].content)
核心组件详解¶
1. 模型配置¶
静态模型配置¶
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
# 方法1:使用模型标识符字符串
agent1 = create_agent(
"openai:gpt-4o", # 自动推断为 OpenAI GPT-4o
tools=[search_web, get_weather]
)
# 方法2:使用模型实例(推荐用于生产环境)
model = ChatOpenAI(
model="gpt-4o",
temperature=0.1, # 控制创造性
max_tokens=1000, # 最大输出长度
timeout=30, # 超时设置
# 其他参数...
)
agent2 = create_agent(
model=model,
tools=[search_web, get_weather]
)
动态模型选择¶
from langchain.agents.middleware import wrap_model_call, ModelRequest
from langchain_openai import ChatOpenAI
# 定义不同模型
basic_model = ChatOpenAI(model="gpt-4o-mini") # 经济型模型
advanced_model = ChatOpenAI(model="gpt-4o") # 高级模型
@wrap_model_call
def dynamic_model_selection(request: ModelRequest, handler):
"""基于对话复杂度选择模型"""
messages = request.state["messages"]
message_count = len(messages)
# 复杂对话使用高级模型
if message_count > 5 or any("复杂" in msg.content for msg in messages if hasattr(msg, 'content')):
request.model = advanced_model
else:
request.model = basic_model
return handler(request)
# 创建支持动态模型选择的 Agent
agent = create_agent(
model=basic_model, # 默认模型
tools=[search_web, get_weather],
middleware=[dynamic_model_selection]
)
2. 工具系统¶
基础工具定义¶
from langchain.tools import tool
from datetime import datetime
@tool
def calculator(expression: str) -> str:
"""计算数学表达式。"""
try:
result = eval(expression)
return f"{expression} = {result}"
except Exception as e:
return f"计算错误: {str(e)}"
@tool
def get_current_time(timezone: str = "UTC") -> str:
"""获取指定时区的当前时间。"""
now = datetime.now()
return f"{timezone}时区当前时间: {now.strftime('%Y-%m-%d %H:%M:%S')}"
@tool
def search_products(query: str, category: str = "all") -> str:
"""搜索产品信息。"""
return f"在 '{category}' 类别中找到关于 '{query}' 的产品"
# 创建包含多个工具的 Agent
agent = create_agent(
model="openai:gpt-4o",
tools=[calculator, get_current_time, search_products]
)
工具错误处理¶
from langchain.agents.middleware import wrap_tool_call
from langchain_core.messages import ToolMessage
@wrap_tool_call
def handle_tool_errors(request, handler):
"""自定义工具错误处理"""
try:
return handler(request)
except Exception as e:
# 返回友好的错误信息
error_message = f"工具执行失败:{str(e)}。请检查输入参数并重试。"
return ToolMessage(
content=error_message,
tool_call_id=request.tool_call["id"]
)
agent = create_agent(
model="openai:gpt-4o",
tools=[calculator, get_current_time],
middleware=[handle_tool_errors]
)
3. 系统提示词¶
静态系统提示词¶
agent = create_agent(
model="openai:gpt-4o",
tools=[search_web, get_weather],
system_prompt="""你是一个专业、友好的助手。请遵循以下指导原则:
1. 回答要准确、简洁
2. 使用工具获取最新信息
3. 如果用户问题涉及专业领域,请说明信息来源
4. 对不确定的信息要明确说明
"""
)
动态系统提示词¶
from langchain.agents.middleware import dynamic_prompt, ModelRequest
from typing import TypedDict
class UserContext(TypedDict):
user_level: str # "beginner", "intermediate", "expert"
language: str
@dynamic_prompt
def adaptive_system_prompt(request: ModelRequest) -> str:
"""基于用户水平和语言生成动态系统提示词"""
context = request.runtime.context
user_level = context.get("user_level", "beginner")
language = context.get("language", "zh-CN")
base_prompt = "你是一个有帮助的AI助手。"
# 根据用户水平调整提示词
level_prompts = {
"beginner": "请用简单易懂的语言解释概念,避免专业术语。",
"intermediate": "提供平衡的解答,包含基本概念和一些进阶信息。",
"expert": "提供详细的技术分析,可以使用专业术语。"
}
level_prompt = level_prompts.get(user_level, level_prompts["beginner"])
# 语言特定提示
if language == "zh-CN":
language_prompt = "请使用中文回复,保持语言的自然和流畅。"
else:
language_prompt = "Please respond in natural and fluent language."
return f"{base_prompt} {level_prompt} {language_prompt}"
# 创建支持动态提示词的 Agent
agent = create_agent(
model="openai:gpt-4o",
tools=[search_web, get_weather],
middleware=[adaptive_system_prompt],
context_schema=UserContext
)
# 使用上下文调用
result = agent.invoke(
{"messages": [{"role": "user", "content": "解释机器学习"}]},
context={"user_level": "beginner", "language": "zh-CN"}
)
高级功能¶
1. 结构化输出¶
from pydantic import BaseModel, Field
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy
class ProductReview(BaseModel):
"""产品评价分析"""
product_name: str = Field(description="产品名称")
rating: int = Field(description="评分(1-5)", ge=1, le=5)
positive_points: list[str] = Field(description="优点列表")
negative_points: list[str] = Field(description="缺点列表")
summary: str = Field(description="总体评价总结")
class CustomerInfo(BaseModel):
"""客户信息提取"""
name: str = Field(description="客户姓名")
email: str = Field(description="邮箱地址")
phone: str = Field(description="电话号码")
interests: list[str] = Field(description="兴趣列表")
# 使用 ToolStrategy 实现结构化输出
agent = create_agent(
model="openai:gpt-4o",
tools=[search_web],
response_format=ToolStrategy(ProductReview) # 或 CustomerInfo
)
# 调用并获取结构化输出
result = agent.invoke({
"messages": [{
"role": "user",
"content": "分析这个产品评价:'iPhone 15 Pro 太棒了!相机质量优秀,电池续航也很好,就是价格有点贵。评分5/5'"
}]
})
structured_data = result["structured_response"]
print(f"产品: {structured_data.product_name}")
print(f"评分: {structured_data.rating}")
print(f"优点: {', '.join(structured_data.positive_points)}")
2. 内存管理¶
自定义状态管理¶
from typing import TypedDict, List, Optional
from langchain.agents import AgentState, create_agent
class CustomAgentState(AgentState):
"""自定义 Agent 状态"""
user_preferences: dict
conversation_topics: List[str]
interaction_count: int = 0
last_active: Optional[str] = None
# 通过 state_schema 定义状态
agent = create_agent(
model="openai:gpt-4o",
tools=[search_web, get_weather],
state_schema=CustomAgentState
)
# 使用自定义状态调用
result = agent.invoke({
"messages": [{"role": "user", "content": "我喜欢技术类内容"}],
"user_preferences": {"category": "technology", "detail_level": "high"},
"conversation_topics": ["AI", "编程"],
"interaction_count": 1
})
通过中间件管理状态¶
from langchain.agents.middleware import AgentMiddleware
from typing import Any
class UserPreferencesMiddleware(AgentMiddleware):
"""用户偏好管理中间件"""
state_schema = CustomAgentState
def before_model(self, state: CustomAgentState, runtime) -> dict[str, Any] | None:
"""在模型调用前处理用户偏好"""
preferences = state.get("user_preferences", {})
# 基于用户偏好调整行为
if preferences.get("detail_level") == "high":
# 可以在这里修改消息或添加上下文
pass
return None
def after_model(self, state: CustomAgentState, runtime) -> dict[str, Any] | None:
"""在模型调用后更新交互统计"""
return {
"interaction_count": state.get("interaction_count", 0) + 1,
"last_active": "2024-01-01T10:00:00" # 实际使用中应为当前时间
}
agent = create_agent(
model="openai:gpt-4o",
tools=[search_web, get_weather],
middleware=[UserPreferencesMiddleware()]
)
3. 流式传输¶
def stream_agent_progress():
"""流式传输 Agent 执行进度"""
print("开始流式传输 Agent 执行...")
for chunk in agent.stream(
{"messages": [{"role": "user", "content": "搜索AI最新发展并总结要点"}]},
stream_mode="values" # 也可以使用 "updates" 或 "messages"
):
# 获取最新消息
latest_message = chunk["messages"][-1]
# 处理AI回复
if hasattr(latest_message, 'content') and latest_message.content:
print(f"🤖 AI: {latest_message.content}")
# 处理工具调用
elif hasattr(latest_message, 'tool_calls') and latest_message.tool_calls:
for tool_call in latest_message.tool_calls:
print(f"🛠️ 调用工具: {tool_call['name']}")
print(f" 参数: {tool_call['args']}")
# 调用流式传输
stream_agent_progress()
4. 中间件系统¶
from langchain.agents.middleware import before_model, after_model, wrap_tool_call
from langchain.messages import RemoveMessage
from langgraph.graph.message import REMOVE_ALL_MESSAGES
@before_model
def trim_long_conversations(state, runtime):
"""修剪过长的对话历史"""
messages = state["messages"]
if len(messages) > 10:
# 保留系统消息和最近5条消息
system_messages = [msg for msg in messages if msg.type == "system"]
recent_messages = messages[-5:]
return {
"messages": [
RemoveMessage(id=REMOVE_ALL_MESSAGES),
*system_messages,
*recent_messages
]
}
return None
@after_model
def validate_response_content(state, runtime):
"""验证模型响应内容"""
last_message = state["messages"][-1]
# 检查是否包含不当内容
inappropriate_keywords = ["暴力", "仇恨", "歧视"]
if any(keyword in last_message.content for keyword in inappropriate_keywords):
return {
"messages": [
RemoveMessage(id=last_message.id),
*state["messages"][:-1]
]
}
return None
@wrap_tool_call
def log_tool_execution(request, handler):
"""记录工具执行日志"""
tool_name = request.tool_call["name"]
tool_args = request.tool_call["args"]
print(f"📝 开始执行工具: {tool_name}")
print(f" 参数: {tool_args}")
start_time = time.time()
result = handler(request)
execution_time = time.time() - start_time
print(f"✅ 工具执行完成: {tool_name} (耗时: {execution_time:.2f}s)")
return result
# 创建包含多个中间件的 Agent
agent = create_agent(
model="openai:gpt-4o",
tools=[search_web, get_weather, calculator],
middleware=[
trim_long_conversations,
validate_response_content,
log_tool_execution
]
)
实际应用场景¶
场景1:客户服务 Agent¶
from langchain.tools import tool
from datetime import datetime
class CustomerServiceAgent:
"""客户服务 Agent"""
def __init__(self):
self.agent = self._create_agent()
@tool
def check_order_status(self, order_id: str) -> str:
"""检查订单状态。"""
# 模拟订单数据库
orders = {
"ORD001": {"status": "已发货", "tracking": "SF123456789"},
"ORD002": {"status": "处理中", "tracking": None},
"ORD003": {"status": "已送达", "tracking": "SF987654321"}
}
if order_id in orders:
order = orders[order_id]
result = f"订单 {order_id} 状态: {order['status']}"
if order['tracking']:
result += f"\n物流单号: {order['tracking']}"
return result
return f"未找到订单 {order_id}"
@tool
def process_refund(self, order_id: str, reason: str) -> str:
"""处理退款申请。"""
return f"订单 {order_id} 的退款申请已提交。原因: {reason}\n预计3-5个工作日处理完成。"
@tool
def get_faq(self, category: str) -> str:
"""获取常见问题解答。"""
faqs = {
"shipping": "配送时间:普通快递3-5天,加急快递1-2天",
"returns": "退换货政策:7天无理由退货,30天质量问题的换货",
"payment": "支付方式:支持支付宝、微信支付、银行卡"
}
return faqs.get(category, "暂无该类别常见问题")
def _create_agent(self):
"""创建客户服务 Agent"""
return create_agent(
model="openai:gpt-4o",
tools=[self.check_order_status, self.process_refund, self.get_faq],
system_prompt="""你是一个专业的客户服务代表。请遵循以下原则:
1. 始终保持友好和专业的态度
2. 准确回答客户问题
3. 使用工具获取最新信息
4. 对于复杂问题,提供清晰的后续步骤
5. 如果无法解决问题,建议联系人工客服
""",
state_schema=CustomAgentState
)
def handle_customer_query(self, query: str, user_id: str):
"""处理客户查询"""
return self.agent.invoke({
"messages": [{"role": "user", "content": query}],
"user_preferences": {"user_id": user_id}
})
# 使用示例
service_agent = CustomerServiceAgent()
result = service_agent.handle_customer_query("我的订单ORD001状态如何?", "user123")
场景2:数据分析 Agent¶
import pandas as pd
import numpy as np
from io import StringIO
class DataAnalysisAgent:
"""数据分析 Agent"""
def __init__(self):
self.agent = self._create_agent()
self.current_dataset = None
@tool
def load_csv_data(self, csv_content: str) -> str:
"""加载CSV数据。"""
try:
self.current_dataset = pd.read_csv(StringIO(csv_content))
stats = {
"行数": len(self.current_dataset),
"列数": len(self.current_dataset.columns),
"列名": list(self.current_dataset.columns)
}
return f"数据加载成功!统计信息: {stats}"
except Exception as e:
return f"数据加载失败: {str(e)}"
@tool
def describe_dataset(self) -> str:
"""描述数据集基本信息。"""
if self.current_dataset is None:
return "请先加载数据"
description = self.current_dataset.describe()
return f"数据集描述:\n{description}"
@tool
def calculate_correlation(self, column1: str, column2: str) -> str:
"""计算两列之间的相关性。"""
if self.current_dataset is None:
return "请先加载数据"
if column1 not in self.current_dataset.columns or column2 not in self.current_dataset.columns:
return "指定的列不存在"
correlation = self.current_dataset[column1].corr(self.current_dataset[column2])
return f"{column1} 和 {column2} 的相关性: {correlation:.3f}"
@tool
def filter_data(self, condition: str) -> str:
"""根据条件过滤数据。"""
if self.current_dataset is None:
return "请先加载数据"
try:
filtered_data = self.current_dataset.query(condition)
return f"过滤后数据: {len(filtered_data)} 行"
except Exception as e:
return f"过滤条件错误: {str(e)}"
def _create_agent(self):
"""创建数据分析 Agent"""
return create_agent(
model="openai:gpt-4o",
tools=[
self.load_csv_data,
self.describe_dataset,
self.calculate_correlation,
self.filter_data
],
system_prompt="""你是一个数据分析专家。请帮助用户:
1. 加载和分析数据
2. 提供数据统计信息
3. 计算指标和相关性
4. 解释分析结果的含义
5. 用通俗易懂的语言解释技术概念
"""
)
# 使用示例
analysis_agent = DataAnalysisAgent()
# 模拟CSV数据
sample_data = """name,age,salary,department
张三,25,50000,技术部
李四,30,60000,销售部
王五,35,70000,技术部
赵六,28,55000,市场部"""
result = analysis_agent.agent.invoke({
"messages": [{"role": "user", "content": f"请分析以下数据:\n{sample_data}"}]
})
场景3:研究助手 Agent¶
class ResearchAssistantAgent:
"""研究助手 Agent"""
def __init__(self):
self.agent = self._create_agent()
self.research_topics = []
@tool
def search_academic_papers(self, topic: str, max_results: int = 5) -> str:
"""搜索学术论文。"""
# 模拟学术搜索
papers = [
f"《{topic}的最新研究进展》- 作者A et al.",
f"《{topic}在实践中的应用》- 作者B et al.",
f"《{topic}的未来发展趋势》- 作者C et al."
]
return f"找到 {len(papers)} 篇相关论文:\n" + "\n".join(papers[:max_results])
@tool
def summarize_research_topic(self, topic: str) -> str:
"""总结研究主题。"""
self.research_topics.append(topic)
return f"""
{topic} 研究总结:
1. 核心概念:{topic}涉及多个交叉学科领域
2. 当前热点:AI驱动的{topic}研究正在兴起
3. 主要挑战:数据质量和算法可解释性
4. 未来方向:自动化、智能化{topic}解决方案
"""
@tool
def compare_topics(self, topic1: str, topic2: str) -> str:
"""比较两个研究主题。"""
return f"""
{topic1} vs {topic2} 比较:
相似点:
- 都是前沿技术领域
- 都需要跨学科知识
- 都有广泛的应用场景
不同点:
- {topic1}更注重理论发展
- {topic2}更注重实践应用
- 技术栈和研究方法有所不同
"""
@tool
def generate_research_questions(self, topic: str) -> str:
"""生成研究问题。"""
questions = [
f"{topic}如何影响相关行业?",
f"{topic}面临的主要技术挑战是什么?",
f"{topic}的未来发展方向有哪些?",
f"如何评估{topic}的实际效果?"
]
return "潜在研究问题:\n" + "\n".join([f"{i+1}. {q}" for i, q in enumerate(questions)])
def _create_agent(self):
"""创建研究助手 Agent"""
return create_agent(
model="openai:gpt-4o",
tools=[
self.search_academic_papers,
self.summarize_research_topic,
self.compare_topics,
self.generate_research_questions
],
system_prompt="""你是一个专业的研究助手。请帮助用户:
1. 搜索相关学术文献
2. 总结研究主题和趋势
3. 比较不同研究方向
4. 生成有价值的研究问题
5. 提供研究方法和建议
请保持专业性和准确性,引用可靠的来源。
"""
)
# 使用示例
research_agent = ResearchAssistantAgent()
result = research_agent.agent.invoke({
"messages": [{"role": "user", "content": "帮我研究人工智能在医疗领域的应用"}]
})
最佳实践¶
1. Agent 设计原则¶
def create_well_designed_agent():
"""创建良好设计的 Agent"""
# 1. 明确的工具定义
@tool
def specific_tool(param1: str, param2: int = 10) -> str:
"""执行特定任务的工具。
Args:
param1: 主要参数描述
param2: 可选参数,默认值10
"""
return f"处理结果: {param1} * {param2}"
# 2. 清晰的系统提示词
system_prompt = """
你是一个专业的助手。请遵循:
- 准确回答,不编造信息
- 使用工具获取真实数据
- 对不确定的内容要说明
- 保持友好和专业
"""
# 3. 适当的中间件
@before_model
def ensure_proper_context(state, runtime):
"""确保适当的上下文"""
messages = state["messages"]
if len(messages) > 0:
last_message = messages[-1]
# 可以在这里添加上下文验证逻辑
pass
return None
# 创建 Agent
return create_agent(
model="openai:gpt-4o",
tools=[specific_tool],
system_prompt=system_prompt,
middleware=[ensure_proper_context]
)
2. 错误处理策略¶
class RobustAgent:
"""健壮的 Agent 实现"""
def __init__(self):
self.agent = self._create_robust_agent()
def _create_robust_agent(self):
"""创建健壮的 Agent"""
@wrap_tool_call
def comprehensive_error_handling(request, handler):
"""全面的错误处理"""
try:
# 参数验证
tool_call = request.tool_call
if not self._validate_tool_inputs(tool_call):
return ToolMessage(
content="参数验证失败,请检查输入格式",
tool_call_id=tool_call["id"]
)
return handler(request)
except Exception as e:
# 记录错误
print(f"工具执行错误: {e}")
# 返回用户友好的错误信息
return ToolMessage(
content="服务暂时不可用,请稍后重试",
tool_call_id=request.tool_call["id"]
)
@wrap_model_call
def model_fallback(request, handler):
"""模型调用降级策略"""
try:
return handler(request)
except Exception as e:
# 如果主要模型失败,可以在这里切换到备用模型
print(f"模型调用失败: {e}")
raise # 或实现降级逻辑
return create_agent(
model="openai:gpt-4o",
tools=[search_web, get_weather],
middleware=[comprehensive_error_handling, model_fallback]
)
def _validate_tool_inputs(self, tool_call):
"""验证工具输入参数"""
# 实现参数验证逻辑
return True
3. 性能优化¶
class OptimizedAgent:
"""性能优化的 Agent"""
def __init__(self):
self.agent = self._create_optimized_agent()
self.response_cache = {} # 简单缓存
def _create_optimized_agent(self):
"""创建性能优化的 Agent"""
@before_model
def check_cache(state, runtime):
"""检查缓存以避免重复处理"""
user_message = state["messages"][-1].content
cache_key = hash(user_message)
if cache_key in self.response_cache:
# 返回缓存响应
return self.response_cache[cache_key]
return None
@after_model
def update_cache(state, runtime):
"""更新响应缓存"""
if len(state["messages"]) > 0:
last_message = state["messages"][-1]
user_message = state["messages"][-2].content # 假设上一条是用户消息
cache_key = hash(user_message)
self.response_cache[cache_key] = {"messages": [last_message]}
return None
@wrap_tool_call
def timeout_protection(request, handler):
"""工具调用超时保护"""
import signal
import time
def timeout_handler(signum, frame):
raise TimeoutError("工具执行超时")
# 设置超时(5秒)
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(5)
try:
result = handler(request)
signal.alarm(0) # 取消超时
return result
except TimeoutError:
return ToolMessage(
content="工具执行超时,请简化请求或稍后重试",
tool_call_id=request.tool_call["id"]
)
return create_agent(
model="openai:gpt-4o",
tools=[search_web, get_weather],
middleware=[check_cache, update_cache, timeout_protection]
)
总结¶
LangChain Agents 提供了强大的AI应用构建能力:
- 灵活配置:支持多种模型、工具和提示词配置
- 强大扩展:通过中间件系统实现高度定制化
- 状态管理:内置对话状态和自定义状态管理
- 生产就绪:包含错误处理、性能优化等生产级特性
- 实时交互:支持流式传输和进度监控
通过合理设计和使用 Agents,可以构建出能够处理复杂任务、与外部系统交互并提供智能服务的AI应用系统。