公司动态

从API调用到智能体构建:LangChain Agent实战指南

📅 2026/8/12 10:40:21
从API调用到智能体构建:LangChain Agent实战指南
1. 项目概述从“单次问答”到“智能体”的思维跃迁最近和不少刚开始接触大模型应用开发的朋友聊天发现一个挺普遍的现象很多人上手的第一步就是直接调用大模型的API比如OpenAI的ChatCompletion或者类似DeepSeek的接口把问题扔进去然后等着拿答案。这当然没错这是最直接、最基础的用法。但当你真正想做一个能“自己动起来”、能处理复杂任务的应用时很快就会发现仅仅调用API是远远不够的。这就好比你想造一辆能自动驾驶的汽车但你手头只有一个非常聪明的“大脑”大模型它能告诉你“前面有行人应该刹车”但它不会自己去踩刹车踏板不会去转动方向盘更不会规划从A点到B点的完整路线。这个“大脑”需要被组装进一个拥有感知、决策和执行能力的完整身体里这个“身体”就是Agent智能体而LangChain这类框架就是帮你搭建这个身体、连接神经与肢体的“工具箱”和“设计图”。为什么不够想象一个实际场景用户说“帮我分析一下上周销售数据总结趋势并给销售团队写一封鼓励邮件”。如果你直接把这个长句丢给大模型API它可能会给你一段笼统的分析和一篇模板化的邮件。但一个真正的智能体应该能自主完成以下步骤1. 理解指令拆解出“获取销售数据”、“分析趋势”、“撰写邮件”三个子任务。2. 找到正确的工具比如连接数据库的查询接口、数据分析库、邮件发送服务。3. 按顺序执行先查询数据将结果交给大模型分析再根据分析结果生成邮件内容最后调用邮件API发送。在这个过程中大模型的核心角色是“规划师”和“文案撰写员”而LangChain Agent则负责搭建一个工作流让大模型能安全、可靠、按需地使用各种外部工具和知识并管理整个执行过程包括错误处理和状态记忆。所以这个内容的核心就是想和你深入聊聊当我们从“直接调API”的思维升级到“构建Agent”的思维时我们究竟在解决哪些关键问题以及如何利用LangChain这个目前最流行的框架之一迈出构建实用AI智能体的第一步。无论你是开发者、产品经理还是对AI应用感兴趣的爱好者理解这套范式都能帮你更清晰地看到当前AI技术的应用边界和突破方向。2. 直接调用大模型API的局限性深度剖析在兴奋地开始组装Agent之前我们有必要先彻底搞清楚为什么那条看似简单的“调API”之路在复杂任务面前会很快走到尽头。这不仅仅是“功能不足”更是一种设计范式的根本差异。2.1 “静态”响应与“动态”世界的矛盾大模型API本质是一个无状态的、一次性的问答接口。你发送一个Prompt提示词它基于训练数据生成一个Completion补全内容然后连接就结束了。这个过程是静态的、封闭的。但现实世界的问题往往是动态的、需要多轮交互和依赖上下文的。举个例子你问API“我今天的日程安排是什么” 一个优秀的、经过精心Prompt工程设计的API或许能回复你“作为一个AI我无法访问你的个人日历。不过你可以告诉我你的日程我来帮你整理。” 但这已经是它的极限了。它无法主动去调用你的Google Calendar API获取真实数据除非你在这次请求中把整个日历数据都粘贴到Prompt里这显然不现实且会超长。而一个Agent可以这样做1. 理解你需要查询日程。2. 自动调用已授权的日历工具Tool去获取数据。3. 将获取到的结构化数据如JSON格式的日程列表再次交给大模型去总结、提炼。4. 将最终结果返回给你。这个“调用工具-获取新信息-再次分析”的循环是单次API调用无法实现的。注意这里常有一个误解认为通过超长的Prompt把函数描述和用户指令一起塞给GPT-4等支持函数调用Function Calling的模型就能实现类似Agent的功能。这确实是一种“准Agent”模式但框架的价值在于标准化、可复用地管理这些描述、调用、结果解析和错误处理的复杂流程而不是每次都在Prompt里手动拼接。2.2 缺乏“行动”与“感知”的能力大模型是一个强大的“思考者”和“生成者”但它没有“手”和“眼睛”。它无法执行任何实际动作也无法主动获取实时信息。它的知识截止于训练数据对于“现在几点了”、“某某股票最新股价是多少”、“我的服务器负载高吗”这类问题如果训练数据里没有它要么瞎编幻觉要么老实说不知道。Agent框架的核心能力之一就是工具调用Tool Calling。LangChain允许你将任意的函数、API接口封装成“工具”并教会大模型在何时、如何使用这些工具。这些工具就是Agent的“手”和“眼睛”。例如搜索工具连接SerpAPI或Google Search API获取实时信息。计算工具调用Python的math或sympy库进行精确计算避免大模型数学计算错误。代码执行工具在安全沙箱中运行代码片段处理数据或验证逻辑。业务系统工具连接你的CRM、数据库、内部API成为企业知识的入口。没有这些工具大模型只是一个与世隔绝的“天才思想家”有了它们大模型才进化为可以解决实际问题的“智能体”。2.3 复杂任务分解与状态管理的缺失“帮我制定一个从北京到上海的五天旅游计划预算5000元包含交通、住宿和景点推荐。”这是一个典型的复杂、多步骤任务。人类会自然地将它分解为查交通方式与价格、选酒店、排景点路线、计算总预算、调整平衡。单次API调用可能会生成一个看似完整但经不起推敲的计划因为它缺乏“分步验证”和“全局统筹”的机制。Agent通过**任务规划Planning和记忆Memory**组件来解决这个问题。规划Agent可以利用大模型的能力将用户目标拆解成一个有向无环图DAG式的子任务列表。有些框架如LangGraph更是明确引入了“循环”和“状态”的概念让Agent能根据上一步的结果动态决定下一步做什么。记忆无论是对话的短期记忆记住用户刚才说了什么还是长期记忆保存用户偏好、历史操作记录对于多轮协作至关重要。LangChain提供了多种记忆后端从简单的缓冲区到向量数据库使得Agent能够拥有“上下文感”。2.4 稳定性、成本与幻觉的挑战直接裸调API在简单场景下很快但在复杂场景下问题多多长上下文与成本为了提供足够背景你可能需要将大量文本塞进Prompt这会急剧增加Token消耗和API成本并且可能触及模型的最大上下文长度限制比如提示中出现maximum context length is 1048565 tokens这类错误。幻觉Hallucination当问题涉及训练数据之外或模糊的信息时大模型容易“信口开河”。Agent可以通过“检索增强生成RAG”模式先从权威知识库如你的文档、数据库中检索相关片段再基于这些确凿证据生成答案大幅减少幻觉。错误处理API调用可能失败网络错误、速率限制、服务异常。在裸调用的代码里你需要自己写一堆try...catch。而在Agent框架中你可以定义更优雅的重试逻辑、备选方案fallback和错误处理流程。3. LangChain Agent的核心架构与工作原理理解了“为什么不够”我们再来看看LangChain Agent是如何搭建这个“智能身体”的。它的设计哲学是将大模型作为推理引擎Reasoning Engine并围绕它构建一套可插拔的组件系统。3.1 核心组件六边形一个典型的LangChain Agent由以下几个核心部分组成它们像齿轮一样相互咬合代理Agent这是智能体的大脑决策中心。它本身包含一个大语言模型LLM和一个代理类型Agent Type的配置。代理类型决定了大脑的“思考策略”例如ZERO_SHOT_REACT_DESCRIPTION最常用的一种基于ReAct框架。对于每个步骤它都会输出“Thought”思考、“Action”选择哪个工具、“Action Input”工具的输入参数、“Observation”工具执行的结果。这种结构化的输出使得推理过程透明、可调试。OPENAI_FUNCTIONS专为OpenAI的Function Calling能力优化利用其原生的函数描述格式调用更稳定。STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION在ReAct基础上要求输出严格结构化的JSON便于与复杂工具交互。工具ToolsAgent可以调用的函数集合。每个工具都有名称、描述和实现函数。大模型通过工具描述来学习何时使用它。例如一个“搜索”工具的描述可能是“当需要获取最新的、训练数据之外的信息时使用此工具如当前事件、天气、股价等。”工具包Toolkits一组相关工具的集合方便模块化组织。例如一个“SQL Toolkit”可能包含sql_db_query、sql_db_schema等工具。记忆Memory存储和读取对话或任务历史。它可以是简单的ConversationBufferMemory只保留最近的几条记录也可以是ConversationSummaryMemory将长对话总结成摘要保存或是VectorStoreRetrieverMemory将记忆存入向量数据库实现基于语义的长期记忆检索。执行器AgentExecutor这是Agent的“脊柱”和“神经系统”。它负责驱动整个运行循环接收用户输入和当前记忆。调用AgentLLM进行思考得到下一步决策。解析决策调用指定的工具并获取结果。将工具结果作为“Observation”反馈给Agent形成下一步的输入。处理循环结束条件Agent输出Final Answer或达到最大迭代次数。管理错误、超时和中断。提示模板Prompt Templates定义给大模型的指令框架。一个好的系统提示词System Prompt是Agent成功的关键它需要清晰地定义Agent的角色、可用工具、输出格式和任务目标。LangChain的模板支持变量插值可以动态地将工具描述、历史对话等内容注入。3.2 工作流程一次完整的任务执行循环让我们跟随着一个用户查询“旧金山现在的天气怎么样”看看Agent内部是如何运转的初始化AgentExecutor将用户问题Q和当前的记忆M可能是空的组合起来。构建PromptExecutor使用预设的Prompt Template将Q、M以及所有Tools的描述填充进去形成一个完整的、结构化的提示发送给LLM。LLM思考与决策LLM收到提示理解任务和可用工具。它可能会想“用户问天气我需要实时信息。我有一个‘获取天气’的工具。” 于是它输出结构化的响应Thought: 用户需要旧金山的实时天气信息我应该使用天气查询工具。 Action: get_current_weather Action Input: {location: San Francisco}工具执行Executor解析出Action是get_current_weather找到对应的工具函数并以{location: San Francisco}为参数调用它。这个函数内部可能调用了一个第三方天气API。观察与反馈工具函数返回结果例如{temperature: 18°C, condition: Sunny}。Executor将这个结果格式化为Observation: 旧金山当前天气晴朗气温18摄氏度。。下一轮循环Executor将Thought、Action、Action Input、Observation以及最初的用户问题Q一起作为新的上下文再次发送给LLM。生成最终答案LLM这次看到工具执行成功并返回了数据它可能会想“我已经获得了所需信息现在可以直接回答用户了。” 于是输出Thought: 我已经获取了天气信息可以给出最终答案了。 Final Answer: 旧金山目前天气晴朗气温大约18摄氏度。循环结束Executor识别到Final Answer停止循环。将最终答案返回给用户并可能更新记忆M记录下这次完整的交互过程。这个“思考-行动-观察”的循环就是ReAct框架的核心也是大多数LangChain Agent的工作基础。它让大模型从单纯的文本生成器变成了一个可以与环境工具交互的理性决策者。4. 从零构建你的第一个LangChain Agent一个天气查询助手理论说了这么多现在让我们动手用代码搭建一个最简单的天气查询Agent。我会使用OpenAI的模型你也可以替换为其他兼容API的模型如DeepSeek、Ollama本地模型等和一个模拟的天气工具。4.1 环境准备与依赖安装首先确保你的Python环境建议3.8以上并安装必要库。我们将使用langchain-openai新版LangChain将不同供应商的LLM拆分为独立包和langchain核心库。pip install langchain langchain-openai python-dotenv你需要一个OpenAI的API密钥。将其保存在项目根目录的.env文件中OPENAI_API_KEY你的-api-key-here4.2 第一步定义工具 - 给Agent装上“手”工具是Agent能力的延伸。我们先创建一个模拟的天气查询工具。在实际应用中你会替换成真正的天气API如OpenWeatherMap。from langchain.tools import tool import random tool def get_current_weather(location: str) - str: 获取指定城市的当前天气。location参数是城市名例如“北京”或“San Francisco”。 # 模拟一些天气数据 weather_conditions [晴朗, 多云, 小雨, 大雪, 雾霾] temperatures { 北京: random.randint(-5, 10), 上海: random.randint(5, 15), 旧金山: random.randint(10, 20), 伦敦: random.randint(0, 8), } # 默认温度 temp temperatures.get(location, random.randint(0, 25)) condition random.choice(weather_conditions) return f{location}的当前天气是{condition}气温{temp}摄氏度。 # 测试工具 print(get_current_weather.invoke(北京))关键点使用tool装饰器将一个普通Python函数声明为LangChain工具。函数的文档字符串Docstring至关重要LLM就是通过阅读这个描述来理解工具用途的。描述要清晰、准确说明输入参数的意义。工具函数应该返回字符串或可序列化为字符串的对象作为给LLM的“观察Observation”。4.3 第二步初始化LLM与Agent - 组装“大脑”与“策略”接下来我们初始化大语言模型并创建一个使用ReAct策略的Agent。from langchain_openai import ChatOpenAI from langchain.agents import initialize_agent, AgentType from langchain.memory import ConversationBufferMemory import os from dotenv import load_dotenv load_dotenv() # 加载.env文件中的环境变量 # 1. 初始化LLM。我们使用gpt-3.5-turbo性价比高适合实验。 # 如果你遇到api error: 400可能是模型名称不对或参数错误请检查API文档。 llm ChatOpenAI( modelgpt-3.5-turbo, temperature0, # 温度设为0让输出更确定、更稳定适合工具调用 openai_api_keyos.getenv(OPENAI_API_KEY) ) # 2. 创建记忆。这里使用简单的对话缓冲区记住最近的对话。 memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) # 3. 定义工具列表 tools [get_current_weather] # 4. 初始化Agent agent initialize_agent( toolstools, llmllm, agentAgentType.ZERO_SHOT_REACT_DESCRIPTION, # 使用Zero-Shot ReAct代理 verboseTrue, # 开启详细日志方便我们看到Agent的“思考过程” memorymemory, handle_parsing_errorsTrue, # 处理解析错误当LLM输出格式不对时尝试修复 max_iterations5, # 防止Agent陷入死循环最多执行5轮思考-行动 early_stopping_methodgenerate # 达到最大迭代次数时强制LLM生成最终答案 ) print(Agent初始化完成)参数解析AgentType.ZERO_SHOT_REACT_DESCRIPTION这是我们选择的“思考策略”。它不需要示例Zero-Shot并遵循ReAct格式。verboseTrue强烈建议在开发时开启。你会看到Agent完整的“Thought/Action/Action Input/Observation”链条这是调试和理解其工作逻辑的窗口。handle_parsing_errorsTrueLLM有时会输出不符合预期格式的内容。这个参数让执行器尝试去理解和修复避免直接崩溃。max_iterations和early_stopping_method这是重要的安全阀。防止Agent因为逻辑错误或工具问题陷入无限循环消耗大量API调用。4.4 第三步运行与交互 - 让Agent动起来现在让我们向Agent提问。# 第一个问题 response agent.invoke({input: 北京现在的天气怎么样}) print(\n--- 用户问题1 ---) print(f问题北京现在的天气怎么样) print(f回答{response[output]}) # 第二个问题测试记忆能力 response2 agent.invoke({input: 那上海呢}) print(\n--- 用户问题2 ---) print(f问题那上海呢) print(f回答{response2[output]}) print(f\n当前记忆内容{memory.buffer})运行这段代码在控制台你会看到类似以下的详细输出因为verboseTrue Entering new AgentExecutor chain... Thought: 用户想知道北京的天气我需要使用天气查询工具。 Action: get_current_weather Action Input: {location: 北京} Observation: 北京的当前天气是小雨气温3摄氏度。 Thought: 我已经获得了北京的天气信息可以回答用户了。 Final Answer: 北京目前正在下小雨气温大约3摄氏度。 Finished chain. --- 用户问题1 --- 问题北京现在的天气怎么样 回答北京目前正在下小雨气温大约3摄氏度。 Entering new AgentExecutor chain... Thought: 用户问“那上海呢”结合之前的对话历史他应该是在问上海的天气。我需要再次使用天气查询工具。 Action: get_current_weather Action Input: {location: 上海} Observation: 上海的当前天气是晴朗气温12摄氏度。 Thought: 我已经获得了上海的天气信息可以回答用户了。 Final Answer: 上海目前天气晴朗气温大约12摄氏度。 Finished chain. --- 用户问题2 --- 问题那上海呢 回答上海目前天气晴朗气温大约12摄氏度。成功你看到了吗Agent成功理解了自然语言指令并正确选择了get_current_weather工具。它将“北京”和“上海”正确地提取为location参数。在第二个问题中它利用了记忆chat_history理解了“那上海呢”这个指代无需用户重复说明。整个“思考-行动-观察-回答”的过程清晰可见。4.5 第四步增强现实感 - 接入真实API让我们把模拟工具换成真实的天气API这里以OpenWeatherMap为例需要免费注册获取API Key。import requests from langchain.tools import tool tool def get_real_weather(location: str) - str: 使用OpenWeatherMap API获取指定城市的真实天气。location参数是城市名如London。 api_key 你的_openweathermap_api_key # 请替换成你的真实Key base_url http://api.openweathermap.org/data/2.5/weather params { q: location, appid: api_key, units: metric, # 使用摄氏度 lang: zh_cn } try: response requests.get(base_url, paramsparams, timeout10) data response.json() if response.status_code 200: city data[name] temp data[main][temp] desc data[weather][0][description] return f{city}的当前天气是{desc}气温{temp:.1f}摄氏度。 else: return f查询天气失败{data.get(message, 未知错误)} except Exception as e: return f调用天气API时发生异常{str(e)} # 更新工具列表并重新初始化Agent tools_v2 [get_real_weather] agent_v2 initialize_agent( toolstools_v2, llmllm, agentAgentType.ZERO_SHOT_REACT_DESCRIPTION, verboseTrue, memorymemory, # 可以复用之前的记忆 handle_parsing_errorsTrue ) # 测试真实API response_real agent_v2.invoke({input: 伦敦的天气如何}) print(response_real[output])现在你的Agent已经能提供真实的、实时的天气信息了这个模式可以扩展到任何你有API或能通过代码访问的服务股票、新闻、数据库、企业内部系统等等。5. 高级模式与实战技巧超越基础问答构建出第一个能跑通的Agent只是起点。在实际项目中你会遇到更复杂的需求。下面分享几个进阶模式和避坑经验。5.1 多工具协作与顺序控制一个强大的Agent往往配备多个工具。LLM如何知道该用哪个这依赖于清晰的工具描述和Prompt设计。但有时任务有严格的顺序比如“先查天气如果下雨就提醒我带伞”。基础的ReAct Agent能处理简单序列但对于复杂工作流可能需要更精细的控制。这时你可以考虑LangGraph。它是LangChain生态中用于构建有状态、多参与者Agent工作流的框架。你可以把每个步骤调用工具、条件判断定义为一个节点通过边来控制流程。# 这是一个LangGraph的简化概念示例实际代码更复杂 # 假设我们有两个工具get_weather(获取天气), send_alert(发送提醒) # 工作流获取天气 - 判断是否下雨 - 是则发送提醒 from langgraph.graph import StateGraph, END def router(state): 根据天气决定下一步 if 雨 in state[weather_result]: return send_alert else: return END # 构建图定义节点和路由逻辑 graph_builder StateGraph() graph_builder.add_node(get_weather, call_weather_tool) graph_builder.add_node(send_alert, call_alert_tool) graph_builder.set_entry_point(get_weather) graph_builder.add_conditional_edges(get_weather, router) # 条件路由 graph_builder.add_edge(send_alert, END) workflow graph_builder.compile() # 运行工作流 result workflow.invoke({location: 上海})对于大多数顺序明确的链式任务使用LangChain的SequentialChain或TransformationChain也能很好地解决。选择哪种取决于你的流程是“智能规划驱动”还是“固定流程驱动”。5.2 处理复杂输出与结构化数据工具返回的可能是复杂的JSON或对象直接丢给LLM可能信息过载。好的做法是在工具内部或返回前将数据提炼成简洁、自然的语言描述。例如数据库查询工具不应返回100行原始数据而应返回如“查询到最近一周有50笔订单总金额为12,000元”的总结。另一种方法是使用Pydantic工具。你可以定义一个Pydantic模型来描述工具的输出结构LangChain能更好地处理它。from pydantic import BaseModel, Field from langchain.tools import StructuredTool class WeatherOutput(BaseModel): location: str Field(description城市名称) temperature: float Field(description温度摄氏度) condition: str Field(description天气状况描述) humidity: int Field(description湿度百分比) def get_weather_structured(location: str) - WeatherOutput: # ... 调用API ... data api_call(location) return WeatherOutput( locationdata[name], temperaturedata[main][temp], conditiondata[weather][0][description], humiditydata[main][humidity] ) # 创建结构化工具 structured_tool StructuredTool.from_function( funcget_weather_structured, nameGetStructuredWeather, description获取结构化天气信息, args_schema... # 也可以定义输入模型 )5.3 记忆的优化从缓冲区到向量检索ConversationBufferMemory简单但容量有限对话长了就会丢失早期信息。对于需要长期记忆的场景如个性化助手有几种升级方案ConversationSummaryMemory每次交互后让LLM自动生成对话摘要保存起来只把摘要和最近几条原始记录作为上下文。这能显著压缩Token占用。ConversationSummaryBufferMemory结合缓冲区和摘要保留最近N条原始记录更早的则汇总成摘要。VectorStoreRetrieverMemory这是更强大的长期记忆。将每次对话的片段或用户/AI的发言转换成向量存入向量数据库如Chroma、FAISS。当需要回忆时根据当前问题的语义进行相似度搜索找回最相关的历史片段。这实现了基于“意义”的记忆检索而不是简单的时间顺序。from langchain.memory import VectorStoreRetrieverMemory from langchain.embeddings import OpenAIEmbeddings from langchain.vectorstores import Chroma # 创建向量数据库作为记忆后端 embeddings OpenAIEmbeddings() vectorstore Chroma(embedding_functionembeddings, persist_directory./chroma_db_memory) retriever vectorstore.as_retriever(search_kwargs{k: 3}) # 检索最相关的3条记忆 memory VectorStoreRetrieverMemory( retrieverretriever, memory_keychat_history, input_keyinput ) # 使用此memory的Agent能在对话中“想起”很久以前相关的讨论。5.4 提示工程Prompt Engineering的威力Agent的表现极大程度上受限于给LLM的提示词。一个精心设计的系统提示System Prompt能显著提升其可靠性和准确性。在你的Agent初始化中可以通过agent_kwargs参数来自定义提示词。from langchain.prompts import MessagesPlaceholder from langchain.agents import OpenAIFunctionsAgent system_prompt 你是一个专业的天气与出行助手。你的职责是准确回答用户关于天气的查询并根据天气情况提供贴心的出行建议。 你拥有一个名为get_current_weather的工具可以查询任何城市的实时天气。 请严格按照以下步骤工作 1. 如果用户询问天气你必须使用工具查询。 2. 得到天气信息后结合常识如下雨建议带伞高温建议防晒提供简短的出行建议。 3. 如果用户的问题与天气无关请礼貌地告知你的能力范围。 请始终以友好、专业的口吻回答。 prompt OpenAIFunctionsAgent.create_prompt( system_messagesystem_prompt, extra_prompt_messages[MessagesPlaceholder(variable_namechat_history)] ) agent_custom initialize_agent( toolstools, llmllm, agentAgentType.OPENAI_FUNCTIONS, # 使用OpenAI函数代理与自定义提示兼容性好 verboseTrue, memorymemory, agent_kwargs{prompt: prompt}, # 注入自定义提示 )这个提示词明确了角色、职责、工具使用规则和输出风格能引导LLM做出更符合预期的行为。6. 常见问题、调试技巧与性能优化在实际开发中你一定会遇到各种问题。下面是一些高频问题和我踩过的坑。6.1 Agent陷入循环或行为异常症状Agent不停地调用同一个工具或者在不该调用工具的时候调用始终无法输出Final Answer。检查工具描述工具的描述是否清晰、无歧义LLM是否可能误解了工具的用途确保描述简洁准确避免使用可能混淆的词汇。调整Prompt在系统提示中明确给出停止条件例如“当你获得了足够的信息来直接、完整地回答用户问题时请输出Final Answer不要再次调用工具。”设置迭代限制务必设置max_iterations如5-10次这是最后的防线。使用verboseTrue调试仔细观察“Thought”部分。如果LLM的思考逻辑混乱可能是Prompt或模型能力问题。尝试换用更强大的模型如GPT-4进行测试对比。检查Action Input格式对于ZERO_SHOT_REACT_DESCRIPTION代理要求Action Input是一个字符串。如果你的工具期望JSONLLM需要输出像{location: 北京}这样的字符串。有时LLM会忘记引号或格式错误导致解析失败。可以在Prompt中明确格式示例。6.2 处理解析错误Parsing Errors症状控制台报错ValueError: Could not parse LLM output: ...。启用handle_parsing_errorsTrue这是第一道保险执行器会尝试让LLM重试或修复输出。输出格式强化在Prompt中使用更严格的示例Few-Shot Prompting展示正确的输出格式。更换代理类型OPENAI_FUNCTIONS或STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION代理类型利用了大模型原生的结构化输出能力通常比纯文本解析的ZERO_SHOT_REACT_DESCRIPTION更稳定。6.3 工具调用失败或超时症状工具执行抛出异常导致Agent流程中断。工具函数的健壮性在工具函数内部进行完善的错误处理try...except并返回有意义的错误信息字符串而不是抛出异常。例如return f工具执行失败{str(e)}。这样Observation里会是错误描述LLM可以据此进行下一步决策比如重试或告知用户失败。设置超时对于网络请求类工具务必设置超时参数如requests.get(timeout10)避免长时间阻塞。使用备用工具对于关键功能可以设计两个实现相同功能的工具如不同的搜索API在初始化Agent时都提供。LLM可能会在第一个失败后尝试另一个。6.4 控制成本与延迟症状API调用费用增长快或Agent响应速度慢。缓存Caching对重复的查询进行缓存。LangChain内置了SQLiteCache或RedisCache。例如对相同的天气查询可以直接返回缓存结果避免重复调用昂贵的LLM和外部API。from langchain.cache import SQLiteCache import langchain langchain.llm_cache SQLiteCache(database_path.langchain.db)限制工具使用在Prompt中强调“仅在必要时使用工具”。对于简单、常识性问题鼓励LLM直接回答。优化上下文长度使用ConversationSummaryMemory或ConversationSummaryBufferMemory来减少送入LLM的历史Token数量。定期清理无关的记忆。选择性价比高的模型对于工具调用等逻辑性强的任务gpt-3.5-turbo通常足够且便宜。对于需要复杂推理或创意生成的任务再考虑gpt-4。6.5 安全性与可靠性考量工具权限隔离不是所有工具都应被所有用户或所有问题触发。考虑实现一个工具路由层根据用户身份或问题内容动态过滤可用的工具列表。例如只有管理员才能使用“删除数据库”工具。输入验证与清理在工具函数内部对所有输入参数进行严格的验证和清理防止注入攻击。特别是执行代码或系统命令的工具风险极高应避免或在极度受控的沙箱中使用。监控与审计记录Agent所有的“Thought”、“Action”和“Observation”。这不仅是调试的需要也是事后审查、理解AI决策过程、发现潜在偏见或错误的关键。构建一个成熟、可靠的Agent系统是一个持续迭代和优化的过程。从最简单的原型开始逐步增加工具、优化提示、完善错误处理、引入记忆和流程控制你会慢慢体会到将大模型从“聊天玩具”转变为“生产力工具”的巨大潜力。这条路虽然比直接调API复杂但它通向的是真正智能、自主的下一代应用。