加载中

当 Claude 以工具使用请求进行响应时,您的服务器需要实际运行所请求的工具并将结果发送回去。这一步涉及从 Claude 的响应中提取工具使用部分、执行相应的函数,以及正确格式化结果。

处理多个工具请求

Claude 可以在单个响应中发送多个工具使用部分。您的代码需要防御性地处理这种可能性。一条助手消息可能包含一个文本部分,后面跟着一个、两个甚至更多的工具使用部分。

整个流程是这样的:Claude 发送带有 JSON 模式的请求,接收到一个工具使用部分,然后您的服务器运行该工具并发送回一个工具结果部分,供 Claude 提供最终响应。

提取工具使用部分

首先,创建一个函数来处理聊天请求返回的所有部分:

python
def run_tools(parts):
    tool_requests = [part for part in parts if "toolUse" in part]
    tool_result_parts = []
    
    for tool_request in tool_requests:
        tool_use_id = tool_request["toolUse"]["toolUseId"]
        tool_name = tool_request["toolUse"]["name"]
        tool_input = tool_request["toolUse"]["input"]

这个推导式会过滤部分列表,只保留包含 "toolUse" 键的字典,忽略文本部分。

运行实际的工具

创建一个辅助函数来执行所请求的工具:

python
def run_tool(tool_name, tool_input):
    if tool_name == "get_current_datetime":
        return get_current_datetime(**tool_input)
    else:
        raise Exception(f"Unknown tool name: {tool_name}")

这里的关键细节是使用 **tool_input 将参数字典展开传入您的工具函数。Claude 始终将参数作为字典对象返回,因此您需要正确地将其解包。

创建工具结果部分

运行工具后,您需要将响应格式化为工具结果部分:

工具结果部分需要三个关键属性:

  • toolUseId - 必须与原始工具使用部分的 ID 匹配
  • content - 来自您工具的输出,序列化为字符串
  • status - "success" 或 "error"

理解工具使用 ID

当 Claude 并行请求多个工具时,工具使用 ID 系统就变得很重要。例如,如果 Claude 想要运行两次计算器工具:

每个工具使用都会获得一个唯一的 ID(例如 "ab3" 和 "po9"),并且您的工具结果必须包含匹配的 ID,以便 Claude 知道哪个结果对应哪个请求。

错误处理

将您的工具执行包裹在 try-catch 代码块中。Claude 对工具错误很智能,如果您返回正确的错误信息,它可能会调整其处理方式:

python
try:
    tool_output = run_tool(tool_name, tool_input)
    tool_result_part = {
        "toolResult": {
            "toolUseId": tool_use_id,
            "content": [{"text": json.dumps(tool_output)}],
            "status": "success"
        }
    }
except Exception as e:
    tool_result_part = {
        "toolResult": {
            "toolUseId": tool_use_id,
            "content": [{"text": f"Error: {e}"}],
            "status": "error"
        }
    }

完整实现

以下是处理工具请求并返回格式化结果的完整函数:

python
def run_tools(parts):
    tool_requests = [part for part in parts if "toolUse" in part]
    tool_result_parts = []
    
    for tool_request in tool_requests:
        tool_use_id = tool_request["toolUse"]["toolUseId"]
        tool_name = tool_request["toolUse"]["name"]
        tool_input = tool_request["toolUse"]["input"]
        
        try:
            tool_output = run_tool(tool_name, tool_input)
            tool_result_part = {
                "toolResult": {
                    "toolUseId": tool_use_id,
                    "content": [{"text": json.dumps(tool_output)}],
                    "status": "success"
                }
            }
        except Exception as e:
            tool_result_part = {
                "toolResult": {
                    "toolUseId": tool_use_id,
                    "content": [{"text": f"Error: {e}"}],
                    "status": "error"
                }
            }
        
        tool_result_parts.append(tool_result_part)
    
    return tool_result_parts

一旦您获得了工具结果部分,就可以在下一次聊天请求中将它们发送回 Claude,从而完成工具使用循环。