LangChain 实战:Agent 思维框架与代码实现
前言
大型语言模型(LLM)虽然具备强大的自然语言理解和生成能力,但其本质是基于训练数据预测下一个 token。这意味着它存在几个固有局限:无法访问实时信息、缺乏特定领域知识库、无法执行外部操作(如搜索、计算、调用 API)。为了解决这些问题,我们需要引入'外部工具'。当大模型需要通过自主判断调用外部工具来进一步完成任务时,LangChain 提供了 Agent(代理)模块。
Agent 的核心思想是让大模型像人类一样,通过观察环境、思考决策、采取行动来解决问题。在 LangChain 中,Agent 充当了连接大模型与外部工具的桥梁。
Agent 核心概念
Agent 是一个抽象概念,当 LLM 无法仅凭自身内部知识准确回复用户请求时,Agent 会协助其调用外部工具。除了基础的代理概念外,LangChain 提供了一系列常用的 Agent 实现,例如用于数据库查询的 create_sql_agent,以及本文重点介绍的基于 ReAct 框架的通用 Agent。
我们可以从以下几个维度理解 Agent 的工作机制:
1. 大模型(LLM)
大模型是 Agent 的大脑。在 Agent 的工作过程中,LLM 负责逻辑推理、任务拆解和决策生成。它接收用户的输入和当前的状态信息,输出下一步的行动指令。
2. 外部工具(Tools)
工具是 Agent 的手脚。这包括接口调用、文件处理、搜索引擎、计算器等。LangChain 封装了多种常用工具,开发者也可以自定义工具函数。
3. 控制交互的代理(Controller)
这是 Agent 的管家。当有多个代理协作时,负责调度分配任务。对于单个 Agent,它负责决定何时调用哪个工具,以及如何解析工具返回的结果。
ReAct 思维框架
ReAct(Reasoning + Acting)是 Agent 工作的核心思维框架。它模拟了人类解决问题的过程:先思考(Reasoning),再行动(Acting),然后根据观察结果再次思考。
以开发一个智能定价 Agent 为例:
- 行动(Action):去批发网查找今天的干货成本价。
- 观察(Observation):获取到当前价格为 4.2 元。
- 思考(Thought):根据成本价决定加价幅度,比如加价 20%。
- 行动(Action):使用计算器计算最终售价。
- 最终答案:输出定价建议。
这种'观察 - 思考 - 行动'的循环,将人类学习新任务并做出决策的能力赋予了 LLM。LangChain 的 Agent 类对 ReAct 进行了封装和实现,使得大模型获得了极大的自主性。
干货定价 Agent 代码实现
下面我们通过一个完整的 Demo,开发一个 Agent,帮助找到大蒜子的当前市场价格,并自动计算加价 20% 后的销售价格。
1. 安装依赖
首先,我们需要安装 LangChain 及相关工具库。
pip install langchain
pip install openai
pip install google-search-results
这里我们使用了 SerpAPI,它是 Agent 需要的 Google 搜索工具,用于找出大蒜子的价格。同时需要 llm-math 工具来进行数学计算。
2. 配置 API Key
为了使用 OpenAI 的大模型和 SerpAPI 的搜索服务,需要配置环境变量。
import os
os.environ["OPENAI_API_KEY"] = "Your_OpenAI_API_Key_Here"
os.environ["SERPAPI_API_KEY"] = "Your_SerpAPI_Key_Here"
3. 导入必要的库
我们需要加载工具、初始化 Agent 以及指定使用的 LLM。
# 加载工具
from langchain.agents import load_tools
# 初始化 agent 工具
from langchain.agents import initialize_agent
from langchain.agents import AgentType
# 导入 LLM
from langchain.llms import OpenAI
4. 实例化 LLM,加载工具,生成 Agent
这一步是核心。我们定义温度参数,加载搜索和计算工具,并选择 Zero-Shot ReAct 策略。
# 实例化 LLM,temperature=0 表示输出更确定
llm = OpenAI(temperature=0)
# 加载工具:serpapi 负责搜索,llm-math 负责计算 20%
tools = load_tools(["serpapi", "llm-math"], llm=llm)
# 初始化 Agent
# ZERO_SHOT_REACT_DESCRIPTION 的意思是使用 react 思维框架、不使用样本
agent = initialize_agent(
tools,
llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
5. 执行并拿到结果
运行 Agent,传入自然语言指令。
result = agent.run("目前市场上大蒜子的平均价格是多少?如果我在此基础上加价 20% 卖出,应该如何定价?")
print(result)
6. 运行日志分析
大模型根据 ReAct 框架,会自动生成如下推理链条:
> Entering new chain...
I need to find the current market price of garlic and then calculate the new price with a 20% markup.
Action: Search
Action Input: "Average price of garlic"
Observation: According to the study, the average price for garlic in Shandong is 4.2.
Thought: I need to calculate the new price with a 20% markup.
Action: Calculator
Action Input: 4.2 * 1.2
Observation: Answer: 5.04
Thought: I now know the final answer.
Final Answer: The new price with a 20% markup would be 5.04.
> Finished chain.
可以看到,Agent 自动完成了搜索、思考、计算三个步骤,无需人工干预中间过程。
进阶:自定义工具与多 Agent 协作
自定义工具
LangChain 允许开发者编写自己的 Python 函数并将其注册为工具。这对于业务特定的逻辑非常有用。
from langchain.tools import BaseTool
class MyCustomTool(BaseTool):
name = "custom_search"
description = "用于查询特定内部系统的数据"
def _run(self, query: str):
# 这里可以写具体的业务逻辑
return f"查询结果:{query}"
def _arun(self, query: str):
raise NotImplementedError("This tool does not support async run.")
# 注册工具
my_tool = Tool(
name="MyCustomTool",
func=my_custom_function,
description="..."
)
多 Agent 协作
除了单个 Agent,我们还可以同时使用多个 Agents。一个 Agent 的输出可以作为另一个 Agent 的输入。这便于将复杂任务分步细致地解决。例如,一个 Agent 负责数据收集,另一个 Agent 负责数据分析。
常见 Agent 类型对比
在 LangChain 中,不同的 Agent 类型适用于不同的场景:
- Zero-Shot React: 不需要示例,直接根据工具描述进行推理。适合通用任务,但可能不够精准。
- Few-Shot React: 提供少量示例(Prompt 中包含问答对),引导模型模仿。适合特定格式或复杂逻辑的任务。
- Conversational React: 支持对话历史记忆,适合客服、助手类应用。
- Self-Ask: 让模型自己提出问题并搜索答案,适合需要多步检索的复杂问题。
常见问题与调试技巧
在实际开发 Agent 时,可能会遇到以下问题:
- 死循环:Agent 可能在思考和行动之间无限循环。可以通过设置
max_iterations参数限制最大步数。 - 幻觉:模型可能编造工具输入。需要在 Prompt 中强调必须使用提供的工具。
- 超时:网络请求可能失败。建议增加重试机制或使用异步调用。
最佳实践
- Prompt Engineering:优化 Agent 的系统提示词,明确工具的使用边界。
- 工具描述:为每个工具编写清晰、准确的描述,帮助 LLM 理解何时调用。
- 错误处理:捕获工具调用的异常,并反馈给 LLM 以便其调整策略。
总结
驱动 Agent 工作的是 ReAct 思想框架。通过结合大模型的推理能力和外部工具的执行力,Agent 能够完成复杂的任务闭环。
在实际应用中,需要注意以下几点:
- 成本控制:每次调用都会消耗 Token,需合理设计 Prompt 和工具调用次数。
- 安全性:确保调用的工具不会执行危险操作(如删除文件)。
- 稳定性:网络请求可能失败,需要增加重试机制。
LangChain 的 Agent 模块极大地扩展了大模型的应用边界,使其从单纯的对话机器人转变为能够执行任务的智能助手。随着技术的发展,未来我们将看到更多自主规划、多模态交互的 Agent 出现。


