小火苗变声器
65.51MB · 2026-04-16
在前一章中,我们掌握了「工具(Tools)」的开发与调用,但这种调用更偏向于“单任务执行”——用户明确指令调用某个工具,程序被动执行。而在复杂的业务场景中,用户的需求往往是模糊的、多步骤的,例如:“帮我看看某只股票现在的价格,再算一下我持有1000股的收益,最后给出卖出建议”。
此时,我们需要一个“决策者”来统筹全局,这就是 LangChain Agents(智能体) 的核心价值。Agent 以 LLM 为“大脑”,能够自主理解复杂需求、规划执行步骤、选择合适工具、反思执行结果,最终完成多步骤的复杂任务。
本章将从 Agent 的核心概念出发,拆解其工作流程,对比主流 Agent 类型,掌握初始化方法与安全防护,并通过实战构建一个能查股票、算收益的金融助理,代码简洁可复用,贴合掘金技术博客的实战风格。
引用来源:LangChain Agents 官方文档、LangChain Agent Types 官方文档
在 LangChain 中,Agent(智能体) 是一个集成了“认知能力”与“执行能力”的核心组件。它不仅仅是工具的调用者,更是任务的“规划者”和“决策者”。
Agent 的本质是 “LLM + 工具 + 决策逻辑” 的组合体:
| 特性 | Chain(链) | Agent(智能体) |
|---|---|---|
| 执行逻辑 | 固定流程,按预设顺序执行 | 动态流程,根据实时情况调整 |
| 决策能力 | 无,完全依赖开发者编写的逻辑 | 有,LLM 自主规划步骤 |
| 适用场景 | 简单、固定的单任务/多任务流水线 | 复杂、模糊、需要多步骤推理的任务 |
| 例子 | 先查天气 → 再查航班(固定顺序) | “帮我规划明天的出行”(需自主判断先做什么) |
简单来说,Chain 是“按剧本演戏”,而 Agent 是“即兴发挥”。
Agent 的工作流程遵循 ReAct(Reason + Act) 框架,这是一种让 LLM 结合推理与行动来解决问题的范式。其核心流程可以概括为 4 个循环步骤,直到满足停止条件。
为了让你更直观地理解,我们将流程拆解为以下步骤,并配合极简图例。
用户输入 → [思考] → [选择工具] → [执行工具] → [反思] → 满足条件?→ 生成回答/继续循环
思考(Reason): Agent 接收用户输入后,结合历史对话,推理出当前需要解决的子任务,判断是否需要调用工具,以及需要什么信息。
选择工具(Action Selection): Agent 根据思考结果,从已注册的工具列表中,选择最适合的工具,并生成符合格式的调用指令(包含工具名称和参数)。
执行工具(Action Execution): Agent 调用选定的工具,传入参数,执行并获取工具的返回结果。
反思(Observation & Reflection): Agent 接收工具的返回结果,分析结果是否有效、是否足够回答用户问题。
tool)和参数(tool_input)。LangChain 提供了多种 Agent 类型,分别适配不同的任务场景和 LLM 能力。选择合适的 Agent 类型,是保证任务成功执行的关键。
本节重点介绍 4 种最常用的 Agent 类型,并说明其适用场景。
| Agent 类型 | 核心特点 | 适用场景 | 依赖 LLM 能力 |
|---|---|---|---|
| Zero-shot ReAct | 最经典,无历史训练,完全依赖工具描述进行推理 | 通用场景、多工具协同、复杂推理 | 中高(需理解工具描述) |
| Self-ask with Search | 擅长多轮自问自答,逐步拆解问题 | 知识问答、需要逐步探索的问题 | 中(需擅长拆解问题) |
| Chat Conversational ReAct | 专为对话场景设计,支持记忆(Memory) | 聊天机器人、带记忆的客服助理 | 中高(需结合对话历史) |
| Structured Chat | 支持结构化工具调用,参数校验更严格 | 企业级应用、复杂参数工具 | 高(需严格遵循格式) |
description(描述)来判断如何调用工具,无需任何示例。AgentType.ZERO_SHOT_REACT_DESCRIPTION。AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION。AgentType.SELF_ASK_WITH_SEARCH。AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION。LangChain 提供了 initialize_agent 函数,这是创建 Agent 最快捷、最常用的方法。它封装了复杂的底层逻辑,只需传入 LLM、工具列表和 Agent 类型,即可一键生成可执行的 Agent。
agent.run() 或 agent.invoke() 执行用户需求。本示例使用 Zero-shot ReAct 类型,结合「计算器工具」,实现一个简单的数学计算助理。
from langchain.chat_models import ChatOpenAI
from langchain.tools import Calculator
from langchain.agents import initialize_agent, AgentType
from dotenv import load_dotenv
import os
# 1. 加载环境变量
load_dotenv()
# 2. 初始化 LLM(大脑)
llm = ChatOpenAI(
model_name="gpt-3.5-turbo",
temperature=0.1, # 智能体推理时,温度建议设低,保证逻辑严谨
openai_api_key=os.getenv("OPENAI_API_KEY")
)
# 3. 初始化工具(手脚)
tools = [Calculator()]
# 4. 快速创建 Agent
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, # 选择 Zero-shot ReAct 类型
verbose=True, # 开启详细日志,便于查看思考和执行过程
handle_parsing_errors="请检查你的输入格式,确保参数正确" # 处理解析错误
)
# 5. 执行复杂任务
task = "计算 123 的平方,加上 456 的立方,最后除以 789,结果是多少?"
result = agent.run(task)
print(f"n【最终结果】:{result}")
在 initialize_agent 中,除了必填参数,还有几个关键的可选参数需要掌握:
verbose:是否开启详细日志。开发阶段建议设为 True,可以清晰看到 Agent 的「思考-行动-观察」过程。handle_parsing_errors:当 Agent 生成的工具调用格式错误时,如何处理。可以设为字符串(错误提示)或函数(自定义处理逻辑)。max_iterations:最大循环次数。防止 Agent 陷入死循环(详见 13.5 节)。memory:传入 Memory 实例,让 Agent 具备记忆能力(如 Chat Conversational ReAct 类型)。Agent 的工作流程是一个循环,如果没有合理的停止条件,它可能会陷入无限循环(例如:工具调用失败 → 重新思考 → 再次失败 → ...)。
因此,设置 停止条件 和 循环防护 是生产环境中必不可少的步骤。
LangChain Agent 有两个核心的内置停止条件,满足其一即停止循环:
Final Answer: 开头的回答。max_iterations 设定的值。在 initialize_agent 中,通过以下参数进行循环防护:
| 参数 | 作用 | 推荐值 |
|---|---|---|
max_iterations | 设置最大循环次数 | 3-5(根据任务复杂度调整) |
early_stopping_method | 达到最大次数时的停止策略 | "force"(强制停止) |
max_execution_time | 设置最大执行时间(秒) | 60(防止长时间运行) |
# 在 initialize_agent 中添加防护参数
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
max_iterations=3, # 最多循环 3 次
early_stopping_method="force", # 达到次数后强制停止
max_execution_time=60, # 最多运行 60 秒
)
# 测试一个可能导致循环的任务(工具无法回答的问题)
try:
task = "告诉我宇宙的尽头在哪里?"
result = agent.run(task)
except Exception as e:
print(f"任务执行失败:{e}")
除了内置条件,你还可以通过自定义 AgentExecutor 来实现更复杂的停止条件(如:当工具返回特定关键词时停止)。
引用来源:LangChain Agent 停止条件文档
在开发和调试 Agent 时,仅仅看到最终结果是不够的。我们需要了解 Agent “为什么这么想”、“为什么选这个工具”,这就需要借助日志和中间步骤可视化。
最简单的方式是将 verbose=True,此时控制台会打印出完整的 ReAct 循环过程,包含 Thought、Action、Observation。
日志示例:
> Entering new AgentExecutor chain...
Thought: 我需要计算 123 的平方,应该使用计算器工具。
Action:
{
"action": "Calculator",
"action_input": "123 ** 2"
}
Observation: 15129
Thought: 现在我需要加上 456 的立方,继续使用计算器。
Action:
{
"action": "Calculator",
"action_input": "15129 + 456 ** 3"
}
Observation: 95459185
...
对于更复杂的 Agent,LangChain 官方提供了 LangSmith 平台,用于追踪、调试和可视化 LLM 应用的执行过程。
pip install langsmith
在 .env 中添加:
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=你的LangSmith密钥
LANGCHAIN_PROJECT=agent-demo
配置完成后,所有 Agent 的执行过程会自动上传到 LangSmith 平台。你可以在网页上看到:
这对于生产环境的问题排查和性能优化至关重要。
引用来源:LangSmith 官方文档
尽管 Agent 很强大,但它并非万能的。了解其局限性,能帮助我们在实际开发中避坑,并设计更稳健的系统。
现象:用户问“查一下天气”,Agent 不知道调用哪个工具(或传什么参数)。 原因:工具描述中未明确说明参数要求。 解决方案:严格遵循 12.5 节的工具描述模板,清晰说明功能、参数、适用场景。
现象:Agent 生成的 Action 不是合法的 JSON。
原因:LLM 生成内容时偶尔会出现格式错误。
解决方案:设置 handle_parsing_errors 参数,捕获错误并让 Agent 重试。
现象:Agent 反复调用“查股票”工具,因为股票代码输入错误,一直返回“无效代码”。 原因:Agent 没有判断出是参数错误,而是认为工具执行失败。 解决方案:
max_iterations,设置强制停止。结合本章所学,我们将实战构建一个 金融助理 Agent。该 Agent 能够:
pip install langchain openai python-dotenv
创建 .env 文件:
OPENAI_API_KEY=你的OpenAI API密钥
from langchain.chat_models import ChatOpenAI
from langchain.tools import tool, Calculator
from langchain.agents import initialize_agent, AgentType
from pydantic import BaseModel, Field, validator
from dotenv import load_dotenv
import os
# ---------------------- 1. 加载环境变量 ----------------------
load_dotenv()
# ---------------------- 2. 自定义工具:股票查询工具 ----------------------
# 定义输入模型,校验股票代码
class StockQueryInput(BaseModel):
stock_code: str = Field(description="股票代码,如 600519(贵州茅台)、000858(五粮液)")
@validator("stock_code")
def valid_code(cls, v):
valid_codes = ["600519", "000858", "601318"]
if v not in valid_codes:
raise ValueError(f"暂不支持该股票,支持的代码:{valid_codes}")
return v
# 模拟股票行情数据
STOCK_DATA = {
"600519": {"name": "贵州茅台", "price": 1800.0},
"000858": {"name": "五粮液", "price": 140.0},
"601318": {"name": "中国平安", "price": 50.0}
}
@tool(
name="get_stock_price",
description="用于查询中国A股股票的实时价格,输入参数为股票代码(如600519),返回股票名称和当前价格。",
args_schema=StockQueryInput
)
def get_stock_price(stock_code: str) -> str:
"""获取股票实时价格"""
stock = STOCK_DATA.get(stock_code)
return f"股票名称:{stock['name']},实时价格:{stock['price']} 元/股"
# ---------------------- 3. 初始化核心组件 ----------------------
# 1. LLM
llm = ChatOpenAI(
model_name="gpt-3.5-turbo",
temperature=0.1,
openai_api_key=os.getenv("OPENAI_API_KEY")
)
# 2. 工具列表(股票查询 + 计算器)
tools = [get_stock_price, Calculator()]
# 3. 初始化 Agent(带循环防护)
financial_agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True,
max_iterations=3,
early_stopping_method="force",
handle_parsing_errors="参数格式错误,请重新检查股票代码。"
)
# ---------------------- 4. 执行实战任务 ----------------------
print("=== 金融助理 Agent 实战 ===")
# 任务:复杂的多步骤金融计算
user_task = "我持有 1000 股贵州茅台(代码600519),买入成本是每股 1000 元,帮我算一下现在赚了多少钱?"
try:
result = financial_agent.run(user_task)
print(f"n 助理回答:{result}")
except Exception as e:
print(f"n 任务执行失败:{e}")
运行代码后,你将在控制台看到清晰的 ReAct 循环过程:
get_stock_price 工具,参数 600519。(1800 - 1000) * 1000,调用 Calculator 工具。最终输出:
助理回答:你持有1000股贵州茅台,当前每股价格为1800元,买入成本为每股1000元,每股盈利800元,总盈利为800000元。
本实战是基础版本,你可以根据业务需求进行以下拓展:
STOCK_DATA 替换为新浪财经、东方财富等真实的股票行情 API。Chat Conversational ReAct 类型,让 Agent 记住用户的持仓信息,下次用户只需问“我的茅台又赚了多少?”。本章我们系统学习了 LangChain Agents 的基础核心知识,关键要点如下:
Zero-shot ReAct,对话场景选 Chat Conversational ReAct。initialize_agent 函数,一键生成 Agent。max_iterations 等参数,防止无限循环。verbose 日志或使用 LangSmith 进行可视化调试。下一章,我们将进入 Agent 进阶 内容,学习如何构建多智能体协作系统、自定义 Agent 以及处理更复杂的业务逻辑。