尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

LangChain工具调用:从原理到实战,构建能行动的AI智能体

LangChain工具调用:从原理到实战,构建能行动的AI智能体 1. 从“玩具”到“工具”为什么我们需要LangChain的工具调用能力如果你和我一样在早期接触大语言模型LLM时大概率会经历一个“兴奋-困惑-冷静”的过程。兴奋于它能写诗、能对话、能生成代码困惑于它怎么连今天的天气都查不了或者让它算个复杂点的账目它就开始一本正经地胡说八道最后冷静下来意识到LLM本质上是一个强大的“文本预测器”它没有感知能力也无法直接操作外部世界。这就是LLM的“幻觉”问题也是其能力的边界。它知道“如何描述查询天气的API”但它自己并不会去调用这个API。它理解“计算器”的概念但无法执行22的运算。要让LLM从一个“聪明的聊天玩具”变成一个真正能解决问题的“智能工具”就必须赋予它“手”和“脚”——也就是调用外部工具的能力。这正是LangChain框架中“工具调用”Tool Calling或“代理”Agent模块的核心价值所在。简单来说工具调用就是让LLM学会在需要的时候说一句“这事儿我干不了但我可以调用某个工具来干”然后由系统去执行这个工具并把结果喂回给LLM让它继续思考或回答。这个过程模拟了人类专家在解决问题时的行为我们的大脑LLM负责规划、决策和整合信息而我们的手、计算器、搜索引擎外部工具则负责执行具体的、确定性的任务。为什么这如此重要因为现实世界的问题很少是纯文本生成问题。一个完整的智能应用往往是“LLM的推理能力”与“专用工具的精确能力”的结合。比如一个智能数据分析助手LLM理解用户用自然语言提出的问题如“上个月华东区销售额最高的产品是什么”然后调用SQL查询工具从数据库中获取精确数据最后LLM再将数据组织成人类可读的报告。一个自动化客服机器人LLM判断用户意图是“查询订单状态”则调用订单查询API获取物流信息后再组织语言回复给用户。一个代码生成与执行环境LLM根据需求生成Python代码片段然后调用一个安全的代码执行工具如Docker沙箱来运行这段代码验证结果是否正确。没有工具调用LLM就像是一个被关在玻璃房里的天才能看到世界却无法触碰。LangChain提供了一套标准化的、优雅的“接口”和“工作流”让开发者能够相对轻松地为LLM装配上各种“义肢”从而构建出功能强大、可靠的AI应用。这不仅仅是技术上的优化更是应用范式从“对话”到“行动”的关键跃迁。2. 核心原理拆解LLM是如何“思考”并“决定”使用工具的要理解LangChain的工具调用我们不能只停留在API层面必须深入到其背后的工作原理。这个过程本质上是一个规划-决策-执行的循环。LangChain通过其Agent和Tool的抽象将这个循环标准化了。2.1 工具Tool的本质一个可被描述的“函数”在LangChain中一个Tool就是一个包装好的、可以被LLM调用的函数。但关键在于这个函数必须有一个清晰的“描述”告诉LLM它是干什么的。这个描述通常包括名称name一个简短的标识符如search、calculator。描述description用自然语言详细说明这个工具的功能、输入和输出。这是最重要的部分LLM完全依赖这段描述来判断是否以及如何调用它。例如一个计算器工具的描述可能是“一个用于执行数学运算的工具。输入一个数学表达式字符串如‘22’或‘sin(30)’返回计算结果。”参数模式args_schema可选但推荐使用。用Pydantic模型明确定义工具需要的参数名称、类型和说明这能让LLM更精确地生成调用参数。为什么描述如此重要因为LLM在“思考”时并不是直接“看到”你的代码。它看到的是你提供给它的“上下文”其中就包含了所有可用工具的描述列表。LLM通过理解这些描述来构建一个关于“我能指挥哪些资源”的心理地图。2.2 代理Agent的大脑ReAct模式与思维链LangChain的代理Agent是协调LLM和工具的核心“大脑”。最经典、最有效的模式之一是ReActReason Act。ReAct模式模拟了人类解决问题时的思考过程思考ThoughtLLM分析当前情况用户问题、已有信息、可用工具并推理出下一步应该做什么。例如“用户问今天北京的天气。我需要一个能获取实时天气的工具。”行动Action基于上一步的思考LLM生成一个具体的“动作”。这个动作就是工具调用格式通常是Action: 工具名称和Action Input: 工具输入参数。例如Action: get_weatherAction Input: {location: 北京}。观察Observation系统执行指定的工具并将执行结果成功或失败返回给LLM。例如Observation: 北京今天晴气温15-25摄氏度空气质量良。循环LLM接收到观察结果后再次进入“思考”阶段判断问题是否已解决。如果未解决则继续“行动-观察”的循环如果已解决则最终生成给用户的“回答Final Answer”。这个过程的核心是“思维链”Chain-of-Thought的显式化。早期的简单提示如“直接回答用户问题”会让LLM试图一次性生成答案容易产生幻觉或错误。而ReAct强制LLM“把思考过程说出来”这大大提高了其推理的可靠性和可追溯性。在LangChain中你通常会看到类似这样的对话历史被构建起来Human: 今天北京和上海哪个更热 AI Thought: 我需要比较北京和上海的天气。我需要分别获取两地的天气信息。 AI Action: get_weather Action Input: {location: 北京} Observation: 北京晴15-25°C。 AI Thought: 我得到了北京的天气。现在需要上海的天气。 AI Action: get_weather Action Input: {location: 上海} Observation: 上海多云18-28°C。 AI Thought: 北京最高25度上海最高28度所以上海更热。我可以给出最终答案了。 AI Final Answer: 根据实时天气信息上海最高28°C比北京最高25°C更热一些。2.3 模型的支持Function Calling 与 Tool Calling为了让LLM能稳定地输出结构化的Action和Action Input而不是自由发挥的文本OpenAI等模型提供商引入了Function Calling能力现在OpenAI的API中已演进为Tool Calling。这本质上是对模型输出的一种“约束”和“格式化”。它的工作流程是定义工具列表在向LLM发送请求时除了常规的对话消息Message还会附带一个“工具”Tools列表其中每个工具都有name,description,parameters(符合JSON Schema格式)。模型决策LLM根据对话历史和工具描述判断是否需要调用工具。如果需要它不会生成普通文本回复而是生成一个特殊的、结构化的响应指明它想调用哪个工具以及具体的参数是什么。这个响应是一个标准的JSON对象。系统执行你的应用程序解析这个JSON找到对应的本地函数用提供的参数执行它。结果返回将工具执行的结果作为一条新的“工具结果”消息追加到对话历史中再次发送给LLM让它基于结果继续生成回复。LangChain的价值在于它为你封装了这一切。你不需要手动拼接这些复杂的消息格式也不需要自己解析JSON。你只需要用LangChain的方式定义好Tool然后选择一个支持工具调用的LLM如ChatOpenAI和一个Agent类型如create_react_agentLangChain就会在底层帮你处理好与模型的通信、工具调用的触发和结果的回传。这极大地降低了开发门槛。注意不是所有模型都原生支持工具调用。对于不支持的模型LangChain会尝试通过巧妙的提示词工程Prompt Engineering来“诱导”模型输出结构化的内容但稳定性和准确性通常不如原生支持的工具调用。因此在选型时优先选择像GPT-4、Claude 3、DeepSeek等明确支持此功能的模型。3. 从零到一构建你的第一个工具调用代理理论讲得再多不如亲手跑通一个例子来得实在。下面我将带你一步步构建一个最简单的、具备工具调用能力的智能代理。这个代理将拥有两个工具一个计算器和一个模拟的网络搜索工具。3.1 环境准备与依赖安装首先确保你有一个Python环境建议3.8以上。我们使用pip安装必要的包。这里的关键是langchain核心库和对应LLM的集成包以OpenAI为例。# 安装LangChain核心库和OpenAI集成 pip install langchain langchain-openai # 安装用于定义工具参数模型的PydanticLangChain常用 pip install pydantic接下来你需要一个OpenAI的API密钥。如果你没有可以去OpenAI官网注册获取。在代码中我们通常通过环境变量来管理密钥这样更安全。# 在终端中设置环境变量Linux/macOS export OPENAI_API_KEY你的-api-key-here # 在Windows命令提示符中 set OPENAI_API_KEY你的-api-key-here # 或者在Windows PowerShell中 $env:OPENAI_API_KEY你的-api-key-here3.2 定义你的第一个工具我们将创建两个工具。第一个是计算器使用Python的eval函数注意在生产环境中使用eval是极度危险的这里仅用于演示后面会讲安全替代方案。第二个是一个模拟的搜索工具它只是返回一个固定的字符串。from langchain.tools import tool from pydantic import BaseModel, Field import math # 定义计算器工具的输入参数模型 class CalculatorInput(BaseModel): expression: str Field(description一个有效的数学表达式例如 22 或 sqrt(16)) # 使用 tool 装饰器创建工具 tool(args_schemaCalculatorInput) def calculator(expression: str) - str: 执行数学计算。支持加减乘除(,-,*,/)、乘方(**)、括号和常见数学函数如sqrt, sin, cos等。 try: # 警告实际生产环境应对表达式做严格的安全检查和沙箱执行 result eval(expression, {__builtins__: None}, {sqrt: math.sqrt, sin: math.sin, cos: math.cos, pi: math.pi}) return str(result) except Exception as e: return f计算错误{e} # 定义搜索工具的输入参数模型 class SearchInput(BaseModel): query: str Field(description一个用于搜索的查询字符串) tool(args_schemaSearchInput) def search_web(query: str) - str: 模拟一个网络搜索引擎。根据查询返回模拟的结果。 # 这里只是一个模拟。真实场景下这里会调用Google Search API、SerpAPI等。 return f关于{query}的模拟搜索结果这是一个非常热门的话题涉及多个方面。根据最新信息其核心要点是...代码解读与避坑点tool装饰器这是LangChain提供的便捷方式能将一个普通Python函数包装成Tool对象。args_schema参数指定了输入模型这能让LLM更准确地生成调用参数。description参数在Field和函数文档字符串...中我们都提供了描述。LangChain会优先使用装饰器args_schema中Field的description如果未设置则会使用函数文档字符串。清晰、准确的描述是工具调用成功的关键。安全警告示例中的calculator工具使用了eval这允许执行任意Python代码是严重的安全漏洞。在实际项目中绝对不要这样用应该使用安全的数学表达式解析库如asteval、numexpr或者将计算任务交给专门的API或沙箱环境。3.3 组装代理并运行现在我们将工具、LLM和代理执行器Agent Executor组合起来。from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain import hub # 1. 初始化LLM选择支持工具调用的模型 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # temperature0使输出更确定 # 2. 准备工具列表 tools [calculator, search_web] # 3. 获取一个预设的ReAct提示词模板 # LangChain Hub是一个提示词仓库hwchase17/react 是一个经典的ReAct模板。 prompt hub.pull(hwchase17/react) # 4. 创建ReAct代理 agent create_react_agent(llm, tools, prompt) # 5. 创建代理执行器它负责管理思考-行动-观察的循环 agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue) # 6. 运行代理 question “请先计算 (3的4次方) 除以 5 是多少然后搜索一下‘人工智能的最新发展趋势’。” result agent_executor.invoke({input: question}) print(result[output])运行这段代码你将看到类似以下的详细输出因为设置了verboseTrue Entering new AgentExecutor chain... 我需要回答一个包含两个部分的问题先计算一个数学表达式然后进行搜索。 首先我需要计算 (3的4次方) 除以 5。这需要一个计算器工具。 Action: calculator Action Input: {expression: (3**4)/5} Observation: 16.2 我已经得到了计算结果16.2。现在需要执行第二部分搜索“人工智能的最新发展趋势”。我需要使用搜索工具。 Action: search_web Action Input: {query: 人工智能的最新发展趋势} Observation: 关于‘人工智能的最新发展趋势’的模拟搜索结果这是一个非常热门的话题涉及多个方面。根据最新信息其核心要点是... 现在我有两部分的信息计算结果是16.2以及关于AI趋势的模拟搜索结果。我可以综合这些来给出最终答案。 Final Answer: 计算结果(3的4次方)除以5等于16.2。关于人工智能的最新发展趋势根据搜索信息这是一个涵盖大模型多模态、AI智能体Agent、具身智能等多个方向的快速演进领域。 Finished chain.关键点解析AgentExecutor这是真正的“发动机”。它控制着循环将输入和对话历史传给agent即LLM提示词解析LLM的输出调用工具将结果作为新的Observation加入历史然后继续循环直到LLM输出Final Answer。verboseTrue这是一个极其有用的调试参数。它能将代理的完整思考链Thought-Action-Observation打印出来让你清晰地看到LLM的“内心活动”和决策过程对于排查问题至关重要。handle_parsing_errorsTrue当LLM的输出格式不符合工具调用预期解析失败时这个参数会让执行器尝试修复或给出友好错误而不是直接崩溃。提示词模板我们使用了hwchase17/react这个预设模板。这个模板已经写好了ReAct框架所需的指令如“你可以使用以下工具...”“思考过程...”等。你也可以完全自定义提示词但对于入门使用成熟模板是最快的方式。至此你已经成功创建了一个具备基础工具调用能力的AI代理。它能够理解复杂指令自主规划步骤并正确调用工具完成任务。4. 进阶实战构建一个真实可用的多功能AI助手一个简单的计算和搜索代理只是个开始。真正的挑战在于将这套机制应用于解决实际问题。下面我们来构建一个更贴近真实场景的“个人知识库问答助手”。这个助手能从本地文档如PDF、TXT中提取信息并建立索引使用RAG技术。回答用户基于文档的提问。在问题涉及外部实时信息如天气、股价时自动调用网络搜索工具。这个例子将融合LangChain的多个核心概念文档加载、文本分割、向量化存储RAG、检索以及工具调用。4.1 场景设计与架构假设你是一个项目经理电脑里有很多项目相关的文档需求说明书、会议纪要等。你想快速从这些文档中查找信息同时对于一些需要最新市场数据的问题助手也能联网搜索。系统工作流如下初始化阶段加载所有本地文档进行文本分割转换为向量Embedding并存入向量数据库如Chroma。问答阶段用户提问。代理LLM首先判断这个问题能从本地知识库中找到答案吗还是需要实时信息如果需要本地知识则调用“知识库检索工具”从向量库中找到相关文档片段。如果需要实时信息则调用“网络搜索工具”。LLM综合工具返回的结果生成最终答案。4.2 实现步骤与代码详解首先安装额外的依赖。pip install chromadb langchain-chroma tiktoken pypdf接下来是完整的实现代码import os from pathlib import Path from langchain_openai import ChatOpenAI, OpenAIEmbeddings from langchain_community.document_loaders import PyPDFLoader, TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_chroma import Chroma from langchain.tools.retriever import create_retriever_tool from langchain.tools import Tool from langchain.agents import create_react_agent, AgentExecutor from langchain import hub from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain.agents.format_scratchpad import format_log_to_str from langchain.agents.output_parsers import ReActSingleInputOutputParser # --- 第一部分构建知识库RAG --- def build_knowledge_base(doc_dir: str, persist_directory: str “./chroma_db”): 加载文档分割嵌入并持久化到向量数据库 documents [] for file_path in Path(doc_dir).glob(“*”): if file_path.suffix “.pdf”: loader PyPDFLoader(str(file_path)) elif file_path.suffix “.txt”: loader TextLoader(str(file_path)) else: continue documents.extend(loader.load()) print(f“已加载 {len(documents)} 个文档片段”) # 文本分割将长文档切成小块便于检索 text_splitter RecursiveCharacterTextSplitter(chunk_size1000, chunk_overlap200) splits text_splitter.split_documents(documents) print(f“分割为 {len(splits)} 个文本块”) # 创建嵌入模型和向量库 embeddings OpenAIEmbeddings() vectordb Chroma.from_documents( documentssplits, embeddingembeddings, persist_directorypersist_directory ) vectordb.persist() print(f“知识库已构建并保存至 {persist_directory}”) return vectordb # 假设你的文档放在 ./my_docs 目录下 # 首次运行需要构建知识库 # vectordb build_knowledge_base(“./my_docs”) # 之后可以直接加载 vectordb Chroma(persist_directory“./chroma_db”, embedding_functionOpenAIEmbeddings()) retriever vectordb.as_retriever(search_kwargs{“k”: 4}) # 检索最相关的4个片段 # --- 第二部分定义工具 --- # 工具1知识库检索工具 retriever_tool create_retriever_tool( retriever, “project_docs_search”, “在本地项目文档知识库中搜索信息。当用户询问关于项目需求、会议内容、技术细节等已知文档中的内容时使用此工具。” ) # 工具2增强版网络搜索工具模拟 def enhanced_search(query: str) - str: 一个增强的模拟搜索工具能根据查询类型返回更结构化的模拟数据。 # 在实际应用中这里应集成SerpAPI、Google Search API或Bing API等。 query_lower query.lower() if “天气” in query_lower: return f“模拟天气数据查询‘{query}’。北京晴15-25°C上海多云18-28°C。数据来源模拟气象站” elif “股价” in query_lower or “stock” in query_lower: return f“模拟股价数据查询‘{query}’。AAPL: $172.50 (1.2%)MSFT: $415.00 (0.8%)。数据来源模拟金融终端” else: return f“关于‘{query}’的网络搜索结果摘要这是一个广泛讨论的议题。当前焦点包括技术突破、行业应用和伦理治理等方面。建议查阅权威行业报告获取最新动态。” search_tool Tool.from_function( funcenhanced_search, name“web_search”, description“用于获取实时或最新信息的网络搜索工具。当问题涉及当前天气、股票价格、新闻、最新技术动态等不在本地知识库的信息时使用此工具。” ) tools [retriever_tool, search_tool] # --- 第三部分构建自定义代理 --- llm ChatOpenAI(model“gpt-4”, temperature0) # 使用能力更强的GPT-4处理复杂规划 # 自定义提示词模板更清晰地定义代理的角色和能力 prompt_template ChatPromptTemplate.from_messages([ (“system”, “””你是一个专业的项目助理拥有两个能力 1. 从本地项目文档知识库中搜索信息。 2. 使用网络搜索获取实时信息。 请严格按照以下步骤工作 1. 仔细分析用户的问题。 2. 判断问题答案是否可能存在于本地项目文档中如需求、会议记录、设计稿等。如果是使用 project_docs_search 工具。 3. 如果问题明显是关于实时信息、通用知识或文档中绝对没有的内容如天气、股价、新闻则使用 web_search 工具。 4. 根据工具返回的结果组织语言清晰、准确地回答用户。 请始终使用提供的工具。你的思考过程应简短清晰。”””), MessagesPlaceholder(variable_name“chat_history”), (“user”, “{input}”), MessagesPlaceholder(variable_name“agent_scratchpad”), ]) # 构建代理 agent ( { “input”: lambda x: x[“input”], “chat_history”: lambda x: x.get(“chat_history”, []), “agent_scratchpad”: lambda x: format_log_to_str(x[“intermediate_steps”]), } | prompt_template | llm | ReActSingleInputOutputParser() ) # 创建执行器 agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, max_iterations5, handle_parsing_errorsTrue) # --- 第四部分测试运行 --- print(“ 测试1知识库查询 ) result1 agent_executor.invoke({“input”: “我们项目第三阶段的交付物主要有哪些”}) print(“回答”, result1[“output”]) print(“\n”) print(“ 测试2实时信息查询 ) result2 agent_executor.invoke({“input”: “今天纽约的天气怎么样这会影响我们下周的跨国会议吗”}) print(“回答”, result2[“output”]) print(“\n”) print(“ 测试3混合查询 ) result3 agent_executor.invoke({ “input”: “根据项目文档我们的核心竞品是谁另外查一下这家公司最近的股价表现。” }) print(“回答”, result3[“output”])核心要点与深度解析RAG与工具调用的结合create_retriever_tool是LangChain提供的一个非常便捷的函数它能将一个检索器Retriever直接包装成一个工具。当代理调用这个工具时它会将用户的查询或LLM提炼后的查询输入检索器从向量数据库中找到相关文档片段并将这些片段作为“观察结果”返回给LLM。LLM再基于这些上下文生成答案。这完美解决了LLM的“知识截止”和“幻觉”问题让答案有据可依。工具描述的精准性注意我们为两个工具撰写的description。对project_docs_search我们限定了范围“当用户询问关于项目需求、会议内容、技术细节等已知文档中的内容时”。这能引导LLM在相关问题时优先使用它。对web_search我们明确了使用场景“当问题涉及当前天气、股票价格、新闻、最新技术动态等不在本地知识库的信息时”。清晰的描述是代理正确进行工具路由Tool Routing的基石。自定义提示词的力量我们没有使用默认的react模板而是自己写了一个system提示词。这个提示词更具体地定义了代理的角色、可用的工具、以及决策逻辑先判断问题类型再选择工具。通过精心设计的提示词你可以极大地提升代理的决策准确性和可靠性。这是高级应用中的关键技巧。代理的构建方式我们使用了更底层的LCELLangChain Expression Language方式来构建代理input | prompt | llm | parser。这种方式提供了极大的灵活性允许你精细控制输入输出的格式和流程。format_log_to_str函数负责将之前的“思考-行动”历史格式化成字符串放入agent_scratchpad中供LLM在下一轮思考时参考。max_iterations参数这个参数限制了代理“思考-行动”循环的最大次数防止在复杂或循环问题上陷入死循环。一般设置为5-10次是安全的。通过这个实战案例你将一个简单的工具调用代理升级成了一个能够结合静态知识和动态信息的智能助手。这种架构模式正是当前AI应用落地的典型范式。5. 避坑指南与生产环境最佳实践在开发工具调用应用时你会遇到各种各样的问题。以下是我从实际项目中总结出的常见“坑”及其解决方案以及面向生产环境的建议。5.1 工具调用失败解析错误与路由错误问题现象代理输出混乱没有正确调用工具或者调用工具时参数格式错误。根因与排查模型不支持或提示词不当确保你使用的LLM如gpt-3.5-turbo-1106及以上版本、gpt-4、claude-3支持工具调用。对于不支持的工具调用模型需要更复杂的提示词工程。工具描述不清这是最常见的原因。LLM完全依赖描述来理解工具。描述必须准确、无歧义、包含输入输出示例。避免使用模糊词汇。对比以下两种描述差“一个搜索工具。”太模糊搜什么怎么搜好“一个用于获取最新新闻和实时信息的网络搜索工具。输入一个搜索关键词如‘OpenAI最新发布会’返回相关的新闻摘要和链接。”参数模式args_schema缺失或不匹配强烈建议为每个工具定义args_schemaPydantic模型。这为LLM提供了明确的参数JSON Schema能显著提高参数生成的准确性。确保Field(description...)中对每个参数的描述清晰。提示词未明确要求使用工具在system提示词中必须明确指令代理“你可以使用以下工具...”并鼓励它在需要时使用工具。可以参考LangChain Hub上的标准ReAct或OpenAI Functions代理提示词。解决方案开启verboseTrue这是第一诊断步骤。观察LLM的Thought看它是否正确地识别了需要使用工具以及它选择的Action和Action Input是什么。简化测试先用一个最简单的工具和问题测试整个流程是否通畅。迭代优化描述根据verbose日志反复修改工具描述和提示词直到代理能稳定做出正确决策。5.2 处理复杂逻辑与多轮对话问题用户的问题可能需要多个工具按特定顺序调用或者依赖前几轮对话的上下文。解决方案利用AgentExecutor的memoryAgentExecutor可以配置记忆Memory如ConversationBufferMemory。这样每一轮的输入、输出和中间步骤都会自动保存到对话历史中。在下一轮提问时这些历史会作为上下文提供给LLM使其能处理指代如“它”、“上面提到的”和连贯的多轮任务。from langchain.memory import ConversationBufferMemory memory ConversationBufferMemory(memory_key“chat_history”, return_messagesTrue) agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, memorymemory) # 后续调用时会自动管理历史 agent_executor.invoke({“input”: “第一个问题...”}) agent_executor.invoke({“input”: “那么针对刚才说的它的优势是什么”}) # 这里能引用历史设计更智能的工具有时与其让代理笨拙地调用多个工具不如设计一个“宏工具”Macro-Tool在工具内部完成一系列子操作。例如一个“生成项目周报”的工具内部可以依次调用“获取本周任务列表”、“查询完成状态”、“汇总风险信息”等多个函数最后返回一个整合的报告。这降低了代理的规划难度。5.3 性能、安全与成本优化1. 控制成本与延迟设置超时与最大迭代次数AgentExecutor(max_iterations5, max_execution_time30)可以防止代理在复杂问题上无限循环消耗大量Token和时间。缓存Caching对于重复的、确定性的工具调用结果如对相同查询的搜索可以使用缓存。LangChain支持多种缓存后端如InMemoryCache, RedisCache能有效降低API调用次数和成本。使用更便宜的模型进行路由对于简单的工具选择路由决策可以使用gpt-3.5-turbo这类更便宜、更快的模型。只有需要复杂推理或生成最终答案时才调用gpt-4。2. 增强安全性与可靠性永远不要信任LLM的输入LLM生成的工具参数可能包含恶意内容。在工具函数内部必须对输入进行严格的验证、清洗和转义。绝对禁止将未经处理的LLM输出直接用于系统命令执行os.system、数据库查询拼接SQL或eval。实施用户权限控制不同的用户可能拥有不同的工具调用权限。在调用工具前应检查当前用户是否有权执行此操作。为工具添加异常处理工具函数内部应有完善的try...except返回清晰的错误信息而不是让整个代理崩溃。使用“人工确认”环节对于高风险操作如发送邮件、修改数据库、执行支付可以让代理在调用工具前先输出一个需要用户确认的提示待用户批准后再执行。这可以通过设计特殊的“确认工具”或在前端实现。3. 监控与评估记录完整的执行轨迹保存每一次代理运行的intermediate_steps思考、行动、观察。这是分析和改进代理行为、排查问题的最宝贵数据。定义评估指标对于问答类应用可以评估最终答案的准确性基于事实对于任务完成类应用可以评估任务是否成功完成。通过A/B测试不同的提示词、工具描述或模型来持续优化代理性能。工具调用是LangChain最强大也最复杂的特性之一。从原理理解到入门实践再到生产级部署每一步都需要细致的考量和设计。它不是一个“开箱即用”的魔法而是一个需要你精心设计工具、编写提示词、并不断调试优化的系统工程。但一旦跑通你将真正释放LLM的潜力构建出能够理解、规划并作用于真实世界的智能体。
返回列表