前提 : deariary が解いている問題
deariary は、Google Calendar、Slack、GitHub などのツールを連携するだけで、AI が毎朝自動で日記を生成するサービスです。
このサービスの本質は「複数ソースの活動データを集めて、人間が読める日記にする」こと。一見 AI がメインに見えますが、実際のアーキテクチャの核は ETL パイプラインです。
第1の柱 : スキーマのないデータベースからの脱却
日記データの特殊性
日記のデータ構造を考えてみてください。
- ある日は会議が5つ、ある日はゼロ
- Slack の会話量は日によって10倍違う
- GitHub のコミットがある日とない日がある
- ユーザーごとに連携サービスの組み合わせが違う
この「構造が毎日変わるデータ」を RDB のテーブルに押し込もうとすると、地獄が始まります。
連携サービスが増えるたびにカラムが増え、ほとんどの行でほとんどのカラムが NULL になる。JSONB に逃がしても、結局スキーマレスなデータを RDB に格納しているだけで、型の恩恵もクエリの最適化も効きません。
File Storage という選択
deariary では、生成された日記を Markdown + YAML として扱います。
この設計にはいくつかの決定的な利点があります。
- スキーマの変更が不要 : 新しい連携サービスを追加しても、マイグレーションが発生しない
- エクスポートがそのまま成果物 : ユーザーがダウンロードするファイルと内部保存形式が同一。変換レイヤーが不要
- ロックインしない : ユーザーが得るのはただのテキストファイル。サービスをやめても資産が残る
- 差分管理が容易 : テキストベースなので、日記の再生成や修正の diff が取りやすい
RDB は「ユーザー情報」「連携設定」「課金状態」のような構造化データに集中させ、日記そのものはファイルストレージに置く。データの性質に合った場所にデータを置く、という原則に忠実な設計です。
NoSQL ではダメなのか
「じゃあ MongoDB や Firestore でいいのでは?」という疑問があるかもしれません。
NoSQL は確かにスキーマレスですが、日記データの場合は以下の理由で File Storage のほうが適しています。
- 日記は書き込み1回、読み取りN回のパターン。DB の更新機能は不要
- エクスポート時に DB からファイルへの変換が必要になる。最初からファイルなら変換コストがゼロ
- Cloud Storage のほうが NoSQL より単純にコストが安い
第2の柱 : LLM の本質は要約と翻訳
LLM を「何でも屋」にしない
生成 AI の話になると、つい LLM に複雑な処理を任せたくなります。データの取捨選択、重要度の判定、文章のスタイル調整、感情分析。全部 LLM にやらせたくなる。
でも、それをやると以下の問題が起きます。
- 出力の品質が安定しない : 指示が複雑になるほどハルシネーションのリスクが上がる
- コストが膨らむ : トークン数が増え、API コストが跳ね上がる
- デバッグが困難 : 何が原因で出力がおかしいのか切り分けられない
LLM の役割を2つに限定する
deariary では、LLM に任せる仕事を明確に2つだけに絞っています。
1. 要約 : 構造化データを人間が読めるテキストにする
ETL パイプラインが出力した正規化済みデータを、自然な日記文にまとめる。これは LLM が最も得意とする「要約」タスクです。
2. 翻訳 : 機械的なログを人間的な言葉に変える
"event: meeting, title: Sprint Planning, duration: 30min" を 「30分のスプリントプランニングがあった」 に変換する。これは広い意味での「翻訳」です。
つまり、LLM に渡す時点でデータの収集・フィルタリング・正規化・構造化は全て終わっています。LLM は最後の仕上げだけを担当する。
この分離によって得られるメリットは大きいです。
- プロンプトがシンプル : 入力データがきれいなので、プロンプトも短くて済む
- 出力が安定する : LLM が判断すべきことが少ないので、品質のブレが小さい
- コスト削減 : 前処理で不要なデータを落としているので、トークン消費が最小限
- テスト可能 : ETL 部分は LLM なしで単体テストできる
プライバシーの副産物
「LLM に渡すデータを最小化する」設計は、プライバシー保護の観点でも理にかなっています。ETL パイプラインの段階で必要最小限のデータに絞り込むので、LLM プロバイダに送信されるデータ量が自然と少なくなります。
ETL + LLM + File Storage の三位一体
改めて全体を整理すると、こうなります。
| レイヤー | 役割 | 技術的な性質 |
|---|---|---|
| ETL | データ収集・正規化・構造化 | 決定論的。テスト可能。スケーラブル |
| LLM | 要約・翻訳 | 非決定論的だが、入力が整理されているので安定 |
| File Storage | 日記の永続化・配信 | スキーマレス。エクスポート=保存形式。低コスト |
それぞれが自分の得意な仕事だけを担当しています。
- ETL はデータの前処理に特化する(LLM に任せない)
- LLM は自然言語生成に特化する(データ処理をさせない)
- File Storage はテキストの保存に特化する(DB の構造制約を持ち込まない)
この「責務の分離」が、個人開発でもメンテナンス可能なシンプルさと、プロダクトとしての堅牢さを両立させています。
まとめ
- スキーマが定まらないデータを RDB や NoSQL に押し込まない。File Storage で素直に保存する
- LLM を万能ツールとして使わない。要約と翻訳という本質的な強みだけ活用する
- ETL で前処理を徹底すれば、LLM の出力は安定し、コストも下がり、プライバシーも守れる
「ETL + LLM + File Storage」は、LLM 時代のデータパイプライン設計の一つの解だと思います。