在 LangChain 中,Tool 是一种把 Python 函数和它的调用规范(schema)包装起来的机制,这样模型就可以“请求”调用这个函数并传入参数。
1. 工具定义
from langchain_core.tools import tool @tool(parse_docstring=True) def mul(a : int, b : int) -> int: """ 乘法计算器 Args: a : 第一个整数参数 b : 第二个整数参数 """ return a + b from pydantic import BaseModel, Field class CalculatorInput(BaseModel): a : int = Field(description='第一个整数参数') b : int = Field(description='第二个整数参数') @tool(description='加法计算器', args_schema=CalculatorInput) def add(a : int, b : int) -> int: return a + b def demo(): # 工具描述 print(mul.description) print(mul.args) print(add.description) print(add.args) # 工具使用,需要通过 invoke 函数调用,不可直接调用 result = add.invoke({'a': 100, 'b': 200}) print(type(result), result) # 下面格式是 LLM 返回的工具调用信息,如果传递这些到工具函数中,则会返回 ToolMessage 类型的对象 # {'name': 'add', 'args': {'a': 8, 'b': 5}, 'id': 'call_0_b0cff3df-7e23-4da0-b5db-439e079ec518', 'type': 'tool_call'} result = add.invoke({'args': {'a': 8, 'b': 5}, 'id': 'call_abc_123', 'type': 'tool_call'}) print(type(result), result) if __name__ == '__main__': demo()
乘法计算器 {'a': {'description': '第一个整数参数', 'title': 'A', 'type': 'integer'}, 'b': {'description': '第二个整数参数', 'title': 'B', 'type': 'integer'}} 加法计算器 {'a': {'description': '第一个整数参数', 'title': 'A', 'type': 'integer'}, 'b': {'description': '第二个整数参数', 'title': 'B', 'type': 'integer'}} <class 'int'> 300 <class 'langchain_core.messages.tool.ToolMessage'> content='13' name='add' tool_call_id='call_abc_123'
2. 工具使用
from dotenv import load_dotenv load_dotenv('llm.env') from langchain_deepseek import ChatDeepSeek from langchain_core.tools import tool from langchain_core.messages import HumanMessage from langchain_core.messages import ToolMessage @tool(parse_docstring=True) def mul(a : int, b : int) -> int: """ 乘法计算器 Args: a : 第一个整数参数 b : 第二个整数参数 """ return a + b from pydantic import BaseModel, Field class CalculatorInput(BaseModel): a : int = Field(description='第一个整数参数') b : int = Field(description='第二个整数参数') @tool(description='加法计算器', args_schema=CalculatorInput) def add(a : int, b : int) -> int: return a + b def demo(): llm = ChatDeepSeek(model='deepseek-chat') # 绑定工具函数 llm_with_tools = llm.bind_tools([add, mul]) # 匹配工具函数 # 根据函数名、函数文档的语义进行工具匹配和参数提取 # response = llm_with_tools.invoke('请问:八加五等于多少?') # print(response.tool_calls) # 根据函数名、函数文档的语义进行工具匹配和参数提取 messages = [HumanMessage('请问:8加5等于多少?13乘10等于多少?')] response = llm_with_tools.invoke(messages) print('-' * 30 + '匹配工具' + '-' * 30) print(response.tool_calls) messages.append(response) # 调用工具函数 print('-' * 30 + '调用工具' + '-' * 30) for tool_call in response.tool_calls: my_tool = {'add': add, 'mul': mul}[tool_call['name']] message : ToolMessage = my_tool.invoke(tool_call) print(message) messages.append(message) # 向大模型传回结果 print('-' * 30 + '最终输出' + '-' * 30) response = llm_with_tools.invoke(messages) print(response.content) if __name__ == '__main__': demo()
------------------------------匹配工具------------------------------ [{'name': 'add', 'args': {'a': 8, 'b': 5}, 'id': 'call_0_12aece4f-272f-4421-bcfe-8a2b36241c57', 'type': 'tool_call'}, {'name': 'mul', 'args': {'a': 13, 'b': 10}, 'id': 'call_1_84dc87d8-8794-4a36-9782-26cc093d3fd1', 'type': 'tool_call'}] ------------------------------调用工具------------------------------ content='13' name='add' tool_call_id='call_0_12aece4f-272f-4421-bcfe-8a2b36241c57' content='23' name='mul' tool_call_id='call_1_84dc87d8-8794-4a36-9782-26cc093d3fd1' ------------------------------最终输出------------------------------ 8加5等于13,13乘10等于23。