小さきことをコツコツと ― 指示を足すより、周りを直す
MONET(僕が普段話しかけている、中心のAI)を作っている途中、この日はメインの作業(MONETの記憶を整理する仕組みづくり)をいったん脇に置いた。MONETのアプリの画面で前から気になっていた小さな不満を、思いつく順に、コーディングしてくれているClaude Code(以降Code)に頼んでいった。
MONETのアプリには、チャット欄の右から出てくるパネルがある。今はほとんどHandler(ハンドラー。タスクとスケジュール管理アプリ)のタスク一覧を出すのに使っていて、あとはTypewriter(タイプライター。代筆アプリ)の下書きも出せる。
溜まっていた不満はこんな感じ。
- MONETが把握している時刻が日本時間とずれていて、しかもMONETの返事の頭に、けっこうな頻度でその時刻が出てくる
- 入力欄の右下に、古いボタンが2つ残っている
- 前はできていたのに、今はできなくなっている機能がある
原因はそれぞれ別だった。でも3つとも、最後に効いたのはMONETへの指示ではなかった。
返事の頭の時刻は、MONETが自分の過去の発言を真似ていた
まず時間。MONETが今の時刻を分かっているのはいい。でもそれは裏で分かっていてくれればよくて、返事の頭にわざわざ書かなくていい。
Codeが調べると、原因は2つあった。
1つ目は単純で、会話を保存しているデータベースの時刻が世界標準時のままだった。MONETには、メッセージごとに「何時何分」の印を付けて渡している。この印の時刻も世界標準時のままだったので、MONETの時計は日本より9時間遅れていた。
2つ目が、返事の頭の時刻。時刻を書けとは、どこにも指示していない。時刻の印は、僕のメッセージだけでなく、MONET自身の過去の発言にも付けて渡していた。MONETは返事のたびに会話の履歴を読み直すので、そこには時刻付きでしゃべっている自分がいる。それを真似て、次の返事にも時刻を書いていた、というのがCodeの見立て。
直し方は2つ。時刻の印を日本時間にする。印を付けるのは僕のメッセージだけにする。これで履歴から真似る元が消える。MONETは僕のメッセージに付いた印で今の時刻が分かるので、時刻の感覚は裏でちゃんと残る。
存在しないツールを使えと頼むボタンが残っていた
次に、入力欄の右下の2つのボタン。どちらも古いもので、今は使っていない。
1つは、MONETにTypewriterを使わせるボタン。同じことはもう右のパネルからできるので、消して終わり。
もう1つはメモリ保存のボタンで、押すとMONETに「このツールで保存して」という指示を送る作りだった。Codeが裏側のプログラムを調べたら、そのツールがもうどこにも無かった。
Code「あのボタンは存在しないツールを使えとMONETに指示してた=ハルシ誘発装置。消して正解。」
ハルシ、つまりハルシネーション(AIが事実と違うことを、もっともらしく言ってしまう問題)。実際、2月にMONETが保存ツールを呼ばずに「保存した」と報告した記録が残っている。あの時の呼び水も、たぶんこのボタンだった。そのボタンが5ヶ月半、ずっと画面に置いてあった。
2つとも消して、入力欄の右下には画像の追加と送信のボタンだけが残った。
パネルを自分で開く機能は、作った翌日に止まっていた
最後の1つは、MONETがパネルを自分で開く機能。会話がタスクの話になったのに僕がパネルを出し忘れていたら、MONETが自分でシュッと出してくれる。前はそれができていたのに、なんでか今はできない。
Codeがプログラムの変更の履歴をさかのぼって調べた。
仕組みはこうだった。MONETが返事の頭に <domain_suggest> という短い合図(目印の文字列)を書く。画面の側がそれを見つけて、パネルを開く。
ところが、この機能を作った翌日に、僕とCodeでSP(システムプロンプト=AIへの事前の指示書)を全面的に作り直していた。その時に、MONETに「この合図を書いて」と教える文言まで消してしまっていた。画面の側の、合図を見つけたら開く仕組みはそのまま残っていた。でも、MONETはもう合図のことを知らない。
Code「『前はできてた』の記憶は正しい——できてた期間が1日だっただけw」
Codeは教える文言をSPに書き戻した。話題に単語が出ただけでは開かない、実際にタスクを触り始めたら開く、という基準も一緒に。
教え直しても、MONETは合図を書かなかった
3日後、パネルを閉じたまま「今日のタスクどうなってる?」とMONETに話しかけてみた。
・・・出さなかった。
Codeが調べると、書き戻した文言は本番のSPにちゃんと入っていた。本番の会話の記録を見ると、MONETはHandlerのツールを呼んで、タスクも正しく答えていた。でも合図は書いていない。
Codeの見立てでは、文言は届いているのに、MONETは合図を書くひと手間を飛ばして、ツールを直接呼んでいた。
ツールを呼んだら、パネルが開くようにした
普通なら、ここでSPの文言をもっと強く書き直すところ。でもCodeはそうしなかった。
Code「文言を強めるんじゃなく、仕組みで必ず開くようにした」
MONETがHandlerかTypewriterのツールを呼んだ瞬間、画面の側がそれに気づいて、パネルが閉じていれば開く。MONETが合図を書くかどうかは関係ない。ツールを呼んだこと自体を、合図の代わりにした。
合図を教える文言も消さずに残した。まだツールを呼ぶほどではないけど話がタスクに近づいてきた、という時は、合図の方でパネルを開けるから。これでパネルが開く道は、合図とツール呼び出しの2本になった。
もう一回、パネルを閉じたまま同じように話しかけた。MONETが「ちゃんと自分で開くね」と言いながらパネルを開いた。
おお、開いた!!
Code「どっちの経路で開いたかはもう見分けつかないけど、どっちでも開くから見分ける必要がないのが、仕組みで必ず開く作りの良いところ。」
時刻は真似る元を履歴から消し、ボタンは画面から消し、パネルはツールを呼んだら開くようにした。少なくともこの3件では、指示を足すより、指示が要らないように周りを整える方が効いた。