logo

Claude Tool Use (工具调用)

Tool Use 让 Claude 能够调用你定义的工具/函数,是构建 AI Agent 的核心能力。

把它当成“让 AI 学会按流程调用企业内工具”的能力。
模型负责理解意图和填参数,业务系统仍由你掌控执行与权限。

什么是 Tool Use?

Tool Use 让 Claude 能够:

  1. 理解用户意图
  2. 决定使用哪个工具
  3. 提取工具参数
  4. 等待工具结果并生成回复
用户: "北京今天天气怎么样?"
     ↓
Claude: 需要使用 get_weather 工具,参数 city="北京"
     ↓
你的代码: 调用天气 API,返回结果
     ↓
Claude: "北京今天晴朗,气温 25°C,适合户外活动。"

读者导向:建议实践顺序

  1. 先做单工具闭环(请求 -> tool_use -> tool_result -> 最终回复)。
  2. 再做多工具路由和并行调用。
  3. 最后补权限、审计、失败重试与幂等策略。

基础用法

定义工具

tools = [
    {
        "name": "get_weather",
        "description": "获取指定城市的当前天气信息",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "城市名称,如:北京、上海、深圳"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "温度单位,默认摄氏度"
                }
            },
            "required": ["city"]
        }
    }
]

调用 API

import anthropic
import json

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=tools,
    messages=[
        {"role": "user", "content": "北京天气怎么样?"}
    ]
)

# 检查响应类型
for block in response.content:
    if block.type == "tool_use":
        print(f"工具: {block.name}")
        print(f"参数: {block.input}")
        print(f"ID: {block.id}")

执行工具并返回结果

def get_weather(city: str, unit: str = "celsius") -> str:
    """模拟天气 API"""
    return f"{city}今天晴,气温 25°C"

# 1. 第一次调用 - 获取工具调用请求
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "北京天气怎么样?"}]
)

# 2. 检查并执行工具
messages = [{"role": "user", "content": "北京天气怎么样?"}]
messages.append({"role": "assistant", "content": response.content})

for block in response.content:
    if block.type == "tool_use":
        # 执行工具
        result = get_weather(**block.input)

        # 添加工具结果
        messages.append({
            "role": "user",
            "content": [{
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": result
            }]
        })

# 3. 获取最终回复
final_response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=tools,
    messages=messages
)

print(final_response.content[0].text)

多工具定义

tools = [
    {
        "name": "get_weather",
        "description": "获取城市天气",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "城市名"}
            },
            "required": ["city"]
        }
    },
    {
        "name": "search_web",
        "description": "搜索网络信息",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {"type": "string", "description": "搜索关键词"}
            },
            "required": ["query"]
        }
    },
    {
        "name": "send_email",
        "description": "发送邮件",
        "input_schema": {
            "type": "object",
            "properties": {
                "to": {"type": "string", "description": "收件人邮箱"},
                "subject": {"type": "string", "description": "邮件主题"},
                "body": {"type": "string", "description": "邮件内容"}
            },
            "required": ["to", "subject", "body"]
        }
    }
]

控制工具使用

tool_choice 参数

# 自动决定(默认)
tool_choice = {"type": "auto"}

# 强制使用特定工具
tool_choice = {"type": "tool", "name": "get_weather"}

# 强制使用任意一个工具
tool_choice = {"type": "any"}

# 禁止使用工具
tool_choice = {"type": "none"}  # 或不传 tools 参数

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=tools,
    tool_choice=tool_choice,
    messages=[...]
)

常见误区

  • 把工具 schema 写得过于宽松,导致参数不稳定
  • 工具执行失败只返回“失败”,不返回结构化错误信息
  • 忽略权限边界,让模型可触达不该调用的高风险接口

一句轻松提醒:
Tool Use 像给 AI 发工作证,权限开太大,出事概率会同步放大。

并行工具调用

Claude 可以同时请求多个工具:

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=tools,
    messages=[
        {"role": "user", "content": "北京和上海的天气分别怎么样?"}
    ]
)

# 可能返回多个 tool_use blocks
tool_calls = [block for block in response.content if block.type == "tool_use"]
print(f"需要调用 {len(tool_calls)} 个工具")

for tc in tool_calls:
    print(f"- {tc.name}: {tc.input}")

处理并行调用

def process_tool_calls(response, available_functions):
    """处理所有工具调用"""
    tool_results = []

    for block in response.content:
        if block.type == "tool_use":
            func = available_functions.get(block.name)
            if func:
                result = func(**block.input)
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": str(result)
                })

    return tool_results

# 使用
available_functions = {
    "get_weather": get_weather,
    "search_web": search_web,
    "send_email": send_email
}

tool_results = process_tool_calls(response, available_functions)

完整示例:AI 助手

import anthropic
import json

client = anthropic.Anthropic()

# 工具定义
tools = [
    {
        "name": "get_weather",
        "description": "获取城市天气信息",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "城市名"}
            },
            "required": ["city"]
        }
    },
    {
        "name": "calculate",
        "description": "数学计算",
        "input_schema": {
            "type": "object",
            "properties": {
                "expression": {"type": "string", "description": "数学表达式"}
            },
            "required": ["expression"]
        }
    }
]

# 工具实现
def get_weather(city: str) -> str:
    weather_data = {
        "北京": "晴,25°C",
        "上海": "多云,28°C",
    }
    return weather_data.get(city, f"{city}天气数据暂不可用")

def calculate(expression: str) -> str:
    try:
        return str(eval(expression))
    except:
        return "计算错误"

available_functions = {
    "get_weather": get_weather,
    "calculate": calculate
}

def chat(user_message: str):
    messages = [{"role": "user", "content": user_message}]

    while True:
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=1024,
            tools=tools,
            messages=messages
        )

        # 检查是否有工具调用
        tool_uses = [b for b in response.content if b.type == "tool_use"]

        if not tool_uses:
            # 没有工具调用,返回文本响应
            text_blocks = [b for b in response.content if b.type == "text"]
            return text_blocks[0].text if text_blocks else ""

        # 处理工具调用
        messages.append({"role": "assistant", "content": response.content})

        tool_results = []
        for tool_use in tool_uses:
            func = available_functions.get(tool_use.name)
            if func:
                result = func(**tool_use.input)
                print(f"[调用] {tool_use.name}({tool_use.input}) -> {result}")
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": tool_use.id,
                    "content": result
                })

        messages.append({"role": "user", "content": tool_results})

# 测试
print(chat("北京天气怎么样?"))
print(chat("123 * 456 等于多少?"))
print(chat("北京天气如何?另外帮我算一下 15 的平方"))

工具结果格式

成功结果

{
    "type": "tool_result",
    "tool_use_id": "toolu_xxx",
    "content": "北京今天晴,25°C"
}

错误结果

{
    "type": "tool_result",
    "tool_use_id": "toolu_xxx",
    "content": "错误:无法获取天气数据",
    "is_error": True
}

图片结果

{
    "type": "tool_result",
    "tool_use_id": "toolu_xxx",
    "content": [
        {
            "type": "image",
            "source": {
                "type": "base64",
                "media_type": "image/png",
                "data": "base64_encoded_data"
            }
        },
        {
            "type": "text",
            "text": "生成的图表"
        }
    ]
}

最佳实践

1. 清晰的工具描述

# ❌ 不够清晰
"description": "获取数据"

# ✅ 清晰明确
"description": "获取指定城市的实时天气信息,包括温度、湿度和天气状况。支持中国主要城市。"

2. 详细的参数说明

"properties": {
    "date": {
        "type": "string",
        "description": "查询日期,格式为 YYYY-MM-DD,如 2024-01-15。不填则查询今天。"
    }
}

3. 使用枚举限制选项

"status": {
    "type": "string",
    "enum": ["pending", "approved", "rejected"],
    "description": "订单状态"
}

4. 错误处理

def safe_tool_call(func, **kwargs):
    try:
        return func(**kwargs)
    except Exception as e:
        return f"工具执行错误: {str(e)}"

与 OpenAI Function Calling 的区别

特性Claude Tool UseOpenAI Function Calling
参数名input_schemaparameters
工具类型直接定义type: "function" 包装
结果格式tool_resultfunction role
控制参数tool_choicetool_choice

下一步


提示:Tool Use 是构建 AI Agent 的基础,结合多个工具可以实现复杂的自动化任务。

Claude API 开发指南
AI Engineer

Claude API 开发指南

Anthropic Claude API 提供了强大的 AI 模型访问,以安全性和准确性著称,适合企业级应用。

Claude API 开发指南Tool Use

Claude Tool Use (工具调用)

Tool Use 让 Claude 能够调用你定义的工具/函数,是构建 AI Agent 的核心能力。

把它当成“让 AI 学会按流程调用企业内工具”的能力。
模型负责理解意图和填参数,业务系统仍由你掌控执行与权限。

#什么是 Tool Use?

Tool Use 让 Claude 能够:

  1. 理解用户意图
  2. 决定使用哪个工具
  3. 提取工具参数
  4. 等待工具结果并生成回复
用户: "北京今天天气怎么样?"
     ↓
Claude: 需要使用 get_weather 工具,参数 city="北京"
     ↓
你的代码: 调用天气 API,返回结果
     ↓
Claude: "北京今天晴朗,气温 25°C,适合户外活动。"

#读者导向:建议实践顺序

  1. 先做单工具闭环(请求 -> tool_use -> tool_result -> 最终回复)。
  2. 再做多工具路由和并行调用。
  3. 最后补权限、审计、失败重试与幂等策略。

#基础用法

#定义工具

python
tools = [ { "name": "get_weather", "description": "获取指定城市的当前天气信息", "input_schema": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,如:北京、上海、深圳" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "温度单位,默认摄氏度" } }, "required": ["city"] } } ]

#调用 API

python
import anthropic import json client = anthropic.Anthropic() response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, tools=tools, messages=[ {"role": "user", "content": "北京天气怎么样?"} ] ) # 检查响应类型 for block in response.content: if block.type == "tool_use": print(f"工具: {block.name}") print(f"参数: {block.input}") print(f"ID: {block.id}")

#执行工具并返回结果

python
def get_weather(city: str, unit: str = "celsius") -> str: """模拟天气 API""" return f"{city}今天晴,气温 25°C" # 1. 第一次调用 - 获取工具调用请求 response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, tools=tools, messages=[{"role": "user", "content": "北京天气怎么样?"}] ) # 2. 检查并执行工具 messages = [{"role": "user", "content": "北京天气怎么样?"}] messages.append({"role": "assistant", "content": response.content}) for block in response.content: if block.type == "tool_use": # 执行工具 result = get_weather(**block.input) # 添加工具结果 messages.append({ "role": "user", "content": [{ "type": "tool_result", "tool_use_id": block.id, "content": result }] }) # 3. 获取最终回复 final_response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, tools=tools, messages=messages ) print(final_response.content[0].text)

#多工具定义

python
tools = [ { "name": "get_weather", "description": "获取城市天气", "input_schema": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名"} }, "required": ["city"] } }, { "name": "search_web", "description": "搜索网络信息", "input_schema": { "type": "object", "properties": { "query": {"type": "string", "description": "搜索关键词"} }, "required": ["query"] } }, { "name": "send_email", "description": "发送邮件", "input_schema": { "type": "object", "properties": { "to": {"type": "string", "description": "收件人邮箱"}, "subject": {"type": "string", "description": "邮件主题"}, "body": {"type": "string", "description": "邮件内容"} }, "required": ["to", "subject", "body"] } } ]

#控制工具使用

#tool_choice 参数

python
# 自动决定(默认) tool_choice = {"type": "auto"} # 强制使用特定工具 tool_choice = {"type": "tool", "name": "get_weather"} # 强制使用任意一个工具 tool_choice = {"type": "any"} # 禁止使用工具 tool_choice = {"type": "none"} # 或不传 tools 参数 response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, tools=tools, tool_choice=tool_choice, messages=[...] )

#常见误区

  • 把工具 schema 写得过于宽松,导致参数不稳定
  • 工具执行失败只返回“失败”,不返回结构化错误信息
  • 忽略权限边界,让模型可触达不该调用的高风险接口

一句轻松提醒:
Tool Use 像给 AI 发工作证,权限开太大,出事概率会同步放大。

#并行工具调用

Claude 可以同时请求多个工具:

python
response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, tools=tools, messages=[ {"role": "user", "content": "北京和上海的天气分别怎么样?"} ] ) # 可能返回多个 tool_use blocks tool_calls = [block for block in response.content if block.type == "tool_use"] print(f"需要调用 {len(tool_calls)} 个工具") for tc in tool_calls: print(f"- {tc.name}: {tc.input}")

#处理并行调用

python
def process_tool_calls(response, available_functions): """处理所有工具调用""" tool_results = [] for block in response.content: if block.type == "tool_use": func = available_functions.get(block.name) if func: result = func(**block.input) tool_results.append({ "type": "tool_result", "tool_use_id": block.id, "content": str(result) }) return tool_results # 使用 available_functions = { "get_weather": get_weather, "search_web": search_web, "send_email": send_email } tool_results = process_tool_calls(response, available_functions)

#完整示例:AI 助手

python
import anthropic import json client = anthropic.Anthropic() # 工具定义 tools = [ { "name": "get_weather", "description": "获取城市天气信息", "input_schema": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名"} }, "required": ["city"] } }, { "name": "calculate", "description": "数学计算", "input_schema": { "type": "object", "properties": { "expression": {"type": "string", "description": "数学表达式"} }, "required": ["expression"] } } ] # 工具实现 def get_weather(city: str) -> str: weather_data = { "北京": "晴,25°C", "上海": "多云,28°C", } return weather_data.get(city, f"{city}天气数据暂不可用") def calculate(expression: str) -> str: try: return str(eval(expression)) except: return "计算错误" available_functions = { "get_weather": get_weather, "calculate": calculate } def chat(user_message: str): messages = [{"role": "user", "content": user_message}] while True: response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, tools=tools, messages=messages ) # 检查是否有工具调用 tool_uses = [b for b in response.content if b.type == "tool_use"] if not tool_uses: # 没有工具调用,返回文本响应 text_blocks = [b for b in response.content if b.type == "text"] return text_blocks[0].text if text_blocks else "" # 处理工具调用 messages.append({"role": "assistant", "content": response.content}) tool_results = [] for tool_use in tool_uses: func = available_functions.get(tool_use.name) if func: result = func(**tool_use.input) print(f"[调用] {tool_use.name}({tool_use.input}) -> {result}") tool_results.append({ "type": "tool_result", "tool_use_id": tool_use.id, "content": result }) messages.append({"role": "user", "content": tool_results}) # 测试 print(chat("北京天气怎么样?")) print(chat("123 * 456 等于多少?")) print(chat("北京天气如何?另外帮我算一下 15 的平方"))

#工具结果格式

#成功结果

python
{ "type": "tool_result", "tool_use_id": "toolu_xxx", "content": "北京今天晴,25°C" }

#错误结果

python
{ "type": "tool_result", "tool_use_id": "toolu_xxx", "content": "错误:无法获取天气数据", "is_error": True }

#图片结果

python
{ "type": "tool_result", "tool_use_id": "toolu_xxx", "content": [ { "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": "base64_encoded_data" } }, { "type": "text", "text": "生成的图表" } ] }

#最佳实践

#1. 清晰的工具描述

python
# ❌ 不够清晰 "description": "获取数据" # ✅ 清晰明确 "description": "获取指定城市的实时天气信息,包括温度、湿度和天气状况。支持中国主要城市。"

#2. 详细的参数说明

python
"properties": { "date": { "type": "string", "description": "查询日期,格式为 YYYY-MM-DD,如 2024-01-15。不填则查询今天。" } }

#3. 使用枚举限制选项

python
"status": { "type": "string", "enum": ["pending", "approved", "rejected"], "description": "订单状态" }

#4. 错误处理

python
def safe_tool_call(func, **kwargs): try: return func(**kwargs) except Exception as e: return f"工具执行错误: {str(e)}"

#与 OpenAI Function Calling 的区别

特性Claude Tool UseOpenAI Function Calling
参数名input_schemaparameters
工具类型直接定义type: "function" 包装
结果格式tool_resultfunction role
控制参数tool_choicetool_choice

#下一步


提示:Tool Use 是构建 AI Agent 的基础,结合多个工具可以实现复杂的自动化任务。

System Design

系统设计必备:核心概念 + 经典案例

快速掌握取舍与设计套路,备战系统设计面试。

进入 System Design →

相关路线图