资讯动态

从零构建AI Agent:基于LangChain的工程化实践指南

发布时间:2026/8/22 10:19:23 来源:尧图企业网站定制
在实际项目中AI Agent 已经从实验室概念演变为解决复杂任务、连接工具与服务的核心组件。无论是自动化客服、数据分析助手还是代码生成工具其背后都有一套从感知、决策到执行的完整架构。对于开发者而言理解如何构建一个可运行、可扩展的 AI Agent远比单纯调用大模型 API 更具挑战性。本文旨在提供一个从零开始的工程化指南涵盖从核心概念、环境搭建、框架选择、代码实现到生产部署的全链路。我们将以一个能够理解用户意图、调用外部工具如搜索、计算并给出结构化响应的任务型 Agent 为例逐步拆解其开发过程。无论你是希望将 AI 能力集成到现有系统的后端工程师还是对智能体开发充满好奇的初学者通过跟随本文的步骤你将能够搭建一个具备基础能力的 AI Agent并掌握排查常见问题、优化其性能的关键方法。1. 理解 AI Agent 的核心架构与工作流在编写第一行代码之前必须清晰地理解 AI Agent 与传统程序或简单 API 调用的本质区别。一个典型的 AI Agent 并非一个静态函数而是一个具备感知、规划、行动和反思能力的循环系统。1.1 AI Agent 的基本组成模块一个功能完备的 AI Agent 通常由以下几个核心模块构成感知模块负责接收和处理来自用户的输入文本、语音、图像等并将其转化为 Agent 内部可以理解的结构化信息。在文本场景下这通常意味着对用户 Query 进行意图识别和实体抽取。大脑/推理模块这是 Agent 的“思考”中心通常由一个或多个大语言模型驱动。它根据感知模块的输入、自身的记忆以及可用的工具列表进行规划、决策和推理决定下一步该做什么。工具模块Agent 能力的延伸。大脑本身不直接执行搜索、计算、数据库查询等操作而是通过调用预定义的工具来完成。每个工具都有明确的名称、描述和调用参数。记忆模块使 Agent 具备连续对话和上下文理解能力的关键。短期记忆保存当前会话的上下文长期记忆则可以存储用户偏好、历史交互等持久化信息。执行模块负责将大脑的决策如“调用工具A”转化为具体的动作调用相应的工具函数并处理返回结果。反思与学习模块高级 Agent 具备的能力用于评估行动结果修正错误策略或从历史交互中学习优化。1.2 典型工作流ReAct 模式目前最主流的 Agent 工作流模式之一是ReAct。它清晰地展示了思考与行动的交替过程。Thought: Agent 分析当前情况用户问题、已有信息、可用工具思考下一步该做什么。Action: 根据思考决定执行一个具体动作通常是调用一个工具并生成符合工具要求的输入参数。Observation: 接收工具执行后的返回结果Observation。循环基于新的观察Observation再次进行思考Thought决定下一个动作直到任务完成或达到终止条件。这个循环使得 Agent 能够处理多步骤的复杂任务例如“查询北京今天的天气如果下雨就推荐室内活动”。1.3 主流开发框架选型为了高效开发我们不会从零实现所有底层逻辑而是基于成熟的框架。以下是几个主流选择及其适用场景框架名称语言核心特点适用场景LangChain / LangGraphPython/JS生态最丰富组件齐全社区活跃文档详细。LangGraph 专门用于构建有状态的、多步骤的 Agent。快速原型验证研究需要丰富工具生态的项目。LlamaIndexPython专注于数据连接和检索增强生成其 Agent 能力与数据查询深度集成。构建基于私有知识库的问答、分析型 Agent。Semantic Kernel.NET/Python微软出品与 Azure OpenAI 集成好强调规划器和技能Skills的概念。.NET 技术栈或深度依赖微软云服务的项目。AutoGenPython专注于多智能体协作可以轻松构建多个 Agent 对话、协作完成任务的系统。需要模拟团队协作、分工处理复杂流程的场景。对于入门和大多数应用场景LangChain因其较低的入门门槛和丰富的示例是首选。本文将基于 LangChain 进行演示。2. 开发环境准备与项目初始化一个稳定的开发环境是后续所有工作的基础。我们将创建一个独立的 Python 虚拟环境并安装必要的依赖。2.1 基础环境配置首先确保你的系统已安装 Python推荐 3.9 或更高版本和 pip。然后使用venv创建虚拟环境。# 创建项目目录并进入 mkdir ai-agent-tutorial cd ai-agent-tutorial # 创建 Python 虚拟环境 python -m venv venv # 激活虚拟环境 # 在 Windows 上 venv\Scripts\activate # 在 macOS/Linux 上 source venv/bin/activate激活后命令行提示符前会出现(venv)标识。2.2 核心依赖安装我们将安装 LangChain 及其相关组件。由于需要调用大模型还需要安装对应 SDK这里以 OpenAI 为例。同时为了示例中的工具调用我们安装requests用于网络请求langchain-community包含社区贡献的工具。# 升级 pip pip install --upgrade pip # 安装 LangChain 核心、OpenAI SDK、社区工具和 requests pip install langchain langchain-openai langchain-community requests # 可选安装用于结构化输出的 Pydantic pip install pydantic注意langchain是一个元包它会安装一系列核心组件。langchain-openai是官方维护的 OpenAI 集成包比旧的openai包集成方式更现代。2.3 项目结构与 API 密钥管理在项目根目录下创建以下基础结构ai-agent-tutorial/ ├── .env # 存储敏感信息如API密钥 ├── .gitignore # Git忽略文件 ├── requirements.txt # 项目依赖清单 ├── src/ │ ├── __init__.py │ ├── tools/ # 自定义工具存放目录 │ │ ├── __init__.py │ │ └── calculator.py │ ├── agents/ # Agent 定义目录 │ │ ├── __init__.py │ │ └── task_agent.py │ └── main.py # 主入口文件 └── README.md首先创建.gitignore文件确保不提交虚拟环境和密钥文件。# .gitignore venv/ .env __pycache__/ *.pyc接下来管理你的 OpenAI API 密钥。永远不要将密钥硬编码在代码中。我们使用.env文件。# 在项目根目录创建 .env 文件并填入你的密钥 OPENAI_API_KEYsk-your-actual-openai-api-key-here然后安装python-dotenv包来读取环境变量。pip install python-dotenv最后生成requirements.txt文件方便他人复现环境。pip freeze requirements.txt3. 构建你的第一个工具增强型 AI Agent现在我们从构建一个最简单的 Agent 开始它能够回答一般性问题并在需要时调用一个计算器工具进行数学运算。3.1 创建自定义工具工具是 Agent 的手臂。我们首先在src/tools/calculator.py中定义一个简单的计算器工具。# src/tools/calculator.py from langchain.tools import tool from pydantic import BaseModel, Field # 定义工具的输入参数模型这有助于LLM生成正确的参数 class CalculatorInput(BaseModel): a: float Field(description第一个数字) b: float Field(description第二个数字) operator: str Field(description运算符必须是 , -, *, / 中的一个) tool(args_schemaCalculatorInput) def calculator(a: float, b: float, operator: str) - str: 执行简单的数学运算。支持加、减、乘、除。 当除数为零时会返回错误信息。 try: if operator : result a b elif operator -: result a - b elif operator *: result a * b elif operator /: if b 0: return 错误除数不能为零。 result a / b else: return f错误不支持的运算符 {operator}。仅支持 , -, *, /。 # 返回格式化的字符串结果便于Agent理解 return f计算结果{a} {operator} {b} {result} except Exception as e: return f计算过程中发生错误{e}关键点解释tool装饰器将普通函数转换为 LangChain 可识别的工具。args_schema参数指定了输入参数的 Pydantic 模型这为 LLM 提供了清晰的参数规范和类型提示能显著提升工具调用的准确性。函数的文档字符串内容至关重要LLM 会据此理解工具的用途因此描述必须清晰准确。工具返回字符串这是给 LLMObservation的反馈。3.2 构建 Agent 并集成工具接下来在src/agents/task_agent.py中创建 Agent。我们将使用 LangChain 的create_react_agent辅助函数它封装了 ReAct 逻辑。# src/agents/task_agent.py import os from dotenv import load_dotenv from langchain import hub from langchain.agents import create_react_agent, AgentExecutor from langchain_openai import ChatOpenAI from src.tools.calculator import calculator # 加载 .env 文件中的环境变量 load_dotenv() def get_task_agent(): 初始化并返回一个具备计算能力的任务型 Agent。 # 1. 初始化大语言模型 # 使用 gpt-3.5-turbo 作为推理核心温度调低使输出更确定 llm ChatOpenAI( modelgpt-3.5-turbo, temperature0, openai_api_keyos.getenv(OPENAI_API_KEY) # 从环境变量读取密钥 ) # 2. 定义工具列表 tools [calculator] # 3. 获取 ReAct 提示词模板 # LangChain Hub 是一个提示词仓库我们拉取一个标准的 ReAct 提示词 prompt hub.pull(hwchase17/react) # 4. 创建 ReAct Agent agent create_react_agent(llm, tools, prompt) # 5. 创建 Agent 执行器 # 执行器负责运行 Agent 的循环处理工具调用和解析 LLM 输出 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 设置为 True 可以看到 Agent 的思考过程Thought/Action/Observation handle_parsing_errorsTrue, # 优雅处理 LLM 输出解析错误 max_iterations5, # 防止 Agent 陷入无限循环 early_stopping_methodgenerate, # 当 Agent 认为任务完成时停止 ) return agent_executor if __name__ __main__: # 本地测试 agent_executor get_task_agent() result agent_executor.invoke({input: 123乘以456等于多少}) print(\n最终答案, result[output])3.3 运行与验证创建一个主入口文件src/main.py来测试我们的 Agent。# src/main.py from src.agents.task_agent import get_task_agent def main(): print(初始化任务型 AI Agent...) agent get_task_agent() # 测试用例 test_queries [ 你好你是谁, 请计算一下 15.7 加上 28.3 等于多少, 如果我有100块钱买了三本书每本23.5元还剩多少钱, 今天的天气怎么样, # 注意我们没有天气工具看Agent如何反应 ] for query in test_queries: print(f\n{*50}) print(f用户问题: {query}) print(f{*50}) try: # 因为我们在 AgentExecutor 中设置了 verboseTrue思考过程会直接打印出来 result agent.invoke({input: query}) print(f\nAgent 最终回复: {result[output]}) except Exception as e: print(f执行出错: {e}) if __name__ __main__: main()在终端中确保处于虚拟环境并已设置好.env文件然后运行python src/main.py你将看到类似以下的输出verbose 模式初始化任务型 AI Agent... 用户问题: 请计算一下 15.7 加上 28.3 等于多少 Entering new AgentExecutor chain... 我需要计算 15.7 加上 28.3。我有一个计算器工具可以使用。 Action: calculator Action Input: {a: 15.7, b: 28.3, operator: } Observation: 计算结果15.7 28.3 44.0 Thought: 我已经得到了计算结果可以回答用户了。 Action: Final Answer Action Input: 15.7 加上 28.3 等于 44.0。 Finished chain. Agent 最终回复: 15.7 加上 28.3 等于 44.0。对于“今天的天气怎么样”由于没有对应工具Agent 会基于其知识给出回答但不会尝试调用工具。这就是 ReAct 框架的优势有工具则用无工具则靠自身知识回答。4. 扩展 Agent 能力集成搜索与记忆一个只会计算的 Agent 实用性有限。接下来我们为其增加搜索能力和对话记忆。4.1 集成网络搜索工具我们将使用 LangChain 社区中集成的 Tavily 搜索工具。首先需要注册 Tavily 获取 API 密钥并将其添加到.env文件。# .env OPENAI_API_KEYsk-... TAVILY_API_KEYyour-tavily-api-key然后安装 Tavily 包并更新工具列表。pip install tavily-python修改src/agents/task_agent.py# ... 之前的导入 ... from langchain_community.tools.tavily_search import TavilySearchResults def get_enhanced_agent(): 初始化一个具备计算和搜索能力的增强型 Agent。 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 1. 初始化搜索工具 search_tool TavilySearchResults( nameweb_search, description当需要获取实时信息或最新知识时使用此工具进行网络搜索。, max_results3, # 控制返回结果数量 tavily_api_keyos.getenv(TAVILY_API_KEY) ) # 2. 工具列表现在包含计算器和搜索 tools [calculator, search_tool] prompt hub.pull(hwchase17/react) agent create_react_agent(llm, tools, prompt) agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue, max_iterations7, # 搜索可能增加步骤 ) return agent_executor4.2 为 Agent 添加对话记忆没有记忆的 Agent 每次对话都是独立的。我们使用ConversationBufferMemory来为其添加短期会话记忆。首先需要调整提示词以支持记忆。我们使用一个专为对话设计的提示词模板。# src/agents/agent_with_memory.py import os from dotenv import load_dotenv from langchain import hub from langchain.agents import create_react_agent, AgentExecutor from langchain_openai import ChatOpenAI from langchain_community.tools.tavily_search import TavilySearchResults from langchain.memory import ConversationBufferMemory from src.tools.calculator import calculator load_dotenv() def get_agent_with_memory(): 初始化一个具备计算、搜索和对话记忆的 Agent。 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 工具 search_tool TavilySearchResults( nameweb_search, description用于搜索实时信息。, max_results2, tavily_api_keyos.getenv(TAVILY_API_KEY) ) tools [calculator, search_tool] # 记忆 memory ConversationBufferMemory( memory_keychat_history, # 存储在提示词中的变量名 return_messagesTrue, # 以消息列表格式返回 input_keyinput, # 输入键名 output_keyoutput # 输出键名 ) # 使用支持对话的提示词 prompt hub.pull(hwchase17/react-chat) # 或者使用本地自定义的带记忆的提示词模板更推荐 # from langchain.prompts import PromptTemplate # prompt PromptTemplate.from_template(...) agent create_react_agent(llm, tools, prompt) agent_executor AgentExecutor( agentagent, toolstools, memorymemory, verboseTrue, handle_parsing_errorsTrue, max_iterations5, ) return agent_executor if __name__ __main__: agent get_agent_with_memory() # 连续对话测试 queries [ 我叫小明。, 我的名字是什么, 搜索一下 LangChain 是什么。, 根据你刚才搜索的结果用一句话总结。 ] for q in queries: print(f\n用户: {q}) result agent.invoke({input: q}) print(fAgent: {result[output]})运行此脚本你会看到 Agent 能够记住对话历史中“我叫小明”的信息并在后续回答“我的名字是什么”时引用。5. 生产环境考量与常见问题排查将原型 Agent 部署到生产环境需要解决稳定性、性能、成本和安全等一系列问题。5.1 关键配置与优化建议配置项学习/开发环境生产环境建议说明LLM 模型gpt-3.5-turbo根据场景选择gpt-4-turbo或专用微调模型GPT-4 推理能力更强错误更少但成本高。需权衡精度与成本。Temperature0 或 0.10 或 0.1对于任务型 Agent低温度值确保输出稳定、可预测。Max Tokens默认根据工具输出长度合理设置限制单次响应长度防止成本失控。Max Iterations5-103-8限制 ReAct 循环次数防止复杂任务消耗过多 token 或陷入死循环。Verbose LoggingTrueFalse生产环境关闭详细日志但需将关键步骤Thought/Action记录到应用日志。错误处理基础try-except结构化异常处理与重试机制对网络超时、API 限流、工具调用失败等进行分级处理和重试。API 密钥管理.env文件密钥管理服务如 Vault, AWS Secrets Manager严禁硬编码使用安全的密钥注入方式。异步调用同步强烈建议异步使用ainvoke避免阻塞提高吞吐量。LangChain 支持AsyncAgentExecutor。5.2 常见问题与排查路径在开发和生产中你会遇到各种问题。以下是系统性的排查思路。问题一Agent 不调用工具直接用自己的知识回答。现象对于“计算 123*456”Agent 直接说出答案可能对也可能错而不是调用计算器工具。可能原因与排查工具描述不清检查工具的description和函数文档字符串是否清晰指明了工具的用途和适用场景。LLM 根据描述决定是否调用。提示词不合适使用的prompt可能没有强烈鼓励 Agent 使用工具。尝试更换或微调提示词。模型能力不足gpt-3.5-turbo在复杂工具调用上不如gpt-4可靠。尝试升级模型。参数解析失败即使决定调用工具如果 LLM 生成的Action Input不符合args_schema执行器可能会失败并回退。检查verbose日志中的Action Input格式。问题二Agent 陷入循环或达到最大迭代次数。现象日志中 Thought/Action/Observation 循环多次最终以“Agent stopped due to iteration limit”结束。可能原因与排查工具返回结果无法推动任务前进观察Observation。如果工具返回错误或无关信息Agent 可能无法理解。确保工具返回清晰、结构化的结果。任务过于复杂或模糊Agent 的规划能力有限。将复杂任务拆解或提供更明确的指令。max_iterations设置过小对于需要多步搜索和推理的任务适当增加该值。缺少关键工具Agent 试图完成一个没有对应工具的任务只能在原地打转。评估任务是否需要补充新工具。问题三工具调用出错如网络超时、API 错误。现象Observation显示工具调用异常Agent 后续行为异常。解决方案在工具函数内部加强异常捕获返回明确的错误信息给 Agent如“网络请求失败请稍后重试”。为工具调用添加重试机制可以使用tenacity库或 LangChain 的tool装饰器参数进行配置。设置超时时间对于网络工具务必设置合理的超时如requests的timeout参数。使用 Agent 的handle_parsing_errors和handle_tool_errors参数配置执行器以更优雅地处理错误。问题四Token 消耗过高成本失控。现象简单的查询消耗了数千 token。优化策略精简提示词移除不必要的上下文和指令。使用更高效的记忆方式ConversationBufferMemory会存储所有历史导致 token 增长。考虑ConversationSummaryMemory定期总结或ConversationBufferWindowMemory只保留最近 N 轮。限制工具输出的长度例如让搜索工具只返回摘要而非全文。监控与预算在调用 LLM API 的客户端设置预算和用量告警。5.3 生产部署清单在将 Agent 服务部署上线前请对照此清单进行检查[ ]安全性API 密钥已从代码中移除并通过环境变量或密钥管理服务注入。对用户输入进行了基本的清理和过滤防止 Prompt 注入攻击。工具调用如数据库查询、系统命令实施了严格的权限控制和输入验证。[ ]可靠性对 LLM API 调用和工具调用实现了重试逻辑如指数退避。设置了合理的超时时间避免线程阻塞。关键步骤Agent 决策、工具调用、最终输出有日志记录便于追踪。[ ]可观测性集成了应用性能监控跟踪请求延迟、错误率和 token 消耗。日志中包含唯一的请求 ID可以串联一次会话中的所有步骤。[ ]性能对于 Web 服务考虑使用异步执行器AsyncAgentExecutor提高并发能力。评估是否需要对频繁使用的 Agent 进行缓存缓存最终答案或中间步骤。[ ]成本设置了每月/每日的 API 调用预算或 token 消耗告警。在非关键场景考虑使用性价比更高的模型如gpt-3.5-turbo。6. 进阶方向与扩展思路当你掌握了基础 Agent 的构建后可以朝以下方向深入构建更强大、更专业的智能体系统。6.1 实现智能体编排与多智能体协作对于复杂工作流单个 Agent 可能力不从心。可以使用LangGraph来编排多个具有不同专长的 Agent。思路创建一个“主管”Agent负责接收任务并将其分解为子任务然后分配给不同的“专家”Agent如数据分析 Agent、文档撰写 Agent、代码审查 Agent执行最后汇总结果。关键LangGraph 通过有向图来定义 Agent 之间的状态流转非常适合描述这种多步骤、有分支的协作流程。6.2 构建检索增强生成型智能体当 Agent 需要基于特定领域知识如公司内部文档、产品手册进行回答时需要 RAG 能力。实现使用LlamaIndex或 LangChain 的RetrievalQA链。先将文档切片、向量化并存入向量数据库。当用户提问时先检索相关文档片段再将“问题文档”一起交给 LLM 生成答案。进阶让 Agent 自主决定何时进行检索。可以将检索器也封装成一个工具由 Agent 在需要时调用。6.3 开发自定义工具与复杂工具包工具是 Agent 能力的边界。开发高质量的工具至关重要。工具设计原则功能单一一个工具只做一件事。描述清晰名称和描述要能让 LLM 准确理解其用途和适用场景。输入明确使用args_schema严格定义参数类型和约束。输出稳定返回格式应尽量结构化、可预测便于 LLM 解析。复杂工具示例可以创建“发送邮件”、“在数据库创建工单”、“调用内部 API 生成报表”等工具将 Agent 与企业内部系统连接。6.4 长期记忆与个性化让 Agent 记住跨会话的用户信息提供个性化体验。实现将ConversationBufferMemory替换为支持持久化的存储后端如RedisChatMessageHistory或PostgresChatMessageHistory。将用户 ID 与会话历史关联。注意隐私和安全至关重要。必须明确告知用户数据如何使用并提供数据管理选项。构建 AI Agent 是一个迭代过程从最小可行产品开始逐步增加工具、优化提示词、完善记忆和错误处理。核心在于理解其作为“基于 LLM 的决策循环”这一本质并围绕可靠性、安全性和用户体验进行工程化打磨。下一步你可以尝试将本文的示例 Agent 封装成一个简单的 Web API使用 FastAPI 或 Flask并为其添加一个搜索新闻或查询数据库的工具从而创建一个真正有用的自动化助手。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价