3. メモリシステム — 動的なコンテキストをどこに、どのように蓄積するか
RAG でも Vector DB でもない — 数個の markdown ファイルで作るメモリ。4種類のメモリ・インデックス戦略・自動ロードと手動呼び出しの分離、そしてメモリを膨らませない刈り込みの規律。
これは Alice Way シリーズの第3回だ。第2回 ペルソナ設計 では、ペルソナ(「この協働者が誰か」)とメモリ(「この協働者が現在真実として知っていること」)を分離した。この投稿は、そのメモリをどのように構築したかの記録だ。
最初は精巧なものを考えた。Vector DB、エンベディング、RAG パイプライン。数日で全部やめた。実際に一日に積み重なるコンテキストの量はそれほど多くない。必要だったのは 不揮発で、人間が読めて、ツールが自動ロードできる場所だ。答えはファイルシステムだった。
メモリシステムの本質は複雑なインフラではなく規律にあると考える。以前は「高度な技術で解決しよう」と考えていた。いまでは数個の markdown ファイルと単一インデックスで十分なのは、インフラより刈り込みの規律が重要だからこそだとわかっている。
0. メモリは意図の延長
ペルソナが「この協働者が誰か」であれば、メモリは「この協働者が現在頭の中に持っているもの」だ。
消えてしまうコンテキストは、毎日同じ意図の再構築コストを運営者に払わせる。昨日決めたこと、なぜそう決めたか、何がうまくいかなかったか — それがすべて次のセッション開始時に消えていれば、運営者は毎朝昨日の意図から再構築することになる。
メモリは RAG ではない、Vector DB でもない。運営者の決定・フィードバック・コンテキストを次のセッションで失わないための、最もシンプルな仕組みだ。刈り込まずに積み重ねるだけでは崩壊するためだ — 古い情報が生き続けることで誤った判断が生まれる。インデックスが膨張すれば自動ロードが意味を失うというより、メモリがシステムの足かせになる。
§1 以降では、その仕組みがどのように作られたかを扱う — 数個の markdown ファイルと単一のインデックスから。
1. シンプルな決断 — markdown ファイル
収束した構成:
memory/
├── MEMORY.md # インデックス(自動ロード)
├── user_role.md # user タイプ
├── feedback_testing.md # feedback タイプ
├── project_q2_release.md # project タイプ
├── reference_grafana.md # reference タイプ
└── ...- メモリ1件 = ファイル1個
- 全ファイルへの一行ポインタを持つ単一インデックス(
MEMORY.md) - 全ファイルは markdown、人間が直接読める
- ツールはセッション開始時にインデックスの先頭 N 行を自動ロード
これだけだ。凝ったインフラは不要。git で管理、テキストエディタで編集、grep で検索。
実際に毎日積み重なるコンテキストは驚くほど少ない。インフラより規律が重要だ。
2. 4種類のメモリ
すべての情報を同じ種類として扱わない。4種類に分類する。
2.1 user — 運営者に関する事実
運営者が誰で、どんな役割で、どの分野を知っているか。
---
name: user-role-and-expertise
description: Operator's role · expertise · platforms
metadata:
type: user
---
Operator is a senior engineer, primary languages X·Y·Z, mostly works on A·B.
Frontend is recent — explain frontend concepts via backend analogies.このタイプの最大の恩恵は、応答が運営者のレベルとドメインに合わせてチューニングされること。学生トーンが消え、運営者がすでに知っていることを再説明されなくなる。
2.2 feedback — 明示的な指示
運営者からの明示的な指示。「これはやるな」も「これは続けろ」も含む。
---
name: integration-test-policy
description: Integration tests must run against a real DB — no mocks
metadata:
type: feedback
---
Run integration tests against the real DB, not a mocked one.
**Why:** Last quarter the mocked test passed but the prod migration broke.
**How to apply:** Every test under integration/. unit/ may still mock.feedback タイプには、ルールと一緒に必ず Why(なぜ) と How to apply(どう適用するか) を書く。理由のないルールはエッジケースで崩れる。理由があれば、新しい状況でも同じ意図を引き継げる。
フィードバックは失敗後の修正のときも、成功後の確認のときも記録する。後者はスキップされがちだが、スキップすると次のセッションで同じ良い決定をまた一から確認することになる。
2.3 project — 進行中の作業に関するコンテキスト
現在の作業に関する事実。最も変動しやすいタイプ。
---
name: q2-merge-freeze
description: Merge freeze schedule for Q2 mobile release cut
metadata:
type: project
---
Merge freeze begins 2026-03-05 (mobile release branch cut).
**Why:** Mobile team is cutting their release branch.
**How to apply:** Flag non-critical PR work scheduled after that date.重要なのは相対時間を絶対時間に変換することだ。「来週」「木曜日」のような表現はメモリに入れた数日後に意味を失う。「2026-03-05」のような絶対日付に変換して記録する。
project タイプは最も早く古くなるので、最も頻繁に刈り込まれる(§5 参照)。
2.4 reference — 外部システムへのポインタ
情報がある場所へのポインタ。情報そのものではない。
---
name: oncall-latency-dashboard
description: Grafana board grafana.internal/d/api-latency — the oncall latency dashboard
metadata:
type: reference
---
Dashboard to check when touching request-handling code.
Oncall watches this; it's what pages someone, so compare before/after on changes.reference は外部システム(Linear、Grafana、Notion、Slack 等)のある場所に何があるかを記録する。情報そのものは変わる。場所は安定している。場所を覚えておけば毎回探し直さなくて済む。
3. インデックス — 単一の MEMORY.md
全メモリファイルは一つのインデックスを通じて発見される。
# Memory
> First 200 lines auto-load. Core rules live in the persona; this is pointers only.
## Memory file index
### Rules / procedures
- [work-process.md](rules/work-process.md) — work intake procedure
- [multi-agent.md](rules/multi-agent.md) — subagent delegation, Quality Gate
- ...
### Feedback / references
- [feedback/](feedback/) — testing / model_policy / env_minimalism / ...
- [reference/dashboards.md](reference/dashboards.md) — oncall dashboard indexインデックスはメモリではない。メモリへの一行 hook のコレクションだ。インデックス自体はコンテンツを持たない — 常にポインタだけ。
この分離によってインデックスは短く保たれる。ツールがセッション開始時に先頭 N 行だけを自動ロードするとはいえ、すべてのメモリの hook がそこに収まる。特定のメモリが必要になったとき、そのファイルだけをその瞬間に Read する。
インデックス + トリガーベースの Read は、ほとんどのケースで RAG より単純に機能する。
4. 自動ロード vs オンデマンド — トークンエコノミー
システムは二つのロードモードを組み合わせる。
| モード | 何が入るか | いつ |
|---|---|---|
| 自動ロード | MEMORY.md の先頭 N 行 | 毎セッション開始時 |
| オンデマンド Read | インデックスが指し示す特定ファイル | そのファイルに関連する作業に入るとき |
この分離がトークンエコノミーの核心だ。毎セッション全メモリファイルを読み込めばトークンが爆発する。インデックスだけを自動ロードし、本体は必要なときだけ Read すれば、ほぼ全セッションが非常に軽く始まる。
本体を Read するタイミングを決める二つのトリガーがある。
- 運営者が明示的に参照する — 「インテグレーションテストのポリシーを確認して」
- 作業そのものが関連領域に入る — DB 関連の PR を始めると DB 関連のメモリが引き込まれる
二つ目のほうが重要だ。運営者が「このポリシーを見て」と毎回言わなくても、協働者が関連するメモリを自分で引き込む。インデックスの一行 description がその判断の根拠になる。
5. 刈り込み — メモリは増えるだけでは崩壊する
メモリシステムの最大の落とし穴は刈り込まずに蓄積し続けることだ。純粋な蓄積は二つの問題を引き起こす。
- 古い情報が生き続ける — 一か月前に終わったプロジェクトのスケジュールがまだメモリにあり、誤った判断に引きずられる
- インデックスが膨張する — アイテムが 200 行の自動ロード範囲を超え、自動ロードが意味を失う
以下の刈り込みパターンを実行している。
| タイプ | 刈り込み頻度 | 基準 |
|---|---|---|
user | ほとんどなし | アイデンティティはゆっくり変わる |
feedback | 四半期に一度 | 今は適用されない指示を削除 |
project | 月に一度 | 終了プロジェクトをアーカイブディレクトリへ |
reference | 年に二度 | 壊れたリンクと消えたシステムを削除 |
アーカイブは削除ではない。memory/archived/ のような別ディレクトリに移動する。インデックスからは外れるが git 履歴とディスク上には残るので、必要なら引き戻せる。
もう一つのパターンは自動監査ツールだ。定期的にメモリディレクトリをスキャンし、「このアイテムは 60 日以上参照されていない」といったレポートを出力する。運営者はそのレポートを読んで迅速に刈り込みを判断できる。
6. 失敗パターン — 試してやめたすべて
このシステムに至るまでに試して諦めたパターン。
6.1 単一の巨大ファイル
最初はすべてのメモリを一つのファイルに入れた。単一の notes.md。数日以内に 1,000 行を超え、ツールはセッション開始のほぼ全トークンをその読み込みに費やすようになった。
→ 教訓: メモリは分割しなければならない。インデックス + 本体ファイルの分離。
6.2 細かく分けすぎ
反対の失敗 — 細かく分けすぎ。決定一件につき一ファイル。50 ファイルが現れ、インデックスが膨張して自動ロードウィンドウ全体を消費した。
→ 教訓: 一ファイル = 一「トピック」であり、一「決定」ではない。同じトピックに関する複数の決定は同じファイルに入れる。
6.3 無差別な蓄積
セッション終了時に「今日の作業を要約してメモリに追記する」という自動化を試みた。毎日メモリが育ち、重要な決定がノイズに埋もれるようになった。
→ 教訓: メモリに入るのは次のセッションでも役立つ決定・事実・ポインタだけ。今日限りの進捗はタスクボードや履歴ログへ、メモリには入れない。
6.4 メタデータのないプレーンテキスト
最初はプレーンな markdown で frontmatter なしから始めた。数が増えると「これはどのタイプか」「なぜ書かれたか」が追跡不能になった。
→ 教訓: 最低でも三つの frontmatter フィールドを必ず入れる — name、description、type。本文にはさらに二行 — Why(なぜ) と How to apply(どう適用するか)。
7. 実際の効果
このシステムを採用した後に変わったこと。
| 項目 | 導入前 | 導入後 |
|---|---|---|
| セッション開始時のコンテキスト復元 | 5〜10分 | 即時(インデックス自動ロード) |
| 同じ決定の再交渉 | 頻繁 | ほぼなし |
| 昨日の作業の再説明 | 毎回 | なし(メモリにある) |
| 古い情報による誤判断 | ときどき | まれ(刈り込み) |
| トークン消費パターン | 毎セッション一定・高い | 作業の深さに比例(浅い作業は軽い) |
最大の変化は最後の行だ。トークン消費が作業の深さを追跡するようになった。浅い作業はほぼ無料で終わり、リソースは深い作業へ。
8. 一つの原則に圧縮する
メモリシステムの設計は一つの原則に圧縮できる。
「インデックスは常にそこにある。本体は必要なときだけ入ってくる。もはや有効でないものはインデックスから外れる。」
この三つが成立したとき、メモリは増え続ける重荷でなく、作業を加速するアセットになる。
次の投稿では、ペルソナとメモリが指し示す次の層 — Skills と slash commands、すなわちどの繰り返しが一行の呼び出しに格上げする価値があるか — を扱う。