1953年、ヘンリー・モライソンは、自分に起きたことを何も思い出せなくなりました——どんな会話も彼にとっては「初めて」だったのです。あなたのコーディングエージェントにも同じ状態が起きます。
すべてのセッションは最初からやり直しです。エージェントは毎回オンボードされる必要があり、あなたがその埋め合わせをしていくことになります。
修正は、まずヘンリーの記憶で何が間違っていたのかを理解すれば、簡単に設計できます。
Brute Force Doesn't Scale
正直に言えば、エージェントに記憶を与える必要はありません。総当たりで良い結果に到達することはできます。リトライループ、修正のためのプロンプト、タスクの言い換え、そして増え続ける指示ファイル……それらがあれば、いずれは辿り着けるかもしれません。
でも、それが目標であるべきではないのでは?
それはコストが高く、信頼できず、さらにコンテキスト・ロト(context rot)を引き起こします。
また、あまりにも単純化されすぎています。正しさは成功の唯一の尺度として使うべきではありません。不要なやり直しは時間とお金を消費し、そして何より、私たちが重要視すべき「忍耐」を奪います。
目標は、最終的に成功することではあるべきではありません。最小コストでの、継続性と「決定論的で再現可能な」アウトカムこそがあるべき姿です。
What Is Memory?
私たちは皆、記憶を直感的に理解していますが、その仕組みは思っている以上に複雑です。分解してみましょう……
記憶とは、情報を必要なときに符号化し、保存し、取り出すことです。
主な種類は3つあります:
短期記憶
これは感覚情報で、脳が「符号化して保存するのに十分関連しているか」を判断しながら、約30秒ほど維持されます。ここで触れるのは完全性のためですが、以降は再登場しません。エージェントが苦手とする領域ではありません。
長期記憶
これは、長い時間の間に符号化され、保存され、再び取り出し可能にされた情報です。重要なのは、区別すべき2つのサブタイプです。宣言的記憶(事実や出来事)と、非宣言的記憶(スキル、習慣、プライミング)です。
作業記憶
これはとても重要です。というのも、作業記憶は脳の作業場であり、タスクを達成できるようにするものだからです。情報を操作し、長期記憶に強く依存しています。作業記憶がなければ、知識としては知っていても、それを適用できません。
| ℹ️ |
|---|
| ここで提示する概念は、認知神経科学の研究から薄めたものです。脳は非常に複雑で、ここでは扱わない多くのニュアンスや、さらに多様な種類の記憶があります。ここで提示する内容は、真実であることが知られており、この記事の目的には十分です。より深く掘り下げたい人のために、最後に情報源のリストを掲載しています。 |
The Tools of Working Memory
つまり、作業記憶がタスクの達成を可能にし、長期の宣言的記憶がその機能に不可欠です。しかし、それだけではありません。
さらに、現在の目標に対してどの情報が関連しているかを判断し、そうでないものをふるい落とすための制御プロセスも必要です。
作業記憶の機能を助ける制御プロセスには、さまざまなモデルがあります。ここで関係するのは次のものです:
中枢実行系(central executive)
これは作業記憶の制御中枢です。注意を調整し、目標を選び、目の前の課題に対してどの情報が関連しているかを決定します。
トップダウン処理(top-down processing)
これは、先行する知識を引き出して、新しい情報を統合し、意味づけする能力です。そこから抜けている部分を埋め、推論し、そして私たちが知っていることを新しい状況に適用できます。
エピソードバッファ(episodic buffer)
これは、異なる情報源からの情報を結び付けて、筋の通った作業状態として一体化する一時的な保存システムです。長期記憶からの情報、感覚入力、そして他の認知プロセスからの情報を統合することを可能にします。
作業記憶は単一のメカニズムではありません。これらのプロセスが連携して働き、情報を目的のために取り出し、選別し、結び付けることで生まれます。
The Case of Henry Molaison
これがヘンリー・モライソンです。27歳のとき、重度のてんかんを治療するために側頭葉の一部と、海馬の大部分が摘出されました。
手術後もてんかんは残りましたが、新しい長期の宣言的記憶を形成する能力を失いました。既存の記憶はすべて無傷のままでした。興味深いことに、新しいスキルを学ぶ能力は残っていましたが、新しい宣言的記憶を確実に符号化することはできませんでした。
彼は行動することはできましたが、手術後に起きた事実や出来事を思い出すことはできませんでした。出会うたびに、課題に取り組むたびに、すべてがゼロから始まる——蓄積されたコンテキストもなく、頼れる事前知識もありません。
ヘンリーは有能でしたが、常に最初からやり直していました。
聞き覚えはありませんか?
エージェントは目の前のタスクを実行できます。欠けているのは能力ではなく、セッションをまたいだ宣言的な継続性です——何が決められたのか、なぜそれが決められたのか、どんな制約があるのか、そしてその後の目標にとって何が重要なのか、ということです。
エージェントは目の前のタスクを実行できます。欠けているのは能力ではなく、セッションをまたいだ宣言的な継続性です——何が決められたのか、なぜそれが決められたのか、どんな制約があるのか、そしてその後の目標にとって何が重要なのか、ということです。
Agent Amnesia
そういう意味で、コーディングエージェントはヘンリーによく似ています。
彼らの長期記憶は、学習時に与えられたデータと、SKILL.md および AGENTS.md を通じてあなたが提供する非宣言的記憶に限られています。しかし、確実に知識を蓄積したり、必要になったときに後で取り出したりできません。なぜなら、事実や出来事に関する構造化された宣言的記憶がなく、それらの記憶を効果的に使うための制御プロセスも欠けているからです。
プロジェクトに関する長期の宣言的記憶がなければ、エージェントの記憶はヘンリーと同じくらい損なわれてしまいます。
エージェントの健忘は本物です。
The Missing Primitive
エージェントにナレッジグラフを渡して「これで終わり」とするだけでは不十分です。作業記憶を機能させる制御プロセスが、まだ欠けているからです。これらのプロセスが、記憶の定義における「必要なときに(when needed)」の部分です。それがなければ、エージェントは自力で何とかするしかなくなり、コンテキストウィンドウが膨張しがちになります。
保存された情報を取り出し、何が重要かを判断し、残りをふるい落とし、それらを組み立てて、作業記憶に投入するための仕組みが必要です。
最後に、これらすべての部品を取りまとめる「何か」も必要です。それがゴール——まさにこれらのプロセスが果たすよう意図されているものです。
Why Do I Need a System?
厳密に言えば、システムは必須ではありません。現時点で実務としてよく使われる代表的なアプローチが2つあります。
1. 手動のキュレーション
あなたは、不変条件、ガイドライン、コンポーネント、制約、意思決定ごとにマークダウンのファイルライブラリを用意し、そのうえで各セッションの前に、関連するものだけを選んでプロンプトに貼り付けます。
これは、本来エージェントが出力したコードをあなたが出荷する前に読むことに使った方がよいほど、多くのエネルギーと注意を消費します。
2. 投げ込み(ダンプ)
修正はすべて、ルールはすべて、プロジェクト履歴の注記はすべて、AGENTS.mdファイルに丸ごと投げ込まれます。しかし、ある文脈での修正は普遍的ではありませんし、無関係な文脈は、導いてくれる以上に注意を散らします。
Christopher Meiklejohn は、その道がどこへ至るかを説明しています。繰り返される退行、不測の事態に対する応急処置、そして、新しい失敗が起きるたびに別のルールが書き足され、どんどん大きくなるCLAUDE.mdです。この文書は、エージェントの挙動を変えるための信頼できる仕組みではなく、インシデントの記録に堕ちていきます。
一方は、反復的な手動組み立てに依存していて、抜け漏れのリスクがあり、作業そのものから注意を奪います。もう一方は、関連性が崩壊するまで文脈を抱え込みます。どちらにも欠けているのは、適切なタイミングで、正しい文脈を取り出して提供する自動化されたシステムです。
利点は、システムがより多くの情報を保持することではありません。反復的な手作業ではなく、再利用可能な目標駆動のプロセスへと、取り出しとスコーピングを移すことにあります。
System Design
このシステムの構成要素は、認知モデルから直接マッピングできます。
| 認知上のニーズ | システム実装 |
|---|---|
| 非宣言的記憶 | 再利用可能な運用手順とプロトコル(SKILL.md、AGENTS.md) |
| 宣言的記憶 | 事実、出来事、関係のための構造化された記憶ストア |
| 結び付け機構 | 目標エンティティと関係グラフ |
| エピソードバッファ | 目標スコープの文脈アセンブリ |
| 中央実行系(Central executive) | 目標オーケストレーション層(バックログ、状態モデル、ルーティングルール) |
| トップダウン処理 | 目標駆動の取り出し、優先度付け、関連性フィルタリング |
これらのマッピングは、排他的な担当者を示すものではなく、機能上の責務を表しています。実装によっては、開発者、オーケストレーション層、そして1つ以上のエージェントが、さまざまなフェーズにわたってこれらの責務を分担することもあり得ます。
要するに、正しいタイミングで正しい文脈を提供する、目標駆動のメモリシステムと、行動のための信頼できる出発点が得られます。
From Goal to Action: A Memory Cycle
これは単なる部品の寄せ集めではありません。目標を中心にした機能サイクルです。各フェーズはそれぞれ独立したセッションで実行することをおすすめします。
1. 定義(Define)
目標が記述されます。これは、目的、成功基準、スコープの提示にすぎません。それ以上のものはありません。ここで重要なのはミニマリズムです。加えて、文言の完璧さ。
また、開発者としてあなたが最も注力したいのもここです。これが、継続性を維持する方法です。エージェントを絶えず立ち上げ直すのではなく、自分が何を作っているのかを考えることに、ここで時間の大半を使いたいはずです。
2. 洗練(Refine)
関連する長期記憶が取り出され、関係として目標に結び付けられます。不変条件、ガイドライン、コンポーネント、意思決定、依存関係です。このフェーズでは無関係な情報もフィルタリングされるべきです。そうしないと文脈が腐ったり、エージェントの注意を逸らしたりします。
その結果、目標に合わせてフィルタされ、スコープされた文脈パケットが得られます。これは、トップダウン処理、長期記憶の取り出し、そしてエピソードバッファが一緒に働くことで実現します。
このフェーズの仕事は、目標を解決することではありません。解決が確実になるように、そのための文脈を組み立てることです。
3. 実行(Execute)
セッション開始時、エージェントにはプロジェクトの状態についての小さなオリエンテーションパケットが渡されるべきです。これにより、目標固有の作業が始まる前に、安定した出発の枠組みが提供されます。
目標が選ばれたら、オーケストレーション層がその時点の状態を解決し、どの文脈を提供すべきかを決定し、Refine で組み立てられた目標に結び付いたパケットを配信します。このフェーズの目的は、重要なものを再発見することではなく、すでに目標のために組み立てられた文脈を適用することです。
新しい情報が出てきたら(修正、制約、発見など)、それは失われる前に長期記憶へと整合させられるように、必ず取り込まなければなりません。
ここが中央実行系とトップダウン処理の中核です。アクティブな目標を選び、重要なものに注意を絞り、進行中の作業に先行する知識を適用します。
4. レビュー(Review)
結果は、実行を導いたのと同じ目標文脈に照らして評価されます。成功基準を満たしたか。不変条件を守ったか。目標は、フィードバックとともに承認または却下されます。
これは「だいたい(ish)」のための安全網です。批評家は「ハルシネーション」を致命的な欠陥だと指摘しますが、メモリ駆動のシステムでは失敗が謎であることは稀です。もしRefineが誤った記憶を取り出してしまったなら、Executeは必然的に(決定論的に)失敗します。Reviewは、その失敗を捕捉する制御プロセスです。つまり、プロジェクトで確立された記憶に照らして、エージェントの作業を検証します。
このモデルでの却下は失敗ではありません。シグナルです。問題はメモリとしてシステムにフィードバックされるべきで、以降の目標や、現在の目標におけるブロッカーとして反映されます。
5. 成文化(Codify)
このフェーズは帳簿づけのように考えられます。ドキュメントを更新し、新しいコンポーネントをメモリにコミットし、変更内容をCHANGELOGに記録します。
各フェーズは繰り返し可能なやり取りです。つまり、各フェーズは非宣言的なスキル定義の候補になり得ます。すなわち、サイクルを通過したあらゆる目標に対して一度符号化して再利用できる、システムの使い方のためのプロトコルです。
これは単純なワークフローではありません。反復のたびに、システムが前回より賢くなっていくようなサイクルです。
Structure Still Matters
メモリを追加することは非常に役立ちますが、それでもコードベースが適切に構造化されていること、そしてSDLCのベストプラクティスに従うことが重要です。
クリーンコード、SOLID、関心の分離、共通のクロージャ、DDD、クリーンアーキテクチャ、そして確立された設計パターンの活用――これらは儀式ではありません。エージェントにとって、解決策を読みやすくします。
幸いなことに、これらはシステムを整えたときに、そのメモリシステムへ組み込むことができます。そして組み込むべきです。リスコフの置換原則(Liskov Substitution Principle)は、多くのフロントエンドのタスクに対してはほとんど関係しないはずなので、毎回のセッションで腐った状態として現れてしまうAGENTS.mdに載せるべきではありません。しかし、それは長期記憶に載せるべきであり、目の前の目標に関連するタイミングで取り出せるようにすべきです。
エージェントと働くのは新しいパラダイムであり、新しいスキルが必要です。目標を小さく保つこと、セッションを独立させること、そして出荷する前にコードを読むこと――これらがすべて、あなたを大いに前に進めます。
| これらの点の有益さについては、多くが書かれています。とはいえ、ここで強調する価値があると思います。というのも、メモリは万能薬ではないからです。メモリは、エージェントで良い成果を実現するために不可欠なソフトウェアエンジニアリングの原則とベストプラクティスを補完します。 |
Closing
ここまでで多くのことを扱いました。エージェントの健忘の問題、メモリの認知モデル、この問題を解くためのシステム設計、そしてそのシステムを使って機能するメモリサイクルを作る方法です。
少なくとも、この記事から次の2つの重要な洞察を持ち帰ってくれることを願っています。
エージェントは能力がありますが、メモリがそれに継続性を与え、そして一貫性を保たせます。
メモリは機能ではなく、仕組みです。単にエージェントにより多くの情報へのアクセスを与えることにとどまりません。重要なのは、その情報を取り出し、フィルタリングし、目標に資する形で結び付けるための仕組みを提供することです。
意図的に実装の詳細は省きました。各コンポーネントは、設計上の判断やトレードオフの深い“穴”になり得て、それだけで完結した1本の記事に値します。
これを実装する一つの方法を見てみたいなら、Jumbo CLIを確認してください。これはオープンソースで、まさにこの問題のために設計されています。そうでなければ、本記事が、独自のシステムを構築するための考え方として役立つ枠組みを提供できていれば幸いです。





