載入中

代理循環解析

第 4 課7 分鐘
載入中

代理循環解析

您已經呼叫過 API,但單一次呼叫只會回傳一個回應。如果您想要自動化一個工作流程,Claude 需要執行動作、查看結果、決定下一步,然後繼續進行。這個模式就是大家所說的代理工作流程(agentic workflows)。

代理究竟是什麼

代理(agent) 是 Claude 的自主版本,會在沒有人類介入的情況下,自行運作訊息循環的兩端。代理接收一項任務、選擇一個工具,並在迴圈中執行程式碼,直到 Claude 判定任務已完成為止。

實作代理循環最簡單的方式如下:

  1. 將包含可用工具的訊息傳送給 Claude。
  2. Claude 會回應最終答案,或是要求使用您所定義的工具。
  3. 您的程式碼執行該工具。
  4. 您將結果傳回給 Claude。
  5. 只要停止原因(stop reason)是 tool_use,就重複上述步驟。end_turn 代表 Claude 已完成,而任何其他停止原因也會結束這個循環。

可以把它想像成一場輪流對話:使用者開啟話題,代理呼叫工具,工具回傳結果,代理持續進行,直到得出答案為止。

一個最簡單的實作範例

為了讓您看到這個循環從頭到尾完整運作,而不需要牽涉資料庫或使用者介面,我們會串接一個名為 get_weather 的假工具,並詢問 Claude 今天在奧斯汀(Austin)該穿什麼。Claude 本身無法得知天氣狀況,因此它必須呼叫該工具、讀取結果,然後才能給您答案。

以下是完整的程式碼:

python
import anthropic

client = anthropic.Anthropic()

# tools 陣列告訴 Claude 有哪些可用的工具:
# 一個名稱、一段描述,以及輸入的 JSON schema。
tools = [
    {
        "name": "get_weather",
        "description": "Get the current weather for a city.",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "The city to get weather for",
                }
            },
            "required": ["city"],
        },
    }
]

# run_tool 只是一個寫死的查找表。
# 在真實的應用程式中,這裡會存取您的資料庫、某個 API,或其他任何東西。
def run_tool(name, tool_input):
    if name == "get_weather":
        return f"Weather in {tool_input['city']}: 95F, sunny"
    raise ValueError(f"Unknown tool: {name}")

messages = [
    {"role": "user", "content": "What should I wear in Austin today?"}
]

# 代理迴圈。每次迭代都會將訊息傳送給 Claude,
# 並依據回應的 stop reason 進行切換處理。
while True:
    response = client.messages.create(
        model="claude-sonnet-5",
        max_tokens=1024,
        tools=tools,
        messages=messages,
    )

    if response.stop_reason == "end_turn":
        # Claude 已完成。印出最終文字並跳出迴圈。
        for block in response.content:
            if block.type == "text":
                print(block.text)
        break

    elif response.stop_reason == "tool_use":
        # 在回應中找出工具使用區塊,並逐一執行。
        tool_results = []
        for block in response.content:
            if block.type == "tool_use":
                result = run_tool(block.name, block.input)
                tool_results.append(
                    {
                        "type": "tool_result",
                        "tool_use_id": block.id,
                        "content": result,
                    }
                )

        # 將助理的回應與我們的工具結果
        # 推回 messages 中,然後再次迴圈,讓 Claude 能夠回答。
        messages.append({"role": "assistant", "content": response.content})
        messages.append({"role": "user", "content": tool_results})

    else:
        # 任何其他的 stop reason,例如 max_tokens 或拒絕回答。
        # messages 中沒有任何變化,因此在此停止。再次迴圈
        # 只會一再為相同的請求重複付費。
        print(f"Stopped early: {response.stop_reason}")
        break

請注意以下三個部分:

  • 工具陣列(tools array)會告訴 Claude 有哪些可用項目:名稱、描述,以及輸入值的 JSON schema。
  • run_tool 只是一個寫死的查詢表。在真實應用程式中,這裡會連接您的資料庫、某個 API,或任何其他資源。
  • 迴圈(loop)就是代理循環。每一次迭代都會將訊息傳送給 Claude,並根據回應的停止原因做出對應處理。遇到 end_turn 時,代表 Claude 已完成,因此印出最終文字並結束迴圈。遇到 tool_use 時,找出工具使用區塊,逐一執行,再將助理的回應與您的工具結果推回 messages,然後再次進行迴圈,讓 Claude 能夠回覆。遇到其他任何情況,則印出停止原因並結束迴圈。

請不要省略最後這個分支。如果少了它,一個因為 max_tokens 被截斷的回覆將不會被加入 messages 中,於是迴圈會再次送出相同的請求,導致您每次都得為此付費。文件中列出了每一種停止原因以及對應的處理方式。

執行它

當您執行這個程式碼時,您會看到兩個回合:

  1. 第一回合:停止原因是 tool_use。Claude 要求針對奧斯汀呼叫 get_weather,而您的程式碼則回傳溫度與天氣狀況。
  2. 第二回合:停止原因是 end_turn,Claude 會告訴您穿著輕便透氣的衣物。

代理循環的終端機輸出:第一回合因 tool_use 停止並為奧斯汀呼叫 get_weather,接著第二回合因 end_turn 停止,Claude 印出最終的穿衣建議

兩次 API 呼叫、一次工具執行、一個最終答案。這就是整個循環。您使用 Claude API 打造的一切,基本上都會與此類似。

正式環境中的相同循環

在真實環境中,這個相同的循環會驅動類似自動審查端點(auto-review endpoint)的功能:一個合規代理會讀取結構報告、透過工具查詢相關的建築法規,並逐一將風險發現結果寫回資料庫。

一個合規審查儀表板,列出已上傳的結構報告,每一筆都有一個啟動代理的「執行自動審查」按鈕

這個循環的架構與您剛才執行的完全相同,差異在於:

  • 使用真實的工具,而不是模擬的天氣查詢。
  • 結果會以伺服器發送事件(server-sent events)的方式串流回使用者介面。
  • 發現結果會持久化儲存到風險發現資料表中。

一個正在執行中的合規代理審查軌跡:隨著循環不斷迭代,進行了數十次工具呼叫,搜尋建築法規資料庫並查詢特定法規條文

重點回顧

  • 代理就是處於循環中的 Claude:觀察、決策、行動、重複。
  • 這個循環很單純:傳送帶有工具的訊息、執行 Claude 請求的任何工具、將結果回饋回去,並在停止原因不是 tool_use 時停止。
  • 迴圈與工具由您掌控,推理則由 Claude 負責。
  • 同樣的循環架構,從模擬天氣示範到正式環境的合規代理,都能延伸適用——只有工具與底層串接會隨之改變。
  • 當您不想自行管理這個循環時,受管代理(managed agents)會在 Anthropic 的基礎設施上,為您執行完全相同的這個循環。