Bỏ qua đến nội dung chính

Running tool functions

📖 Nội dung bài học

Kích cỡ chữ Video này đang được xử lý. Vui lòng quay lại sau và tải lại trang.

Tóm tắt

Khi Claude phản hồi bằng một yêu cầu tool use, server của bạn cần thực sự chạy công cụ được yêu cầu và gửi kết quả trở lại. Bước này bao gồm việc trích xuất các phần tool use từ phản hồi của Claude, thực thi các hàm tương ứng và định dạng kết quả đúng cách.

Xử lý nhiều yêu cầu công cụ (tool requests)

Claude có thể gửi nhiều phần tool use trong một phản hồi duy nhất. Mã nguồn của bạn cần xử lý khả năng này một cách chủ động (defensively). Một assistant message có thể chứa một phần văn bản (text part) theo sau bởi một, hai hoặc thậm chí nhiều phần tool use.

Luồng hoạt động như sau: Claude gửi một yêu cầu với JSON schema, nhận về một phần tool use, sau đó server của bạn chạy công cụ và gửi lại một phần kết quả công cụ (tool result part) để Claude đưa ra phản hồi cuối cùng.

Trích xuất các phần tool use

Đầu tiên, hãy tạo một hàm để xử lý tất cả các phần (parts) được trả về từ một yêu cầu chat:

def run_tools(parts):
    # Lọc danh sách các part để chỉ lấy những dictionary có chứa khóa "toolUse"
    tool_requests = [part for part in parts if "toolUse" in part]
    tool_result_parts = []
    
    for tool_request in tool_requests:
        tool_use_id = tool_request["toolUse"]["toolUseId"]
        tool_name = tool_request["toolUse"]["name"]
        tool_input = tool_request["toolUse"]["input"]

Cách viết comprehension này lọc danh sách các part để chỉ bao gồm các dictionary chứa khóa "toolUse", bỏ qua các phần văn bản.

Thực thi các công cụ thực tế

Tạo một hàm bổ trợ (helper function) để thực thi công cụ được yêu cầu:

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

Chi tiết quan trọng ở đây là sử dụng **tool_input để giải nén (splat) dictionary các đối số vào hàm công cụ của bạn. Claude luôn trả về các đối số dưới dạng một đối tượng dictionary, vì vậy bạn cần unpack nó đúng cách.

Tạo các phần tool result

Sau khi chạy một công cụ, bạn cần định dạng phản hồi dưới dạng một phần kết quả công cụ (tool result part):

Các phần tool result yêu cầu ba thuộc tính chính:

  • toolUseId - Phải khớp với ID của phần tool use gốc.
  • content - Đầu ra từ công cụ của bạn, được tuần tự hóa (serialized) dưới dạng chuỗi.
  • status - Có thể là "success" hoặc "error".

Hiểu về tool use ID

Hệ thống tool use ID trở nên quan trọng khi Claude yêu cầu thực thi nhiều công cụ song song (parallel). Ví dụ, nếu Claude muốn chạy một công cụ máy tính hai lần:

Mỗi lần sử dụng công cụ sẽ nhận được một ID duy nhất (như "ab3" và "po9"), và các tool result của bạn phải bao gồm các ID khớp tương ứng để Claude biết kết quả nào thuộc về yêu cầu nào.

Xử lý lỗi

Hãy bao bọc việc thực thi công cụ của bạn trong các khối try-catch. Claude rất thông minh trong việc xử lý lỗi công cụ và có thể điều chỉnh cách tiếp cận nếu bạn trả về thông tin lỗi chính xác:

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

Triển khai hoàn chỉnh

Dưới đây là hàm đầy đủ để xử lý các yêu cầu công cụ và trả về kết quả đã được định dạng:

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

Khi đã có các phần tool result, bạn có thể gửi chúng ngược lại cho Claude trong yêu cầu chat tiếp theo, hoàn tất chu trình tool use.

🔁 Bài học liên quan

📚 Nguồn & ghi nhận

Bài học có hữu ích không?

Góp ý / Báo lỗiPhát hiện sai sót hoặc có ý tưởng cải thiện?