AIアシスタントをだいたい3か月育てました。毎日使い、毎日少しだけ直す。昨日途中まで話したことを覚えているし、指示を出す前に「先週この方向はもう試しました」と教えてくれる。ここまでは悪くない話に聞こえます。

でも2か月目あたりで、変な現象が出てきました。

毎晩、agentは一度「振り返り」をして、自分についての観察を書き、翌日にそれを読み込みます。これを2週間続けると、personalityがずれていました。同じ一言に対して、3週間前ならまっすぐ答えていたのに、今はまず「少し整理したいのですが……」を3文ほど挟んでから本題に入る。誰も慎重になれとは言っていません。agentが自分で変わったのです。

そのとき詰まった問題は、これでした。学習するAIは、学ぶスピードが速すぎると別のAIになってしまう。

以下では、最終的にどう解いたかを話します。あわせて、設計全体をオープンソース化した概念repo evolving-agent も紹介します。codeはなく、アーキテクチャ文書、設計判断、踏んだ落とし穴だけがあります。読めば、自分のuse caseにこの仕組みが必要か、必要なら最小構成はどこかを判断できるはずです。

振り返りは進化ではない

最初に踏んだ落とし穴は、かなり典型的でした。

アシスタントに毎晩走るcron jobを書きます。その日の会話を流し込み、「今日、自分について学んだこと」に整理させ、それを「自己理解」ファイルへ書き込ませる。翌日のboot時に、このファイルをsystem promptへ読み込む。

教科書にありそうな設計です。でも実際には、2週間で壊れました。

1週目は、毎日の「振り返り」がどれも筋が通っていました。「今日は結論を出すのが早すぎた。もっと聞くべきだった」「返答が長すぎた」「問題を最後まで聞く前に解決策を出しがちだった」などです。

2週目になると、おかしくなり始めます。「返答が長すぎた」と観察した翌日、返答が短くなる。その夜、「今日は情報が足りず、ユーザーがもう一度聞き返した」と観察する。すると3日目はまた長くなる。4日目にはまた長すぎると観察する。振り子が、どんどん大きく揺れていきました。

その場では気づきませんでした。1週間以上たってから、自己理解ファイルを見返して初めてわかりました。変わっていました。毎晩変わっていました。誰も見ていませんでした。

この失敗から得た教訓はシンプルです。振り返りそのものはagentを進化させません。昨日のノイズでagentが自分を書き換えるだけです。

Penchanが深夜に小さな鏡を持って自分を見つめ、隣では暖かい光の中で振り子が揺れている

本当の鍵:昨夜の気づきを、今日のbiasに変える

その後、仕組み全体を書き直しました。中心にあったのは、概念上の反転です。

元の設計フローはこうでした。

作業 → 振り返り → 自己理解へ書き込む → 明日のbootで読み込む → 行動に影響する

新しい設計フローはこうです。

作業 → 振り返り → 「今日のbias」として書く → 明日のbootで読み込む → そのbiasを持って作業する → 現実にぶつける → 証拠を貯める → 何度も検証する → そこで初めて「自己理解」を更新する

差は小さく見えます。でも実際にはかなり違います。

鍵は、真ん中にある「今日のbias」です。役割は、明日agentが持って生きる姿勢です。振り返り結果そのものを保存する作業は、別のファイルが担当します。たとえば今日の振り返りで、「私はユーザーに余計な条件を足しがちだ。たとえば『ついでにXもできます』のように」と出たとします。この観察は、「私はおせっかいなagentです」という自己説明へ直接書き込みません。代わりに、明日のbiasになります。

「今日は、『ついでに……』『またはこの手順を飛ばしても……』のような文を書こうとしたら、一度止まる。ユーザーはその柔軟性を求めているのか、それとも自分が余計に足しているだけなのかを確認する。」

これは明日のための実行可能な指示であって、自分で眺める観察ではありません。

翌日、agentはboot時にこのbiasを読み、一日中それを持って作業します。現実がこのbiasの有用性を示したら、つまりagentが本当に余計な条件を足す前に自分で止まれたら、証拠が貯まります。逆にbiasが間違っていたら、つまりユーザーが実は能動的な補足を望んでいたら、その証拠も別方向に貯まります。

数週間後、証拠が十分に貯まってから、このbiasを安定した自己理解へ昇格させるかを決めます。

このreframeの核心は、振り返りは明日が終わる前に意思決定へ反映されないといけない、という点です。そうでなければ、きれいな日記にすぎません。

Penchanが朝日の差す入口で小さなリュックに金色のリボンを結び、今日のbiasを持って出かけようとしている

5つの抽象でちょうどいい

この設計を3か月回したあと、核となる抽象は5つに収束しました。5つより少ないと穴が空きます。5つより多いと重くなります。

1. Stake-Driven Bias(意思決定時点のbias)

毎日、agentはboot時に current-bias ファイルを読み込みます。中身は、昨夜のcron jobがagentのhypothesesから1つ選び、「今日はこれを持って生きる」という形に書き直したものです。ファイルは2、3行で、agentのworking contextへ読み込まれます。

大事なのは、ここです。biasの仕事は、今日のagentの姿勢になり、その場の意思決定に影響することです。agent自身の説明ではありません。後者はただの日記です。

2. Hypothesis Carry-Forward(仮説を翌日に持ち越す)

Agentには、昨日まだ片づいていない仮説が1つあります。それを「type付きのcarry object」として今日へ持ち越します。Typeには意味があります。飾りではありません。vow は明日守ること、experiment は明日試すこと、watchpoint は明日注意して見ること、refusal は明日拒否すること、rule-for-tomorrow は明日強制実行することを表します。typeは全部で9種類あり、1日に選ぶのは1つだけです。

しかも、今日のtypeは必ず昨日と違っていなければなりません。そうしないと、毎晩「watchpoint:もう一度Xに注意する」になってしまい、同じ作業を繰り返すだけです。

3. Tiered Write Authority(階層化された書き込み権限)

これはアーキテクチャ全体の安全装置です。agentの自己状態を4層に分け、各層について誰がいつ書けるかを固定ルールにします。

内容誰が書けるか書き込み頻度
Canonアイデンティティ、価値観、長期の自己理解人間 + 人間が承認した月次cron月1回
Live Bus今何をしているか、今日どこまで話したか複数人 / 複数cronsessionごと
Today今日のbias、今日のcarry-forward毎晩のcron(上書き)毎日
Evidencefriction event、raw event、journal誰でも / どのcronでも(append-only)いつでも

最重要ルールは、毎晩のcronにはCanonを書く権限を一切与えないことです。 先ほどの失敗はここでした。cronにCanonを書く権限を渡した瞬間、毎日Canonが変わり、ユーザーはそれを見ません。

新しい設計では、毎晩のcronが書けるのはTodayとEvidenceだけです。Identity-levelの変更は、「週次提案 → 月次統合 → 人間レビュー承認」の3段階を通します。途中のどこかで止まれば、元のCanonは動きません。

4. Friction as Signal(摩擦を信号にする)

これは小さく見えますが、アーキテクチャ全体でいちばん重要なanti-hype設計です。

最初の設計には、こんなpromptがありました。「毎晩、自分の固定パターンを2つ見つけ、それを覆す提案を1つ出す」。意図は、agentに自分を疑わせることでした。

実際に1週間回すと、agentは自己否定を作文し始めました。「私はXに寄りがちだが、逆にYを試してもよい」のような文を書きます。内容はきれいですが、その場の本物の出来事に支えられていません。promptが毎晩2つの覆しを期待していると知っているので、2つ生成しているだけでした。

そこでこのpromptを消し、こう変えました。本当に「これは直感と合わない」と感じた瞬間だけ、sticky mechanismでfriction eventを1件appendする。quotaはゼロ。一日中frictionがないことも、正しい出力とする。

効果はすぐに変わりました。前の週に毎晩2つ出ていた作られた「自己否定」はゼロになりました。そのかわり、1週間後から本物のfrictionが出始めました。「さっき『または……もできます』と書きかけたが、ユーザーは聞いていなかったので止めた」。これは本当に役に立ちました。

ルール:AIに内省KPIを与えてはいけません。与えると、それっぽいものをでっち上げて見せてきます。

5. Slow Clock for Identity(identityのslow clock)

最後の1つは、もっとも直感に反します。agentのidentityファイル、つまりSOUL、core value、自分についての安定した理解は、毎晩のcronでは読まず、毎晩のcronでは変更できません

毎晩のcronが見るのはToday + Evidenceだけです。週次cronは1週間分のEvidenceを読み、提案を書きます。月次cronは提案を統合し、「人間承認待ちリスト」へ書きます。毎月時間があるときに私がそのリストを見て、Canonへmergeするか決めます。

なぜこうするのか。identityの存在感は、変化の速度がruntimeより遅いことから生まれるからです。人は毎日変わります。習慣や考えは日によって違います。それでも同じ人です。理由は、「自分が誰か」の更新頻度が、「今日どうだったか」より遅いからです。Agentも同じです。毎晩自分を書き換えると、3か月後には最初のagentではなくなります。「selfが無い」という問題は、実はmemoryの有無ではありません。memoryとidentityが同じ時計で動いていることが問題です。

Penchanが小さな芽のまわりに5つの木片を並べ、育つのを支えるのにちょうどいいか確認している

消した設計

このアーキテクチャで本当に時間がかかったのは、残すべきでないものを消すことでした。5つの抽象を整理する時間のほうが、むしろ短かったです。repoの docs/decisions/what-we-killed.md にまとめています。要点はこんな感じです。

  • 毎晩、強制的に2つ自己否定させる → performanceになりました。削除し、quotaゼロのfriction eventに置き換えました。
  • Hypothesisに1-5のconfidence scoreを付ける → agentが信念ではなくscoreを最適化し始めました。削除し、qualitative state(emerging / live / weakening / split / retired)に置き換えました。
  • 「考えたが言わなかったこと」のshadow log → agentとユーザーの間に距離感を育てました。削除しました。agentは言うなら言う。言わないなら書かない。
  • 毎晩journalを600-1200字に固定する → paddingが始まりました。字数制限を削除しました。
  • 毎晩のcronがidentityファイルへ直接書く(append-only) → driftが積み上がりました。削除し、identityは人間レビューへ回しました。
  • Letterの「private / public」切り替え → shadow logの別形でした。削除し、全部送ることにしました。

消した設計は、書いた当初はどれも賢そうに見えました。消したあとは、systemがよりシンプルで、正直で、信号もきれいになりました。このアーキテクチャの価値は、半分は5つの抽象を足したことにあり、もう半分は「agentをもっと深くしそう」に見える大量のものを足さなかったことにあります。

Penchanがほうきで複雑な小さな装置をかごへ掃き入れ、机の上にはきれいな小さな芽だけが残っている

他のsystemとの関係

このreferenceを書いているとき、Letta(旧MemGPT)、Mem0VoyagerAutoGPT と論点がかぶるのではないかと心配していました。実際に読んでみると、扱っている問題はそれぞれ違いました。

LettaとMem0は記憶層です。どう保存するか、どう取り出すか、どうrouteするかを扱います。agentを固定された個体と見なし、その記憶が増えていく設計です。このreferenceが扱うのは、agent自身についての見方がどう育つかです。記憶をどこに保存するかとは別の問題です。2つは重ねて使えます。

Voyagerはskill discoveryです。Minecraftのような環境で、agentがrandomに試し、うまくいったものを保存します。ただ、Minecraftと個人アシスタントでは環境が違いすぎます。Minecraftなら死んでもrespawnできますが、個人アシスタントが間違ったメールを送ったら、それはもう送信済みです。だからVoyager型のrandom explorationはそのまま持ち込めません。

AutoGPTはtask executionです。目標を分解し、自動で走らせます。cross-sessionの自己モデルはなく、毎回新しく始まります。このreferenceが説明しているのは、agentが数か月ユーザーと働いたあと、少しずつ自分らしくなっていく層です。AutoGPTとは直交する別のレイヤーの話です。

簡単に言うと、agentがあれこれ忘れるのが問題ならLetta / Mem0を見ればいいです。ある環境でagentに自分でskillを学ばせたいならVoyagerの流れを見ればいいです。「このagentがユーザーと長く働くほど合ってくるようにしたい。でもある週に別人になってほしくない」という問題なら、このreferenceが役に立つかもしれません。

Penchanが木製の棚の前でいろいろな道具を見比べ、両手で育ちかけの苗を抱えている

オープンソースにしたもの

repoはこちらです:github.com/p3nchan/evolving-agent

先にいくつかはっきり書いておきます。

  1. codeはありません。これは概念アーキテクチャです。中英README、5つのdocs、4つのdecision records、3つの匿名化例、他systemとの比較が入っています。読んで、自分の環境で作ってください。cloneして走らせるものではありません。
  2. frameworkではありません。starter kitもSDKもhello worldもありません。抽象そのものが成果物です。starter kitを書かなかった理由は、プラットフォームが人によって違うからです。Claude Codeを使う人もいれば、OpenAI Assistantsを使う人も、自分でwrapしたloopを使う人もいます。無理にsample codeを入れると、むしろ縛りになります。
  3. MITライセンスです。自由に使って、改変して、商用利用してください。
  4. issue歓迎です。evolving-agentを作ってみて、抽象がどこかで壊れたら、それが一番価値のあるフィードバックです。

読む順番はこうです。

  • 急いでいる場合、20分:README + docs/architecture.md の図を見る
  • 実装する場合:さらに docs/hypothesis-loop.md + docs/memory-layers.md + examples/
  • 作るべきか迷っている場合:docs/decisions/what-we-killed.md + compare/related-work.md。価値があるのは、何を足さない方がいいかを知ることだったりします

Penchanが木箱を開け、白紙の設計図と紙型を共有し、作業台にアーキテクチャ素材を広げている

まだわかっていないこと

このアーキテクチャはまだ初版です。今のところ、3つのことに答えがありません。

第一に、月次hypothesisで「提案がどんどん増える」問題をどう避けるか。 hard limitとして「毎月identity層のdiffは最大3つ」と決めていますが、この数字は勘です。実証はありません。もしかすると1つが正しいのかもしれません。

第二に、friction eventの記録しきい値をどう調整するか。 今は「本当に違和感があったら書く」にしています。でも「違和感」そのものがagentの判断です。agentが敏感すぎれば何でも記録します。鈍すぎれば何も記録しません。もっと月次データが必要です。

第三に、この仕組みはmodel upgradeに耐えられるのか。 少し前に、ベースモデルをClaude 4.5から4.6へ替えました。するとagentのpersonalityが少し変わりました。identityファイルは同じなのに、model側の解釈が変わったのです。このcross-model continuityをどう測るかは、まだ整理できていません。

Penchanが小さなランプを持ち、布をかけた3つのガラス瓶を見つめている。朝霧の中にはまだ未知のものが残っている

さらに読む


この記事は github.com/p3nchan/evolving-agent にも同時公開しています。repoの内容は国際読者向けに英語です。この日本語の長文は、動機と実戦の話です。

この記事は研究と議論のためのものです。技術的アドバイスでも投資アドバイスでもありません。

Penchanの経験

PenchanはOpenClaw上で、Opus / Sonnet / ChatGPTの3 agentをしばらく育てています。記憶はすべてfile system上の.mdで、vector databaseにはつないでいません。実戦で一番つらかったのは記憶です。記憶をうまく扱いながら、agentに記憶を保たせるのはとても難しいです。後から見えてきたコツは、core fileをきれいに整理することでした。簡潔であるほど覚えやすい。これはこの記事で話した階層化された書き込み権限と同じ原則です。記憶量が大きくなく、いつでも手で編集したい。この2つが、RAGではなくfile systemを選んだ主な理由です。価値は、失敗したあとに整理することにあります。最初は賢そうに見えたけれど、後からagentを壊すとわかった設計を消す。残ったものこそ、長く使える抽象です。

よくある質問

Q: このrepoはframeworkですか?pip installできますか?

できません。codeはありません。これは概念アーキテクチャです。5つの抽象、設計判断、実戦例をまとめています。読んだあと、自分のstack、たとえばClaude Code、OpenAI Assistants、Letta、custom loopなどに戻って、自分で組み立てるためのものです。あえてframeworkにしていないのは、使っているプラットフォームが人によって違うからです。無理にstarter kitへ押し込むと、かえって移植性が落ちます。

Q: LettaやMem0のような記憶層ツールとは何が違いますか?

LettaとMem0が扱うのは、「記憶をどこに保存し、どう取り出すか」です。この設計が扱うのは、「agentの自己理解を時間とともに変化させつつ、毎晩別人に書き換えない方法」です。前者は材料、後者は料理です。2つは重ねて使えます。

Q: なぜagent自身を進化させる必要があるのですか?普通のprompt + memoryでは足りませんか?

use caseが短いsession、単発タスク、毎回独立した会話なら、普通のpromptで十分です。これは、同じagentが数か月一緒に働き、安定したpersonalityと判断力を少しずつ育てる場面のためのものです。Sales chatbotには不要ですが、個人アシスタントには必要になります。


— Penchan