{"product_id":"programmatic-tool-calling-ptc-giảm-latency-tang-hiệu-suất","title":"Programmatic Tool Calling (PTC) — Giảm latency, tăng hiệu suất","description":"\n\u003cp\u003eTrong tool use truyền thống, mỗi lần Claude muốn gọi một tool, phải có một \"round-trip\": Claude → API → tool → API → Claude. Với 100 records cần xử lý, đó là 100 round-trips. Với Programmatic Tool Calling (PTC), Claude \u003cstrong\u003eviết code xử lý toàn bộ logic trong Code Execution environment\u003c\/strong\u003e — từ 100 round-trips xuống còn 1.\u003c\/p\u003e\n\n\u003ch2\u003eVấn đề với traditional tool calling\u003c\/h2\u003e\n\n\u003cp\u003eHãy xem xét bài toán: phân tích expense reports của toàn bộ team tháng 12, mỗi nhân viên có 100+ khoản chi.\u003c\/p\u003e\n\n\u003ch3\u003eTraditional approach: Sequential round-trips\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e# Traditional tool calling — mỗi call là một round-trip\n# Với 5 nhân viên x 100 records = 500 round-trips qua API\n\nLuong: Claude call get_expenses(\"nguyen_van_a\")\n       → API round-trip 1\n       Claude call get_expenses(\"nguyen_van_b\")\n       → API round-trip 2\n       ... (500 times total)\n       Claude: \"Tong chi tieu: X\"\n\n# Latency: 500 x 200ms = 100 giay\n# Tokens: 500 tool call definitions x lặp lại mỗi lần\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eĐây không phải vấn đề nhỏ. Với real-world workloads — inventory systems, analytics pipelines, batch processing — traditional tool calling tạo ra bottleneck nghiêm trọng về cả latency lẫn cost.\u003c\/p\u003e\n\n\u003ch2\u003eProgrammatic Tool Calling: Claude viết code thay vì gọi từng tool\u003c\/h2\u003e\n\n\u003cp\u003eVới PTC, Claude có thể viết Python code chạy trong Code Execution environment, trong đó code đó gọi tools trực tiếp. Toàn bộ processing xảy ra trong một \"execution step\" thay vì hàng trăm round-trips.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e# PTC approach — Claude viết code xử lý toàn bộ\n# 1 round-trip duy nhất cho code execution\n\nClaude viết:\n  employees = [\"nguyen_van_a\", \"nguyen_van_b\", ...]\n  all_expenses = []\n  for emp in employees:\n      data = get_expenses(emp)  # tool call trong code\n      all_expenses.extend(data)\n\n  total = sum(e[\"amount\"] for e in all_expenses)\n  by_category = {}\n  for e in all_expenses:\n      cat = e[\"category\"]\n      by_category[cat] = by_category.get(cat, 0) + e[\"amount\"]\n\n  print(f\"Total: {total:,.0f} VND\")\n  print(\"By category:\", by_category)\n\n# Latency: 1 execution step ~ 2-5 giay\n# Tokens: tool definition chi xuat hien 1 lan\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eSetup: Beta API và allowed_callers\u003c\/h2\u003e\n\n\u003cp\u003ePTC yêu cầu \u003cstrong\u003ebeta messages API\u003c\/strong\u003e và cấu hình \u003ccode\u003eallowed_callers\u003c\/code\u003e để chỉ định code execution được phép gọi tools nào:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport anthropic\nimport json\n\nclient = anthropic.Anthropic()\n\n# Define tools với allowed_callers\n# allowed_callers: [\"code_execution\"] cho phép code gọi tool này\nEXPENSE_TOOLS = [\n    {\n        \"name\": \"get_employee_expenses\",\n        \"description\": \"Lay tat ca expense records cua mot nhan vien trong thang\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"employee_id\": {\n                    \"type\": \"string\",\n                    \"description\": \"ID nhan vien\"\n                },\n                \"month\": {\n                    \"type\": \"string\",\n                    \"description\": \"Thang dang ky, format: YYYY-MM\"\n                }\n            },\n            \"required\": [\"employee_id\", \"month\"]\n        },\n        # PTC key: cho phep code execution goi tool nay\n        \"allowed_callers\": [\"code_execution\"]\n    },\n    {\n        \"name\": \"get_expense_policy\",\n        \"description\": \"Lay chinh sach chi tieu cua cong ty\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"category\": {\"type\": \"string\"}\n            },\n            \"required\": [\"category\"]\n        },\n        \"allowed_callers\": [\"code_execution\"]\n    },\n    {\n        \"name\": \"flag_expense_violation\",\n        \"description\": \"Danh dau mot expense vi pham chinh sach\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"expense_id\": {\"type\": \"string\"},\n                \"reason\": {\"type\": \"string\"},\n                \"amount_over_limit\": {\"type\": \"number\"}\n            },\n            \"required\": [\"expense_id\", \"reason\"]\n        },\n        \"allowed_callers\": [\"code_execution\"]\n    }\n]\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eMock data cho demo\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003eimport random\n\ndef generate_mock_expenses(employee_id, month):\n    \"\"\"Tao du lieu expense gia.\"\"\"\n    categories = [\"travel\", \"meals\", \"software\", \"office\", \"training\"]\n    limits = {\n        \"travel\": 5000000,    # 5M VND\n        \"meals\": 500000,       # 500K VND\/lan\n        \"software\": 2000000,  # 2M VND\n        \"office\": 300000,\n        \"training\": 3000000\n    }\n\n    expenses = []\n    random.seed(hash(employee_id + month))\n\n    for i in range(random.randint(80, 120)):\n        cat = random.choice(categories)\n        limit = limits[cat]\n        # 10% chance vi pham\n        amount = random.randint(\n            int(limit * 0.3),\n            int(limit * 1.4 if random.random() \u0026lt; 0.1 else limit * 0.9)\n        )\n        expenses.append({\n            \"id\": f\"EXP-{employee_id}-{i:03d}\",\n            \"employee_id\": employee_id,\n            \"category\": cat,\n            \"amount\": amount,\n            \"date\": f\"{month}-{random.randint(1,28):02d}\",\n            \"description\": f\"Chi tieu {cat} ngay {i+1}\",\n            \"limit\": limit\n        })\n\n    return expenses\n\n# Simulate tool execution\ndef execute_tool(tool_name, tool_input):\n    if tool_name == \"get_employee_expenses\":\n        return generate_mock_expenses(\n            tool_input[\"employee_id\"],\n            tool_input[\"month\"]\n        )\n\n    elif tool_name == \"get_expense_policy\":\n        policies = {\n            \"travel\": {\"limit\": 5000000, \"requires_receipt\": True, \"approval\": \"manager\"},\n            \"meals\": {\"limit\": 500000, \"requires_receipt\": False, \"approval\": \"none\"},\n            \"software\": {\"limit\": 2000000, \"requires_receipt\": True, \"approval\": \"it_dept\"},\n            \"office\": {\"limit\": 300000, \"requires_receipt\": False, \"approval\": \"none\"},\n            \"training\": {\"limit\": 3000000, \"requires_receipt\": True, \"approval\": \"hr\"}\n        }\n        return policies.get(tool_input[\"category\"], {\"error\": \"Unknown category\"})\n\n    elif tool_name == \"flag_expense_violation\":\n        print(f\"[FLAG] Expense {tool_input['expense_id']}: {tool_input['reason']}\")\n        return {\"flagged\": True, \"ticket_id\": f\"VIOL-{tool_input['expense_id']}\"}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eChạy PTC Agent\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003edef run_ptc_expense_analysis():\n    employees = [\n        \"nguyen_van_a\", \"tran_thi_b\", \"le_van_c\",\n        \"pham_thi_d\", \"hoang_van_e\"\n    ]\n\n    user_prompt = f\"\"\"Phan tich expense reports thang 12\/2024 cho cac nhan vien sau: {employees}\n\n    Hay viet Python code de:\n    1. Lay tat ca expenses cua tung nhan vien (dung get_employee_expenses)\n    2. Kiem tra tung khoan chi voi policy (dung get_expense_policy)\n    3. Flag cac violation (dung flag_expense_violation)\n    4. Tao bao cao tong ket: tong chi tieu theo nhan vien, theo category, so violation\n\n    Xu ly tat ca records bang code, khong goi tool tung cai mot.\"\"\"\n\n    messages = [{\"role\": \"user\", \"content\": user_prompt}]\n\n    print(\"Starting PTC expense analysis...\")\n    import time\n    start = time.time()\n\n    while True:\n        response = client.messages.create(\n            model=\"claude-opus-4-5\",\n            max_tokens=8192,\n            tools=EXPENSE_TOOLS,\n            messages=messages,\n            # Enable beta API cho PTC\n            extra_headers={\n                \"anthropic-beta\": \"interleaved-thinking-2025-05-14\"\n            }\n        )\n\n        if response.stop_reason == \"end_turn\":\n            elapsed = time.time() - start\n            print(f\"\nCompleted in {elapsed:.1f}s\")\n            for block in response.content:\n                if hasattr(block, 'text'):\n                    print(block.text)\n            break\n\n        elif response.stop_reason == \"tool_use\":\n            messages.append({\"role\": \"assistant\", \"content\": response.content})\n            tool_results = []\n\n            for block in response.content:\n                if block.type == \"tool_use\":\n                    result = execute_tool(block.name, block.input)\n                    records = len(result) if isinstance(result, list) else 1\n                    print(f\"[Tool] {block.name} returned {records} records\")\n                    tool_results.append({\n                        \"type\": \"tool_result\",\n                        \"tool_use_id\": block.id,\n                        \"content\": json.dumps(result)\n                    })\n\n            messages.append({\"role\": \"user\", \"content\": tool_results})\n        else:\n            break\n\nrun_ptc_expense_analysis()\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eStateful workflows với container_id\u003c\/h2\u003e\n\n\u003cp\u003eMột tính năng mạnh của PTC: \u003cstrong\u003econtainer_id\u003c\/strong\u003e cho phép nhiều requests chia sẻ cùng một execution environment. Biến, kết quả tính toán, datasets được persist giữa các calls:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e# Request 1: Load và preprocess data\nresponse1 = client.messages.create(\n    model=\"claude-opus-4-5\",\n    max_tokens=4096,\n    tools=EXPENSE_TOOLS,\n    messages=[{\n        \"role\": \"user\",\n        \"content\": \"Load expense data cho Q4 2024 va tinh toan statistics co ban\"\n    }],\n    extra_body={\n        \"container_id\": \"expense-analysis-q4-2024\"  # stateful container\n    }\n)\n\n# Request 2: Cung container, data tu request 1 van con\nresponse2 = client.messages.create(\n    model=\"claude-opus-4-5\",\n    max_tokens=4096,\n    tools=EXPENSE_TOOLS,\n    messages=[{\n        \"role\": \"user\",\n        \"content\": \"Dung data da load, tim cac outliers va vi pham nghiem trong nhat\"\n    }],\n    extra_body={\n        \"container_id\": \"expense-analysis-q4-2024\"  # same container\n    }\n)\n\n# Request 3: Generate final report tu ket qua da co\nresponse3 = client.messages.create(\n    model=\"claude-opus-4-5\",\n    max_tokens=4096,\n    tools=EXPENSE_TOOLS,\n    messages=[{\n        \"role\": \"user\",\n        \"content\": \"Tao bao cao PDF-ready tu tat ca analysis tren\"\n    }],\n    extra_body={\n        \"container_id\": \"expense-analysis-q4-2024\"\n    }\n)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eSo sánh hiệu suất\u003c\/h2\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eMetric\u003c\/th\u003e\n      \u003cth\u003eTraditional Tool Calling\u003c\/th\u003e\n      \u003cth\u003eProgrammatic Tool Calling\u003c\/th\u003e\n    \u003c\/tr\u003e\n  \u003c\/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eAPI round-trips\u003c\/td\u003e\n      \u003ctd\u003e~500 (5 emp x 100 records)\u003c\/td\u003e\n      \u003ctd\u003e5-10 (code execution steps)\u003c\/td\u003e\n    \u003c\/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eEstimated latency\u003c\/td\u003e\n      \u003ctd\u003e60-120 giây\u003c\/td\u003e\n      \u003ctd\u003e5-15 giây\u003c\/td\u003e\n    \u003c\/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eToken usage\u003c\/td\u003e\n      \u003ctd\u003eHigh (tool def lặp lại)\u003c\/td\u003e\n      \u003ctd\u003eThấp hơn 60-80%\u003c\/td\u003e\n    \u003c\/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eScalability\u003c\/td\u003e\n      \u003ctd\u003eLinear với số records\u003c\/td\u003e\n      \u003ctd\u003eGần constant\u003c\/td\u003e\n    \u003c\/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eError handling\u003c\/td\u003e\n      \u003ctd\u003ePhức tạp (từng call)\u003c\/td\u003e\n      \u003ctd\u003eCode xử lý batch errors\u003c\/td\u003e\n    \u003c\/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eData processing\u003c\/td\u003e\n      \u003ctd\u003eLimited (sequential)\u003c\/td\u003e\n      \u003ctd\u003eFull Python (pandas, etc.)\u003c\/td\u003e\n    \u003c\/tr\u003e\n  \u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003ch2\u003eKhi nào nên dùng PTC?\u003c\/h2\u003e\n\n\u003ch3\u003eIdeal use cases:\u003c\/h3\u003e\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eBatch processing\u003c\/strong\u003e — Xử lý 50+ records trong một session\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eData analysis pipelines\u003c\/strong\u003e — Aggregate, filter, transform large datasets\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eReport generation\u003c\/strong\u003e — Thu thập data từ nhiều sources, tổng hợp\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eInventory management\u003c\/strong\u003e — Check stock levels, update pricing cho toàn bộ catalog\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eScheduled jobs\u003c\/strong\u003e — Nightly reconciliation, monthly reports\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eKhông phù hợp khi:\u003c\/h3\u003e\n\u003cul\u003e\n  \u003cli\u003eTool calls cần human-in-the-loop approval từng bước\u003c\/li\u003e\n  \u003cli\u003eReal-time streaming responses quan trọng\u003c\/li\u003e\n  \u003cli\u003eTool calls có side effects nguy hiểm cần review thủ công\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eTổng kết\u003c\/h2\u003e\n\n\u003cp\u003eProgrammatic Tool Calling là bước tiến lớn trong hiệu suất của Claude agents:\u003c\/p\u003e\n\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eGiảm latency 10-20x\u003c\/strong\u003e bằng cách loại bỏ round-trips không cần thiết\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eGiảm token usage 60-80%\u003c\/strong\u003e vì tool definitions không lặp lại mỗi turn\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eXử lý large datasets\u003c\/strong\u003e với full Python power trong Code Execution\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eStateful workflows\u003c\/strong\u003e qua container_id cho multi-step analysis\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eBước tiếp theo: Tìm hiểu \u003ca href=\"\/collections\/nang-cao\"\u003eTool Use với Pydantic\u003c\/a\u003e để thêm type safety và validation cho tool responses — đặc biệt quan trọng khi xử lý large batches như trong PTC.\u003c\/p\u003e\n","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721768026324,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/programmatic-tool-calling-ptc-gi_m-latency-tang-hi_u-su_t.jpg?v=1774521671","url":"https:\/\/claude.vn\/products\/programmatic-tool-calling-ptc-gi%e1%ba%a3m-latency-tang-hi%e1%bb%87u-su%e1%ba%a5t","provider":"CLAUDE.VN","version":"1.0","type":"link"}