05-工具与MCP
第05章:工具与 MCP(Tools)
版本:LangChain v1.3.7 | 讲师:汤姆小白
1. Tools 概述
1.1 什么是工具
大模型只能生成文本,无法与外部世界交互。Tools(工具)为 LLM 装上"手脚",让它能调用 API、搜索互联网、查询数据库、执行代码、操作文件等。
用户提问 → LLM 思考 → 决定调用工具 → 执行工具 → 获取结果 → 继续推理1.2 工具的构成要素
每个 Tool 包含以下要素:
| 要素 | 说明 | 示例 |
|---|---|---|
name | 唯一标识名称 | "web_search" |
description | 功能描述(LLM 据此判断何时调用) | "搜索互联网获取最新信息" |
args_schema | 参数 JSON Schema(Pydantic 模型) | {"query": "string"} |
func | 实际执行的函数 | 调用搜索 API |
return_direct | 是否直接返回结果给用户 | False(让 Agent 继续) |
Tool 的 name 和 description 至关重要——LLM 完全靠这两项判断何时调用哪个工具。
2. 自定义工具
2.1 @tool 装饰器(最简单)
fromlangchain_core.toolsimporttool@tooldefadd(a:int,b:int)->int:"""两个整数相加"""returna+bprint(add.name)# addprint(add.description)# 两个整数相加print(add.args)# {'a': {'type': 'integer'}, 'b': {'type': 'integer'}}# 调用result=add.invoke({"a":10,"b":20})# 30自定义名称和描述:
@tool("calculator",description="执行数学计算",return_direct=True)defcalculate(expression:str)->float:"""计算数学表达式"""returneval(expression)使用 Pydantic 完善参数描述:
frompydanticimportBaseModel,FieldclassSearchInput(BaseModel):query:str=Field(description="搜索关键词")max_results:int=Field(default=5,description="最大结果数")@tool(args_schema=SearchInput)defweb_search(query:str,max_results:int=5)->str:"""搜索互联网获取信息"""# 实际调用搜索 APIreturnf"关于 '{query}' 的搜索结果..."2.2 StructuredTool.from_function(更灵活)
fromlangchain_core.toolsimportStructuredTooldefget_weather(city:str)->str:"""获取城市天气"""returnf"{city}今天晴,28°C"weather_tool=StructuredTool.from_function(func=get_weather,name="get_weather",description="查询指定城市的天气情况",)weather_tool.invoke({"city":"北京"})# 北京今天晴,28°C异步工具:
asyncdeffetch_stock_price(symbol:str)->str:"""获取股票实时价格"""awaitasyncio.sleep(0.5)# 模拟 API 调用returnf"{symbol}当前价格: ¥128.50"stock_tool=StructuredTool.from_function(coroutine=fetch_stock_price,# 用 coroutine 而不是 funcname="stock_price",description="查询股票实时价格",)2.3 两种方式对比
| 特性 | @tool 装饰器 | StructuredTool.from_function |
|---|---|---|
| 简洁度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 灵活性 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 异步支持 | ✅ | ✅ |
| 适用场景 | 大部分自定义工具 | 需要精细控制的工具 |
3. 工具与模型绑定
3.1 bind_tools:将工具绑定到模型
fromlangchain.chat_modelsimportinit_chat_modelfromlangchain_core.toolsimporttoolfromlangchain_core.messagesimportHumanMessage@tooldefadd(a:int,b:int)->int:"""两个整数相加"""returna+b@tooldefmultiply(a:int,b:int)->int:"""两个整数相乘"""returna*b model=init_chat_model("openai:gpt-4o-mini")model_with_tools=model.bind_tools([add,multiply])# LLM 会判断需要调用哪个工具response=model_with_tools.invoke([HumanMessage(content="10 加 20 等于多少?")])# 查看工具调用ifresponse.tool_calls:fortcinresponse.tool_calls:print(f"调用工具:{tc['name']}")print(f"参数:{tc['args']}")# 手动执行工具iftc['name']=='add':result=add.invoke(tc['args'])print(f"结果:{result}")3.2 工具调用执行循环
完整的工具调用流程:
fromlangchain_core.messagesimportHumanMessage,ToolMessage# 1. 模型判断需要调用工具response=model_with_tools.invoke([HumanMessage(content="25乘以4是多少?")])# 2. 执行工具tool_results=[]fortcinresponse.tool_calls:tool_name=tc['name']iftool_name=='multiply':result=multiply.invoke(tc['args'])tool_results.append(ToolMessage(content=str(result),tool_call_id=tc['id']))# 3. 将工具结果返回给模型,获得最终回答final_response=model_with_tools.invoke([HumanMessage(content="25乘以4是多少?"),response,# AI 的工具调用消息*tool_results,# 工具执行结果])print(final_response.content)# 25乘以4等于1003.3 控制工具调用行为
# 强制调用任意工具model_with_forced_tool=model.bind_tools([add,multiply],tool_choice="any",# 必须调用某个工具)# 强制调用指定工具model_with_specific=model.bind_tools([add,multiply],tool_choice="add",# 必须调用 add)# 禁用并行调用(某些模型支持)model_serial=model.bind_tools([add,multiply],parallel_tool_calls=False,)4. MCP 协议
4.1 什么是 MCP
MCP(Model 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 Serverclient=MultiServerMCPClient({"weather":{"command":"python","args":["-m","mcp_server_weather"],},"database":{"command":"python","args":["-m","mcp_server_sqlite","--db-path","data.db"],},})# 获取工具列表tools=client.get_tools()fortintools:print(f"{t.name}:{t.description}")# 绑定到模型model=init_chat_model("openai:gpt-4o-mini")model_with_mcp=model.bind_tools(tools)# Agent 会自动调用 MCP 工具MCP Server 可以用 Python、Node.js 等任何语言编写,也可以安装社区已有的各类 MCP Server(文件系统、数据库、搜索引擎等)。
5. 内置工具
LangChain 提供了丰富的内置工具。
5.1 Tavily 搜索引擎
pipinstalltavily-pythonfromlangchain_community.tools.tavily_searchimportTavilySearchResults search=TavilySearchResults(max_results=3,api_key="your_key")results=search.invoke("2026年AI最新进展")forrinresults:print(r["content"])5.2 Wikipedia 查询
pipinstallwikipediafromlangchain_community.toolsimportWikipediaQueryRunfromlangchain_community.utilitiesimportWikipediaAPIWrapper wikipedia=WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())result=wikipedia.invoke("量子计算")print(result)5.3 Python REPL(代码执行)
fromlangchain_experimental.toolsimportPythonREPLTool repl=PythonREPLTool()result=repl.invoke("print(sum([i**2 for i in range(10)]))")# 输出: 2855.4 文件操作工具
fromlangchain_community.tools.file_managementimport(ReadFileTool,WriteFileTool,ListDirectoryTool,MoveFileTool,CopyFileTool)reader=ReadFileTool()content=reader.invoke({"file_path":"./data.txt"})writer=WriteFileTool()writer.invoke({"file_path":"./output.txt","text":"Hello LangChain"})6. 工具集 Toolkits
Toolkit 是一组紧密相关的工具集合,开箱即用。
6.1 SQL 数据库工具集
pipinstallpymysqlfromlangchain_community.agent_toolkitsimportSQLDatabaseToolkitfromlangchain_community.utilitiesimportSQLDatabase db=SQLDatabase.from_uri("mysql+pymysql://user:pass@localhost/db")toolkit=SQLDatabaseToolkit(db=db,llm=model)tools=toolkit.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_spec=JsonSpec(dict_={"name":"产品","price":99})toolkit=JsonToolkit(spec=json_spec)7. 工具最佳实践
- 描述要精准:工具描述直接决定 LLM 能否正确调用。写明"什么时候用"“输入什么”“输出什么”
- 参数用 Pydantic:
args_schema让 LLM 精确理解参数格式和含义 invoke代替run:v1 统一用invoke()方法- 工具要原子化:每个工具只做一件事,复杂流程用多个工具组合
- 异常处理:工具内部做好错误捕获,返回有意义的错误信息而非 traceback
- MCP 优先:系统级操作(数据库、文件系统、API)优先考虑用 MCP 协议接入
本章小结
| 概念 | 说明 |
|---|---|
| @tool | 最简单的自定义工具方式 |
| StructuredTool | 灵活的工具构造器 |
| bind_tools() | 将工具绑定到模型 |
| tool_choice | 控制工具调用的强制行为 |
| MCP | 标准化工具协议,即插即用 |
| Toolkit | 一组相关工具的集合 |
