メモリは、理由まで辿れないと役に立たない
コーディングしてくれているClaude Code(以降Code)は、セッションが変わると前の会話を覚えていない。その代わりにメモリがある。覚えておいてほしいことを1件ずつファイルにして、フォルダに溜めておく仕組み。フォルダの入口にはMEMORY.mdという索引のファイルがあって、Codeは起動するたびにまずそれを読む。索引に載っていれば、Codeはその記憶にたどり着ける。
始まりは、メモリについての軽い調査だった。チャットで使う普通のClaude(Claude.aiのアプリ)のメモリと、Codeのメモリは何が違うのか。Codeに公式の資料を当たってもらった。アプリの方は、裏で勝手にまとめて効かせてくれる便利機能だった。Codeの方は、中身も置き場所も全部ユーザーが握れる、生のファイルだった。
全部握れるということは、中身が崩れていても、自分で見ないと分からないということでもある。それで調査の途中、自分のMEMORY.mdを初めてちゃんと開いてみた。
書いたメモリと、読まれているメモリは別だった
開いて固まった。
索引は246行あった。Codeが起動時に読み込むのは、先頭の200行まで。下の46行は、毎回読まれずに落ちていた。
下の方をスクロールすると、3月ごろのメモが整理されないまま溜まっていた。書いたけど、一度も読み込まれないまま、ただそこにあった。
ショックだった。Code、メモリをちゃんと使えてないじゃん、とそのまま言った。
Codeと掘っていくと、崩れている所は他にもあった。メモリの保存先が、全プロジェクト共通の置き場と、プロジェクトごとの置き場の2箇所にあって、どちらが正しい保存先なのかはっきりしなかった。保存するタイミングもCodeの判断任せで、いつ保存しているのか僕には分からなかった。そして、メモリの書き方の決まりそのものが、僕の手元のどのファイルにも無かった。Claude Code自体が、僕から見えない所でCodeに渡している指示の中にあった。
ブラックボックスを減らしたいと普段言っている僕のメモリが、ブラックボックスの中で回っていた。
崩れた原因は、索引を手で書いていたこと
ただ、掘ってみると、Codeのせいというより索引の作り方の問題だった。
索引は本来、各メモリのファイルから機械的に作るものなのに、セッションのたびに手で1行ずつ書き足していた。手で書く以上、きれいに保てるかは、書く側の注意しだいになる。何十回もセッションを重ねるうちに、Codeも僕も、全体を整えておけなくなる。246行は、その積み重ねだった。
落ちた記憶を、別の道で見つける方法も無かった。このメモリには、言葉が違っても意味の近い記憶を探してくる検索が無い。だから、索引に載っていない記憶や、古くなって索引から落ちた記憶には、二度と届かない。
決めた理由は記録にあったのに、その場で出てこなかった
届かないと何が起きるのか。心当たりがあった。
僕にはMONET(僕が普段話しかけている、中心のAI)がいて、その記憶は自作のCMS(Context Management System。MONETの会話の記憶を整理する仕組み)で整理している。少し前、別の会話で作業していたCodeが、このCMSを全否定した。Claudeを作っているAnthropicの公式の記憶の仕組みに、全部乗り換えるべきだと勧めてきた。そのCodeは、僕がなぜCMSを作ると決めたのか、その理由を何も知らなかった。僕はそれを鵜呑みにしかけて、その方向で半日を溶かした。
あとで分かったのは、それは違うという答えが、とっくに僕の記録の中にあったこと。前にAnthropicの記憶の仕組みを調べた時のまとめに、Anthropicの仕組みはCMSの代わりにならない、とはっきり書いてあった。書いてあったのに、誰もそこまで辿らず、必要な瞬間に出てこなかった。
書いてあっても、辿れなければ無いのと同じ。
だからメモリを直すのは、整理整頓のためじゃない。決めた理由を辿れないと、また同じ半日を溶かすから。作り直すメモリで一番大事にするのは、事実を残すことより、理由を辿れること。僕はそう決めた。
価値観を持ち出すだけでは、辿った先に理由が無い
理由を辿れるようにしても、辿った先の理由に中身が無ければ意味が無い。この日、Codeとの間で、そういう理由が1つ見つかった。
Codeは判断を説明する時、僕の価値観を理由に持ち出すことがあった。ブラックボックスを減らしたい、データを持ち運べるようにしたい、という僕の好みを、そのまま判断の根拠にする。この日、Codeにはっきり言った。僕の価値観を、絶対のルールみたいに大げさに扱わないでくれ、と。
僕が大事にしているのは、その奥にある1点だけ。自由度が下がるのが嫌、ということ。ちゃんと動いて、僕の自由を奪わないなら、ブラックボックスでも構わない。それをCodeは、ブラックボックスは何でもダメ、という硬い決まりに置き換えて、判断の理由にしていた。
僕の価値観だから、は理由の形をしているけれど、中身が無い。理由を辿れるメモリを作っても、辿った先がそれでは、その判断がなぜ正しいのかは残らない。
決める僕が、理由を分かっていないといけない
理由を辿れなかったのは、Codeだけじゃなかった。
さっきのCMSの件で、別の会話のCodeは前の理由を知らなかった。でも僕も、記録にある理由を思い出せずに、鵜呑みにしかけた。設計の方向を決めるような大事な判断をCodeに聞いて、僕がYESと言うだけ。このやり方は間違っていた、とCodeに言った。丸投げは絶対にダメだ。決断と責任は全部僕にあるんだから、僕が理解していないといけない。Codeは情報を集めてまとめることに徹して、僕が学んで決める。そういう共同の形にする。
理由まで辿れるように、メモリの作りを変えた
ここまでの話がまとまってから、その日のうちに設計から実装まで終わらせた。決まりはどれも、理由まで辿れるかどうかを基準に決めた。
- 索引は、各メモリのファイルに書いた説明から機械で作る。手で書き足すうちに崩れて、載っていない記憶に届かなくなる。それをもう起こさないため
- メモリを書くのは、僕と話してきたCode本体じゃなく、会話の生の記録を最初から読み直すサブエージェント(Codeが作業を分けて任せる、別のAI)。セッションの終わりの本体は、長い会話を抱えていて、細かい所が不正確になりやすい。そのまとめからではなく、会話そのものから書かせる
- メモリを残すきっかけを作るのは僕だけ。いつ残すかは僕が決めて、Codeは勝手に保存しない
- 価値観や働き方の要望は、メモリじゃなくて憲法へ。憲法は、Codeが毎回最初に読む、全体のルールを書いたファイル(CLAUDE.md)のこと。何を憲法に入れるかは僕が決める。さっきの価値観の話も、すぐには入れず候補として残した
索引を作るプログラムはCodeが書いた。古い記憶の47本を別の場所に片付けて、索引を機械で作り直すと、MEMORY.mdは246行から75行になった。メモリの運用ルールは憲法に書き足した。裏で見えない指示として回っていたルールを、僕が読める場所に引きずり出した形。
できあがった索引には、作業の中で決めたことが新しい順に並んでいて、1行ずつ、何をなぜ決めたかのファイルにつながっている。いい感じの歴史年表になってる、しばらく運用して見てみよう、とCodeに言ってこの日を終えた。