このアプリのすべてを形作っている、たった一つのアーキテクチャ上の判断は、言葉にすれば小さいが、実際にそれを中心に組み立てるのは厄介だ:写真ドライブは厳格に読み取り専用で開かれ、決して書き込まれない。原本の隣に置くサイドカーファイルもない、隠しフォルダのメタデータもない、リネームもない、移動した重複もない。入ってきたドライブは、1バイト単位で同じまま出ていく。
この制約は、それが実際に何を排除するかに気づくまでは、あれば嬉しい程度のものに聞こえる。しかしこれは、ファイルを移動したりリネームしたりして「整理する」タイプのツール全体を排除する。原本の近くに、派生した状態 — サムネイル、顔の特徴ベクトル、イベントの境界 — を保存することも一切排除する。アプリがアーカイブについて学んだことすべてが、まったく別の場所に存在しなければならなくなり、それは早い段階で、その「別の場所」がどこになるかを決める必要があったということだ。
派生したものはすべて内蔵ディスクに置く
答えはSQLiteで、外付けドライブではなく、Macの内蔵ディスク上にある。インデックス(日付、顔、イベントの境界、検索用の特徴ベクトル)とサムネイルキャッシュは、どちらもそこに置かれ、アーカイブ自体からは完全に分離している。アプリのデータディレクトリを削除しても、アーカイブは手つかずであることが証明できる。アーカイブについての何かが、そのディレクトリの存在に依存したことは一度もないからだ。ゼロから再インストールすれば、アプリは自分自身の状態のバックアップを信頼する必要なく、ドライブを再び読み取ることで理解を再構築する。
SQLiteのライトアヘッドログ(WAL)は、理論上ではなく実際上、最も重要だった要素だった。開発中に、2回の本物のハードクラッシュがあった — 実際の停電で、シミュレートした障害注入テストではない — 解析処理が実際のアーカイブに対して実行中の書き込みの途中だった。どちらの場合も、WALジャーナリングによってデータの損失はゼロだった:データベースは次回起動時に一貫した状態で立ち上がり、ほぼ中断したところから再開し、手動での修復は一切必要なかった。これは、必要になったことがなく、自分でテストしたこともない保証であってほしいと思う類のものだが、外付けドライブ、何時間も動く背後の解析処理、そしてケーブルが時々ぶつかって外れる家庭という組み合わせの中で、公開前に本当に2回テストされてしまった。
「読み取る」ことで実際に回収できるもの
読み取り専用の保証は、それを守りながら実際に抽出できるものの分だけしか価値がなく、実際の家族アーカイブのメタデータは、きれいなテストセットよりも乱雑だ。元になったアーカイブでは、92%のファイルが、そのまま使える正しいEXIFの日付を持っていた。残りの8%にはフォールバックが必要だった — ファイルシステムのタイムスタンプ、フォルダ名の日付、同じイベント内の近隣写真からの推測 — そして、そのフォールバックを経て、カバレッジは98.1%に達した。最後の2%が、正直な限界だ:一部のファイルには、ファイル自体にも周辺にも、まったく何の手がかりも存在せず、どんなフォールバックの連鎖も、無から何かを作り出すことはない。
理解が終わる前から、閲覧できる
読み取り専用と、派生状態を別の場所に置くことは、安全性の問題を解決する。しかしそれとは別に、待ち時間の問題がある:大きなアーカイブの完全な解析には数時間かかり、1枚の写真を見られるようになる前に進捗バーを眺めていたい人などいない。ライブラリは、ドライブにアプリを向けた最初の数分のうちに閲覧可能になる — 早い段階のパスが、基本的な閲覧を本物にするだけのインデックスとサムネイルを揃える。もっと深いパス(顔のクラスタリング、イベントの命名、意味検索を支える特徴ベクトル)は、その裏で動き続け、すでに写真を見ている間に、静かにより豊かな答えを埋めていく。最初に有用な瞬間を、最後の重い処理の背後に閉じ込めることはしない。
リソース統制は、提案ではなく、ルールだ
最後の要素は、省略しやすく、下手に省略すると高くつく部分だ:数十万ファイルを読み取って理解する解析処理は、本当に重い作業であり、誰かが他の用途にMacを使おうとしているときにその唯一のMacの上で重いバックグラウンド処理をすることは、「プライバシー重視のローカルAI」を「なぜノートパソコンが電気ストーブになっているのか」に変えてしまう典型的な原因だ。ここでのルールはベストエフォートではなく、厳格なものだ:解析処理がフォアグラウンド作業と優先度を争わないようにするバックグラウンドQoSスケジューリング、ユーザーが操作を始めた瞬間から数秒以内に後退する適応的なワーカー数、メモリ使用量への厳格な上限、そしてバッテリーや発熱の圧力下での完全な一時停止。標準的なMacで動く完全な解析処理は、感じ取れるようなものであってはならない。感じ取れるなら、それはトレードオフではなく、バグだ。
これらすべて — 読み取り専用の原本、内蔵ディスク上の派生状態、クラッシュに強いジャーナリング、実際に守られるリソース上限 — が積み重なって、かなり地味なエンジニアリングの主張になる:「ローカルファースト」の面白い部分は、AIがサーバーではなく端末上で動くということではない。それも本当だが。面白いのは、そもそも信頼すべきサーバーが存在しないということだ。つまり、これらの保証のそれぞれが、あなたが他のすべてをすでに信頼している、あなたの机の上にある1台のマシンについてだけ、真実であればいいということだ。