🤖 LangChain Agent 深度实战:从原理到构建自定义智能体

摘要: 在大模型应用开发中,RAG(检索增强生成)解决了模型“知识陈旧”的问题,而 Agent(智能体)则赋予了大模型“使用工具”和“规划任务”的能力。本文将深入 LangChain Agent 的核心机制,通过 Python 代码实战演示如何构建具备联网搜索、计算能力的智能体,并探讨如何利用 LangSmith 进行调试与优化,这是通往 AGI(通用人工智能)架构的关键一步。

1. 前言:为什么我们需要 Agent?

如果你使用过 ChatGPT,你会发现它擅长聊天,但在需要实时数据(如“现在的天气如何”)或精确计算(“12345 乘以 67890 等于多少”)时,它往往会一本正经地胡说八道。

Agent 的核心思想是:LLM 是大脑,但它需要手(工具)和眼睛(感知)。
LangChain Agent 的工作流程通常是:

  • 感知:接收用户指令。
  • 推理:LLM 分析指令,决定下一步动作(是回答问题,还是调用工具)。
  • 行动:调用外部工具(API、数据库、函数)。
  • 观察:获取工具的返回结果。
  • 重复:基于结果继续推理,直到任务完成。
    这个过程在 LangChain 中通过 ReAct (Reason + Act) 模式实现。

2. 核心组件解析

在开始写代码前,我们需要理解 LangChain Agent 的“三剑客”:

  • LLM(大语言模型): 负责思考和决策。推荐使用支持 Function Calling 的模型(如 GPT-4, GPT-3.5-turbo, Claude 3),效果远好于纯文本模型。
  • Tools(工具集): Agent 可以调用的函数集合。LangChain 内置了数百种工具,如 SerpAPI(搜索)、Requests(HTTP请求)、PythonREPL(代码执行)。
  • Agent Executor(执行器): 这是一个运行时环境,负责处理 Agent 的循环、解析模型的输出、传递工具参数以及处理异常。

3. 实战一:构建一个全能信息助手

我们将构建一个能够联网搜索和执行复杂数学运算的 Agent。

3.1 环境准备
pip install langchain langchain-openai langchain-community google-search-results numexpr

配置环境变量(.env):

OPENAI_API_KEY=sk-...
SERPAPI_API_KEY=...  # 用于 Google 搜索
LANGCHAIN_TRACING_V2=true
LANGCHAIN_API_KEY=... # 开启 LangSmith 调试(强烈推荐)
3.2 定义工具

我们需要自定义一个计算工具,并加载一个搜索工具。

from langchain_openai import ChatOpenAI
from langchain.agents import initialize_agent, AgentType
from langchain.tools import Tool
from langchain_community.utilities import SerpAPIWrapper
import os
from dotenv import load_dotenv

load_dotenv()

# 1. 定义计算器工具
def calculator(expression):
    """简单的数学计算工具,仅用于演示,生产环境请限制代码执行权限"""
    try:
        # 这里使用 Python 的 eval,生产环境建议用 numexpr 或 ast 解析更安全
        return f"计算结果: {eval(expression)}"
    except Exception as e:
        return f"计算错误: {str(e)}"

calc_tool = Tool(
    name="高级计算器",
    func=calculator,
    description="用于计算数学表达式,输入必须是数学公式字符串,例如 '12 * 5' 或 '100 / 20'"
)

# 2. 定义搜索工具 (使用 SerpAPI)
search = SerpAPIWrapper()
search_tool = Tool(
    name="实时搜索",
    func=search.run,
    description="用于获取实时信息,例如天气、新闻、股票价格。输入应该是搜索查询字符串。"
)

tools = [search_tool, calc_tool]
3.3 初始化 Agent

我们使用 ZERO_SHOT_REACT 描述,这意味着 Agent 不需要示例,直接根据工具描述进行零样本推理。

# 初始化 LLM
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

# 初始化 Agent
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,  # 打印思考过程,Debug 必备
    handle_parsing_errors=True  # 自动修复 LLM 输出的格式错误
)

print("Agent 已就绪,开始提问...")
3.4 运行与观察

让我们问一个既需要搜索又需要计算的问题。

query = "苹果公司现在的股价是多少?如果我有100股,价值多少美元?"
response = agent.invoke(query)

print(f"\n最终答案: {response['output']}")

运行日志解析(Verbose 输出):
你会看到类似这样的思考链:

Thought: 我需要先查询苹果公司的股价。
Action: 实时搜索
Action Input: “Apple stock price”
Observation: 175.50 USD
Thought: 我已经知道了股价,现在我需要计算100股的总价值。
Action: 高级计算器
Action Input: “175.50 * 100”
Observation: 计算结果: 17550.0
Thought: 我现在知道了最终答案。
Final Answer: 如果你有100股苹果股票,按照当前股价175.50美元计算,总价值为17550美元。

4. 实战二:利用 LangChain 表达式语言 (LCEL) 构建现代 Agent

除了传统的 initialize_agent,LangChain 现在更推荐使用 LCEL 来构建更灵活的 Agent,这给了开发者对 Prompt 和中间流更细粒度的控制。

from langchain import hub
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_openai import ChatOpenAI

# 1. 获取一个预设的 Prompt 模板(也可以自定义)
# LangChain Hub 提供了许多经过验证的 Prompt 模板
prompt = hub.pull("hwchase17/openai-functions-agent")

# 2. 定义 LLM(必须支持 Tool Calling)
llm = ChatOpenAI(model="gpt-4", temperature=0)

# 3. 构造 Agent
# create_tool_calling_agent 是 LCEL 风格的构建方式
agent = create_tool_calling_agent(llm, tools, prompt)

# 4. 创建执行器
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

# 执行
result = agent_executor.invoke({"input": "帮我查一下北京现在的天气,然后换算成华氏度。"})

这种方式的优势在于,你可以很容易地将 prompt 替换为自己的版本,或者在 agent 和 executor 之间插入自定义的中间件逻辑。

5. 生产环境下的 Agent 调试与优化

开发 Agent 最痛苦的时刻往往是它“发疯”的时候——无限循环、调用错误的工具、或者因为网络超时而崩溃。以下是几个生产实践建议:

5.1 使用 LangSmith 可视化调试

LangSmith 是 LangChain 官方推出的调试平台。它能可视化 Agent 的每一步思考、每个工具的输入输出以及耗时。

在代码中加入:

os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "My-Agent-Project"

通过 LangSmith 的 UI,你可以精准地发现 Agent 是在哪一步出了逻辑错误。

5.2 设置最大迭代次数

防止 Agent 在死循环中浪费 Token 资源。

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    max_iterations=5, # 最多思考5步
    max_execution_time=60, # 最多执行60秒
    early_stopping_method="generate" # 超时后直接让 LLM 生成结果,而不是报错
)

5.3 记忆管理
Agent 默认是无状态的。如果需要多轮对话,需要引入 Memory 组件。

from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)

# 在 initialize_agent 中加入 memory 参数
agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory,
    verbose=True
)

6. 总结

LangChain Agent 将大模型从单纯的“文本生成器”升级为“任务执行者”。本文介绍了 Agent 的核心原理,并通过代码演示了如何构建一个具备搜索和计算能力的智能体。

在未来的开发中,Agent 将会更加自动化和自主化。掌握 Agent 的构建与调试,是每一位 AI 工程师从“Prompt 调优师”迈向“AI 系统架构师”的必经之路。

参考资源: LangChain 官方文档, LangSmith Hub

希望这篇文章能帮助你打开 Agent 开发的大门!如有问题,欢迎在评论区交流。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐