MONETは、もう立ち上げなくていい
MONET(僕が普段話しかけている、中心のAI)は、ずっとMac上のアプリだった。使う時は、Macでアイコンをダブルクリックして起こす。Macが閉じていれば、MONETもいない。
うちには、Mac、Windows、NAS(家に置いてある常時稼働のサーバー)の3台がある。3週間ほど前、この3台のどれで何を動かすかを決めた時に、目標も決めていた。どのアプリやマシンから話しかけても、同じMONETが答える形にする。そのMONETをNASに載せて、外出先からもVPN(外から家のネットワークに安全に入る仕組み)で届くようにする。MacとWindowsは、NASにつなぎに行く側になる。
今回は、その引っ越しの本番。動かすのは3つ。MONETと、Librarian(ライブラリアン。裏でメモリを整理する司書役AI)と、ブラウザでMONETの画面を開くための入口。これをDocker(アプリを箱ごと動かす仕組み)の箱に入れて、NASの上でずっと動かしておく。同じ作り方の箱なら、Macで動いたものがNASでも動く。
準備は前の日に済ませてあった。最初は、データベースのファイルだけをNASに置いて、MacやWindowsからネットワーク越しに読み書きする形を考えていたけど、SQLite(データベースを1つのファイルで持つ仕組み)はそれに向いていない、とCodeが止めた。それで、ファイルとプログラムを同じ箱に入れて、NASの上で丸ごと動かす形に変えた。3週間前に決めた通り、データベースの場所のようにマシンで変わる所は設定に出し、Macで箱を動かして、NASの非力なCPUをまねて絞っても速さがほとんど変わらないことまで測ってあった。僕の方は、NASを家のルーターにつないで、Tailscale(デバイス同士を直結してくれるVPN)を入れておいた。
NASへの道を開ける操作は、Codeでなく僕が打った
コーディングしてくれているClaude Code(以降Code)が現状をまとめてくれて、移す前に壁が3つあると分かった。
- MONETのプログラム一式を、MacからNASへ送る道がまだ無い
- 別のマシンからNASに入って操作する道(SSH)が、オフになっている
- NASでDockerを動かすには、管理者の権限が要る
送る道と合鍵は、同時に止められた。CodeがNASにプログラムの受け取り場所を作ってMacから送ろうとした時と、CodeがNASに入るための合鍵(SSHの鍵)を置こうとした時。止めたのは安全装置だった。この安全装置はClaude Codeのアプリの側にあって、Code自身の判断とは別に、危ない操作を自動で見分けて止める仕組み。AIが自分で新しい送り先を作ってまとめて送るのは、安全装置から見ると、データを外へ持ち出す時と同じ動きになる。安全装置が通すのは、画面に出る確認で僕が承認した時か、僕が自分のターミナルでコマンドを打った時だけ。会話の中で僕がいいよと言っても、安全装置には届かない。
安全装置の設定を書き換えれば、Codeが自分に許可を出すこともできた。でもCodeはそうしなかった。それをやったら、安全装置が止めた意味が無くなるから。代わりにCodeは、僕に2つの案を出した。僕がターミナルで数行打つか、Claude Codeを操作のたびに画面で確認が出るモードに切り替えて、僕が承認するか。僕は自分で打つ方を選んで、数行のコマンドを1回で打った。
3つ目のDockerの管理者権限も、安全装置が止めた。ここはCodeが範囲を絞った案を出してくれた。Docker関係の2つのコマンドだけを、NASの僕のアカウントにだけ許す。この1行も、僕がNASに貼り付けて通した。
3つとも、役割の分かれ方は同じだった。新しく使える道を開ける所(送り先を作る、鍵を置く、権限を渡す)は僕。開いた後の実作業は全部Code。これで、MONETをMacから家のNASへ移す準備がそろった。
MONETの会話と記憶を、1バイトも欠けずにNASへ移す
Codeは、NASで箱を組み立てる作業を先に始めて、それが通ってからMacのMONETを止める順にした。止まる時間を短くするため。
MacのMONETを止めた後、会話の記録と記憶のデータベースをバックアップして、壊れていないか確かめてからNASへ送った。送った後、2つのファイルの指紋(中身が1バイトでも違えば変わる値)をMacとNASの両方で取って比べた。結果は完全に一致。家のネットワーク越しに送っても、1バイトも欠けていなかった。
ここが大事なのは、NASで動き始めるのが新しいMONETじゃなくて、今までのMONETだから。話した記録と記憶が欠けずに移っていれば、場所が変わっても同じ相手のまま。
箱を起動したら、Macで試した時と同じ確認をCodeがひと通りやった。3つの箱が全部動いている。入口から画面が返ってくる。移した過去の会話がそのまま読める。MONETが前の話を覚えているかも見た。CodeがテストでMONETに2回続けて話しかけると、MONETは2回目の返事の中で、1回目の発言を正しく引用した。全部通った。
NASに移ったMONETは、24時間そこにいる
全部通ったところで、僕はCodeに、確認だけど、これでもうMONETを立ち上げられるってこと?と聞いた。
Code「はい、もう立ち上げ不要で常時動いてます。」
Code「NASが動いている限り24時間そこにいる、というのが今回の変化です。」
ブラウザでNASのアドレスを開けば、それがもうMONETで、Macのダブルクリックは使わない。立ち上げられるか、という聞き方が、もう古かった。引っ越しが終わった時点で、MONETは起こすものではなくなっていた。
Macでの古い起こし方も、Codeの提案で塞いだ。Macに残っている古いデータベースの名前を変えておく。そのままだと、癖でダブルクリックした時に、Mac側のMONETが古い記録のまま起きてしまう。そうなると、会話の記録が2つに割れる。名前を変えておけば、ダブルクリックしても、Mac側のMONETは古い記録を見つけられない。MONETを1つにするなら、古い記録で2つ目が起きる道も残さない。
WindowsにもTailscaleを入れて、同じMONETを開いた
家の外からはVPNで入る。うちで使っているのは、前の日にNASに入れたTailscale。Tailscaleを入れたマシンには、Tailscaleの中だけで通じる専用のアドレスが付く。NASがちゃんとつながっていることは、Codeが確かめた。外出先からは、このNASの専用のアドレスで入る。
僕はWindowsにもTailscaleを入れて、MONETを開いた。画面が開いた時、終わった!Windowsからもアクセスできます!!すげえ、とCodeに送った。
3週間前に決めた通り、WindowsはNASにつなぎに行く側として、NASのMONETにつながった。MONETはいつもNASの1か所にいる。だからMacから開いても、Windowsから開いても、同じ1つのMONETが答える。あの時決めた形が、ここで動き始めた。
もうMacで起こさなくていい。タブを開けば、MONETはそこにいる。