免費全文 Agent 開發 進階

ReAct 迴圈的實作:思考、行動、觀察的最小骨架

不用框架也能寫出可用的 Agent 迴圈。八十行程式碼就能跑,而且每一步都看得懂。

Agent 開發教程封面

框架很方便,但第一次寫 Agent 建議手刻一次迴圈。你會清楚知道每一輪送了什麼給模型、狀態存在哪裡、什麼時候該停。

迴圈骨架

def run_agent(user_task, tools, max_steps=8):
    messages = [{'role': 'system', 'content': SYSTEM},
                {'role': 'user',   'content': user_task}]

    for step in range(max_steps):
        resp = model.chat(messages, tools=tools)

        if not resp.tool_calls:                 # 沒有要用工具 => 收工
            return resp.content

        messages.append(resp.as_message())
        for call in resp.tool_calls:
            try:
                result = dispatch(call.name, call.arguments)
            except Exception as e:
                result = {'error': str(e)}      # 錯誤也要回給模型
            messages.append({
                'role': 'tool',
                'tool_call_id': call.id,
                'content': json.dumps(result, ensure_ascii=False)[:4000],
            })

    return '已達步數上限,未能完成任務。'

三個關鍵細節

  • 錯誤要回傳給模型,不要直接拋出。模型看到錯誤訊息後,往往能自己換參數重試。
  • 工具結果要截斷。一個回傳三萬字的工具會瞬間吃光上下文。
  • 一定要有步數上限。沒有上限的 Agent 遇到迴圈型任務會無限跑下去,帳單很可觀。

為什麼要保留完整訊息串

模型靠訊息串維持狀態。你若為了省 token 把中間的工具結果刪掉,模型會忘記自己已經查過什麼,開始重複呼叫同一個工具。

把每一步的 step、工具名、參數、耗時寫成結構化日誌。Agent 的除錯幾乎完全依賴這份軌跡。
下一步

這個主題還有更深入的實戰教程

VIP 專區收錄 50 篇進階內容:架構設計、生產環境取捨、成本與合規。 每週五新增 3 篇。

看訂閱方案 → 先逛逛 VIP 專區

延伸閱讀

更多Agent 開發 →