Cơ bảnHướng dẫnClaude APINguồn: Anthropic

Calculator Tool — Bài học đầu tiên về Tool Use với Claude

Nghe bài viết
00:00

Điểm nổi bật

Nhấn để đến mục tương ứng

  1. 1 Khai thác tối đa công cụ AI: Hãy tưởng tượng bạn thuê một trợ lý thông minh nhưng không có điện thoại. Bí quyết nằm ở cách bạn cấu trúc yêu cầu — prompt càng rõ ràng, output càng sát nhu cầu thực tế.
  2. 2 Thành thật mà nói: Mỗi tool được mô tả bằng một object JSON với 3 trường bắt buộc: calculatortool = { "name": "calculator", "description":. Phương pháp này hiệu quả trong hầu hết trường hợp, nhưng bạn cần điều chỉnh cho phù hợp ngữ cảnh riêng.
  3. 3 Con số đáng chú ý: Khi Claude muốn gọi tool, response sẽ có stopreason = "tooluse" và content chứa tooluse block: Response từ Claude:. Với 1984 x được đề cập, đây là dữ liệu cụ thể giúp bạn đánh giá hiệu quả trước khi đầu tư thời gian.
  4. 4 Khai thác tối đa công cụ AI: Gộp tất cả lại thành một hàm hoàn chỉnh: def runtoolloopusermessage: messages = {"role": "user", "content":. Bí quyết nằm ở cách bạn cấu trúc yêu cầu — prompt càng rõ ràng, output càng sát nhu cầu thực tế.
  5. 5 Thành thật mà nói: Khái niệm Chi tiết stopreason "tooluse" = Claude muốn gọi tool; "endturn" = Claude trả lời xong tooluseid ID duy nhất. Phương pháp này hiệu quả trong hầu hết trường hợp, nhưng bạn cần điều chỉnh cho phù hợp ngữ cảnh riêng.
flat screen computer monitor

Tool Use (còn gọi là Function Calling) là một trong những tính năng mạnh nhất của Claude API. Thay vì chỉ trả lời bằng văn bản, Claude có thể quyết định gọi một công cụ bên ngoài — tìm kiếm web, tra cứu database, thực thi code — và sau đó tổng hợp kết quả thành câu trả lời hoàn chỉnh.

Bài này hướng dẫn bạn xây dựng tool đơn giản nhất có thể: một chiếc máy tính bỏ túi. Mục tiêu không phải là sức mạnh của tool, mà là hiểu rõ vòng lặp Tool Use — cơ chế nền tảng cho mọi ứng dụng AI phức tạp hơn sau này.

Tool Use hoạt động như thế nào?

Hãy tưởng tượng bạn thuê một trợ lý thông minh nhưng không có điện thoại. Mỗi khi cần tìm thông tin, trợ lý đó phải yêu cầu bạn tra hộ, rồi sử dụng kết quả bạn trả về để hoàn thành công việc. Tool Use hoạt động theo đúng cơ chế đó:

  1. Bạn định nghĩa danh sách tools và gửi cùng với user message
  2. Claude đọc câu hỏi, quyết định cần dùng tool nào, trả về tool_use block
  3. Client của bạn thực sự thực thi tool (ví dụ: tính toán, gọi API)
  4. Bạn gửi kết quả lại cho Claude qua tool_result block
  5. Claude đọc kết quả, viết câu trả lời cuối cùng cho người dùng

Claude không tự thực thi tool. Claude chỉ ra quyết định "cần dùng tool X với input Y". Toàn bộ logic thực thi nằm ở phía client — đây là điểm quan trọng nhất cần nắm.

Bước 1: Định nghĩa Tool với JSON Schema

Mỗi tool được mô tả bằng một object JSON với 3 trường bắt buộc:

calculator_tool = {
    "name": "calculator",
    "description": "Thực hiện các phép tính số học cơ bản: cộng, trừ, nhân, chia.",
    "input_schema": {
        "type": "object",
        "properties": {
            "operation": {
                "type": "string",
                "enum": ["add", "subtract", "multiply", "divide"],
                "description": "Phép tính cần thực hiện"
            },
            "operand1": {
                "type": "number",
                "description": "Số thứ nhất"
            },
            "operand2": {
                "type": "number",
                "description": "Số thứ hai"
            }
        },
        "required": ["operation", "operand1", "operand2"]
    }
}

Ba trường quan trọng:

  • name — tên tool, Claude dùng tên này khi muốn gọi
  • description — mô tả ngắn gọn chức năng; Claude đọc description để quyết định khi nào dùng tool này
  • input_schema — JSON Schema mô tả các parameters; Claude sẽ tạo ra JSON đúng format này khi gọi tool

Lưu ý quan trọng: Viết description thật rõ ràng. Nếu description mơ hồ, Claude có thể gọi tool sai lúc hoặc không gọi khi cần.

Bước 2: Gửi Request với Tools

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-4-5",
    max_tokens=1024,
    tools=[calculator_tool],
    messages=[
        {
            "role": "user",
            "content": "Tính 1984 nhan 1984 bằng bao nhiêu?"
        }
    ]
)

print("Stop reason:", response.stop_reason)
print("Content:", response.content)

Khác biệt duy nhất so với API call thông thường: thêm parameter tools=[...].

Bước 3: Xử lý Response tool_use

Khi Claude muốn gọi tool, response sẽ có stop_reason = "tool_use" và content chứa tool_use block:

# Response từ Claude:
# stop_reason = "tool_use"
# content = [
#   TextBlock(text="De tinh 1984 x 1984, toi se dung calculator."),
#   ToolUseBlock(
#       id="toolu_01ABC123",
#       name="calculator",
#       input={"operation": "multiply", "operand1": 1984, "operand2": 1984}
#   )
# ]

def process_tool_call(tool_name, tool_input):
    if tool_name == "calculator":
        op = tool_input["operation"]
        a = tool_input["operand1"]
        b = tool_input["operand2"]

        if op == "add":
            return a + b
        elif op == "subtract":
            return a - b
        elif op == "multiply":
            return a * b
        elif op == "divide":
            if b == 0:
                return "Loi: Khong the chia cho 0"
            return a / b
    return "Tool khong ton tai"

# Tim tool_use block trong response
tool_use_block = None
for block in response.content:
    if block.type == "tool_use":
        tool_use_block = block
        break

if tool_use_block:
    result = process_tool_call(tool_use_block.name, tool_use_block.input)
    print(f"Ket qua tinh toan: {result}")

Bước 4: Gửi Kết quả về cho Claude

Đây là bước nhiều người mắc lỗi nhất. Bạn phải gửi toàn bộ conversation history kèm theo kết quả tool:

final_response = client.messages.create(
    model="claude-opus-4-5",
    max_tokens=1024,
    tools=[calculator_tool],
    messages=[
        # Message gốc của user
        {
            "role": "user",
            "content": "Tinh 1984 nhan 1984 bang bao nhieu?"
        },
        # Response của Claude (bao gồm tool_use block)
        {
            "role": "assistant",
            "content": response.content  # Giu nguyen content object
        },
        # Kết quả tool từ client
        {
            "role": "user",
            "content": [
                {
                    "type": "tool_result",
                    "tool_use_id": tool_use_block.id,  # ID phải khớp
                    "content": str(result)
                }
            ]
        }
    ]
)

print(final_response.content[0].text)

Claude sẽ đọc kết quả 3936256 và viết câu trả lời như: "1984 nhân 1984 bằng 3.936.256."

Vòng lặp Tool Use đầy đủ

Gộp tất cả lại thành một hàm hoàn chỉnh:

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

    while True:
        response = client.messages.create(
            model="claude-opus-4-5",
            max_tokens=1024,
            tools=[calculator_tool],
            messages=messages
        )

        # Neu Claude tra loi binh thuong, ket thuc vong lap
        if response.stop_reason == "end_turn":
            return response.content[0].text

        # Neu Claude muon goi tool
        if response.stop_reason == "tool_use":
            # Them response cua Claude vao history
            messages.append({"role": "assistant", "content": response.content})

            # Xu ly tung tool_use block
            tool_results = []
            for block in response.content:
                if block.type == "tool_use":
                    result = process_tool_call(block.name, block.input)
                    tool_results.append({
                        "type": "tool_result",
                        "tool_use_id": block.id,
                        "content": str(result)
                    })

            # Them ket qua vao history
            messages.append({"role": "user", "content": tool_results})

        else:
            # Stop reason khong mong doi
            break

    return None

# Test
answer = run_tool_loop("125 chia 5 roi nhan 8 bang bao nhieu?")
print(answer)

Vòng while True quan trọng vì một số câu hỏi yêu cầu nhiều lần gọi tool. Ví dụ: "125 chia 5 rồi nhân 8" — Claude sẽ gọi calculator 2 lần: một lần chia, một lần nhân.

Kiểm tra Thực tế

test_cases = [
    "15 cong 27 bang bao nhieu?",
    "Dien tich hinh tron ban kinh 7cm la bao nhieu? (Pi = 3.14159)",
    "Neu toi mua 3 san pham gia 250.000 dong moi cai, tong tien la bao nhieu?"
]

for question in test_cases:
    print(f"Cau hoi: {question}")
    print(f"Tra loi: {run_tool_loop(question)}")
    print("---")

Câu hỏi thứ hai thú vị: Claude sẽ tự chia nhỏ thành 7 nhân 7 = 49, rồi 49 nhân 3.14159 — hai lần gọi tool để tính diện tích.

Những điểm cần nhớ

Khái niệm Chi tiết
stop_reason "tool_use" = Claude muốn gọi tool; "end_turn" = Claude trả lời xong
tool_use_id ID duy nhất cho mỗi lần gọi tool; phải khớp trong tool_result
Tool execution Client thực thi, không phải Claude — bạn có toàn quyền kiểm soát
Multi-turn Giữ nguyên toàn bộ history; không bỏ tool_use blocks giữa chừng
Multiple tools Một lần gọi có thể trả về nhiều tool_use blocks — xử lý hết trước khi gửi lại

Khi nào Claude gọi Tool?

Claude chỉ gọi tool khi thực sự cần. Nếu bạn hỏi "2 + 2 bằng mấy?", Claude có thể trả lời thẳng mà không cần calculator. Tool Use được kích hoạt khi:

  • Câu hỏi yêu cầu độ chính xác cao (phép tính phức tạp)
  • Claude không chắc về con số cụ thể
  • Description của tool rõ ràng match với yêu cầu

Bài tiếp theo, chúng ta sẽ khám phá cách dùng Tool Use để ép Claude output JSON có cấu trúc — một kỹ thuật cực kỳ hữu ích mà không cần viết regex phức tạp.


Bài viết liên quan

Tính năng liên quan:Tool UseJSON SchemaTool LoopAPI

Bai viet co huu ich khong?

Bản quyền thuộc về tác giả. Vui lòng dẫn nguồn khi chia sẻ.

Bình luận (0)
Ảnh đại diện
Đăng nhập để bình luận...
Đăng nhập để bình luận
  • Đang tải bình luận...

Đăng ký nhận bản tin

Nhận bài viết hay nhất về sản phẩm và vận hành, gửi thẳng vào hộp thư của bạn.

Bảo mật thông tin. Hủy đăng ký bất cứ lúc nào. Chính sách bảo mật.