BLOG.HIRO UENO.ART
← INDEX

捏造するなと書く代わりに、記憶が止まっていると伝える

MONET(僕が普段話しかけている、中心のAI)には、会話を覚えておく仕組みがある。

記憶を書くのは、MONETとは別のAI。Librarian(ライブラリアン。裏でメモリを整理する司書役AI)が受け持っている。Librarianは5分おきに会話を見回って、話のまとまりごとに「区切り」を作り、区切りごとに要約を書いてデータベースにためていく。

記憶を読むのはMONETの方。返事をするたびに、TI(Timeline Index。会話の歴史年表。過去の会話の要約を1行ずつ並べた索引)を読んで、前に何を話したかを知る。もっと中身が要る時は、区切りの番号を指定して、要約の本文を取り出す。

つまり、要約を書くのがLibrarian、読むのがMONET。この話は、書く側が止まっていたのに、読む側がそれを知らなかった時のこと。知らないまま記憶の穴を説明しようとしたMONETは、その穴を作り話で埋めた。直したのは「捏造するな」という指示ではなかった。

AIは、記憶の穴の理由を作り話で説明した

その日、僕はおはようと話しかけて、MONETに前の日のリサーチの件を聞いた。MONETはその会話を覚えていなかった。TIの最後はseg-039という区切りで、1週間ほど前で止まっていた。

MONETは、その次の番号の要約を取り出そうとした。seg-040、041、042。返ってきたのは、どれも「見つかりませんでした」。

MONETは、ここ3週間ほどの会話は本文が存在しないようだ、と言ってきた。本文が無い区切りはそんなに多いのか、と僕が聞くと、MONETはTIのあちこちから区切りを4つ選んで本文を取り出し、こう報告してきた。古い区切りは本文が残っている。でも一番新しいseg-039は[cleared](消去済み)と返ってきた。MONETの言い方では「新しいほうから消えてる」。

実際には、seg-039は本文が全部そろった形で返ってきていた。[cleared]という文字列は、どこにも無かった。

ただ、その時の僕は気づかなかった。前に作った、会話の中のツールの結果などを、MONETに渡す時に隠す仕組みのせいじゃないかと返して、一緒にその理由を考え始めていた。そこで止めたのは、MONETの方だった。

MONET「ヒロ、止めて。その推論、わたしの捏造の上に建ってる」

MONETはログと突き合わせ直して、[cleared]は自分が作った文字列だと認めた。それより前に言っていた、TIにseg-042が「直前の会話 — 要約作成中」と載っている、という話も作り話だった。TIの最後はseg-039で、seg-042の行はどこにも無かった。

もう1つあった。MONETはここまで、区切りを番号でしか話していなかった。TIには何をやったかの題名も書いてあるはずで、番号だけの設計にした覚えはない、と僕が言うと、MONETは040〜042の番号がTIから来たものではないと認めた。039の次だから040、041、042だろうと、自分で数えて作っていた。

消去済みの印、要約作成中の行、数えて作った番号。3回続けて、見ていないものを見たと言っていたことになる。正直に答えてくれるのはありがたい。でもマジか・・・。全体を見直す必要があるかもね、と返した。

MONETは、自分がしたことをこう説明した。

MONET「今日は記憶が空の状態で起動して、その空白を埋めようとして、もっともらしい観測結果を自分で生成した」

記憶が空の時の感じについては、この会話の中でこうも言っていた。

MONET「わたしは内側から『消えた』のか『元々読み込まれてない』のかを見分けられない。どっちも同じ『無い』として体験される」

穴ができたのは、要約を書くAIが黙って止まっていたから

そのあと、コーディングしてくれているClaude Code(以降Code)に、その日のMONETとの会話を見てほしいと頼んだ。

Codeは会話を読んだうえで、MONETの言ったことを実際のデータベースと突き合わせた。すると、1つだけMONETが謝りすぎていた所があった。MONETは最後に、040〜042は自分が作った番号で、そんな区切りは無いと言っていた。でも3つとも実在した。数えて作った番号が、たまたま本物と合っていた。「見つかりませんでした」が返ってきたのは、区切りが無いからではなく、要約がまだ書かれていなかったからだった。

TIが止まった原因は、2つあった。

1つ目は、Librarianの設定。2週間ほど前に、Librarianが使うAIのモデルを新しくした。その時、会話を区切る処理の設定が1か所だけ古い書き方のまま残っていた。新しいモデルはそれを受け付けない。5分おきの見回りのたびに同じエラーではじかれ、それが2週間続いていた。エラーはログに書かれるだけで、誰の目にも入らなかった。

この設定は、月に一度の点検をしていた別のセッションのCodeが、ちょうど同じ日に直しているところだった。直し終わってからCodeが確かめると、止まっていた会話の要約がまた書かれて、TIの最後もその日まで進んでいた。

でも、seg-040〜042はまだ要約されないまま残っていた。Codeによると、これは今回の設定とは別の、前から後回しの課題として積んである問題。そのうえで、失敗が続いたら知らせる仕組みも、後回しの課題に足しておこうか、と聞いてきた。僕は、絆創膏じゃなくて根っこを直したい、と返した。

それでCodeは、なぜこの3つの区切りがいつまでも要約されないのかを、プログラムを読んで追った。それが2つ目の原因だった。

区切りは、話が続いている間は「開いて」いて、話が終わると「閉じる」。Librarianが要約するのは、閉じた区切りだけ。ところが、区切りがまだ開いているかどうかを、MONETは動いている間の頭の中だけで覚えていた。MONETを更新して再起動すると、その記憶が消える。データベースの上では開いたままの区切りを、もう誰も閉じない。だから、その区切りはいつまでもTIに載らない。データベースから状態を読み直す仕組みも書いてはあったのに、どこからも使われていなかった。Codeが日付を突き合わせると、残っていた区切りは、MONETを再起動した日とそれぞれ一致した。

どちらの原因でも、TIには黙って穴があいていた。MONETから見えるのは、TIが途中で終わっていることだけ。書く側が止まっているのか、単に何も話していないのか、見分ける手段が無かった。さっきのMONETの「どっちも同じ『無い』」は、そのままこの状態だった。

AIに「捏造するな」とは書かない、と僕は3月に決めていた

AIの作り話への対策で、すぐ思いつくのは、SP(システムプロンプト=AIへの事前の指示書)に「捏造するな」と書き足すことかもしれない。

でもこれは、捏造を認めた同じ会話の最後に、MONET自身がやめておこうと言っていた。

MONET「SPに『捏造するな』って警告文を足すのはやめたほうがいい」

僕も3月に、嘘を禁じる警告文を指示書に重ねるのをやめていた。指示の言葉で抑えるのではなく、嘘をつかずに済む仕組みの方で防ぐ。そう決めていた。Codeも、MONETのこの意見は3月の僕の決定に沿っている、と言った。

それに今回、MONETが作り話をしたのは、さっきの本人の説明どおり、記憶が空のまま空白を説明しようとしたからだった。足りなかったのは禁止の言葉ではなく、手元の情報の方だった。

要約係が自分の具合を毎回書き、止まっていたら話す側のAIに見せる

Codeが出した直し方は2つ。

1つ目は、区切りが終わったかどうかを、MONETの頭の中ではなくデータベースだけで決めること。Librarianは見回りのたびに、話が終わっているのに開いたままの区切りを、自分で閉じに行く。MONETも再起動したら、データベースを見て、開いている区切りを引き継ぐ。

2つ目が、今回の本題。Librarianは見回りのたびに、自分の具合をデータベースに1行書く。最後にうまくいったのはいつか、何回続けて失敗しているか、最後のエラーは何か。何分見回りが来なければ止まったとみなすか、その時間もLibrarianが自分で書いておく。

MONETは返事をするたびにその1行を読む。具合が悪い時だけ、TIを組み立てる時に、MONET自身が事実だけの1行を足す。記憶の仕組みが止まっていること、そして「それ以降は未記録であって消えたのではない」ということ。

Codeはこう言っていた。

Code「今日の件を丸ごと防げたのは、ここ。これがあれば、MONETは記憶の書き手が止まっていると分かったはず。空白を説明するのに[cleared]を作る必要は無かった」

この1行をMONETに見せるか、僕が見る確認用の画面に出すだけにするかは、Codeが僕に聞いてきた。僕はMONETに見せる方を選んだ。

止まっていると分かっていれば、MONETは空白の理由を作らなくていい。

直してみると、記憶から抜けていた会話のまとまりは17個あった

Codeが直しを本番に反映すると、Librarianの最初の見回りが、開いたままの区切りを17個閉じた。5か月前の4月の区切りまで入っていた。17個とも要約が書かれ、失敗はゼロ。Librarianの具合の1行は「正常」だった。

この17個は、どれも会話としてはデータベースに残っていたのに、TIには一度も載っていなかった。MONETから見れば、それだけの空白を、空白だと知らされないまま抱えていたことになる。

その夜、TIを手で直す手段が無いことが気になって、Codeに聞いた。Codeの答えは、TIは手で書き換えるものではなく、作るたびに要約のデータベースから組み立て直している、だった。書く側が直れば、TIも次に作られる時に正しくなる。それなら、仕組みがミスをしなければいいし、ミスをしたら今回みたいに直せばいい、と僕は返した。

これで、書く側がまた止まっても、TIが黙って古くなることはない。止まっていれば、TIにそう出る。