🎯 Agent 基础
深入理解 LangChain 1.0 的 Agent 系统,掌握 create_agent() 函数和 ReAct 模式, 构建智能、自主的 AI Agent。
📚 什么是 Agent?
Agent(智能体)是一个能够自主推理并采取行动的 AI 系统。 与简单的 LLM 调用不同,Agent 可以:
- 推理:分析任务,制定计划
- 行动:调用工具与外部系统交互
- 观察:获取工具执行结果
- 迭代:基于结果调整策略,直到完成任务
| 特性 | 简单 LLM 调用 | Agent |
|---|---|---|
| 推理能力 | 单次推理 | 多轮推理和规划 |
| 工具使用 | 无 | 可调用多个工具 |
| 执行模式 | 一次性输入输出 | 循环执行直到完成 |
| 复杂度 | 简单任务 | 复杂、多步骤任务 |
🔄 ReAct 模式(Reasoning + Acting)
LangChain Agent 采用 ReAct 模式,结合推理和行动:
ReAct 流程示例
假设用户问:"找到最受欢迎的无线耳机并检查库存"
步骤 1 - 推理:流行度是时效性的,需要搜索最新数据
步骤 2 - 行动:调用 search_products("wireless headphones")
步骤 3 - 观察:获得前 5 个结果,第一名是 WH-1000XM5
步骤 4 - 推理:需要确认该产品的库存情况
步骤 5 - 行动:调用 check_inventory("WH-1000XM5")
步骤 6 - 观察:库存 10 件
步骤 7 - 最终答案:
"WH-1000XM5 是目前最受欢迎的无线耳机,库存 10 件。"
- 透明性:可以看到 Agent 的推理过程
- 可控性:每步都有明确的输入输出
- 可调试:容易定位问题环节
- 高效性:只在需要时调用工具
⚙️ create_agent() 函数详解
create_agent() 是 LangChain 1.0 创建 Agent 的核心函数。
它构建了一个基于 LangGraph 的图形化运行时。
基础用法
"""
create_agent() 基础示例
功能:创建一个带搜索和天气工具的简单 Agent
"""
from langchain.agents import create_agent
from langchain.tools import tool
# 定义工具
@tool
def search(query: str) -> str:
"""搜索信息"""
return f"搜索结果:{query}"
@tool
def get_weather(location: str) -> str:
"""获取天气信息"""
return f"{location} 的天气:晴朗,22°C"
# 创建 Agent
agent = create_agent(
model="gpt-4", # 模型标识符(字符串)
tools=[search, get_weather], # 工具列表
system_prompt="你是一个有用的助手。请简洁准确地回答问题。"
)
# 调用 Agent
result = agent.invoke({
"messages": [{"role": "user", "content": "旧金山今天天气怎么样?"}]
})
print(result["messages"][-1].content)
核心参数说明
| 参数 | 类型 | 说明 | 示例 |
|---|---|---|---|
model |
str 或 ChatModel | 推理引擎 | "gpt-4" 或 ChatOpenAI() |
tools |
list | 可用工具列表 | [tool1, tool2] |
system_prompt |
str | Agent 行为指南 | "你是专业的助手" |
middleware |
list | 扩展钩子 | [custom_middleware] |
state_schema |
TypedDict | 自定义状态结构 | CustomState |
response_format |
Strategy | 结构化输出 | ToolStrategy(Model) |
高级配置:完整控制
"""
create_agent() 高级配置示例
功能:使用 ChatModel 实例进行精细控制
"""
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def calculator(expression: str) -> str:
"""计算数学表达式"""
try:
result = eval(expression) # 仅用于演示,生产环境需安全处理
return f"计算结果:{result}"
except Exception as e:
return f"计算错误:{str(e)}"
# 使用 ChatModel 实例进行精细配置
model = ChatOpenAI(
model="gpt-4",
temperature=0.1, # 降低随机性,提高准确性
max_tokens=1000, # 限制输出长度
timeout=30, # 设置超时时间(秒)
max_retries=2 # 失败重试次数
)
# 创建 Agent
agent = create_agent(
model=model,
tools=[calculator],
system_prompt="""你是一个精确的数学助手。
职责:
1. 使用 calculator 工具计算数学表达式
2. 解释计算步骤
3. 确保结果准确无误
注意:
- 只处理数学相关的问题
- 对于非数学问题,礼貌地拒绝"""
)
# 测试
result = agent.invoke({
"messages": [{"role": "user", "content": "计算 (123 + 456) * 2 等于多少?"}]
})
print(result["messages"][-1].content)
📝 system_prompt 设计技巧
system_prompt 定义了 Agent 的行为、角色和工作方式。
好的提示词是成功 Agent 的关键。
提示词结构模板
"""
优秀的 system_prompt 模板
"""
SYSTEM_PROMPT = """# 角色定义
你是 [角色名称],专门负责 [主要职责]。
# 核心职责
1. [职责1]
2. [职责2]
3. [职责3]
# 工作流程
当用户提出请求时:
- 步骤1:[分析需求]
- 步骤2:[调用工具]
- 步骤3:[整合结果]
- 步骤4:[生成回复]
# 工具使用
你有以下工具可用:
- tool1:[用途和使用时机]
- tool2:[用途和使用时机]
# 回复风格
- 简洁:直接回答问题
- 准确:基于工具返回的实际数据
- 友好:保持礼貌和专业
# 限制和注意事项
- 不要:[禁止行为]
- 必须:[强制要求]
- 如果遇到 [情况],则 [处理方式]
"""
# 使用示例
from langchain.agents import create_agent
agent = create_agent(
model="gpt-4",
tools=[...],
system_prompt=SYSTEM_PROMPT
)
动态 system_prompt
根据用户角色或上下文动态生成提示词:
"""
动态 system_prompt 示例
功能:根据用户角色生成不同的提示词
"""
from langchain.agents.middleware import dynamic_prompt, ModelRequest
from langchain.agents import create_agent
@dynamic_prompt
def user_role_prompt(request: ModelRequest) -> str:
"""根据用户角色生成系统提示词"""
# 从运行时上下文获取用户角色
user_role = request.runtime.context.get("user_role", "user")
base = "你是一个有用的技术助手。"
if user_role == "expert":
return f"""{base}
用户是技术专家,你应该:
- 提供深入的技术细节
- 使用专业术语
- 假设用户了解基础概念
- 直接给出高级解决方案"""
elif user_role == "beginner":
return f"""{base}
用户是初学者,你应该:
- 用简单的语言解释概念
- 避免复杂的术语
- 提供步骤化的指导
- 多给示例和类比"""
else:
return f"""{base}
提供平衡的技术解释,适合一般开发者。"""
# 创建 Agent
agent = create_agent(
model="gpt-4",
tools=[...],
middleware=[user_role_prompt]
)
# 调用时提供用户角色
result = agent.invoke(
{"messages": [{"role": "user", "content": "什么是 Agent?"}]},
context={"user_role": "beginner"} # 指定用户角色
)
- 明确性:清楚定义 Agent 应该做什么
- 具体性:给出具体的指令和示例
- 结构化:使用标题、列表组织内容
- 限制性:说明 Agent 不应该做什么
- 可测试:提示词应该可以被验证和改进
🔄 Agent 执行流程
停止条件
Agent 在以下情况下停止执行:
- 模型输出最终答案:LLM 决定不再需要工具
- 达到迭代上限:防止无限循环
- 工具执行失败:无法继续时优雅退出
- 用户中断:Human-in-the-loop 场景
📡 流式输出 Agent
对于多步骤任务,使用流式输出可以实时看到 Agent 的中间步骤:
"""
Agent 流式输出示例
功能:实时显示 Agent 的推理和工具调用过程
"""
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search(query: str) -> str:
"""搜索 AI 相关新闻"""
return f"找到关于 '{query}' 的最新新闻..."
# 创建 Agent
agent = create_agent(
model="gpt-4",
tools=[search],
system_prompt="你是新闻助手,帮助用户搜索最新资讯。"
)
# 流式调用 Agent
print("=== Agent 执行过程 ===\n")
for chunk in agent.stream(
{"messages": [{"role": "user", "content": "搜索最新的 AI 新闻"}]},
stream_mode="values" # 流式模式
):
# 获取最新消息
latest_message = chunk["messages"][-1]
# 如果是文本内容
if latest_message.content:
print(f"💬 Agent: {latest_message.content}")
# 如果是工具调用
elif hasattr(latest_message, 'tool_calls') and latest_message.tool_calls:
tool_names = [tc['name'] for tc in latest_message.tool_calls]
print(f"🔧 调用工具: {', '.join(tool_names)}")
print("\n=== 执行完成 ===")
预期输出
=== Agent 执行过程 ===
💬 Agent: 让我帮你搜索最新的 AI 新闻
🔧 调用工具: search
💬 Agent: 找到关于 'AI' 的最新新闻...
💬 Agent: 根据搜索结果,这里是最新的 AI 新闻摘要...
=== 执行完成 ===
🛡️ 工具错误处理
使用中间件处理工具执行中的错误,提供更好的用户体验:
"""
工具错误处理示例
功能:优雅地处理工具执行错误
"""
from langchain.agents.middleware import wrap_tool_call
from langchain.messages import ToolMessage
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def divide(a: float, b: float) -> float:
"""除法运算"""
return a / b # 可能抛出 ZeroDivisionError
# 定义错误处理中间件
@wrap_tool_call
def handle_tool_errors(request, handler):
"""捕获并优雅地处理工具执行错误"""
try:
# 执行工具
return handler(request)
except ZeroDivisionError:
# 除零错误
return ToolMessage(
content="错误:除数不能为零。请检查输入参数。",
tool_call_id=request.tool_call["id"]
)
except Exception as e:
# 其他错误
return ToolMessage(
content=f"工具执行失败:{str(e)}。请检查输入并重试。",
tool_call_id=request.tool_call["id"]
)
# 创建带错误处理的 Agent
agent = create_agent(
model="gpt-4",
tools=[divide],
middleware=[handle_tool_errors], # 应用错误处理中间件
system_prompt="你是数学助手。如果工具执行失败,请向用户解释问题并建议解决方案。"
)
# 测试:正常情况
print("=== 正常情况 ===")
result1 = agent.invoke({
"messages": [{"role": "user", "content": "10 除以 2 等于多少?"}]
})
print(result1["messages"][-1].content)
# 测试:除零错误
print("\n=== 除零错误 ===")
result2 = agent.invoke({
"messages": [{"role": "user", "content": "10 除以 0 等于多少?"}]
})
print(result2["messages"][-1].content)
🐛 Agent 调试技巧
1. 启用详细日志
import logging
# 启用 LangChain 日志
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("langchain")
logger.setLevel(logging.DEBUG)
2. 使用 LangSmith 追踪
import os
# 配置 LangSmith
os.environ["LANGSMITH_API_KEY"] = "your-key"
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_PROJECT"] = "agent-debugging"
# 之后的 Agent 调用会自动追踪
3. 检查中间状态
# 使用流式输出查看每一步
for chunk in agent.stream(input_data, stream_mode="values"):
print(f"步骤: {chunk}")
print(f"消息数: {len(chunk['messages'])}")
print(f"最新消息: {chunk['messages'][-1]}")
print("-" * 50)
常见问题排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| Agent 一直调用同一个工具 | 工具返回值不清晰 | 改进工具描述和返回格式 |
| Agent 不调用工具 | system_prompt 不明确 | 明确指示何时使用工具 |
| 输出格式不一致 | 缺少结构化输出 | 使用 response_format 参数 |
| 执行超时 | 无限循环或工具慢 | 设置迭代上限和超时 |
❓ 常见问题
Q1: Agent 可以不使用工具吗?
可以。传递空的工具列表 tools=[] 会创建一个纯 LLM 节点,
只进行推理不执行行动。
Q2: 如何限制 Agent 的迭代次数?
目前 LangChain 1.0 有默认的迭代限制。如需自定义,可以通过中间件实现:
from langchain.agents.middleware import before_agent
@before_agent
def limit_iterations(state, runtime):
"""限制 Agent 迭代次数"""
max_iterations = 10
current = len([m for m in state["messages"] if m.type == "ai"])
if current >= max_iterations:
raise ValueError(f"达到最大迭代次数 {max_iterations}")
return state
Q3: 如何在运行时动态选择模型?
使用 @wrap_model_call 中间件根据对话状态选择模型。
详见 中间件系统 章节。
Q4: Agent 状态如何持久化?
使用 checkpointer 参数。详见 LangGraph 集成 章节。