ブログ
アーキテクチャ

公開日: 更新日

AragとShouryamaan

長時間実行するAIエージェントの永続状態を構築する方法

Markdownで読む

永続的なエージェント状態とは、新しいworkerが完了済みの作業を再実行したりchat履歴から推測したりせず、タスクを再開するために必要な構造化記録です。現在の手順、完了済み操作、保留中のsignal、再試行状態、次の有効なtransitionを識別できる必要があります。

状態は、メモリ、ビジネスデータ、成果物、監査履歴とは異なります。5種類すべてを一つのvector store documentとして扱うと、復旧が曖昧になり、アクセス制御も難しくなります。

保存する5種類の情報を分ける

種類 答える問い 一般的な保存先
ワークフロー状態 実行はどこまで進み、次に何ができるか? relational rowまたはworkflow engine
ビジネス状態 注文、顧客、デプロイについて何が事実か? 正式なapplication databaseまたはprovider
メモリ 以前のどのコンテキストが今後の判断に役立つか? relational record、search index、vector store
成果物 生成したファイル、レポート、code bundleはどこか? metadata付きobject storage
監査記録 誰が何を判断、実行し、いつ行ったか? append-only eventまたはaudit table

請求書のstatusはビジネス状態に属します。ワークフローが財務部門の承認待ちであることはワークフロー状態に属します。顧客設定の要約はメモリに属する場合があります。PDFはobject storageに置きます。承認判断は監査記録に属します。

エージェント・アーキテクチャの総合ガイドでは、これらの保存先とツール、永続実行のつながりを説明しています。

文章の要約ではなくstate machineを保存する

明示的な状態と許可された遷移を使います。

stateDiagram-v2
    [*] --> Created
    Created --> Running
    Running --> WaitingForApproval
    WaitingForApproval --> Running: approved
    WaitingForApproval --> Cancelled: rejected or expired
    Running --> RetryScheduled: retryable failure
    RetryScheduled --> Running
    Running --> Completed
    Running --> Failed

タスクrowにはstate、state_version、current_step、attempt、wake_at、approval_id、timestampを持たせられます。完了した副作用は自由形式のモデルテキストへ埋め込まず、操作記録から参照します。

有効なtransitionをコードで定義し、古いupdateを拒否します。モデルはtransitionを提案できますが、approval recordなしでwaiting_for_approvalからcompletedへ移行できるかは状態レイヤーが判断します。

並行worker間の競合を安全に処理する

queueは同じ項目を2回配信する場合があり、leaseは失効し、遅いworkerが同じタスクを再開した別workerより後に完了する場合があります。version columnによるoptimistic concurrencyを追加するか、ownerとexpiryを持つleaseを使います。状態updateには読み取ったversionを含め、別workerが先へ進めていたら失敗させます。

leaseとワークフロー状態は分けます。クラッシュしたworkerはタスクをfailedに変えず、leaseだけを失うべきです。次のworkerがleaseを取得し、永続状態を読んで再開できます。

効果の前後でcheckpointする

書き込み前に意図を永続化し、検証済みの完了を後から保存します。タイムアウトで結果が不明なら、失敗したことにせずreconcilingなどの状態へ移します。

永続実行ガイドでは冪等性と照合を詳しく説明しています。状態storeの役割は、操作参照を保持し、結果未解決の間は危険なtransitionを止めることです。

人間の待機を第一級の記録として永続化する

承認記録には、正確なアクション、リソース、要求したscope、要求者、承認者、失効期限、判断、ポリシーバージョンを含めます。数時間後にワークフローを再開するとき、承認が現在のparameterに適用でき、代理対象のユーザーがまだアクセス権を持つことを再確認します。

待機中にサーバープロセスをsleepさせないでください。条件を永続化し、signalまたはscheduled jobから次のtransitionをenqueueします。Temporalの永続実行モデルは、この種の待機にevent historyとsignalを使います。同じ設計はデータベースとqueueでも構築できます。

古い実行を取り残さずに状態をversion管理する

長時間タスクはデプロイより長く続く場合があります。ワークフロー定義のversionを保存し、active state向けのmigrationを設計します。新しいworkerは、古いpayloadを読めるか、移行できるか、古いhandlerで継続すべきかを判断できなければなりません。

モデルコンテキスト全体を、versionなしの一つのJSON blobへ入れないでください。手順固有のpayloadにはJSONが役立ちますが、schedule、認可、保持、操作で使う安定したフィールドは明示してindexを付けます。

すべての記録に保持ルールを設ける

ワークフロー状態は完了後にcompactできます。監査記録にはより長い保持が必要な場合があります。メモリは訂正と削除に対応させます。成果物には失効期限と所有権metadataが必要です。ビジネスデータはプロダクト固有のポリシーに従います。

削除は参照先にも及ぶ必要があります。ユーザーのメモリを削除しても、同じ個人データがプロンプト、トレース、成果物に残っていれば完全な削除ではありません。クリーンアップ経路が各copyを見つけられるよう、参照と分類を保存します。

空のプロセスで再開をテストする

承認中、プロバイダー呼び出し後、再試行のbackoff中にworkerを停止します。ローカルcacheも会話オブジェクトもないプロセスで再開します。永続状態と正式なバックエンド記録から次のアクションを導出できる必要があります。

以下のプロンプトは、変更を提案する前にinventoryを作成します。必要な事実がログ行やプロンプトだけに見つかった場合、それは具体的な永続化の欠落です。