dairy-snap に MAS(マルチエージェント)を入れた理由と、オーケストレータ+サブエージェント分割の効用。04-10 前後の変更と、品質・拡張性・レイテンシのトレードオフの話。
振り返りチャットを「ただのチャット API 呼び出し」にすると、すぐ破綻する。天気、予定、学校の時間割、趣味の文脈、恋愛の地雷(避けたい話題)みたいな要素が混ざると、単一プロンプトで全部やろうとするほど不安定になる。だから daily-snap では MAS(マルチエージェント)に寄せた。
やりたかったのはショーじゃなくて、品質と拡張性だ。役割が分かれていると、プロンプトも評価も差し替えやすい。あわよくば並列化でレイテンシも殴れる。そして個人的には、設計が楽しい(これは正直な動機)。
CHANGELOG 上だと、この塊はかなり太い。代表として e6de2ba が「内省チャット向け MAS」入りのコミットとして分かりやすい。オーケストレータが tool calling で回り、カレンダー系はカテゴリでイベントを切る、学校エージェントは時間割スライスを読む、みたいな 専門家の割り振りがコードに現れる。
「分割したから速い」より先に、責務がぶつからないことが個人開発では効く。ざっくり次のイメージ。
| 層 | やること | やらない方が楽なこと |
| --- | --- | --- |
| オーケストレータ | ツール選択、会話の段取り、各エージェントへの委譲 | カレンダーの細目まで一人で文章化 |
| カレンダー系エージェント | 予定集合の取得・分類・プロンプト向け要約 | 天気の数値解釈まで抱え込む |
| 学校系エージェント | 時間割スライスの読み取り | 恋愛トピックの地雷回避まで一手に引き受ける |
| 天気ツール(weather-tool) | Open-Meteo / DB キャッシュの優先、narrativeHint | 長期記憶の整合(別コンポーネント) |
分割の代償は 失敗の多様性だ。ルーティングが外れたときに「沈黙」「空回り」「誤った自信」が出る。だから AIArtifact / AuditLog を厚くする話は、性能の話というより 運用の話に近い。
同じ日付帯には、カレンダーの 色メタデータやオープニング話題の分類も載る(例: 90a1844)。ここが効くのは、予定を「ただの文字列」じゃなく、文脈のタグとして扱える点だ。後から振り返ると「あの週は仕事の予定が詰まってたな」みたいな話が立ち上がりやすい。
トレードオフもある。エージェントが増えるほど、失敗パターンも増える。ルーティングが外れると空回りするし、ログだけ見ても原因が分かりにくい。だから **監査(何を参照して何を生成したか)**を細かく残す方向に寄せている。本文はログに出さない、という前提とセット。
この連載の立ち位置としては、「すごい AI」を見せるより、個人アプリで MAS を採用するのが合理的になる条件を拾い集める。次は、ストリーミングと監査の話に寄せる。
エージェント分割は、動けば正義だけど、運用ではプロンプト差分と失敗ログの読み方が生活になる。だから web/prompts/agents/ のような置き場をリポジトリに残すのは、個人開発でも効く。未来の自分が「なぜこの指示になった?」を追えるからだ。楽しさ(fun)も動機の一部、と言い切っておく。
MAS は強いが、強い分だけ観測可能性が要る。だから監査とセットで語る。次の回は、ストリーミングとログの話に寄せる。
エージェントが増えるほど、「どの会話がどの経路で生成されたか」を後から説明しづらくなる。だから会話ログと生成メタの紐付けは早めに決める。後付けは地獄。
振り返りチャットの画面(ストリーミング中でも可)、カレンダーのフィルタチップや色付きドットが見える UI、設定のカテゴリ関連。内部構造はコード参照だが、体験の説明には画面があると強い。
個人開発でも、エージェントはブラックボックスになりやすい。だから「どのツールが叩かれたか」「どのカレンダー集合を見たか」みたいなメタを残す。本文は残さないが、何を見たかは残す。ここを曖昧にすると、後から直せないバグが増える。
この回のまとめは単純で、会話の質はプロンプトだけじゃなく構造で決まる。分割はコストではなく、長期のメンテ負債を減らす投資に寄せた。
daily-snap 開発ログ
前: pgvector はまだ。でも DB は…
次: ローカルでは SSE が笑う。本番は別腹。監査はここまで踏み込んだ
索引: 04-02 · … 04-30
天気(Open-Meteo)と Google カレンダーのキャッシュ・分類が、日記と AI の文脈にどう効くか。entry-weather・WeatherAmPmDisplay・weather-tool などコード上の出所と、設計意図・本番運用をまとめる。
AI チャットの SSE(ストリーミング)をローカル・本番で確認した手順と、環境差分で再発しうる罠。ai_artifacts / audit_logs を厚くする理由と、本文をサーバログに出さない方針。
dairy-snap を Docker / Cloud Build / Cloud Run 気味に寄せるときに踏んだ地雷の型。standalone、prisma generate、Node heap、ダミー DATABASE_URL、PORT。04-16 前後のコミット列を軸に、個人開発でもハマる点を整理する。
Google OAuth・許可リスト・JWT セッションの方針と、middleware から proxy へ寄せた経緯。HTTPS 背後での secureCookie、Docker 本番との相性。04-17 前後のコミットを手がかりに。
daily-snap の画像アップロード。最大辺2048px、AVIF優先(非対応ならWebP)の圧縮、ストレージ抽象と本番 GCS 前提。日記アプリで画像が重い問題への殴り方。
Prisma + Postgres で daily-snap のテーブル責務を切った話。ベクトル検索は未実装だが、エントリ・チャット・画像・ai_artifacts・memory 系をどう置くか。次に足すならどこか。