🐾 claw-stack

最終更新:2026年3月 · ソース:agent-time-awareness

スマートスケジューラー & デッドラインウォッチ

時間コンテキストサービス(TCS)— LLM エージェントに正確な時間認識、タイムアウト検出付きのバックグラウンドタスク追跡、コンテキスト圧縮後も存続する永続イベントログを提供する軽量 Python サービス。

← モジュール概要

概要

TCS は LLM エージェントが時間に関して抱える3つの問題を解決します:

1. 時間コンテキストの注入

システムプロンプト向けの時間コンテキストブロックを生成します:現在のタイムスタンプ、曜日、相対タイムゾーン情報、連絡先の静音時間帯。このコンテキストで各セッションを開始するエージェントは現在時刻を正確に把握できます。

2. タスクライフサイクルトラッカー

バックグラウンドタスクを登録し、設定可能な間隔でポーリングし、タイムアウトを検出し、完了のマークを付けます。エージェントが重複した作業を開始したり、非同期操作のフォローアップを忘れたりするのを防ぎます。

3. 永続イベントログ

SQLite ベースのエージェントイベントのタイムライン。LLM コンテキストウィンドウの外に存在するため、コンテキスト圧縮後も存続します。コンテキストが削除された後でも、エージェントは「過去2時間に何が起きたか」を照会できます。

なぜ必要か

LLM にはリアルタイムクロックがありません。トレーニングカットオフまでの世界を知っているだけで、現在の瞬間は知りません。明示的な時間注入がなければ、エージェントは「今日は何日?」に正しく答えたり、デッドラインやスケジューリングについて推論したりできません。これはセッション開始時に簡単に修正できますが、信頼できる方法で行うには専用サービスが必要です。

バックグラウンドタスクの追跡はより難しいです。長時間実行プロセス(ビルド、テスト実行、データパイプライン)を開始したエージェントは後で確認する必要があります。外部状態がなければ、エージェントは毎回ポーリングするか(ノイズを生成)、コンテキスト圧縮後に完全に忘れるかのどちらかです。TCS はコンテキストウィンドウ外の SQLite にタスク状態を保持するため、セッションリセット後も持続します。

イベントログは履歴の同じ問題に対処します:コンテキスト圧縮は以前のイベントを静かに削除します。コンテキストウィンドウ外の SQLite イベントログは、コンテキストが何回削除されても任意のセッションが照会できる永続タイムラインを提供します。

アーキテクチャ

TCS は MCP サーバーとして実行され、Model Context Protocol 経由でエージェントがネイティブに呼び出せるツールとして3つの層すべてを公開します。

ツール 説明
get_temporal_contextシステムプロンプト注入用の現在の時間コンテキスト(テキストまたは JSON)
start_task追跡用のバックグラウンドタスクを登録
poll_task設定された間隔に基づいて今タスクをポーリングすべきか確認
finish_taskタスクを完了またはキャンセル済みとしてマーク
list_tasksタスクをリスト表示(ステータスでフィルタリング可能)
check_timeouts実行中のすべてのタスクのタイムアウトをスキャン
log_event永続タイムラインにイベントを追加
query_timeline時間範囲またはタイプでイベントを照会
search_eventsイベントサマリーの全文検索
get_statsアクティビティ統計

重要な設計上の決定

外部プロセス、コンテキスト内状態ではない

TCS は別サービスとして実行されます。状態はエージェントのコンテキストではなく SQLite に存在します。これが根本的な設計上の選択です:状態がコンテキストウィンドウの完全に外部に保存されているため、コンテキスト圧縮でタスク状態やイベント履歴が消去されることはありません。

スマートポーリング — 生のタイムスタンプではなく「今ポーリングすべきか?」

poll_task ツールはブール値を返します:エージェントは今このタスクを確認すべきか?これにより間隔ロジックがエージェントから抽象化されます。エージェントは最終ポーリングのタイムスタンプを自分で追跡する必要はなく、TCS が処理します。

インターフェースとして MCP

MCP 経由で TCS を公開することで、MCP 互換のエージェントはカスタム統合なしに使用できます。エージェントは TCS ツールをツールボックス内の他のツールと同様に扱います。また、エージェント設定を変更せずに新しいツールを追加することも簡単になります。

時間コンテキストはメッセージごとではなくセッション開始時に注入

時間コンテキストブロックはシステムプロンプトに属しており、すべてのユーザーメッセージで繰り返すものではありません。セッション開始時に get_temporal_context を一度呼び出してシステムプロンプトに結果を含めれば十分です。

独自のシステムの構築方法

1. 時間状態をコンテキストウィンドウの外に置く

コアインサイト:コンテキスト圧縮後も存続する必要のある状態は外部ストアに存在しなければなりません。SQLite は良い選択です—軽量、ファイルベース、サーバー不要。WAL モードにより書き込みをブロックせずに並行読み取りが可能です。

2. 各セッション開始時のシステムプロンプトに時間コンテキストブロックを注入

セッション開始時に構造化ブロックを生成します:現在の ISO タイムスタンプ、曜日、ローカルタイムゾーンオフセット、関連する連絡先の静音時間帯。生の JSON ではなく人間が読める散文としてフォーマットしてください—エージェントの時間に関する推論がより信頼性の高いものになります。

3. poll_task をデータソースではなくゲートとして設計

エージェントは追跡中のタスクが関与する可能性のある各ターンで poll_task を呼び出すべきですが、ツールは「はい、今確認して」または「まだです」を返すべきです—タスクステータス自体ではありません。これによりエージェントが外部システムを頻繁にポーリングするのを防ぎます。

4. イベントログスキーマ:タイムスタンプ + タイプ + サマリー + オプションのメタデータ

イベントログスキーマをシンプルに保ってください。サマリーフィールドは FTS で検索可能な短い人間が読める文字列であるべきです。構造化メタデータは別途保存してください。イベントを削除しないでください—アーカイブまたはフラグを立ててください。

5. グローバルではなくタスクごとのタイムアウト

異なるタスクには異なる期待される期間があります。登録時にタスクごとにタイムアウト値を保存してください。check_timeouts ツールはすべての実行中タスクをスキャンし、単一のグローバル制限ではなくそれぞれの個別タイムアウトを超えたものにフラグを立てます。

よくある質問

LLM エージェントになぜ別の時間サービスが必要なのですか?

LLM にはリアルタイムクロックがなく、コンテキストウィンドウ間の永続メモリもありません。TCS は両方を解決します:オンデマンドで現在のタイムスタンプを提供し、SQLite イベントログはコンテキストが圧縮されたりセッションが再起動されても何が起きたかを記録します。

タスクの「スマートポーリング」とは何ですか?

poll_task ツールは設定された間隔に基づいて最後のポーリングから十分な時間が経過したかどうかを返します。これによりエージェントが30秒ごとに確認するだけでよいバックグラウンドジョブを毎メッセージターンでポーリングするのを防ぎます。

イベントログは OpenClaw セッションの再起動後も存続しますか?

はい。イベントはセッション状態の外の SQLite ファイルに保存されます。そのファイルが存在する限り、履歴イベントは任意のセッションから照会できます。

Authors: Qiushi Wu & Orange 🍊