LangChain 工具调用

在 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。
未经允许不得转载:一亩三分地 » LangChain 工具调用
评论 (0)

2 + 2 =