laravel/ai v1.3.0 的實作為基礎,比 AI SDK 的基本操作 更深入一步,整理執行順序與停止條件。
中介層執行的單位
當 Agent 收到模型的回應、執行 Tool 後再次呼叫模型時,下一次的模型呼叫會是另一個步驟。在每個步驟之前,會依宣告順序通過HasMiddleware::middleware() 所回傳的中介層。
傳給中介層 handle(PendingStep $step, Closure $next) 的 PendingStep 包含已執行步驟的陣列 steps、這些步驟的累積用量 usage,以及從零開始的目前步驟編號 number。第一次的 usage 尚未包含本次模型呼叫的用量。
附加在 $next($step) 結果上的 then(),會在模型回應之後、Tool 呼叫執行之前運作。它並不是只在 Tool 執行後才呼叫的 hook。此外,此時的 usage 是先前已完成步驟的合計,並不會預測進行中請求的 token 數。
註冊每個步驟的處理
以下範例只將步驟編號與到目前為止使用的輸入 token 數記錄到日誌。請避免無條件地將 prompt 內容或模型輸出存入日誌。HasMiddleware,並從 middleware() 回傳實例。
middleware() 的排列順序中,請將 Stop 放在前面。當超過上限而不開始下一個步驟時,後面的 LogAgentSteps 在該步驟中不會執行。若順序相反,日誌可能只記錄「開始」,而不會記錄「模型已回應」。請從 handle() 回傳 $next($step) 的結果;then() 的回呼則不需要回傳回應。
Stop 會停止下一次模型呼叫
Stop::when(...) 在條件為 true 時、Stop::unless(...) 在條件為 false 時,會在該步驟之前結束處理。上面的範例在已完成步驟的累積輸入 token 達到 50,000 以上時,就不會進行下一次呼叫。這並不是在單次模型呼叫超過門檻前強制停止的硬性限制。
想以自訂條件停止的中介層,也可以回傳
Laravel\Ai\Gateway\StepResult::stop()。handle() 應回傳 $next($step) 的結果、StepResponse 或 StepResult::stop()。回傳無關的型別會拋出例外。
驗證執行順序
為了避免混淆模型回應與 Tool 執行,請至少確認以下情境。- 只有一個步驟的生成中,開始日誌與模型回應日誌各輸出一次。
- 在 Tool 之後的追加步驟中,編號從 0 開始遞增,且後續步驟的
usage包含前一步驟的用量。 - 若一開始就符合停止條件,不會發生模型呼叫,也不會產生
LogAgentSteps的日誌。 - 若途中達到條件,先前的步驟會保留,且不會發生下一個步驟的模型呼叫。
then() 需要副作用,也請以「在取得模型回應前就失敗或停止的路徑中不會被呼叫」為前提來設計。