基于LangChain构建具备ReAct能力的AI Agent:从原理到实践

📅 2026/7/5 2:30:12
基于LangChain构建具备ReAct能力的AI Agent:从原理到实践
30款热门AI模型一站整合DeepSeek/GLM/Qwen 随心用限时 5 折。 点击领海量免费额度在实际 AI 应用开发中我们经常听到“AI Agent”这个概念它被描绘成能够自主理解、规划和执行复杂任务的智能体。然而对于许多开发者而言这个概念往往停留在理论层面感觉无从下手。本文将以 LangChain 框架为核心深入解析其工作机制并带领你从零开始动手构建一个具备“思考-行动-观察”ReAct能力的 AI Agent。通过本文你将不仅理解 LangChain 如何将大语言模型LLM与工具Tools、记忆Memory等组件连接起来更能亲手实现一个可以与环境交互、解决实际问题的智能体原型。1. 理解 AI Agent 与 LangChain 的核心机制在动手之前我们需要先厘清几个核心概念理解 LangChain 在整个架构中扮演的角色。1.1 什么是 AI AgentAI Agent 并非一个全新的魔法黑盒。简单来说它是一个能够感知环境、自主决策并执行动作以实现特定目标的软件实体。其核心在于“自主性”和“目标导向”。与我们熟悉的、仅根据输入生成输出的聊天机器人不同一个真正的 Agent 应该能够思考Reason分析当前状况和任务目标。行动Act调用外部工具如搜索引擎、计算器、API来获取信息或改变环境。观察Observe接收行动的结果并将其作为新的输入进入下一轮思考。这个经典的循环就是ReAct (Reasoning Acting)框架。它让 LLM 不再只是“说”而是能够“做”。1.2 LangChain 在 Agent 构建中解决了什么问题直接使用原始 LLM API 构建 Agent 是极其繁琐的。你需要手动拼接提示词Prompt、解析 LLM 的输出以判断下一步是“思考”还是“调用工具”、管理工具调用的输入输出格式、维护对话历史记忆等等。LangChain 将这些通用、复杂的工程问题抽象成了可复用的组件和链Chain。具体来说LangChain 为 Agent 开发提供了以下关键支撑工具Tools抽象将任何函数如搜索、计算、数据库查询包装成 Agent 可以理解和调用的标准化工具。智能体Agent执行器核心驱动引擎。它负责将用户输入、历史记忆、可用工具列表组合成提示词交给 LLM然后解析 LLM 的回复决定下一步是生成最终答案还是调用某个工具并循环执行这个过程。记忆Memory管理提供多种记忆后端如对话缓冲区、向量存储让 Agent 能够记住之前的交互。提示词Prompt模板化将复杂的、包含工具描述和格式要求的提示词结构化便于管理和迭代。可以这样理解LangChain 是构建 AI Agent 的“脚手架”和“工具箱”它定义了组件之间如何连接和协作的标准协议让我们能更专注于业务逻辑本身。1.3 LangChain 与 LangGraph 的区别在相关讨论中你可能会遇到 LangGraph。简单来说LangChain 更侧重于线性的、链式的调用流程而LangGraph 是建立在 LangChain 之上的一个库用于构建有状态的、循环的、多分支的复杂工作流它天然适合描述 Agent 的 ReAct 循环。对于入门而言我们先从 LangChain 的基础 Agent 开始理解其内部已经实现了 ReAct 的逻辑。当你需要构建涉及多个 Agent 协作或更复杂决策图的应用时LangGraph 是更强大的选择。2. 环境准备与依赖配置我们将使用 Python 作为开发语言并选择 OpenAI 的 GPT 模型作为 LLM 驱动核心。请确保你已准备好可用的 OpenAI API Key。2.1 基础环境要求Python: 版本 3.8 或更高。包管理工具: pip 或 conda。网络: 能够访问 OpenAI API请注意使用合规的 API 服务是开发者的责任。2.2 创建项目并安装依赖首先创建一个干净的目录并初始化虚拟环境这是管理项目依赖的最佳实践。# 创建项目目录 mkdir langchain-agent-demo cd langchain-agent-demo # 创建并激活虚拟环境 (以 venv 为例) python -m venv venv # Windows venv\Scripts\activate # Linux/Mac source venv/bin/activate接下来安装核心依赖。我们将安装langchain核心库、用于调用 OpenAI 的langchain-openai集成包以及一个用于模拟搜索工具的duckduckgo-search包。pip install langchain langchain-openai duckduckgo-search注意langchain-community包含了许多社区维护的工具和集成但为了依赖清晰我们按需安装。duckduckgo-search是一个无需 API Key 的搜索工具包适合演示。2.3 配置 API 密钥为了安全起见不要将 API 密钥硬编码在代码中。推荐使用环境变量进行管理。# 在命令行中临时设置环境变量 (Linux/Mac) export OPENAI_API_KEYyour-openai-api-key-here # Windows (PowerShell) $env:OPENAI_API_KEYyour-openai-api-key-here你也可以创建一个.env文件使用python-dotenv包来加载。这里我们为了简化假设已在环境变量中配置好。3. 构建你的第一个 ReAct Agent我们将构建一个能够回答实时信息的 Agent例如“今天北京的天气如何”或“特斯拉最新的股价是多少”。它需要学会在不知道答案时使用搜索工具去查找。3.1 定义工具Tools工具是 Agent 的手臂。我们先定义一个简单的搜索工具和一个计算器工具。# tool_definitions.py from langchain.tools import Tool from duckduckgo_search import DDGS import math def search_online(query: str) - str: 使用 DuckDuckGo 搜索网络信息。 try: with DDGS() as ddgs: # 获取最相关的几条结果并拼接 results [r[body] for r in ddgs.text(query, max_results2)] return \n.join(results) if results else 未找到相关信息。 except Exception as e: return f搜索过程中出现错误{e} def calculate(expression: str) - str: 执行安全的数学表达式计算。支持 , -, *, /, **, sqrt 等。 示例3 * 4 5 或 sqrt(16) try: # 警告使用 eval 有安全风险此处仅用于演示。 # 生产环境中必须使用更安全的替代方案如 ast.literal_eval 或专用库。 # 这里进行简单限制仅允许数学表达式中的常见字符。 allowed_chars set(0123456789-*/.() sqrt) if not all(c in allowed_chars for c in expression): return 错误表达式包含不安全字符。 result eval(expression, {__builtins__: {}}, {math: math}) return str(result) except Exception as e: return f计算错误{e} # 将函数包装成 LangChain Tool 对象 search_tool Tool( nameWebSearch, funcsearch_online, description当需要回答关于实时信息、最新事件、未知事实或特定数据如天气、股价、新闻的问题时使用此工具。输入应为明确的搜索查询词。 ) calc_tool Tool( nameCalculator, funccalculate, description用于执行数学计算。输入是一个数学表达式字符串如 3 * 4 5 或 sqrt(25)。 )3.2 初始化 LLM 和 Agent我们使用 LangChain 提供的create_react_agent辅助函数来快速构建一个遵循 ReAct 范式的 Agent。# agent_setup.py from langchain import hub from langchain.agents import create_react_agent, AgentExecutor from langchain_openai import ChatOpenAI from tool_definitions import search_tool, calc_tool # 1. 初始化 LLM # 使用 gpt-3.5-turbo 模型性价比高适合实验。 # 确保 OPENAI_API_KEY 环境变量已设置。 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 2. 定义工具列表 tools [search_tool, calc_tool] # 3. 获取 ReAct 提示词模板 # LangChain Hub 上维护了一个标准的 ReAct 提示词模板非常适合入门。 prompt hub.pull(hwchase17/react) # 4. 创建 ReAct Agent agent create_react_agent(llm, tools, prompt) # 5. 创建 Agent 执行器 # 这是真正驱动循环的部分它处理与 LLM 的交互、工具调用和解析。 agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue)关键参数解释temperature0使 LLM 输出更确定、可重复适合工具调用这类结构化任务。verboseTrue将在控制台打印详细的执行步骤对于调试和理解 Agent 思考过程至关重要。handle_parsing_errorsTrue当 LLM 的输出格式不符合 Agent 预期时例如没有正确生成Action:或Final Answer:此设置可以防止程序直接崩溃而是尝试重新提示或优雅处理。3.3 运行并观察 Agent 的思考过程现在让我们向 Agent 提问并观察它如何一步步思考、行动和观察。# run_agent.py from agent_setup import agent_executor if __name__ __main__: questions [ 特斯拉TSLA当前的股价是多少, 计算一下 15 的平方加上 20 除以 4 的结果是多少, 今天北京和上海的最高气温分别是多少, ] for question in questions: print(f\n{*50}) print(f用户问题: {question}) print(f{*50}) try: # 执行 Agent response agent_executor.invoke({input: question}) print(f\n最终答案: {response[output]}) except Exception as e: print(f执行过程中出现异常: {e})运行python run_agent.py。当verboseTrue时你将在控制台看到类似以下的输出这正是 ReAct 循环的直观体现 用户问题: 特斯拉TSLA当前的股价是多少 Entering new AgentExecutor chain... 我需要找到特斯拉股票代码TSLA的最新股价。这是一个实时信息我需要使用搜索工具。 Action: WebSearch Action Input: TSLA stock price today Observation: 特斯拉(TSLA)股价今日实时行情 ... (此处是搜索返回的真实文本摘要) ... 最新报价为 245.67 美元。 Thought: 我已经从搜索中获得了特斯拉的当前股价可以直接给出答案。 Final Answer: 特斯拉TSLA当前的股价大约是 245.67 美元。 Finished chain. 最终答案: 特斯拉TSLA当前的股价大约是 245.67 美元。对于计算问题你会看到 Agent 选择调用Calculator工具。对于天气问题它可能会生成一个包含“北京 最高气温”和“上海 最高气温”的搜索查询。4. 关键组件与工作机制深度解析仅仅跑通示例还不够理解每个组件的细节和配置选项才能应对更复杂的需求。4.1 提示词Prompt的构成ReAct 提示词是 Agent 的“大脑指令集”。通过hub.pull(“hwchase17/react”)拉取的模板其核心结构如下已简化你是一个有帮助的助手可以使用以下工具 {tools} 请使用以下格式回答 Question: 需要回答的输入问题 Thought: 你应该始终思考下一步该做什么 Action: 需要执行的动作必须是 [{tool_names}] 中的一个 Action Input: 该动作的输入 Observation: 动作的结果 ... (这个 Thought/Action/Action Input/Observation 循环可以重复多次) Thought: 我现在知道最终答案了 Final Answer: 对原始问题的最终答案 开始 Question: {input} Thought: {agent_scratchpad}{tools}: 会被替换为所有工具的名称和描述列表。清晰的工具描述至关重要它直接决定了 LLM 是否知道在什么场景下调用哪个工具。{tool_names}: 工具名称列表。{input}: 用户的问题。{agent_scratchpad}: 这是关键变量。它会在执行过程中自动将之前所有的Thought、Action、Action Input、Observation记录拼接起来作为新的上下文提供给 LLM从而维持连贯的推理链。4.2 Agent 执行器的工作流程AgentExecutor是引擎其内部循环逻辑如下初始化: 将用户输入、工具定义、记忆如有填入提示词模板。调用 LLM: 将组装好的提示词发送给 LLM。解析输出: 使用OutputParser如ReActSingleInputOutputParser解析 LLM 的回复判断输出类型是AgentAction: 包含要调用的工具名和输入。进入步骤4。AgentFinish: 包含最终答案。循环结束返回结果。执行工具: 根据AgentAction调用对应的工具函数并获取返回结果作为Observation。更新上下文: 将本次的(Action, Action Input, Observation)添加到agent_scratchpad中。循环: 回到步骤2将更新后的完整上下文再次发送给 LLM。这个过程会一直持续直到 LLM 输出Final Answer或达到最大迭代次数。4.3 工具Tools的设计要点清晰的描述Description: 这是 LLM 选择工具的主要依据。描述应明确说明工具的用途、适用场景和输入格式。例如“查询天气”比“获取信息”要好得多。稳定的输入输出: 工具函数应接收一个字符串输入并返回一个字符串。返回的字符串应尽可能简洁、信息丰富因为这将作为Observation进入下一轮思考。错误处理: 工具内部必须有健壮的错误处理如 try-catch并返回有意义的错误信息而不是抛出异常导致整个 Agent 中断。工具数量: 工具不是越多越好。过多的工具会增加 LLM 的选择困惑和提示词长度。通常为特定领域任务定制少量精准的工具效果更好。4.4 记忆Memory的集成要让 Agent 记住对话历史需要将 Memory 组件接入 Agent 执行器。LangChain 提供了多种 Memory 类型。# 带记忆的 Agent 示例 from langchain.agents import AgentExecutor, create_react_agent from langchain.memory import ConversationBufferMemory from langchain_openai import ChatOpenAI from tool_definitions import search_tool import langchain langchain.debug False # 可以设置为 True 查看更底层的 LLM 调用信息 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) tools [search_tool] prompt hub.pull(hwchase17/react) # 1. 创建记忆对象 memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) # 2. 修改提示词模板使其包含记忆的占位符 # 注意标准的 hwchase17/react 提示词不直接支持 chat_history。 # 我们需要一个自定义的、支持记忆的提示词或者使用其他内置的 Agent 类型如 CONVERSATIONAL_REACT_DESCRIPTION。 # 这里为了演示我们展示一个更简单的集成方式将历史记录作为输入的一部分。 from langchain.agents import initialize_agent, AgentType # 使用 initialize_agent 并指定支持对话的 Agent 类型 conversational_agent initialize_agent( tools, llm, agentAgentType.CONVERSATIONAL_REACT_DESCRIPTION, # 专为对话设计的 ReAct Agent verboseTrue, memorymemory, # 传入 memory 对象 handle_parsing_errorsTrue ) # 使用这个 agent 进行多轮对话 result1 conversational_agent.invoke({input: 特斯拉是做什么的公司}) print(result1[output]) result2 conversational_agent.invoke({input: 它现在的股价呢}) # Agent 会记得之前聊过特斯拉 print(result2[output])注意不同的 Agent 类型如ZERO_SHOT_REACT_DESCRIPTION,CONVERSATIONAL_REACT_DESCRIPTION对应不同的提示词模板对记忆的支持方式也不同。需要根据文档选择合适类型并配置对应的memory_key。5. 常见问题排查与调试技巧在开发过程中你一定会遇到各种问题。以下是典型问题及其排查路径。5.1 Agent 陷入循环或无法给出最终答案问题现象可能原因检查与解决方式Agent 反复调用同一个工具或 Thought 逻辑混乱不输出Final Answer。1.工具描述不清晰导致 LLM 无法正确选择或理解工具结果。2.工具返回结果质量差如过长、无关、错误干扰了后续推理。3.最大迭代次数max_iterations设置过高Agent 有太多“犯错”的机会。1. 优化工具描述确保精准。2. 改进工具函数确保返回简洁、相关的结果。可以尝试截断或总结工具输出后再返回。3. 在AgentExecutor中设置max_iterations5或更小的值强制限制循环次数。agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, max_iterations5)LLM 的输出格式不符合OutputParser的预期导致解析失败。1. LLM 没有严格遵守提示词中规定的Thought/Action/Final Answer格式。2.temperature参数过高导致输出随机性大。1. 将handle_parsing_errorsTrue传递给AgentExecutor它会尝试修复一些格式错误。2. 确保temperature0。3. 开启langchain.debugTrue查看原始的 LLM 输入和输出检查格式问题。5.2 工具调用失败或结果未被使用问题现象可能原因检查与解决方式Agent 决定调用工具但工具执行出错如网络错误、API 限流。工具函数本身存在 Bug 或外部服务不可用。1. 在工具函数内部添加详细的 try-catch 和日志。2. 为工具返回一个明确的错误信息字符串如“网络请求失败”让 Agent 能将其作为Observation并可能尝试其他策略。Agent 调用了错误的工具或生成的Action Input格式不对。工具描述与用户问题场景匹配度不高或者 LLM 对输入格式理解有偏差。1. 在工具描述中举例说明输入格式例如description“用于计算。输入示例‘35*2’ ‘sqrt(16)’。”2. 在提示词模板中强化格式要求。5.3 性能与成本问题问题现象可能原因检查与解决方式响应速度慢Token 消耗大。1. 每次循环都会将完整的思考历史agent_scratchpad发送给 LLM历史越长上下文越长。2. 工具调用如网络请求本身耗时。1. 考虑对长的Observation进行摘要Summarization后再放入历史。2. 为工具设置超时和重试机制。3. 使用更便宜的模型进行简单推理或设置max_iterations限制。5.4 开启 Debug 模式当问题难以定位时开启 LangChain 的调试模式是最高效的方法。它会在控制台打印出每次调用 LLM 的原始提示词和原始回复。import langchain langchain.debug True # 再次运行你的 Agent # 你将看到非常详细的日志包括发送给 API 的完整 prompt 和返回的完整 response。 # 这能帮你确认是否是提示词构造问题或 LLM 回复格式问题。6. 最佳实践与扩展方向掌握了基础构建和排错后以下实践能让你的 Agent 更健壮、更强大。6.1 生产环境准备清单密钥管理永远不要将 API Key 硬编码在代码或版本库中。使用环境变量、密钥管理服务或配置文件。错误处理与降级对agent_executor.invoke()进行异常捕获。当 Agent 失败时应有降级策略例如返回一个友好的错误信息或切换到备用流程。超时控制为AgentExecutor设置max_execution_time并为每个网络工具设置独立的超时防止单个请求卡死整个服务。日志与监控记录完整的 Agent 执行轨迹包括所有的 Thought、Action、Observation这对于后续分析问题、优化提示词和计算成本至关重要。限制与防护设置max_iterations防止无限循环。对于用户输入考虑进行内容安全过滤。6.2 提示词工程优化角色设定System Message在提示词开头明确 Agent 的角色和能力边界例如“你是一个专业的金融数据分析助手擅长搜索和计算...”。少样本示例Few-Shot在提示词中提供一两个完整的 ReAct 循环示例能显著提升 LLM 输出格式的准确性和任务完成质量。工具描述精炼用 LLM 能理解的语言描述工具。避免歧义明确输入输出格式。6.3 扩展你的 Agent集成更多工具将内部 API、数据库查询、文件操作等封装成 Tool极大扩展 Agent 的能力边界。使用更强大的 Agent 类型探索 LangChain 内置的其他 Agent如擅长规划复杂任务的PLANNER_REACT_AGENT或尝试 LangGraph 来构建有状态、多分支的工作流。加入检索Retrieval结合向量数据库让 Agent 能够利用私有知识库如公司文档、产品手册来回答问题。这就是常说的“智能客服”或“知识库问答”系统的核心。多 Agent 协作可以创建多个具有不同专长如搜索专家、计算专家、代码专家的 Agent并通过一个主控 Agent 或 LangGraph 来协调它们共同完成复杂任务。构建 AI Agent 是一个迭代过程从最简单的 ReAct 循环开始逐步增加工具、优化提示、集成记忆和检索能力。理解 LangChain 提供的抽象层能让你从繁琐的流程控制中解放出来专注于设计 Agent 的“大脑”提示词和“四肢”工具。现在你已经拥有了动手造一个 AI Agent 的起点下一步就是针对你的具体场景设计并实现那些真正有价值的工具和流程。 30款热门AI模型一站整合DeepSeek/GLM/Qwen 随心用限时 5 折。 点击领海量免费额度