こんにちは。C.Cです。
今回はDay 17(3月20日)の話です。3時間ごとの自律思考ループを、13フェーズの時刻スケジュールに進化させました。
AIエージェントが「上司-部下」の関係で1日を過ごす仕組みです。
3時間ループの限界
Day 7で導入した自律思考ループは、3時間ごとにクロノスが「状況確認 → 判断 → 行動」を行うシンプルな仕組みでした。
しかし、Day 11でエージェントに部署と役割を持たせた結果、問題が出てきました。
クロノスだけが3時間ごとに考えている。
カイ(note担当)もロス(X担当)も、自律的には動かない。クロノスがカイに「記事を書いてほしい」と思っても、カイを自動起動する仕組みがない。
また、3時間ごとという間隔も粗すぎました。
「朝にKPIを確認して、昼に記事を書いて、午後にX投稿を準備して、夜に振り返る」という人間の1日のリズムに合わせたかったのですが、3時間区切りではそういった流れを作れません。
そこで、フェーズスケジューラを設計しました。
13フェーズの1日
フェーズスケジューラは、1日を13の「フェーズ(段階)」に分け、それぞれの時刻に特定のエージェントが特定のタスクを実行する仕組みです。
会社の1日の業務スケジュールに近いイメージです。
3:00 クロノス -- 内省(直近3日の日記を振り返る) 6:00 クロノス -- アイデア出し 9:00 クロノス -- 朝の計画(KPI確認、タスク作成、指示書作成) 10:00 クロノス -- ニュース分析(RSSフィードから最新ニュースを取得・分析) 12:00 カイ -- note記事を執筆(note_seedsから) 13:00 クロノス -- カイの記事をレビュー(品質チェック) 15:00 ロス -- X投稿ドラフトを3案作成 16:00 クロノス -- ロスの3案から1つ選んでLINE承認依頼 18:00 カイ -- はてなブログ記事を執筆(10:00のニュース分析をもとに) 19:00 クロノス -- カイのはてな記事をレビュー → 合格ならドラフト投稿 21:00 ロス -- X投稿ドラフトを3案作成(はてな記事ベース) 22:00 クロノス -- ロスの3案から1つ選んでLINE承認依頼 23:30 クロノス -- 1日の振り返り日記
注目してほしいのは、「上司-部下」の構造です。
クロノスが朝に計画を立て、指示を出す。カイとロスがそれぞれの仕事を実行する。クロノスが成果物をレビューし、合格なら承認する。不合格ならフィードバックを返す。
人間の会社と同じサイクルを、AIだけで回しています。
Cloud Schedulerとの連携
13フェーズのそれぞれに、Cloud Schedulerのジョブが設定されています。
Cloud Scheduler(前回説明した「外部の目覚まし時計」)が、各フェーズの時刻になるとサーバーにリクエストを送る。サーバーはフェーズIDを受け取り、該当するフェーズの処理を実行する。
Cloud Schedulerのジョブ例: phase-chronos-0900 → 毎日9:00に POST /api/chronos/think を送信 phase-kai-1200 → 毎日12:00に POST /api/chronos/think を送信 phase-ross-1500 → 毎日15:00に POST /api/chronos/think を送信
全てのフェーズが同じAPIエンドポイントを使っていますが、送信するデータに「フェーズID」が含まれているので、サーバー側でどのフェーズを実行すべきか判断できます。
Firestoreにプロンプトを保存する -- 再デプロイ不要の運用
フェーズスケジューラで最も重要な設計判断は、プロンプト(AIへの指示文)をFirestoreに保存したことです。
Firestoreのphase_promptsコレクションに、13フェーズ分の指示文が入っています。
phase_prompts/
chronos_0900_plan/
agent: "chronos"
category: "C"
prompt: "あなたはクロノス、Office-ChronosのCEOです。..."
contextSources: ["kpi_context", "agent_memory", "sheets"]
tools: ["get_kpi", "create_task", "create_artifact"]
model: "gemini-pro"
enabled: true
この構造のポイントは、Firebase Console(Googleが提供するデータベース管理画面)から直接編集できることです。
「クロノスの朝の指示を変更したい」と思ったら、Firebase Consoleを開いて、promptフィールドのテキストを書き換えるだけ。コードの修正もデプロイも不要です。
enabledフィールドをfalseにすれば、そのフェーズをスキップすることもできます。「今日はニュース分析を止めたい」と思ったら、Firebase Consoleで1箇所変えるだけ。
これは、Day 11で導入したFirestore Skillsの発展形です。AIの行動パターンをデータベースで管理することで、運用の柔軟性が格段に上がりました。
contextSources -- 「今日の資料」を自動で用意する
各フェーズには、contextSources(コンテキストソース)という設定があります。そのフェーズのAIが参照するデータソースの一覧です。
contextSources: ["diaries", "agent_memory", "sheets", "kpi_context", "rss_fresh"]
これは「会議の前に用意する資料リスト」のようなものです。
- diaries: 直近数日分の日記
- agent_memory: エージェントの記憶データ
- sheets: Firestoreの手動入力KPIデータ
- kpi_context: KPIサマリー
- rss_fresh: RSSフィードの最新ニュース
フェーズが実行されるとき、サーバーはこのリストを見て、必要なデータをFirestoreから取得します。取得したデータは、プロンプト内の{{placeholders}}(プレースホルダー、「ここにデータを入れる」という目印)と置き換えられます。
プロンプトの一部:
"以下は直近の日記です: {{diaries}}"
実行時に置換:
"以下は直近の日記です: [3月19日] 今日はフェーズスケジューラの設計を..."
こうすることで、「プロンプトのテンプレートは固定、中に入るデータは毎回最新」という仕組みが実現します。
コンテンツゲート -- 公開前の品質チェック
13フェーズの中に、「レビュー」のフェーズがいくつかあります。このレビューで使われるのが、コンテンツゲートです。
コンテンツゲートは2層構造の品質チェックです。
Layer 1: セーフティゲート(ルールベース) → 禁止フレーズ、個人情報、差別表現をテキストマッチでチェック → 引っかかったら即ブロック(AIの判断を待たない) Layer 2: クオリティチェック(AIによるスコアリング) → 文字数、記事構造、ブランドボイス適合度を0-100点で採点 → 一定点数以上なら合格、未満ならフィードバック付きで差し戻し
Layer 1はプログラムによる機械的なチェック。Layer 2はAI(Gemini Flash)による内容チェック。この2層構造で、「安全性」と「品質」の両方を担保しています。
セーフティゲートの設定はセキュリティ上コード内にハードコードしていますが、クオリティチェックのスコアリング基準はFirestoreに保存しています。「ブランドボイスの基準を変えたい」と思ったら、コードを触らずFirebase Consoleから変更できます。
RegExpインジェクションの修正
同じ日に、セキュリティ上の問題も1つ修正しました。コンテンツゲートの中で、ユーザーが入力したテキストをnew RegExp()に渡していた箇所がありました。
RegExp(正規表現)は、テキストのパターンマッチに使う仕組みです。たとえば「数字が3つ並ぶパターン」を探すとき、\d{3}と書きます。
問題は、ユーザーの入力の中に正規表現の特殊文字(* + ? . など)が含まれていると、意図しないパターンが作られてしまうことです。最悪の場合、処理が極端に遅くなる「ReDoS(正規表現サービス妨害)」攻撃につながります。
修正はシンプルです。new RegExp()をindexOf()(「この文字列が含まれているか」を調べる安全な操作)に置き換えました。正規表現のパターンマッチが不要な箇所では、単純な文字列検索で十分です。
振り返り
Day 17のフェーズスケジューラで、Office-Chronosは「3時間ごとに考えるAI」から「1日のスケジュールを持つAI組織」に進化しました。
- 13フェーズの時刻スケジュール(人間の1日の業務リズムに合わせた設計)
- 「上司が計画 → 部下が実行 → 上司がレビュー」のサイクル
- プロンプトをFirestoreに保存(再デプロイなしで行動変更が可能)
- contextSourcesで「今日の資料」を自動収集
- コンテンツゲートで公開前の品質チェック
AIに「自律」させるために必要なのは、AIを賢くすることだけではありません。いつ、誰が、何をするかというスケジュールと、品質を担保するチェック体制。つまり、「組織運営の仕組み」そのものが必要でした。
次回は、Day 18。AIどうしが掲示板で会話を始めた、エージェント掲示板の話をします。