Tool调用接口

wen IT资讯 31

本文目录导读:

Tool调用接口

  1. 工具调用接口概述
  2. 标准化接口结构
  3. 响应处理流程
  4. 不同模型的工具调用格式
  5. 高级实现模式
  6. 最佳实践建议

我来详细解释AI模型中的工具调用(Function Calling/Tool Calling)接口设计和使用。

工具调用接口概述

工具调用允许LLM在对话过程中调用预定义的外部函数或API,获取实时数据或执行操作。

标准化接口结构

工具定义格式

# 工具定义示例
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名称"
                    },
                    "units": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "温度单位"
                    }
                },
                "required": ["city"]
            }
        }
    }
]

API调用格式

# OpenAI风格调用
import openai
response = openai.chat.completions.create(
    model="gpt-4",
    messages=[
        {"role": "user", "content": "北京今天天气怎么样?"}
    ],
    tools=tools,
    tool_choice="auto"  # auto, none, or {"type": "function", "function": {"name": "get_weather"}}
)

响应处理流程

解析工具调用请求

# 解析模型返回的工具调用
def process_tool_call(response):
    message = response.choices[0].message
    if message.tool_calls:
        for tool_call in message.tool_calls:
            function_name = tool_call.function.name
            arguments = json.loads(tool_call.function.arguments)
            # 执行实际函数
            if function_name == "get_weather":
                result = get_weather(arguments["city"], arguments.get("units", "celsius"))
            # 返回结果给模型
            yield {
                "tool_call_id": tool_call.id,
                "function_name": function_name,
                "result": result
            }

完整的多轮调用示例

def chat_with_tools():
    messages = [{"role": "user", "content": "北京和上海哪个城市今天更暖和?"}]
    while True:
        response = client.chat.completions.create(
            model="gpt-4",
            messages=messages,
            tools=tools
        )
        message = response.choices[0].message
        if message.tool_calls:
            messages.append(message)
            for tool_call in message.tool_calls:
                # 执行工具
                result = execute_tool(tool_call)
                # 将结果添加回消息
                messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "content": json.dumps(result)
                })
        else:
            # 模型最终回复
            return message.content

不同模型的工具调用格式

OpenAI

# OpenAI格式
response = openai.chat.completions.create(
    model="gpt-4-turbo-preview",
    messages=[...],
    tools=[...],  # 或 functions=[...] (旧版)
    tool_choice="auto"
)

Anthropic Claude

# Claude格式
response = anthropic.messages.create(
    model="claude-3-opus-20240229",
    messages=[...],
    tools=[
        {
            "name": "get_weather",
            "description": "获取天气信息",
            "input_schema": {
                "type": "object",
                "properties": {
                    "city": {"type": "string"}
                },
                "required": ["city"]
            }
        }
    ]
)

Google Gemini

# Gemini格式
model = genai.GenerativeModel('gemini-pro')
response = model.generate_content(
    "北京天气怎么样?",
    tools=[
        {
            "function_declarations": [
                {
                    "name": "get_weather",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "city": {"type": "string"}
                        },
                        "required": ["city"]
                    }
                }
            ]
        }
    ]
)

高级实现模式

并行工具调用

# 模型可能同时调用多个工具
def handle_parallel_tool_calls(response):
    calls = response.choices[0].message.tool_calls
    # 使用线程池并行执行
    with ThreadPoolExecutor() as executor:
        futures = []
        for tool_call in calls:
            future = executor.submit(execute_tool, tool_call)
            futures.append((tool_call.id, future))
        # 收集结果
        results = []
        for call_id, future in futures:
            result = future.result()
            results.append({
                "tool_call_id": call_id,
                "content": json.dumps(result)
            })
    return results

工具注册装饰器

tool_registry = {}
def tool(name, description, parameters):
    def decorator(func):
        tool_registry[name] = {
            "function": func,
            "definition": {
                "type": "function",
                "function": {
                    "name": name,
                    "description": description,
                    "parameters": parameters
                }
            }
        }
        return func
    return decorator
# 使用装饰器定义工具
@tool(
    name="search_database",
    description="搜索数据库中的记录",
    parameters={
        "type": "object",
        "properties": {
            "query": {"type": "string"},
            "limit": {"type": "integer", "default": 10}
        },
        "required": ["query"]
    }
)
def search_database(query: str, limit: int = 10):
    # 实现数据库搜索
    return results

错误处理与重试

def safe_tool_call(tool_call, max_retries=3):
    for attempt in range(max_retries):
        try:
            result = execute_tool(tool_call)
            return {
                "tool_call_id": tool_call.id,
                "content": json.dumps(result),
                "status": "success"
            }
        except ToolError as e:
            if attempt == max_retries - 1:
                return {
                    "tool_call_id": tool_call.id,
                    "content": json.dumps({
                        "error": str(e),
                        "message": "工具执行失败,请重试或使用其他方式回答"
                    }),
                    "status": "error"
                }
            time.sleep(1 * (attempt + 1))

最佳实践建议

工具命名规范

  • 使用蛇形命名(snake_case)
  • 动词开头(get, search, create, update, delete_)
  • 明确描述功能

参数设计原则

  • 参数类型明确定义
  • 提供合理的默认值
  • 设置清晰的枚举值
  • 写入易懂的描述

安全性考量

# 验证工具调用权限
def validate_tool_call(user_id, tool_name, arguments):
    # 检查用户权限
    if not has_permission(user_id, tool_name):
        raise PermissionError(f"User {user_id} cannot call {tool_name}")
    # 参数验证
    if tool_name == "delete_user":
        if not is_admin(user_id):
            raise PermissionError("Only admins can delete users")
    return True

工具调用接口的设计重点是清晰、安全和可扩展,让模型能够可靠地发现和使用外部功能。

抱歉,评论功能暂时关闭!