05-工具与MCP

📅 2026/6/25 17:23:32
05-工具与MCP
第05章工具与 MCPTools版本LangChain v1.3.7 | 讲师汤姆小白1. Tools 概述1.1 什么是工具大模型只能生成文本无法与外部世界交互。Tools工具为 LLM 装上手脚让它能调用 API、搜索互联网、查询数据库、执行代码、操作文件等。用户提问 → LLM 思考 → 决定调用工具 → 执行工具 → 获取结果 → 继续推理1.2 工具的构成要素每个 Tool 包含以下要素要素说明示例name唯一标识名称web_searchdescription功能描述LLM 据此判断何时调用搜索互联网获取最新信息args_schema参数 JSON SchemaPydantic 模型{query: string}func实际执行的函数调用搜索 APIreturn_direct是否直接返回结果给用户False让 Agent 继续Tool 的 name 和 description 至关重要——LLM 完全靠这两项判断何时调用哪个工具。2. 自定义工具2.1 tool 装饰器最简单fromlangchain_core.toolsimporttooltooldefadd(a:int,b:int)-int:两个整数相加returnabprint(add.name)# addprint(add.description)# 两个整数相加print(add.args)# {a: {type: integer}, b: {type: integer}}# 调用resultadd.invoke({a:10,b:20})# 30自定义名称和描述tool(calculator,description执行数学计算,return_directTrue)defcalculate(expression:str)-float:计算数学表达式returneval(expression)使用 Pydantic 完善参数描述frompydanticimportBaseModel,FieldclassSearchInput(BaseModel):query:strField(description搜索关键词)max_results:intField(default5,description最大结果数)tool(args_schemaSearchInput)defweb_search(query:str,max_results:int5)-str:搜索互联网获取信息# 实际调用搜索 APIreturnf关于 {query} 的搜索结果...2.2 StructuredTool.from_function更灵活fromlangchain_core.toolsimportStructuredTooldefget_weather(city:str)-str:获取城市天气returnf{city}今天晴28°Cweather_toolStructuredTool.from_function(funcget_weather,nameget_weather,description查询指定城市的天气情况,)weather_tool.invoke({city:北京})# 北京今天晴28°C异步工具asyncdeffetch_stock_price(symbol:str)-str:获取股票实时价格awaitasyncio.sleep(0.5)# 模拟 API 调用returnf{symbol}当前价格: ¥128.50stock_toolStructuredTool.from_function(coroutinefetch_stock_price,# 用 coroutine 而不是 funcnamestock_price,description查询股票实时价格,)2.3 两种方式对比特性tool 装饰器StructuredTool.from_function简洁度⭐⭐⭐⭐⭐⭐⭐⭐灵活性⭐⭐⭐⭐⭐⭐⭐⭐异步支持✅✅适用场景大部分自定义工具需要精细控制的工具3. 工具与模型绑定3.1 bind_tools将工具绑定到模型fromlangchain.chat_modelsimportinit_chat_modelfromlangchain_core.toolsimporttoolfromlangchain_core.messagesimportHumanMessagetooldefadd(a:int,b:int)-int:两个整数相加returnabtooldefmultiply(a:int,b:int)-int:两个整数相乘returna*b modelinit_chat_model(openai:gpt-4o-mini)model_with_toolsmodel.bind_tools([add,multiply])# LLM 会判断需要调用哪个工具responsemodel_with_tools.invoke([HumanMessage(content10 加 20 等于多少)])# 查看工具调用ifresponse.tool_calls:fortcinresponse.tool_calls:print(f调用工具:{tc[name]})print(f参数:{tc[args]})# 手动执行工具iftc[name]add:resultadd.invoke(tc[args])print(f结果:{result})3.2 工具调用执行循环完整的工具调用流程fromlangchain_core.messagesimportHumanMessage,ToolMessage# 1. 模型判断需要调用工具responsemodel_with_tools.invoke([HumanMessage(content25乘以4是多少)])# 2. 执行工具tool_results[]fortcinresponse.tool_calls:tool_nametc[name]iftool_namemultiply:resultmultiply.invoke(tc[args])tool_results.append(ToolMessage(contentstr(result),tool_call_idtc[id]))# 3. 将工具结果返回给模型获得最终回答final_responsemodel_with_tools.invoke([HumanMessage(content25乘以4是多少),response,# AI 的工具调用消息*tool_results,# 工具执行结果])print(final_response.content)# 25乘以4等于1003.3 控制工具调用行为# 强制调用任意工具model_with_forced_toolmodel.bind_tools([add,multiply],tool_choiceany,# 必须调用某个工具)# 强制调用指定工具model_with_specificmodel.bind_tools([add,multiply],tool_choiceadd,# 必须调用 add)# 禁用并行调用某些模型支持model_serialmodel.bind_tools([add,multiply],parallel_tool_callsFalse,)4. MCP 协议4.1 什么是 MCPMCPModel Context Protocol是一种开放的标准化协议让 AI 应用能够通过统一接口连接各种外部工具和数据源。类似 USB 协议统一了外部设备连接——MCP 统一了工具/数据源的接入方式。LangChain → MCP Server → 外部服务数据库/API/文件系统/...4.2 MCP 的优势传统方式MCP 方式每个工具自己写胶水代码统一协议即插即用各服务接口不一致标准化接口难以复用和共享社区共享 MCP Server绑死特定框架跨框架通用Claude/Cursor/Continue…4.3 使用 MCP 工具fromlangchain_mcp_adapters.clientimportMultiServerMCPClient# 连接 MCP ServerclientMultiServerMCPClient({weather:{command:python,args:[-m,mcp_server_weather],},database:{command:python,args:[-m,mcp_server_sqlite,--db-path,data.db],},})# 获取工具列表toolsclient.get_tools()fortintools:print(f{t.name}:{t.description})# 绑定到模型modelinit_chat_model(openai:gpt-4o-mini)model_with_mcpmodel.bind_tools(tools)# Agent 会自动调用 MCP 工具MCP Server 可以用 Python、Node.js 等任何语言编写也可以安装社区已有的各类 MCP Server文件系统、数据库、搜索引擎等。5. 内置工具LangChain 提供了丰富的内置工具。5.1 Tavily 搜索引擎pipinstalltavily-pythonfromlangchain_community.tools.tavily_searchimportTavilySearchResults searchTavilySearchResults(max_results3,api_keyyour_key)resultssearch.invoke(2026年AI最新进展)forrinresults:print(r[content])5.2 Wikipedia 查询pipinstallwikipediafromlangchain_community.toolsimportWikipediaQueryRunfromlangchain_community.utilitiesimportWikipediaAPIWrapper wikipediaWikipediaQueryRun(api_wrapperWikipediaAPIWrapper())resultwikipedia.invoke(量子计算)print(result)5.3 Python REPL代码执行fromlangchain_experimental.toolsimportPythonREPLTool replPythonREPLTool()resultrepl.invoke(print(sum([i**2 for i in range(10)])))# 输出: 2855.4 文件操作工具fromlangchain_community.tools.file_managementimport(ReadFileTool,WriteFileTool,ListDirectoryTool,MoveFileTool,CopyFileTool)readerReadFileTool()contentreader.invoke({file_path:./data.txt})writerWriteFileTool()writer.invoke({file_path:./output.txt,text:Hello LangChain})6. 工具集 ToolkitsToolkit 是一组紧密相关的工具集合开箱即用。6.1 SQL 数据库工具集pipinstallpymysqlfromlangchain_community.agent_toolkitsimportSQLDatabaseToolkitfromlangchain_community.utilitiesimportSQLDatabase dbSQLDatabase.from_uri(mysqlpymysql://user:passlocalhost/db)toolkitSQLDatabaseToolkit(dbdb,llmmodel)toolstoolkit.get_tools()fortintools:print(t.name)# sql_db_query, sql_db_schema, sql_db_list_tables, sql_db_query_checker6.2 JSON 工具集fromlangchain_community.tools.json.toolimportJsonSpecfromlangchain_community.agent_toolkitsimportJsonToolkit json_specJsonSpec(dict_{name:产品,price:99})toolkitJsonToolkit(specjson_spec)7. 工具最佳实践描述要精准工具描述直接决定 LLM 能否正确调用。写明什么时候用“输入什么”“输出什么”参数用 Pydanticargs_schema让 LLM 精确理解参数格式和含义invoke代替runv1 统一用invoke()方法工具要原子化每个工具只做一件事复杂流程用多个工具组合异常处理工具内部做好错误捕获返回有意义的错误信息而非 tracebackMCP 优先系统级操作数据库、文件系统、API优先考虑用 MCP 协议接入本章小结概念说明tool最简单的自定义工具方式StructuredTool灵活的工具构造器bind_tools()将工具绑定到模型tool_choice控制工具调用的强制行为MCP标准化工具协议即插即用Toolkit一组相关工具的集合