编程式工具调用 (PTC)

通过编程方式控制 Claude 的工具调用行为

🌐 查看英文原文 | 源码 Notebook


使用 Claude API 进行编程式工具调用(PTC)

Programmatic Tool Calling (PTC) 允许 Claude 在代码执行环境中以编程方式调用工具,而不是要求每次工具调用都通过模型进行往返。这显著减少了多个工具调用的端到端延迟,并且可以通过允许模型编写在击中模型上下文窗口之前删除无关上下文的代码(例如,在大型和嘈杂的文件中搜索关键信息)来大幅减少令牌消耗。

当面临可能无法直接修改的第三方 API 和工具时,PTC 可以通过允许 Claude 在代码执行环境中编写可调用的代码来帮助减少上下文的使用。

在本教程中,我们将使用一个团队费用管理的模拟 API。该 API 设计为需要多次调用,并将返回大量结果,有助于说明编程式工具调用(PTC)的好处。

在本教程结束时,你将能够:

  • 理解常规工具调用和编程式工具调用(PTC)之间的区别
  • 编写利用 PTC 的代理

前置条件

在遵循此指南之前,请确保您已具备以下条件:

所需知识

  • Python 基础知识 - 熟悉 async/await、函数和基本数据结构
  • 对代理模式和工具调用有基本了解

所需工具

  • Python 3.11 或更高版本
  • Anthropic API 密钥
  • Anthropic Python SDK >= 0.72

环境配置

首先,安装所需的依赖项:

# 示例代码
``````python
# %pip install -r requirements.txt
```注意:确保您的 `.env` 文件包含:

`ANTHROPIC_API_KEY=your_key_here`

加载您的环境变量并配置客户端。我们还会加载一个辅助工具来可视化 Claude 消息响应。


```python
# Example Python code
def process_data(data):
    # Process the data
    pass

请注意,以下代码块中的变量名和函数名将保持不变。

{
    "embedding": "嵌入",
    "token": "标记",
    "prompt": "提示",
    "Agent": "代理",
    "API": "API",
    "Python": "Python",
    "JSON": "JSON",
    "SQL": "SQL"
}
``````python
from dotenv import load_dotenv
from utils.visualize import visualize

load_dotenv()

MODEL = "claude-sonnet-4-6"

viz = visualize(auto_show=True)
```## 了解第三方 API

在 [utils/team_expense_api.py](utils/team_expense_api.py) 中,定义了三个函数:`get_team_members`、`get_expenses` 和 `get_custom_budget`。`get_team_members` 函数允许我们检索给定部门中所有员工及其角色、级别和联系信息。`get_expenses` 函数返回特定季度内员工的全部费用明细——每个员工可能有数百条记录,每条记录包含大量的元数据,包括收据 URL、审批链、商家详情等。`get_custom_budget` 函数检查特定员工是否有自定义差旅预算异常(否则他们使用标准的每季度 5,000 美元限额)。

在这种情况下,我们需要分析团队费用并确定哪些员工超出了预算。传统上,我们可能会手动为每个人提取费用报告,按类别汇总他们的费用,与预算限额(检查自定义预算异常)进行比较,并编制报告。相反,我们将要求 Claude 为我们执行此分析,使用可用的工具检索团队数据,获取可能包含数百条费用明细和丰富元数据的记录,并确定谁超出了预算。

这里的挑战在于,每个员工可能有 100 多条费用明细需要获取、解析和汇总——而 `get_custom_budget` 工具只能在分析费用后调用,以查看是否有人超出了标准预算。这创建了一个顺序依赖链,使其成为演示程序化工具调用的益处的理想用例。

我们将传递我们的工具定义到消息 API,并要求 Claude 执行分析。如果您不熟悉 Claude API 中工具使用的工作方式,请阅读有关 [实现工具使用](https://docs.claude.com/en/docs/agents-and-tools/tool-use/implement-tool-use) 的文档。```python
import json

import anthropic
from utils.team_expense_api import get_custom_budget, get_expenses, get_team_members

client = anthropic.Anthropic()

# Tool definitions for the team expense API
tools = [
    {
        "name": "get_team_members",
        "description": 'Returns a list of team members for a given department. Each team member includes their ID, name, role, level (junior, mid, senior, staff, principal), and contact information. Use this to get a list of people whose expenses you want to analyze. Available departments are: engineering, sales, and marketing.\n\nRETURN FORMAT: Returns a JSON string containing an ARRAY of team member objects (not wrapped in an outer object). Parse with json.loads() to get a list. Example: [{"id": "ENG001", "name": "Alice", ...}, {"id": "ENG002", ...}]',
        "input_schema": {
            "type": "object",
            "properties": {
                "department": {
                    "type": "string",
                    "description": "The department name. Case-insensitive.",
                }
            },
            "required": ["department"],
        },
        "input_examples": [
            {"department": "engineering"},
            {"department": "sales"},
            {"department": "marketing"},
        ],
    },
    {
        "name": "get_expenses",
        "description": "Returns all expense line items for a given employee in a specific quarter. Each expense includes extensive metadata: date, category, description, amount (in USD), currency, status (approved, pending, rejected), receipt URL, approval chain, merchant name and location, payment method, and project codes. An employee may have 20-50+ expense line items per quarter, and each line item contains substantial metadata for audit and compliance purposes. Categories include: 'travel' (flights, trains, rental cars, taxis, parking), 'lodging' (hotels, airbnb), 'meals', 'software', 'equipment', 'conference', 'office', and 'internet'. IMPORTANT: Only expenses with status='approved' should be counted toward budget limits.\n\nRETURN FORMAT: Returns a JSON string containing an ARRAY of expense objects (not wrapped in an outer object with an 'expenses' key). Parse with json.loads() to get a list directly. Example: [{\"expense_id\": \"ENG001_Q3_001\", \"amount\": 1250.50, \"category\": \"travel\", ...}, {...}]",
        "input_schema": {
            "type": "object",
            "properties": {
                "employee_id": {
                    "type": "string",
                    "description": "The unique employee identifier",
                },
                "quarter": {
                    "type": "string",
                    "description": "Quarter identifier: 'Q1', 'Q2', 'Q3', or 'Q4'",
                },
            },
            "required": ["employee_id", "quarter"],
        },
        "input_examples": [
            {"employee_id": "ENG001", "quarter": "Q3"},
            {"employee_id": "SAL002", "quarter": "Q1"},
            {"employee_id": "MKT001", "quarter": "Q4"},
        ],
    },
    {
        "name": "get_custom_budget",
        "description": 'Get the custom quarterly travel budget for a specific employee. Most employees have a standard $5,000 quarterly travel budget. However, some employees have custom budget exceptions based on their role requirements. This function checks if a specific employee has a custom budget assigned.\n\nRETURN FORMAT: Returns a JSON string containing a SINGLE OBJECT (not an array). Parse with json.loads() to get a dict. Example: {"user_id": "ENG001", "has_custom_budget": false, "travel_budget": 5000, "reason": "Standard", "currency": "USD"}',
        "input_schema": {
            "type": "object",
            "properties": {
                "user_id": {
                    "type": "string",
                    "description": "The unique employee identifier",
                }
            },
            "required": ["user_id"],
        },
        "input_examples": [
            {"user_id": "ENG001"},
            {"user_id": "SAL002"},
            {"user_id": "MKT001"},
        ],
    },
]

tool_functions = {
    "get_team_members": get_team_members,
    "get_expenses": get_expenses,
    "get_custom_budget": get_custom_budget,
}
```## 传统工具调用(基线)

在这个第一个例子中,我们将使用传统工具调用方法来建立我们的基线。

我们将使用初始查询调用`messages.create` API。当模型因`tool_use`原因停止时,我们将按照要求执行工具,然后将工具的输出添加到消息中,并再次调用模型。

- 使用传统工具调用方法建立基线。
- 调用`messages.create` API进行初始查询。
- 当模型因`tool_use`原因停止时,执行工具。
- 将工具输出添加到消息中,并再次调用模型。```python
import time

from anthropic.types import TextBlock, ToolUseBlock
from anthropic.types.beta import (
    BetaMessageParam as MessageParam,
)
from anthropic.types.beta import (
    BetaTextBlock,
    BetaToolUseBlock,
)

messages: list[MessageParam] = []


def run_agent_without_ptc(user_message):
    """Run agent using traditional tool calling"""
    messages.append({"role": "user", "content": user_message})
    total_tokens = 0
    start_time = time.time()
    api_counter = 0

    while True:
        response = client.beta.messages.create(
            model=MODEL,
            max_tokens=4000,
            tools=tools,
            messages=messages,
            betas=["advanced-tool-use-2025-11-20"],
        )

        api_counter += 1

        # Track token usage
        total_tokens += response.usage.input_tokens + response.usage.output_tokens
        viz.capture(response)
        if response.stop_reason == "end_turn":
            # Extract the first text block from the response
            final_response = next(
                (
                    block.text
                    for block in response.content
                    if isinstance(block, (BetaTextBlock, TextBlock))
                ),
                None,
            )
            elapsed_time = time.time() - start_time
            return final_response, messages, total_tokens, elapsed_time, api_counter

        # Process tool calls
        if response.stop_reason == "tool_use":
            # First, add the assistant's response to messages
            messages.append({"role": "assistant", "content": response.content})

            # Collect all tool results
            tool_results = []

            for block in response.content:
                if isinstance(block, (BetaToolUseBlock, ToolUseBlock)):
                    tool_name = block.name
                    tool_input = block.input
                    tool_use_id = block.id

                    result = tool_functions[tool_name](**tool_input)

                    content = str(result)

                    tool_result = {
                        "type": "tool_result",
                        "tool_use_id": tool_use_id,
                        "content": content,
                    }
                    tool_results.append(tool_result)

            # Append all tool results at once after collecting them
            messages.append({"role": "user", "content": tool_results})

        else:
            print(f"\nUnexpected stop reason: {response.stop_reason}")
            elapsed_time = time.time() - start_time

            final_response = next(
                (
                    block.text
                    for block in response.content
                    if isinstance(block, (BetaTextBlock, TextBlock))
                ),
                f"Stopped with reason: {response.stop_reason}",
            )
            return final_response, messages, total_tokens, elapsed_time, api_counter
```我们的初始查询向模型提供了一些指令以帮助引导模型。为了简洁,我们要求模型只调用每个工具一次。对于更深入的探究,模型可能希望查看多个系统或时间段。

```markdown
# 初始查询与模型

我们的初始查询向模型提供了一些指令以帮助引导模型。为了简洁,我们已要求模型只调用每个工具一次。对于更深入的探究,模型可能希望查看多个系统或时间段。
``````python
query = "Which engineering team members exceeded their Q3 travel budget? Standard quarterly travel budget is $5,000. However, some employees have custom budget limits. For anyone who exceeded the $5,000 standard budget, check if they have a custom budget exception. If they do, use that custom limit instead to determine if they truly exceeded their budget."
# Run the agent
result, conversation, total_tokens, elapsed_time, api_count_without_ptc = run_agent_without_ptc(
    query
)

print(f"Result: {result}")
print(f"API calls made: {api_count_without_ptc}")
print(f"Total tokens used: {total_tokens:,}")
print(f"Total time taken: {elapsed_time:.2f}s")
╭────────────────────────────────────────────── Claude API Response ──────────────────────────────────────────────╮
│ Claude Message (assistant) │ tokens: 1,859 in • 85 out • 1,944 total                                            │
│ ├── Model: claude-sonnet-4-6                                                                           │
│ ├── Stop Reason: tool_use                                                                                       │
│ └── Content (2 blocks)                                                                                          │
│     ├── Block 1                                                                                                 │
│     │   └── Text                                                                                                │
│     │       └── I'll help you identify which engineering team members exceeded their Q3 travel budget. Let me   │
│     │           start by getting the list of engineering team members.                                          │
│     └── Block 2                                                                                                 │
│         └── Tool Use: get_team_members                                                                          │
│             ├── ID: toolu_01LuouuJYp1sSvBe2Du7EG7v                                                              │
│             ├── Caller: model (direct)                                                                          │
│             └── Input:                                                                                          │
│                 └── {                                                                                           │
│                       "department": "engineering"                                                               │
│                     }                                                                                           │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────── Claude API Response ───────────────────────────────╮
│ Claude Message (assistant) │ tokens: 2,473 in • 497 out • 2,970 total            │
│ ├── Model: claude-sonnet-4-6                                            │
│ ├── Stop Reason: tool_use                                                        │
│ └── Content (9 blocks)                                                           │
│     ├── Block 1                                                                  │
│     │   └── Text                                                                 │
│     │       └── Now let me get the Q3 expenses for all engineering team members: │
│     ├── Block 2                                                                  │
│     │   └── Tool Use: get_expenses                                               │
│     │       ├── ID: toolu_01Wu8LLTT2sKTTqpVwGT65Lj                               │
│     │       ├── Caller: model (direct)                                           │
│     │       └── Input:                                                           │
│     │           └── {                                                            │
│     │                 "employee_id": "ENG001",                                   │
│     │                 "quarter": "Q3"                                            │
│     │               }                                                            │
│     ├── Block 3                                                                  │
│     │   └── Tool Use: get_expenses                                               │
│     │       ├── ID: toolu_01KzjQ5mQJa9ocWjCGzYkD9F                               │
│     │       ├── Caller: model (direct)                                           │
│     │       └── Input:                                                           │
│     │           └── {                                                            │
│     │                 "employee_id": "ENG002",                                   │
│     │                 "quarter": "Q3"                                            │
│     │               }                                                            │
│     ├── Block 4                                                                  │
│     │   └── Tool Use: get_expenses                                               │
│     │       ├── ID: toolu_01RjjhZTg9JsKXE5E9S6Foho                               │
│     │       ├── Caller: model (direct)                                           │
│     │       └── Input:                                                           │
│     │           └── {                                                            │
│     │                 "employee_id": "ENG003",                                   │
│     │                 "quarter": "Q3"                                            │
│     │               }                                                            │
│     ├── Block 5                                                                  │
│     │   └── Tool Use: get_expenses                                               │
│     │       ├── ID: toolu_013xqpxpfc2N9rP5W5uMLAo9                               │
│     │       ├── Caller: model (direct)                                           │
│     │       └── Input:                                                           │
│     │           └── {                                                            │
│     │                 "employee_id": "ENG004",                                   │
│     │                 "quarter": "Q3"                                            │
│     │               }                                                            │
│     ├── Block 6                                                                  │
│     │   └── Tool Use: get_expenses                                               │
│     │       ├── ID: toolu_019zfzG6Wox8iDqy1dUXiH3t                               │
│     │       ├── Caller: model (direct)                                           │
│     │       └── Input:                                                           │
│     │           └── {                                                            │
│     │                 "employee_id": "ENG005",                                   │
│     │                 "quarter": "Q3"                                            │
│     │               }                                                            │
│     ├── Block 7                                                                  │
│     │   └── Tool Use: get_expenses                                               │
│     │       ├── ID: toolu_01RxfTz11tzvbVE7oEtqHaVB                               │
│     │       ├── Caller: model (direct)                                           │
│     │       └── Input:                                                           │
│     │           └── {                                                            │
│     │                 "employee_id": "ENG006",                                   │
│     │                 "quarter": "Q3"                                            │
│     │               }                                                            │
│     ├── Block 8                                                                  │
│     │   └── Tool Use: get_expenses                                               │
│     │       ├── ID: toolu_01FsFEtK1gTEPxg56eVrhhf6                               │
│     │       ├── Caller: model (direct)                                           │
│     │       └── Input:                                                           │
│     │           └── {                                                            │
│     │                 "employee_id": "ENG007",                                   │
│     │                 "quarter": "Q3"                                            │
│     │               }                                                            │
│     └── Block 9                                                                  │
│         └── Tool Use: get_expenses                                               │
│             ├── ID: toolu_01Ctq9dZbvzaVSLSZe86MTzb                               │
│             ├── Caller: model (direct)                                           │
│             └── Input:                                                           │
│                 └── {                                                            │
│                       "employee_id": "ENG008",                                   │
│                       "quarter": "Q3"                                            │
│                     }                                                            │
╰──────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────── Claude API Response ──────────────────────────────────────────────╮
│ Claude Message (assistant) │ tokens: 51,744 in • 290 out • 52,034 total                                         │
│ ├── Model: claude-sonnet-4-6                                                                           │
│ ├── Stop Reason: tool_use                                                                                       │
│ └── Content (7 blocks)                                                                                          │
│     ├── Block 1                                                                                                 │
│     │   └── Text                                                                                                │
│     │       └── Now let me calculate the approved travel expenses for each engineer and identify who exceeded   │
│     │           $5,000:                                                                                         │
│     ├── Block 2                                                                                                 │
│     │   └── Tool Use: get_custom_budget                                                                         │
│     │       ├── ID: toolu_013oegKwjvToLwEW1daDD8av                                                              │
│     │       ├── Caller: model (direct)                                                                          │
│     │       └── Input:                                                                                          │
│     │           └── {                                                                                           │
│     │                 "user_id": "ENG001"                                                                       │
│     │               }                                                                                           │
│     ├── Block 3                                                                                                 │
│     │   └── Tool Use: get_custom_budget                                                                         │
│     │       ├── ID: toolu_0162W4Ycr9FcVVED65exjAj4                                                              │
│     │       ├── Caller: model (direct)                                                                          │
│     │       └── Input:                                                                                          │
│     │           └── {                                                                                           │
│     │                 "user_id": "ENG003"                                                                       │
│     │               }                                                                                           │
│     ├── Block 4                                                                                                 │
│     │   └── Tool Use: get_custom_budget                                                                         │
│     │       ├── ID: toolu_01JcTX5rnwFxA99Am33gXmh6                                                              │
│     │       ├── Caller: model (direct)                                                                          │
│     │       └── Input:                                                                                          │
│     │           └── {                                                                                           │
│     │                 "user_id": "ENG005"                                                                       │
│     │               }                                                                                           │
│     ├── Block 5                                                                                                 │
│     │   └── Tool Use: get_custom_budget                                                                         │
│     │       ├── ID: toolu_01QwNJz1wGeV5VeZoCd4ByER                                                              │
│     │       ├── Caller: model (direct)                                                                          │
│     │       └── Input:                                                                                          │
│     │           └── {                                                                                           │
│     │                 "user_id": "ENG006"                                                                       │
│     │               }                                                                                           │
│     ├── Block 6                                                                                                 │
│     │   └── Tool Use: get_custom_budget                                                                         │
│     │       ├── ID: toolu_01KoJ4gzfiu1TPccLJB86Wiq                                                              │
│     │       ├── Caller: model (direct)                                                                          │
│     │       └── Input:                                                                                          │
│     │           └── {                                                                                           │
│     │                 "user_id": "ENG007"                                                                       │
│     │               }                                                                                           │
│     └── Block 7                                                                                                 │
│         └── Tool Use: get_custom_budget                                                                         │
│             ├── ID: toolu_01MxeFPzHot9aE5fPuniFkui                                                              │
│             ├── Caller: model (direct)                                                                          │
│             └── Input:                                                                                          │
│                 └── {                                                                                           │
│                       "user_id": "ENG008"                                                                       │
│                     }                                                                                           │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────── Claude API Response ──────────────────────────────────────────────╮
│ Claude Message (assistant) │ tokens: 52,533 in • 992 out • 53,525 total                                         │
│ ├── Model: claude-sonnet-4-6                                                                           │
│ ├── Stop Reason: end_turn                                                                                       │
│ └── Content (1 blocks)                                                                                          │
│     └── Block 1                                                                                                 │
│         └── Text                                                                                                │
│             └── Now let me analyze the data. I'll calculate the approved travel expenses for each engineer:     │
│                                                                                                                 │
│                 **Analysis of Q3 Travel Expenses:**                                                             │
│                                                                                                                 │
│                 **ENG001 - Alice Chen (Senior Software Engineer)**                                              │
│                 - Approved travel expenses: $1,161.04 + $18.63 + $13.21 + $36.55 + $1,440.42 + $166.46 + $48.43 │
│                 + $1,124.56 + $1,245.90 + $1,498.42 = **$6,753.62**                                             │
│                 - Budget: $5,000 (Standard)                                                                     │
│                 - **EXCEEDED by $1,753.62** ❌                                                                  │
│                                                                                                                 │
│                 **ENG002 - Bob Martinez (Staff Engineer)**                                                      │
│                 - Approved travel expenses: $180.16 + $10.07 + $20.76 = **$210.99**                             │
│                 - Budget: $5,000 (Standard)                                                                     │
│                 - Under budget ✓                                                                                │
│                                                                                                                 │
│                 **ENG003 - Carol White (Software Engineer)**                                                    │
│                 - Approved travel expenses: $24.75 + $424.74 + $1,397.17 + $1,026.12 + $1,288.36 + $1,128.90 +  │
│                 $1,148.42 + $45.03 = **$6,483.49**                                                              │
│                 - Budget: $5,000 (Standard)                                                                     │
│                 - **EXCEEDED by $1,483.49** ❌                                                                  │
│                                                                                                                 │
│                 **ENG004 - David Kim (Principal Engineer)**                                                     │
│                 - Approved travel expenses: $21.68 + $46.12 + $1,008.68 + $46.43 = **$1,122.91**                │
│                 - Budget: $5,000 (Standard)                                                                     │
│                 - Under budget ✓                                                                                │
│                                                                                                                 │
│                 **ENG005 - Emma Johnson (Junior Software Engineer)                                              │
│                 ... (truncated)                                                                                 │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Result: Now let me analyze the data. I'll calculate the approved travel expenses for each engineer:

**Analysis of Q3 Travel Expenses:**

**ENG001 - Alice Chen (Senior Software Engineer)**
- Approved travel expenses: $1,161.04 + $18.63 + $13.21 + $36.55 + $1,440.42 + $166.46 + $48.43 + $1,124.56 + $1,245.90 + $1,498.42 = **$6,753.62**
- Budget: $5,000 (Standard)
- **EXCEEDED by $1,753.62** ❌

**ENG002 - Bob Martinez (Staff Engineer)**
- Approved travel expenses: $180.16 + $10.07 + $20.76 = **$210.99**
- Budget: $5,000 (Standard)
- Under budget ✓

**ENG003 - Carol White (Software Engineer)**
- Approved travel expenses: $24.75 + $424.74 + $1,397.17 + $1,026.12 + $1,288.36 + $1,128.90 + $1,148.42 + $45.03 = **$6,483.49**
- Budget: $5,000 (Standard)
- **EXCEEDED by $1,483.49** ❌

**ENG004 - David Kim (Principal Engineer)**
- Approved travel expenses: $21.68 + $46.12 + $1,008.68 + $46.43 = **$1,122.91**
- Budget: $5,000 (Standard)
- Under budget ✓

**ENG005 - Emma Johnson (Junior Software Engineer)**
- Approved travel expenses: $450.00 + $1,376.36 + $1,164.49 + $151.55 + $1,253.88 = **$4,396.28**
- Budget: $5,000 (Standard)
- Under budget ✓

**ENG006 - Frank Liu (Senior Software Engineer)**
- Approved travel expenses: $596.48 + $1,018.71 + $1,193.82 + $159.08 + $1,112.11 + $24.97 = **$4,105.17**
- Budget: $5,000 (Standard)
- Under budget ✓

**ENG007 - Grace Taylor (Software Engineer)**
- Approved travel expenses: $1,476.63 + $39.85 + $1,220.19 + $189.16 + $1,032.52 + $1,331.00 = **$5,289.35**
- Budget: $5,000 (Standard)
- **EXCEEDED by $289.35** ❌

**ENG008 - Henry Park (Staff Engineer)**
- Approved travel expenses: $15.63 + $166.05 + $1,018.94 + $1,224.34 + $1,120.32 + $1,345.90 = **$4,891.18**
- Budget: $5,000 (Standard)
- Under budget ✓

---

## Summary: Engineering Team Members Who Exceeded Their Q3 Travel Budget

**3 team members exceeded their quarterly travel budget:**

1. **Alice Chen (ENG001)** - Senior Software Engineer
   - Travel expenses: **$6,753.62**
   - Budget: $5,000
   - **Over budget by $1,753.62 (35% over)**

2. **Carol White (ENG003)** - Software Engineer
   - Travel expenses: **$6,483.49**
   - Budget: $5,000
   - **Over budget by $1,483.49 (30% over)**

3. **Grace Taylor (ENG007)** - Software Engineer
   - Travel expenses: **$5,289.35**
   - Budget: $5,000
   - **Over budget by $289.35 (6% over)**

All three employees have the standard $5,000 quarterly travel budget with no custom exceptions.
API calls made: 4
Total tokens used: 110,473
Total time taken: 35.38s
```太棒了!我们可以看到Claude成功地使用了可用的工具来识别哪些团队成员超出了他们的旅行预算。然而,我们也可以看到,为了完成这个任务,我们使用了大量的tokens。Claude必须通过其上下文窗口摄取所有费用明细——可能每个员工有100+条记录,每条记录都包含大量的元数据,包括收据URL、审批链、商家信息等等——以便解析它们,按类别汇总总额,并与预算限制进行比较。

此外,传统的工具调用方法需要多次顺序往返:首先获取团队成员,然后获取每个人的费用,然后检查超出标准限制的人的定制预算。每次往返都会增加延迟,所有来自费用记录的丰富元数据都会通过模型上下文流动。

让我们看看我们是否可以使用PTC来通过允许Claude在代码执行环境中编写处理这些大型数据集的代码来提高性能。

要启用工具上的PTC,我们首先必须将`allowed_callers`字段添加到任何应通过代码执行调用的工具中。

**需要考虑的关键点**

- 没有允许调用者的工具默认为仅模型调用
- 可以通过包含多个调用者来调用工具:`["direct", "code_execution_20250825"]`
- 只选择那些对程序化/重复执行安全的工具进行启用。```python
import copy

ptc_tools = copy.deepcopy(tools)
for tool in ptc_tools:
    tool["allowed_callers"] = ["code_execution_20250825"]  # type: ignore


# Add the code execution tool
ptc_tools.append(
    {
        "type": "code_execution_20250825",  # type: ignore
        "name": "code_execution",
    }
)
```现在我们已经更新了工具定义,允许程序化调用工具,我们可以使用PTC运行我们的代理。为了做到这一点,我们不得不对我们的函数做了一些修改。我们必须使用`beta`消息API。

1. 我们将`"advanced-tool-use-2025-11-20"`添加到beta版本中。
2. 如果`container_id`在我们的请求中定义了,我们将传递它。这对于像我们这样的有状态工作流是必要的。在单轮工作流中这不必要。
3. 我们可以在`tool_use`块中的`caller`字段检查,以确定这个工具调用是从直接模型调用还是从程序化调用。

请注意,在任一情况下,我们通过Claude API发送我们的工具结果,然而只有`direct`调用会被模型“看到”。`code_execution_20250825`类型的调用只会被代码执行容器看到。

```python
def update_agent_function():
    # 更新代理函数的代码
    pass

请注意,在任一情况下,我们通过Claude API发送我们的工具结果,然而只有direct调用会被模型“看到”。code_execution_20250825类型的调用只会被代码执行容器看到。 :::```python messages = []

def run_agent_with_ptc(user_message): “““Run agent using PTC”“” messages.append({“role”: “user”, “content”: user_message}) total_tokens = 0 start_time = time.time() container_id = None api_counter = 0

while True:
    # Build request with PTC beta headers
    request_params = {
        "model": MODEL,
        "max_tokens": 4000,
        "tools": ptc_tools,
        "messages": messages,
    }

    response = client.beta.messages.create(
        **request_params,
        betas=[
            "advanced-tool-use-2025-11-20",
        ],
        extra_body={"container": container_id} if container_id else None,
    )
    viz.capture(response)
    api_counter += 1

    # Track container for stateful execution
    if hasattr(response, "container") and response.container:
        container_id = response.container.id
        print(f"\n[Container] ID: {container_id}")
        if hasattr(response.container, "expires_at"):
            # If the container has expired, we would need to restart our workflow. In our case, it completes before expiration.
            print(f"[Container] Expires at: {response.container.expires_at}")

    # Track token usage
    total_tokens += response.usage.input_tokens + response.usage.output_tokens

    if response.stop_reason == "end_turn":
        # Extract the first text block from the response
        final_response = next(
            (block.text for block in response.content if isinstance(block, BetaTextBlock)),
            None,
        )
        elapsed_time = time.time() - start_time
        return final_response, messages, total_tokens, elapsed_time, api_counter

    # As before, we process tool calls
    if response.stop_reason == "tool_use":
        # First, add the assistant's response to messages
        messages.append({"role": "assistant", "content": response.content})

        # Collect all tool results
        tool_results = []

        for block in response.content:
            if isinstance(block, BetaToolUseBlock):
                tool_name = block.name
                tool_input = block.input
                tool_use_id = block.id

                # We can use caller type to understand how the tool was invoked
                caller_type = block.caller["type"]  # type: ignore

                if caller_type == "code_execution_20250825":
                    print(f"[PTC] Tool called from code execution environment: {tool_name}")

                elif caller_type == "direct":
                    print(f"[Direct] Tool called by model: {tool_name}")

                result = tool_functions[tool_name](**tool_input)

                # Format result as proper content for the API
                if isinstance(result, list) and result and isinstance(result[0], str):
                    content = "\n".join(result)
                elif isinstance(result, (dict, list)):
                    content = json.dumps(result)
                else:
                    content = str(result)

                tool_results.append(
                    {
                        "type": "tool_result",
                        "tool_use_id": tool_use_id,
                        "content": content,
                    }
                )

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

    else:
        print(f"\nUnexpected stop reason: {response.stop_reason}")
        elapsed_time = time.time() - start_time

        final_response = next(
            (block.text for block in response.content if isinstance(block, BetaTextBlock)),
            f"Stopped with reason: {response.stop_reason}",
        )
        return final_response, messages, total_tokens, elapsed_time, api_counter

```python
# Run the PTC agent
result_ptc, conversation_ptc, total_tokens_ptc, elapsed_time_ptc, api_count_with_ptc = (
    run_agent_with_ptc(query)
)
╭────────────────────────────────────────────── Claude API Response ──────────────────────────────────────────────╮
│ Claude Message (assistant) │ tokens: 4,134 in • 539 out • 4,673 total                                           │
│ ├── Model: claude-sonnet-4-6                                                                           │
│ ├── Stop Reason: tool_use                                                                                       │
│ └── Content (3 blocks)                                                                                          │
│     ├── Block 1                                                                                                 │
│     │   └── Text                                                                                                │
│     │       └── I'll help you identify which engineering team members exceeded their Q3 travel budget. Let me   │
│     │           start by getting the engineering team members and their expenses.                               │
│     ├── Block 2                                                                                                 │
│     │   └── Server Tool Use                                                                                     │
│     │       ├── ID: srvtoolu_015mWPqaFni4B313UieCxbny                                                           │
│     │       ├── Caller: direct                                                                                  │
│     │       └── Code:                                                                                           │
│     │           └──    1                                                                                        │
│     │                  2 import asyncio                                                                         │
│     │                  3 import json                                                                            │
│     │                  4                                                                                        │
│     │                  5 async def main():                                                                      │
│     │                  6     # First, get all engineering team members                                          │
│     │                  7     team_members_json = await get_team_members({'department': 'engineering'})          │
│     │                  8     team_members = json.loads(team_members_json)                                       │
│     │                  9                                                                                        │
│     │                 10     print(f"Found {len(team_members)} engineering team members")                       │
│     │                 11                                                                                        │
│     │                 12     # Get Q3 expenses for all team members in parallel                                 │
│     │                 13     expense_tasks = [                                                                  │
│     │                 14         get_expenses({'employee_id': member['id'], 'quarter': 'Q3'})                   │
│     │                 15         for member in team_members                                                     │
│     │                 16     ]                                                                                  │
│     │                 17                                                                                        │
│     │                 18     expenses_results = await asyncio.gather(*expense_tasks)                            │
│     │                 19                                                                                        │
│     │                 20     # Calculate travel expenses for each member                                        │
│     │                 21     travel_spending = {}                                                               │
│     │                 22     for i, member in enumerate(team_members):                                          │
│     │                 23         expenses = json.loads(expenses_results[i])                                     │
│     │                 24         # Only count approved expenses in travel category                              │
│     │                 25         travel_total = sum(                                                            │
│     │                 26             expense['amount']                                                          │
│     │                 27             for expense in expenses                                                    │
│     │                 28             if expense['category'] == 'travel' and expense['status'] == 'approved'     │
│     │                 29         )                                                                              │
│     │                 30         travel_spending[member[                                                        │
│     │                 31 ... (truncated)                                                                        │
│     └── Block 3                                                                                                 │
│         └── Tool Use: get_team_members                                                                          │
│             ├── ID: toolu_016EtCE7G5rH645G3gvjzrP6                                                              │
│             ├── Caller: code execution environment                                                              │
│             └── Input:                                                                                          │
│                 └── {                                                                                           │
│                       "department": "engineering"                                                               │
│                     }                                                                                           │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

[Container] ID: container_011CVSAwq5J4vNPi3A4P2Rwh
[Container] Expires at: 2025-11-24 05:41:17.467494+00:00
[PTC] Tool called from code execution environment: get_team_members
╭──────────────────── Claude API Response ────────────────────╮
│ Claude Message (assistant) │ tokens: 0 in • 0 out • 0 total │
│ ├── Model: claude-sonnet-4-6                       │
│ ├── Stop Reason: tool_use                                   │
│ └── Content (8 blocks)                                      │
│     ├── Block 1                                             │
│     │   └── Tool Use: get_expenses                          │
│     │       ├── ID: toolu_01Nq2au3W69RmDFZaSdqe6u1          │
│     │       ├── Caller: code execution environment          │
│     │       └── Input:                                      │
│     │           └── {                                       │
│     │                 "employee_id": "ENG007",              │
│     │                 "quarter": "Q3"                       │
│     │               }                                       │
│     ├── Block 2                                             │
│     │   └── Tool Use: get_expenses                          │
│     │       ├── ID: toolu_01YYw9cuTSXk7bu7P38qBz6P          │
│     │       ├── Caller: code execution environment          │
│     │       └── Input:                                      │
│     │           └── {                                       │
│     │                 "employee_id": "ENG005",              │
│     │                 "quarter": "Q3"                       │
│     │               }                                       │
│     ├── Block 3                                             │
│     │   └── Tool Use: get_expenses                          │
│     │       ├── ID: toolu_01Fyxxe2KmVpVmw4jJL2CXSz          │
│     │       ├── Caller: code execution environment          │
│     │       └── Input:                                      │
│     │           └── {                                       │
│     │                 "employee_id": "ENG008",              │
│     │                 "quarter": "Q3"                       │
│     │               }                                       │
│     ├── Block 4                                             │
│     │   └── Tool Use: get_expenses                          │
│     │       ├── ID: toolu_01J4ovDu2UJa9Se19vxKTa6y          │
│     │       ├── Caller: code execution environment          │
│     │       └── Input:                                      │
│     │           └── {                                       │
│     │                 "employee_id": "ENG006",              │
│     │                 "quarter": "Q3"                       │
│     │               }                                       │
│     ├── Block 5                                             │
│     │   └── Tool Use: get_expenses                          │
│     │       ├── ID: toolu_01T24CrvQYA3LqGfZftCmueC          │
│     │       ├── Caller: code execution environment          │
│     │       └── Input:                                      │
│     │           └── {                                       │
│     │                 "employee_id": "ENG003",              │
│     │                 "quarter": "Q3"                       │
│     │               }                                       │
│     ├── Block 6                                             │
│     │   └── Tool Use: get_expenses                          │
│     │       ├── ID: toolu_01HotYZN6sk3gMLkpdWXbdz4          │
│     │       ├── Caller: code execution environment          │
│     │       └── Input:                                      │
│     │           └── {                                       │
│     │                 "employee_id": "ENG004",              │
│     │                 "quarter": "Q3"                       │
│     │               }                                       │
│     ├── Block 7                                             │
│     │   └── Tool Use: get_expenses                          │
│     │       ├── ID: toolu_01AxvEqi3AKqdnH44kGH1U6E          │
│     │       ├── Caller: code execution environment          │
│     │       └── Input:                                      │
│     │           └── {                                       │
│     │                 "employee_id": "ENG002",              │
│     │                 "quarter": "Q3"                       │
│     │               }                                       │
│     └── Block 8                                             │
│         └── Tool Use: get_expenses                          │
│             ├── ID: toolu_01A4agznkK1jA4AyJo3H2jpg          │
│             ├── Caller: code execution environment          │
│             └── Input:                                      │
│                 └── {                                       │
│                       "employee_id": "ENG001",              │
│                       "quarter": "Q3"                       │
│                     }                                       │
╰─────────────────────────────────────────────────────────────╯

[Container] ID: container_011CVSAwq5J4vNPi3A4P2Rwh
[Container] Expires at: 2025-11-24 05:41:19.266670+00:00
[PTC] Tool called from code execution environment: get_expenses
[PTC] Tool called from code execution environment: get_expenses
[PTC] Tool called from code execution environment: get_expenses
[PTC] Tool called from code execution environment: get_expenses
[PTC] Tool called from code execution environment: get_expenses
[PTC] Tool called from code execution environment: get_expenses
[PTC] Tool called from code execution environment: get_expenses
[PTC] Tool called from code execution environment: get_expenses
╭─────────────────────────────────────── Claude API Response ───────────────────────────────────────╮
│ Claude Message (assistant) │ tokens: 4,751 in • 679 out • 5,430 total                             │
│ ├── Model: claude-sonnet-4-6                                                             │
│ ├── Stop Reason: tool_use                                                                         │
│ └── Content (6 blocks)                                                                            │
│     ├── Block 1                                                                                   │
│     │   └── Code Execution Result: Success (exit 0)                                               │
│     │       └── stdout:                                                                           │
│     │           └── Found 8 engineering team members                                              │
│     │                                                                                             │
│     │               Employees who exceeded $5,000 standard budget: 3                              │
│     │               ENG001: Alice Chen - $9177.88                                                 │
│     │               ENG003: Carol White - $6483.49                                                │
│     │               ENG007: Grace Taylor - $5289.35                                               │
│     │                                                                                             │
│     ├── Block 2                                                                                   │
│     │   └── Text                                                                                  │
│     │       └── Now let me check if any of these three employees have custom budget exceptions:   │
│     ├── Block 3                                                                                   │
│     │   └── Server Tool Use                                                                       │
│     │       ├── ID: srvtoolu_015GTpFmCbd2JPAQLAioB4Qb                                             │
│     │       ├── Caller: direct                                                                    │
│     │       └── Code:                                                                             │
│     │           └──    1                                                                          │
│     │                  2 import asyncio                                                           │
│     │                  3 import json                                                              │
│     │                  4                                                                          │
│     │                  5 async def main():                                                        │
│     │                  6     # Check custom budgets for the three employees who exceeded standard │
│     │                  7     exceeded_ids = ['ENG001', 'ENG003', 'ENG007']                        │
│     │                  8     exceeded_amounts = {                                                 │
│     │                  9         'ENG001': {'name': 'Alice Chen', 'travel_total': 9177.88},       │
│     │                 10         'ENG003': {'name': 'Carol White', 'travel_total': 6483.49},      │
│     │                 11         'ENG007': {'name': 'Grace Taylor', 'travel_total': 5289.35}      │
│     │                 12     }                                                                    │
│     │                 13                                                                          │
│     │                 14     # Get custom budgets in parallel                                     │
│     │                 15     budget_tasks = [                                                     │
│     │                 16         get_custom_budget({'user_id': emp_id})                           │
│     │                 17         for emp_id in exceeded_ids                                       │
│     │                 18     ]                                                                    │
│     │                 19                                                                          │
│     │                 20     budget_results = await asyncio.gather(*budget_tasks)                 │
│     │                 21                                                                          │
│     │                 22     # Analyze who truly exceeded their budget                            │
│     │                 23     truly_exceeded = []                                                  │
│     │                 24                                                                          │
│     │                 25     for i, emp_id in enumerate(exceeded_ids):                            │
│     │                 26         budget_info = json.loads(budget_results[i])                      │
│     │                 27         actual_budget = budget_info['travel_budget']                     │
│     │                 28         travel_total = exceeded_amounts[emp_id]['travel_total']          │
│     │                 29         name = exceeded_amounts[emp_id]['name']                          │
│     │                 30                                                                          │
│     │                 31         if travel_total > actua                                          │
│     │                 32 ... (truncated)                                                          │
│     ├── Block 4                                                                                   │
│     │   └── Tool Use: get_custom_budget                                                           │
│     │       ├── ID: toolu_01EaaJ3SikeniibPsEdAqXo8                                                │
│     │       ├── Caller: code execution environment                                                │
│     │       └── Input:                                                                            │
│     │           └── {                                                                             │
│     │                 "user_id": "ENG003"                                                         │
│     │               }                                                                             │
│     ├── Block 5                                                                                   │
│     │   └── Tool Use: get_custom_budget                                                           │
│     │       ├── ID: toolu_01E5bqQ4xKX7FTdhh6xLkw4E                                                │
│     │       ├── Caller: code execution environment                                                │
│     │       └── Input:                                                                            │
│     │           └── {                                                                             │
│     │                 "user_id": "ENG001"                                                         │
│     │               }                                                                             │
│     └── Block 6                                                                                   │
│         └── Tool Use: get_custom_budget                                                           │
│             ├── ID: toolu_01PLF38q7ndVQB4mqdqaFt7u                                                │
│             ├── Caller: code execution environment                                                │
│             └── Input:                                                                            │
│                 └── {                                                                             │
│                       "user_id": "ENG007"                                                         │
│                     }                                                                             │
╰───────────────────────────────────────────────────────────────────────────────────────────────────╯

[Container] ID: container_011CVSAwq5J4vNPi3A4P2Rwh
[Container] Expires at: 2025-11-24 05:41:33.430636+00:00
[PTC] Tool called from code execution environment: get_custom_budget
[PTC] Tool called from code execution environment: get_custom_budget
[PTC] Tool called from code execution environment: get_custom_budget
╭────────────────────────────────────────────── Claude API Response ──────────────────────────────────────────────╮
│ Claude Message (assistant) │ tokens: 5,611 in • 205 out • 5,816 total                                           │
│ ├── Model: claude-sonnet-4-6                                                                           │
│ ├── Stop Reason: end_turn                                                                                       │
│ └── Content (2 blocks)                                                                                          │
│     ├── Block 1                                                                                                 │
│     │   └── Code Execution Result: Success (exit 0)                                                             │
│     │       └── stdout:                                                                                         │
│     │           └── ENGINEERING TEAM MEMBERS WHO EXCEEDED THEIR Q3 TRAVEL BUDGET:                               │
│     │               ================================================================================            │
│     │                                                                                                           │
│     │               Alice Chen (ENG001)                                                                         │
│     │                 Budget Limit: $5,000.00 (Standard)                                                        │
│     │                 Travel Spending: $9,177.88                                                                │
│     │                 Exceeded By: $4,177.88                                                                    │
│     │                                                                                                           │
│     │               Carol White (ENG003)                                                                        │
│     │                 Budget Limit: $5,000.00 (Standard)                                                        │
│     │                 Travel Spending: $6,483.49                                                                │
│     │                 Exceeded By: $1,483.49                                                                    │
│     │                                                                                                           │
│     │               Grace Taylor (ENG007)                                                                       │
│     │                 Budget Limit: $5,000.00 (Standard)                                                        │
│     │                 Travel Spending: $5,289.35                                                                │
│     │                 Exceeded By: $289.35                                                                      │
│     │                                                                                                           │
│     └── Block 2                                                                                                 │
│         └── Text                                                                                                │
│             └── ## Summary                                                                                      │
│                                                                                                                 │
│                 **Three engineering team members exceeded their Q3 travel budget:**                             │
│                                                                                                                 │
│                 1. **Alice Chen (ENG001)**                                                                      │
│                    - Budget: $5,000 (Standard)                                                                  │
│                    - Spent: $9,177.88                                                                           │
│                    - Over budget by: **$4,177.88**                                                              │
│                                                                                                                 │
│                 2. **Carol White (ENG003)**                                                                     │
│                    - Budget: $5,000 (Standard)                                                                  │
│                    - Spent: $6,483.49                                                                           │
│                    - Over budget by: **$1,483.49**                                                              │
│                                                                                                                 │
│                 3. **Grace Taylor (ENG007)**                                                                    │
│                    - Budget: $5,000 (Standard)                                                                  │
│                    - Spent: $5,289.35                                                                           │
│                    - Over budget by: **$289.35**                                                                │
│                                                                                                                 │
│                 All three employees are on the standard $5,000 quarterly travel budget with no custom           │
│                 exceptions, so they all genuinely exceeded their allocated travel budget for Q3.                │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
print(f"\n{'=' * 60}")
print(f"Result: {result_ptc}")
print(f"\n{'=' * 60}")
print("Performance Metrics:")
print(
    f"  Total API calls to Claude: {len([m for m in conversation_ptc if m['role'] == 'assistant'])}"
)
print(f"  Total tokens used: {total_tokens_ptc:,}")
print(f"  Total time taken: {elapsed_time_ptc:.2f}s")

============================================================
Result: ## Summary

**Three engineering team members exceeded their Q3 travel budget:**

1. **Alice Chen (ENG001)**
   - Budget: $5,000 (Standard)
   - Spent: $9,177.88
   - Over budget by: **$4,177.88**

2. **Carol White (ENG003)**
   - Budget: $5,000 (Standard)
   - Spent: $6,483.49
   - Over budget by: **$1,483.49**

3. **Grace Taylor (ENG007)**
   - Budget: $5,000 (Standard)
   - Spent: $5,289.35
   - Over budget by: **$289.35**

All three employees are on the standard $5,000 quarterly travel budget with no custom exceptions, so they all genuinely exceeded their allocated travel budget for Q3.

============================================================
Performance Metrics:
  Total API calls to Claude: 3
  Total tokens used: 15,919
  Total time taken: 34.88s
```## 性能比较

让我们比较传统工具调用和PTC之间的性能:

**关于API调用次数的说明:** 您可能会注意到,在这个例子中PTC需要更多的API调用。这是因为PTC编写了更多结构化、顺序化的代码,遵循最佳实践——例如,将费用获取步骤与预算检查步骤分开。传统的工具调用有时可以在一个回合中将操作批量处理在一起,但代价是所有原始数据都通过模型的上下文发送。PTC在令牌效率上的提升远远超过了往返次数的微小增加,尤其是在处理大型、元数据丰富的数据集时。

```html
::: callout-attention
请注意,PTC在性能上可能不如传统工具调用,但它在代码结构和数据管理方面提供了显著的改进。
:::``````python
import pandas as pd

# Create comparison dataframe
comparison_data = {
    "Metric": [
        "API Calls",
        "Total Tokens",
        "Elapsed Time (s)",
        "Token Reduction",
        "Time Reduction",
    ],
    "Traditional": [
        api_count_without_ptc,
        f"{total_tokens:,}",
        f"{elapsed_time:.2f}",
        "-",
        "-",
    ],
    "PTC": [
        api_count_with_ptc,
        f"{total_tokens_ptc:,}",
        f"{elapsed_time_ptc:.2f}",
        f"{((total_tokens - total_tokens_ptc) / total_tokens * 100):.1f}%",
        f"{((elapsed_time - elapsed_time_ptc) / elapsed_time * 100):.1f}%",
    ],
}

df = pd.DataFrame(comparison_data)
print(df.to_string(index=False))

Metric Traditional PTC API Calls 4 4 Total Tokens 110,473 15,919 Elapsed Time (s) 35.38 34.88 Token Reduction - 85.6% Time Reduction - 1.4%## 关键要点

在这个示例中,PTC通过三个核心能力展示了显著的性能提升:

1. 通过大量数据处理保持上下文

这是我们工作流程中展示的主要好处。Claude编写了代码,在代码执行环境中抓取并处理了数百项费用明细。通过程序化处理这些数据,Claude解析了JSON,按状态过滤,按类别汇总金额,并与预算限制进行比较——所有这些都不需要将原始费用数据和元数据通过模型的上下文窗口发送。这导致了标记使用量的显著减少。

2. 顺序依赖优化

API有一个顺序依赖:get_custom_budget(user_id),它只能在分析费用以确定谁超出了标准5000美元预算之后调用。在传统的工具调用中,这需要多次往返——获取团队成员,获取每个人的费用,确定超预算的人,然后逐个检查他们的自定义预算。使用PTC,Claude编写了代码,在代码执行环境中编排了整个工作流程,循环中进行程序化工具调用,并在调用之间保持状态。这将本将是许多顺序API往返的过程转变为更少的调用和更智能的编排。

3. 代码执行中的计算逻辑

而不是要求模型在心理上跟踪和汇总数十项具有复杂元数据的费用,Claude将算术和聚合逻辑委托给了Python代码。这减少了模型上的认知负担,确保了精确的计算,并将无关的元数据(如收据URL和商家位置)完全排除在模型上下文之外。


何时使用 PTC

PTC在以下情况下最有益:

  • 处理大型、元数据丰富的数据集,需要进行过滤、解析或聚合(如我们的带有收据URL、审批链、商家详情等的费用分析)。
  • 存在顺序依赖,即一个工具调用依赖于先前调用的结果(例如,只为超过标准限额的员工检查自定义预算)
  • 需要多个工具调用,按顺序或在类似实体之间循环(检查每个团队成员的费用和预算)
  • 计算逻辑可以减少需要通过模型上下文流动的内容
  • 工具是安全的,可以在没有人工监督的情况下进行程序化/重复执行

结论

我们的团队费用分析展示了PTC的优势:在处理大型、元数据丰富的数据集时,显著减少上下文消耗,以及通过优化具有顺序依赖的工作流程。通过允许Claude编写协调工具调用并程序化处理结果的代码,我们在保持准确性和洞察力质量的同时,实现了显著的token节省。

PTC对于涉及大量数据处理、具有丰富元数据的工作流程、需要具有依赖关系的重复工具调用,或原始工具输出可能会污染模型上下文的情况尤其有价值。

后续步骤

尝试将此模式应用于您的用例: - 使用顺序查找进行财务数据分析报告 - 依赖于初始扫描结果的跨实体健康检查 - 带有元数据的大文件处理(CSV、JSON、XML解析) - 使用后续查询聚合数据库查询结果 - 基于初始结果的具有条件逻辑的批量API操作


Tip

中文读者提示:本章节的代码和输出为英文原文。如需理解具体实现细节,可参考上方中文导读和代码注释。如有疑问,欢迎在 GitHub Issues 讨论。