yoi/.yoi/tickets/closed/20260527-000011-session-todo-reminder/item.md

6.1 KiB
Raw Blame History

id slug title status kind priority labels created_at updated_at assignee
20260527-000011-session-todo-reminder session-todo-reminder セッション内 Task ツールの注意機構 closed task P2
migrated
2026-05-27T00:00:11Z 2026-05-29T04:31:10Z null

Migration reference

  • legacy_ticket: tickets/session-todo-reminder.md
  • migrated_from: TODO.md / tickets directory migration on 2026-05-27

セッション内 Task ツールの注意機構

背景

tickets/session-todo.md で導入した Task ツール群があっても、LLM はそれを使わずに作業を続け得る。ツールを呼ばないまま会話が長引くと、

  • 開始した作業の inprogress がずっと放置されたままになる
  • 「やったつもり」になって completed への更新を忘れる
  • そもそも TaskStore の存在を忘れて、構造化を諦めて自由記述に回帰する

OpenCode の todo は専用の注意機構を持たない(汎用 reminder 経由)。一方、一部の既存エージェント実装では todo reminder を「N リクエスト無アクティビティで初めて発火するナッジ型」として扱い、毎リクエスト押し戻しはしない。

Insomnia でも同方針を採り、active Task が残っているのに TaskCreate / TaskUpdate が一定リクエスト呼ばれていない場合に限り、<system-reminder> Item を 1件 history に append する。「やったつもり」抑止と、トークン浪費・LLM の自律性侵害のバランスを取るため、毎リクエスト押し戻しはしない。

前提

  • tickets/session-todo.md の TaskStore と TaskCreate / TaskUpdate / TaskList / TaskGet ツールが利用可能
  • Interceptor::pending_history_appends レーンが利用可能(tickets/notify-history-persist.md で導入済み)

方針

  • pending_history_appends で実装。発火時に <system-reminder> ブロックを含む新規 system message Item を返し、Worker が worker.history に append する。Notify / PodEvent と同じレーンで永続化・resume・compaction が自動で揃う
  • 揮発的注入は採らないAGENTS.md 「LLM コンテキストの加工原則」で禁止。history に commit せずに context を変えると、resume 時に LLM の発言の根拠が再現できなくなる)
  • system-reminder 注入機構の汎用化はやらない。利用者が Task 1機構しかない段階で抽象を立てないAGENTS.md「概念の追加は不在が問題になってから」)。タグ形式 <system-reminder>...</system-reminder> の規約は本実装で踏襲する
  • 発火はナッジ型。N リクエスト無アクティビティで初めて発火し、cooldown も持つ

要件

Interceptor

  • pending_history_appends で以下を AND で満たす場合のみ発動し、<system-reminder> ブロックを含む Item::system_message を 1件返す。条件外なら空 Vec<Item> を返す
    • active Taskpending または inprogress)が 1件以上存在する
    • 直近 N リクエスト(暫定 N=8TaskCreate / TaskUpdate のいずれも呼ばれていない
    • 前回 reminder Item の append から M リクエスト(暫定 M=8以上経過
  • ここで言う「リクエスト」は LLM への 1回の推論呼び出しassistant 応答 1回の単位。1ユーザー発火内で tool ループが回れば、tool_result を受けて発火する次のリクエストもそれぞれ 1としてカウントする
  • カウンタは Pod 側の session-lifetime 状態として保持する(requests_since_last_task_management / requests_since_last_reminder。resume 時は worker.history の逆走査で再計算するか 0 リセットで再開する。後者でも「初回ナッジが最大 N リクエスト遅れる」だけで挙動として致命ではない
  • 返す Item の本文は <system-reminder> で囲み、現在の active Task を taskid / status / subject を含む簡潔な形式で列挙する。description は長大化を避けるため省略してよい
  • active Task が空の場合は何も append しない(思い出させる対象が無いなら不要)

完了条件

  • 直近 N リクエスト連続で TaskCreate / TaskUpdate が呼ばれず、かつ active Task が残っている場合に限り、pending_history_appends<system-reminder> を含む Item::system_message を 1件返す
  • 返された Item が worker.history に append され、その後のリクエスト・history.json・resume 後の get_history でも同じ Item が見える(揮発レーンは持たない)
  • TaskCreate / TaskUpdate のいずれかが呼ばれるとカウンタがリセットされ、再び N リクエスト経過するまでは reminder が出ない
  • reminder が一度出たあとは、cooldown M リクエストが経過するまで再注入されない
  • active Task が 0件の場合は reminder が出ない
  • 単体テストで Interceptor の発火条件リクエスト回数閾値、active 0件、cooldownがカバーされる

範囲外

  • inprogress 滞留検出 / 多重 inprogress 検出など、状態異常ベースの追加トリガ(必要になれば別チケットで追加)
  • system-reminder 注入機構の汎用化(TODO.md に立項済み、別途検討)
  • TaskCreate / TaskUpdate の戻り値に active Task 全件を埋め込む強化(必要に応じて Tool ticket 側で対応)
  • サブエージェント / sidechain での独自 reminder 発火main Pod の interceptor から動く構造のため自然に対象外)

参照

  • 設計指針: AGENTS.mdLLM コンテキストの加工原則。揮発的注入は禁止、history に append してから commit する)
  • 前提: tickets/session-todo.mdTool 群と TaskStoretickets/notify-history-persist.mdpending_history_appends レーン)
  • 参考: 一部エージェント実装の todo reminder は、一定リクエスト無アクティビティ後に発火し、再通知にも cooldown を置くナッジ型として扱われている