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

Implementing multiple turns

📖 Nội dung bài học

Tóm tắt

Xây dựng một hệ thống hội thoại với tool use yêu cầu triển khai một vòng lặp để gọi Claude liên tục cho đến khi mô hình ngừng yêu cầu sử dụng tool. Khi Claude không còn yêu cầu tool nữa, đó là tín hiệu cho thấy mô hình đã có câu trả lời cuối cùng sẵn sàng cho người dùng.

Phát hiện yêu cầu Tool (Tool Requests)

Chìa khóa để biết liệu Claude có muốn sử dụng một tool hay không nằm ở trường stop_reason (lý do dừng) của tin nhắn phản hồi. Khi Claude quyết định cần gọi một tool, trường này sẽ được đặt thành "tool_use". Điều này cung cấp cho chúng ta một cách rõ ràng để kiểm tra xem có cần tiếp tục vòng lặp hội thoại hay không:

if response.stop_reason != "tool_use":
    break  # Claude đã hoàn thành, không cần thêm tool nào nữa

Vòng lặp hội thoại (The Conversation Loop)

Hàm hội thoại chính tuân theo một mô hình đơn giản:

def run_conversation(messages):
    while True:
        # Gọi Claude với danh sách tin nhắn và schema của tool
        response = chat(messages, tools=[get_current_datetime_schema])
        # Thêm phản hồi của assistant vào lịch sử tin nhắn
        add_assistant_message(messages, response)
        print(text_from_message(response))
        
        # Nếu lý do dừng không phải là tool_use, thoát vòng lặp
        if response.stop_reason != "tool_use":
            break
            
        # Thực thi các tool được yêu cầu và lấy kết quả
        tool_results = run_tools(response)
        # Thêm kết quả tool vào lịch sử tin nhắn dưới vai trò user
        add_user_message(messages, tool_results)
    
    return messages

Vòng lặp này tiếp tục cho đến khi Claude đưa ra câu trả lời cuối cùng mà không yêu cầu bất kỳ tool nào.

Xử lý nhiều lượt gọi Tool (Multiple Tool Calls)

Claude có thể yêu cầu nhiều tool trong một phản hồi duy nhất. Nội dung tin nhắn chứa một danh sách các block, và chúng ta cần xử lý từng block tool_use riêng biệt:

Hàm run_tools xử lý việc này bằng cách lọc các block tool_use và xử lý từng cái một:

def run_tools(message):
    # Lọc ra các block yêu cầu sử dụng tool
    tool_requests = [
        block for block in message.content if block.type == "tool_use"
    ]
    tool_result_blocks = []
    
    for tool_request in tool_requests:
        # Xử lý từng yêu cầu tool...

Các block kết quả Tool (Tool Result Blocks)

Mỗi block tool_use phải được phản hồi bằng một block tool_result tương ứng. Mối liên kết giữa chúng được duy trì thông qua các ID khớp nhau:

Cấu trúc của block tool_result bao gồm:

tool_result_block = {
    "type": "tool_result",
    "tool_use_id": tool_request.id,
    "content": json.dumps(tool_output),
    "is_error": False
}

Xử lý lỗi (Error Handling)

Việc thực thi tool ổn định (robust) đòi hỏi phải xử lý các lỗi tiềm ẩn. Khi một tool thất bại, chúng ta vẫn cần cung cấp một block kết quả cho Claude:

try:
    tool_output = run_tool(tool_request.name, tool_request.input)
    tool_result_block = {
        "type": "tool_result",
        "tool_use_id": tool_request.id,
        "content": json.dumps(tool_output),
        "is_error": False
    }
except Exception as e:
    # Thông báo lỗi cho Claude để mô hình có thể xử lý hoặc thử lại
    tool_result_block = {
        "type": "tool_result", 
        "tool_use_id": tool_request.id,
        "content": f"Error: {e}",
        "is_error": True
    }

Điều hướng Tool có khả năng mở rộng (Scalable Tool Routing)

Để hỗ trợ nhiều tool, hãy tạo một hàm điều hướng (routing function) để ánh xạ tên tool với phần triển khai thực tế của chúng:

def run_tool(tool_name, tool_input):
    if tool_name == "get_current_datetime":
        return get_current_datetime(**tool_input)
    elif tool_name == "another_tool":
        return another_tool(**tool_input)
    # Thêm các tool khác khi cần

Cách tiếp cận này giúp bạn dễ dàng thêm các tool mới mà không cần sửa đổi logic hội thoại cốt lõi.

Quy trình hoàn chỉnh (Complete Workflow)

Quy trình hội thoại nhiều lượt hoàn chỉnh hoạt động như sau:

  • Gửi tin nhắn của người dùng đến Claude cùng với các tool có sẵn.
  • Claude phản hồi bằng văn bản và/hoặc các yêu cầu tool.
  • Thực thi tất cả các tool được yêu cầu và tạo các block kết quả.
  • Gửi kết quả tool ngược lại cho Claude dưới dạng tin nhắn của người dùng.
  • Lặp lại cho đến khi Claude đưa ra câu trả lời cuối cùng.

Điều này tạo ra một trải nghiệm liền mạch, nơi Claude có thể sử dụng nhiều tool qua nhiều lượt hội thoại để trả lời đầy đủ các yêu cầu phức tạp của người dùng. Lịch sử hội thoại duy trì ngữ cảnh đầy đủ, cho phép Claude dựa trên kết quả của các tool trước đó để đưa ra phản hồi toàn diện.

Tải xuống

🔁 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?