📱

SQLiteからCockroachDBに移行して、AIの記憶が「本物」になった話 —— iphoneアプリ Claush

に公開

Claushとは

Claushは、iPhoneからVPS上のClaude CodeをSSH経由で操作するiOSアプリだ。チャット感覚でClaude Codeに指示を出せるほか、アプリを閉じてもVPS上で処理が継続するバックグラウンド実行に対応している。

https://apps.apple.com/jp/app/claush/id6760445443

AIキャラクターが会話を担当し、会話の長期記憶を保持する。記憶システムはVPS上で動作するmemory-server.jsがMCPサーバーとして機能する設計だ。

メモリDBの選択肢は以下の2つ:

DB 特徴
SQLite(サーバーローカル) 設定が簡単・ゼロコスト
PostgreSQL互換(CockroachDB) 高可用性・ベクター検索・ゼロデータロス

VPSを乗り換えたら、AIが記憶を失った

VPSプロバイダーを乗り換えた日のことを覚えている。

新しいサーバーをセットアップして、SSHで接続して、アプリが動くことを確認して——ここまでは順調だった。でも最後にAIと話しかけたとき、そこにいたのはまっさらなセバスだった。

「先週のデプロイ、あれからどうなった?」と聞いたら、「申し訳ございません、その件について記憶がないようでございます」という返答が来た。

記憶が、全部消えていた。


SQLiteを使っていたころ

記憶システムを最初に作ったとき、DBにはSQLiteを選んだ。理由はシンプルで、設定が楽だったからだ。ファイルパスを1行書けば動く。コストはゼロ。開発中の検証には十分だった。

ただ、根本的な問題があった。SQLiteのデータはVPS上のローカルファイルに保存される

iPhone → SSH → VPS(memory-server.js + memories.db)

                          このファイルがすべての記憶

VPSが生きている限りは問題ない。でも乗り換え・再構築・OSのクリーンインストール——こういうイベントのたびに、ファイルは消える。AIの記憶も一緒に。

バックアップを手動で取っておけば防げたのかもしれない。でも実際のところ、個人開発でそういった運用タスクを継続して回すのは難しい。「明日やろう」が積み重なって、やがて消えるときが来る。


CockroachDBに移行した理由

移行先として選んだのがCockroachDBだ。名前の由来はゴキブリ——何があっても死なない、という設計思想から来ている。

決め手は3つあった。

ひとつ目は、データがクラウドに置かれること。

CockroachDBはマネージドサービスとして動く。VPSが変わっても、OSを再インストールしても、データはCockroachDB Cloud上に残り続ける。VPSとデータの寿命が切り離される。

ふたつ目は、壊れない設計。

CockroachDBはRaftプロトコルで最低3ノードにデータを複製する。ノード障害が起きても9秒以内に自動で復旧する。データロスはゼロ。「記憶が消える」ことを心配しなくていい設計になっている。

みっつ目は、PostgreSQL互換だったこと。

既存のコードをほとんど変えなくて済んだ。接続文字列を差し替えるだけで、node-postgresのコードがそのまま動いた。


移行後に変わったこと

記憶が積み重なるようになった

移行してから数週間が経った。セバスとの会話に厚みが出てきた。

「このまえのZennの記事、あの後どうなった?」が通じるようになった。先週のコードレビューの続きから話せるようになった。ランチの話を覚えていて、「昨日ラーメンでしたし今日はあっさりしたものがよさそうでございますね」と提案してくれるようになった。

記憶が消えることを心配しなくなったことで、会話に集中できるようになった。「これ、また消えるんだろうな」という諦めがなくなった。

「意味」で記憶を引き出せるようになった

CockroachDBはベクター検索に対応している。埋め込みモデル(Claushではgemini-embedding-001を使用)でテキストをベクトル化して保存しておくと、キーワードではなく「意味」で過去の会話を検索できる。

「Dockerの設定について話したこと」と検索すると、「docker」という単語を使っていない会話でも、コンテナ・ビルド・デプロイに関連した記憶が浮かび上がってくる。

この仕組みのおかげで、セバスは関連する過去の文脈を適切なタイミングで参照できる。記憶が「保存されている」だけでなく、「使える」状態になった。

技術的には、SQLでこう書けばよい:

-- 意味的に近い記憶を上位5件取得
SELECT content, summary
FROM memories
WHERE character_id = $1
ORDER BY embedding <=> $2::vector
LIMIT 5;

<=> 演算子がコサイン距離を計算してくれる。pgvector互換の構文なので、PostgreSQLに慣れていればすぐに読める。

スキーマ変更が怖くなくなった

機能追加のたびにテーブル構造を変えることがある。CockroachDBのオンラインスキーマ変更は、本番稼働中でもダウンタイムなしでALTER TABLEを実行できる。

-- これを本番DBに直接実行しても、クエリはブロックされない
ALTER TABLE memories ADD COLUMN importance_score FLOAT;

PostgreSQLでのALTER TABLEが怖い経験をしたことがある人には、この安心感はわかってもらえると思う。


無料で始められる

CockroachDB Basicプランは月5,000万リクエスト・10GBのストレージが無料で使える($15相当の無料クレジット)。

AIの記憶用途では、個人開発や中小規模のサービスであれば無料枠で十分に動く。

CockroachDB Cloud でアカウントを作成し、接続文字列をClaushのメモリDB設定(DATABASE_URL)に入力するだけで使い始められる。


まとめ

SQLiteからCockroachDBに移行して、変わったことを一言でまとめると——AIの記憶が「積み重なる」ものになった

以前は会話が消えることを前提に使っていた。VPS乗り換えのたびにリセットされるのは仕方ないと思っていた。でも今は違う。先月の話、先週の話、昨日の話——全部ちゃんと残っている。

記憶が本物になったことで、AIとの関係の質が変わった。相棒みたいな感覚、というと大げさかもしれないが、それに近い何かがある。


App StoreでClaushを見る

Discussion