タスクが終わらない時:タスクレベルのHandoffドキュメント

Skill Cardは、新しいセッション開始時にAgentが自分が誰で何ができるかを知らないという問題に対処し、ロール定義と振る舞いの境界を提供した。しかし、タスクは常に1つのセッション内で完了するとは限らない。実行が中断され、新しいセッションが作業を引き継ぐ必要がある場合、別の問題が浮上する。新しいセッションのAgentはタスクがどこまで進んだか何も知らない。

タスクが1つのセッション内で完了しないことはエッジケースに聞こえるかもしれないが、そうではない。04bのタスク分解は各サブタスクが1つのセッション内で完了できることを前提としているが、その前提の失敗率は直感よりはるかに高い。

予測不能なcontext消費が第一の理由だ。自己完結したタスク仕様はAgentが読む必要のある情報のスコープを定義するが、実行中にAgentは仕様で明示的に要求されていない外部ドキュメントを能動的に読む。インターフェースを理解するために実装を確認したり、データフォーマットを確認するために上流モジュールのコードを読んだり。これらは合理的なエンジニアリング行動だが、各読み取りがcontext windowを消費する。外部ドキュメントは見積もりよりも頻繁に長く、ウィンドウ容量の60%で完了するはずのタスクが90%でもまだ未完了かもしれない。

モデル出力の非決定性が第二の理由だ。大規模言語モデルは確率的に出力を生成する。同じ入力で10回実行しても同じ結果にはならない。多くの場合Agentはスムーズにタスクを完了するが、時に回り道をする。不要なアプローチを試したり、既に解決済みの問題を再度解こうとしたり、あるブランチを過度に探索したり。この非決定性はモデルの基本的な性質であり、より良い仕様で排除することはできず、フォールトトレランスのメカニズムで吸収するしかない。

供給側の不安定性が第三の理由だ。APIプロバイダーのサービス品質は一定ではない。ピーク時にモデルが暗黙のうちにダウングレードされたり、実際に利用可能なcontext windowがドキュメントより小さかったり、タスク中にレートリミットが発動したり。これらの要因はタスク分解の設計の制御範囲外だ。

これらの要因は一つの結果に収束する。タスクは圧縮をトリガーせずに1つのセッション内で完了できない可能性が高い。contextが飽和に近づくと、多くのツールが自動圧縮をトリガーする。履歴を要約またはトランケートしてスペースを解放する。圧縮は不可逆的な情報損失だ。初期の設計決定、インターフェース規約、完了した作業の詳細が予測不能に破棄される。04aで述べたcontext wallは緩やかな品質劣化だが、圧縮は一度きりの崖だ。圧縮後、Agentの振る舞いの決定性は保証できない。その時点で正しい行動は、現在のセッションを終了し、新しいセッションを開始して続行することだ。

タスクが1つのセッションで終わらない場合、新しいセッションはある中間状態から引き継ぐ必要がある。ゼロから再開するのではない。再開も同じ制約に直面する。context消費、モデルの非決定性、供給側の不安定性はまだ存在し、新しいセッションもおそらく同じポイントで同じ壁にぶつかる。前のセッションが止まったところから続行することでのみ、タスクはセッションをまたいで段階的に進行し、最終的に完了に到達できる。新しいセッションには事前のcontextがなく、頼れるのは書き留められたものだけだ。これがタスクレベルのHandoffドキュメントの根拠である。

Handoffドキュメントの目標は、事前のcontextがゼロのAgentがタスクを引き継げるようにすることだ。ただし「引き継ぐ」とは前のセッションの推論を継承することではない。新しいセッションの価値は、まさに独立した判断者であり、前のセッションが道を誤った箇所を見つけられることにある。

これがHandoffドキュメントのコアとなる設計原則につながる:事実のみを記録し、推論は記録しない。

事実とは既に起こったことだ。どのコードが書かれたか、どの選択がなされたか、どのブロッカーに遭遇したか。これらの情報は実際のコードとテスト結果に照らして検証できる。推論とは将来に関する判断だ。次に何をすべきか、どのアプローチを推奨するか。これらの情報は検証できず、信頼するか疑問を呈するかしかない。

前のセッションの実行パスにバイアスがあった場合、推論型の情報はそのバイアスをHandoffドキュメントにエンコードする。「次のステップの計画」を目にした新しいセッションは、そのパスに直接従う可能性が高く、独立した軌道修正の機会を失う。これはセッション間で現れる共謀問題(03b)だ。前のセッションがタスクの実行と次のステップの計画の両方を行い、自ら方向を設定する。Handoffドキュメント内の推論型情報は、推論汚染(04c)の一形態でもある。あるセッションの推論成果物が次のセッションのcontextに入り込み、独立した判断を妨げる。

したがって、Handoffドキュメントにはnext_stepsフィールドがない。事実情報を受け取った後、新しいセッションは元の仕様(Ring 0の信頼ソース、02e)を参照して次のステップを独立して導き出す。

最小限のHandoffドキュメントは以下のフィールドを含む:

spec_ref: "/specs/auth-module.md"

status:
  completed:
    - "JWT発行ロジック(RS256)— ユニットテストパス"
    - "ログインエンドポイント /api/login — 統合テストパス"
  in_progress:
    - "トークンリフレッシュエンドポイント /api/refresh — 発行完了、失効ロジック未着手"
  pending:
    - "ログアウトエンドポイント /api/logout"
    - "トークンブラックリストメカニズム"

decisions:
  - what: "RS256をHS256より選択"
    why: "クロスサービス検証が必要。非対称署名により各サービスは公開鍵のみ保持すればよい"
  - what: "リフレッシュトークンをRedisではなくデータベースに保存"
    why: "現在のユーザー規模ではRedisは不要。インフラの複雑さを軽減"

blockers:
  - "userテーブルにrefresh_token_hashカラムがない — 先にマイグレーションが必要"
  - "既存のセッションミドルウェアとJWTロジックの間に競合を発見 — 置き換えるべきか確認が必要"

files_changed:
  - "src/auth/jwt.py — 新規作成"
  - "src/auth/login.py — 新規作成"
  - "tests/auth/test_jwt.py — 新規作成"
  - "tests/auth/test_login.py — 新規作成"

spec_refは元の仕様を参照する。仕様の内容はHandoffドキュメント内に複製しない。複製は2つのドキュメントが不整合になりうることを意味する。仕様の劣化(02f)はHandoffドキュメントにも等しく適用される。新しいセッションは仕様を権威ある情報源として扱い、Handoffドキュメントは実行状態のみを提供する。両者が矛盾する場合、仕様が優先される。

statusは単純な完了/未完了ではなく3つの状態を使う。in_progressが最も重要な状態だ。途中まで完了した作業をマークする。未着手か完全に完了したサブタスクは扱いやすい。途中が最も危険だ。新しいセッションがどの部分が既に実装済みでどの部分がまだかを知らなければ、既存のロジックを再実装するか、半分完成した作業の上に構築して不整合を生む可能性がある。

decisionsは既になされた選択とその理由を記録する。ここでのwhyは、意図的に除外されたnext_stepsとは根本的に異なる。決定は既存のコードの事実を記述し(コードは既にRS256を使用している)、whyは新しいセッションがその選択を覆すべきかどうかを判断する助けとなる。遡及的な説明であり、将来に向けた指示ではない。記録されていない決定の根拠は存在しないのと同じだ(02d)。新しいセッションは、よく考えられた設計上の選択をそれと知らずに覆す可能性がある。

blockersは実行中に発見された障害を記録する。人間のエンジニアは昨日どこで行き詰まったかを自然に覚えているが、Agentはそうではない。書き留められていないブロッカーは、新しいセッションによって暗黙のうちにスキップされ、統合時に必然的に失敗するコードを生む可能性がある。

files_changedは変更の事実目録を提供し、新しいセッションがstatusフィールドの主張を盲目的に信頼するのではなく、実際のコード状態を検証できるようにする。

Handoffドキュメントはタスクが1つのセッション内で完了できない場合にのみ作成される。フォールトトレランスメカニズムの産物であり、通常フローの一部ではない。タスクが正常に完了した場合、Handoffドキュメントは不要であり、出力は後続の検証プロセスに直接流れる。

問題は、誰がいつ書くかを決めるかだ。Agent自身は信頼できるトリガーではない。理由は2つある。第一に、agentは現在、自身のcontext消費を一般的に認識する能力を持たない。ウィンドウの残りがどれだけあるか分からない。第二に、たとえモデルがこれを認識できたとしても、大規模言語モデルは確率的に生成するため、同じ条件下での判断は安定しない。Handoffドキュメントの作成は決定的なタスクだ。適切なタイミングで発生しなければならず、確率的な保証に依存することはできない。したがって、トリガーは外部の決定的なツールから来なければならず、モデル自身からではない。

一つのアプローチは、ツールフレームワークのhookメカニズムを通じてだ。しきい値を設定し、トークン使用量がそれを超えた時に、現在の作業を停止しHandoffドキュメント構造に進捗を保存するよう指示をAgentに注入する。もう一つのアプローチは、トークン使用量を継続的に追跡し、制限に近づいた時にプロンプトを注入する独立した監視プロセスだ。前者は特定のツールフレームワークに結合される。後者は追加のインフラが必要だが、より広い適用可能性を持つ。両アプローチに共通するのは、検知とトリガーのロジックが外部の決定的なシステムによって処理され、モデルの確率的な特性から分離されていることだ。

どのアプローチを使うにせよ、トリガーは自動圧縮が始まる前に発生しなければならない。圧縮が始まると、Agentの完了した作業に関するメモリは既に不完全であり、その時点で書かれたHandoffドキュメントは真の状態を反映できない。トリガーのしきい値は、contextがまだ無傷の状態でAgentが書き込みを完了するのに十分なウィンドウスペースを残す必要がある。

Handoffドキュメントが書かれた後、現在のセッションは終了する。新しいセッションは元の仕様とHandoffドキュメントをロードし、事実に基づいて独立して計画を立て、未完了部分の実行を続ける。タスクが最終的に完了した後、Handoffドキュメントは後のレトロスペクションのためにアーカイブされる。

results matching ""

    No results matching ""