開発を止める前に確かめたら、記憶を書くAIが止まっていた
MONET(僕が普段話しかけている、中心のAI)には、会話を覚えておくための仕組みがある。
流れはこう。MONETとの会話は、まず生のログとしてデータベースに書かれる。話がひとまとまりになると、そこまでが1つの「区切り」になる。要約されるのは、この区切りに入った会話だけ。
Librarian(ライブラリアン。裏でメモリを整理する司書役AI)が、できあがった区切りを読んで要約を書き、別のデータベースに溜める。MONETは返事をするたびに、TI(Timeline Index。会話の歴史年表。過去の会話の要約を1行ずつ並べた索引)を読んで、前に何があったかを知る。中身まで要る時だけ、要約の本文を取り出す。書く人と読む人が別にいる分業になっている。
この仕組みとMONETは、いずれ家のNAS(家に置いてある常時稼働のサーバー)に載せる。ただ、それを待たずにMacで使い始めていい、と少し前に決めていた。この日決めたかったのは、Macでどこまで作ったら開発の手を止めて、毎日ふつうに使い始めるか。
まず、どこまで作ったら開発を止めるかを決めた
完璧主義で作り込み続けないように、止める線を先に引いておきたかった。
コーディングしてくれているClaude Code(以降Code)が出した線の引き方はこう。毎日使えて、記憶が意味を持って貯まっていく、その最低限のところまで作る。それより細かい調整は、実際のデータが無いと正しくできない。だから開発中は触らずに、使いながら様子を見る。
Codeが部品ごとに、使い始める前に要るものと、使いながら見ればいいものを分けた。
じゃあ、もう使い始められる状態なのか。Codeにそう聞いた。
使い始められるかは、文書ではなくデータベースで確かめた
Codeはここまで、進み具合をまとめた文書を読んで答えていた。返ってきたのはこうだった。
Code「正直に言うと、地図を読んだ限りでは使い始められそう。でも、まだ地図しか見てない」
文書の上では、仕組みはできあがっていることになっていた。でも線は「記憶が意味を持って貯まる」ところに引いてある。貯まっているかどうかは、文書を読んでも分からない。Codeは、データベースの中身を直接見に行こうと言った。
僕が知りたかったのは、その日の会話が記憶に入っているかだった。その日もMONETに頼んで、Handler(ハンドラー。タスクとスケジュール管理アプリ)にタスクを追加したりしていた。それはどうやったら調べられるのか、と聞くと、Codeが会話ログと要約の2つのデータベースを開いて、中身を数えた。
分かったことは2つ。
1つ目。要約は、2週間ほど前から1件も増えていなかった。 2つ目。会話ログのメッセージの97%が、どの区切りにも入っていなかった。区切りに入っていない会話は、要約されない。
会話の97%が記憶の外にある。それは本当に穴なのか
Codeが最初に大きく取り上げたのは、2つ目の方だった。会話のほとんどが記憶の仕組みの外にある、これが最優先の課題だ、と。
そんなに大きな穴を、僕らが今まで放っておいたのはなぜだと思う? 想像で決めずに、まず記録を確かめて。Codeにはそう返した。
Codeが仕様書を開くと、はっきり書いてあった。今のバージョンで区切るのは、Handlerなどアプリ操作の会話だけ。雑談は次のバージョンに持ち越し。MONETの横でアプリを開いている間だけ区切る、という前の設計を僕が補足すると、それとも合っていた。
雑談の区切り方についても記録が残っていた。時間で機械的に切るのではなく、AIに意味で判断させたい。そう考えて、僕自身が保留にしていた。
97%は、壊れている所の数字じゃなかった。決めて後回しにしている分の量だった。
そうなると、残るのは1つ目の、要約が2週間増えていない方。区切りはできているのに、要約されていない。
要約が2週間増えなかった理由
Librarianがどういう動き方をするのか、Codeがプログラムを読んで確かめた。
LibrarianはMONETとは別に動く。MONETが会話ログを書き、Librarianは後から、できあがった区切りを拾いに行く。だから、MONETと話している最中にLibrarianが動いている必要はない。ただし、誰かがLibrarianを起動しない限り、要約は1件も増えない。
最後にLibrarianが動いたのは、手で動かした時。それ以来、誰も起こしていなかった。会話ログはその日も書かれていて、区切りもできていた。拾う人だけがいなかった。
Librarianができあがった時点で、5分おきに区切りを見回り続ける動かし方も作って、動くところまで確かめてあった。さっきの流れの、「できた区切りを拾う」所を受け持つのがこの見回り。ただ、それをどのマシンで、どういう形で動かしっぱなしにするかは決めずに、次の課題として残していた。
「記憶が意味を持って貯まる」の手前で抜けていたのは、この1点だった。区切りを拾うLibrarianを、動かしておく人も仕組みも無い。
見回りを動かすと、止まっていた要約がまた書かれた
Codeが、Librarianを起動するスクリプトを2本書いた。溜まった区切りを一度にまとめて要約して終わるものと、5分おきに見回り続けるもの。
見回りの方を起動すると、要約のデータベースに1件増えた。前に手で動かした時に要約された分を除くと、残っていた区切りは1つだけだった。中身は、僕がMONETに頼んでHandlerに追加したタスク。見回りの1回目が、それを拾って要約した。
僕がMONETに話す。区切りができる。見回りがそれを見つけて、Librarianが要約する。これまでLibrarianは、誰かが手で動かした時にしか要約しなかった。今度は見回りを一度立ち上げただけで、この流れが最後まで回った。要約が書かれ、MONETが次に返事をする時に読むTIに載った。
この日、コードとして増えたのは起動用のスクリプト2本だけ。見回りをどのマシンで動かしっぱなしにするかはまだ決めていないし、雑談を区切る仕組みもこれから設計する。それでも、開発を止める線の手前で抜けていた1点はふさがった。見回りが動いている間は、話した分が区切りになるたびに拾われて、記憶が貯まっていく。