載入中

使用工具的多輪對話

第 27 課9 分鐘

建構使用工具的多輪對話需要處理來自 Claude 的不同回應類型。當 Claude 回應時,它可能需要使用工具,或者它可能提供直接答案。您的程式碼需要優雅地處理這兩種情況。

簡單工具整合的問題

如果您只是將工具結果加入每次對話,您會遇到問題。當 Claude 回答像「1+1 是多少?」這樣的簡單問題時,它不需要任何工具。但如果您的程式碼總是嘗試處理工具結果,您最終會在對話歷史中加入空白訊息。

解決方案是檢查每次 Claude 回應附帶的 stop_reason。這會告訴您 Claude 為何停止生成——無論是自然完成,還是因為它想要使用工具。

停止原因

Claude 可能因為以下幾種原因而停止:

  • "tool_use" - 模型想要呼叫工具
  • "end_turn" - 模型已完成生成其回應
  • "max_tokens" - 達到輸出限制
  • "stop_sequence" - 遇到您提供的停止序列

改進聊天函式

首先,更新您的聊天函式以回傳更多資訊。不要只是分別回傳文字和部分內容,而是回傳一個包含您所需一切的字典:

python
def chat(messages, tools=None, system=None, **kwargs):
    # ...現有程式碼...
    
    return {
        "parts": parts,
        "stop_reason": response["stopReason"],
        "text": "\n".join([p["text"] for p in parts if "text" in p])
    }

這種方法會從回應部分中提取所有文字內容,這比假設第一個部分總是文字更為穩健。

建構對話迴圈

建立一個處理完整對話流程的函式:

python
def run_conversation(messages):
    while True:
        result = chat(messages, tools=[get_current_datetime_schema])
        
        add_assistant_message(messages, result["parts"])
        print(result["text"])
        
        if result["stop_reason"] != "tool_use":
            break
            
        tool_result_parts = run_tools(result["parts"])
        add_user_message(messages, tool_result_parts)
    
    return messages

這個迴圈會持續進行,直到 Claude 因為非工具使用的原因而停止。每次迭代:

  1. 將目前的訊息傳送給 Claude
  2. 將 Claude 的回應加入訊息歷史
  3. 檢查 Claude 是否想要使用工具
  4. 如果是,執行工具並將結果加回對話中
  5. 如果不是,退出迴圈

測試實作

這種方法可以處理需要工具和簡單問題兩種情況:

python
# 需要工具的問題
messages = []
add_user_message(messages, "What time is it?")
run_conversation(messages)

# 簡單問題
messages = []
add_user_message(messages, "What is 1+1?")
run_conversation(messages)

對於時間相關問題,Claude 會使用 datetime 工具。對於數學問題,它會直接回應而不進行任何工具呼叫。對話迴圈會根據 Claude 的停止原因自動調整。

當您加入更多工具時,這種模式能很好地擴展——同一個迴圈可以處理工具使用和直接回應的任何組合,使您的對話式 AI 更加穩健和自然。