セッションが切れると全部消える
LLMを使った開発で一番もったいないのは、セッションが切れるたびにコンテキストがゼロに戻ることだと思っている。
前回のチャットで「VueをやめてHTMXにする」と決めた。理由も、検討した選択肢も、全部話した。でも次のセッションではAIはそれを知らない。人間がもう一度説明するか、過去ログを貼るか、あるいは諦めてゼロから話し直す。
プロジェクトが1つならまだいい。自分の場合は個人開発のプロジェクトが 20 以上あって、それぞれに仕様と設計判断と進捗がある。さらにClaude Code、Codex、OpenCodeなど複数のエージェントツールを試していた時期は、毎回「このプロジェクトはこういう構成で、前回ここまでやって、次はこれをやりたい」と説明するのがかなり苦痛だった。
セッションごと、エージェントツールごとで情報を共有できる場所がほしくて、既存のツールをいろいろ試した。
既存ツールでは足りなかった
最初はローカルのMarkdownファイルで管理していた。プロジェクトのドキュメントをGitで管理する一般的なやり方で、ある程度は機能したが、プロジェクト間の情報参照がしづらいのと、チャットツールからアクセスできないのが不満だった。
次に Notionを試した。MCP経由でチャットツールからもアクセスできるし、人間もWebで読み書きできる。構成としては悪くなかった。ただ使い込むとMCP経由で取得する時のレイテンシやトークン消費が気になるようになった。特にまとめて複数ページを更新する場面では結構待たされる。Notionはもともと人間が読み書きするために設計されたツールなので、AIのアクセス効率が前提になっていないのは仕方ない。
Obsidianも検討した。ローカルMarkdownでツールロックインがなくClaude Codeからはアクセスできるが、Claude.aiなどのチャットからローカルファイルにはアクセスできない。GitHubリポジトリ + GitHub MCP は当時チャット側にコネクターがなかった。
要するに、チャットアプリからもCLIのエージェントからもアクセスできて、AI向きに軽い構造のものが見つからなかった。どうせ自分しか使わないなら自分で作るか、と思って作り始めたのが Context Mixer だ。Hono on Cloudflare Workers + D1(SQLite 互換)+ R2 という構成で、Cloudflareの無料枠内で動くのでランニングコストはほぼゼロ。
KarpathyのLLM Wikiパターン
作り始めてしばらくしてから、Karpathyが公開した「LLM Wiki」パターンを知った。RAGのように毎回ドキュメントの断片を検索するのではなく、LLMがソースを読んで構造化されたwikiを自分で構築・維持するというアプローチで、公開直後から大きく話題になったらしい。
自分がやろうとしていたことを綺麗に言語化してくれた感覚があった。ただKarpathyのパターンは「ローカルの Markdownファイル + コーディングエージェント」で完結する設計で、個人の研究ノートには向いているけど自分のユースケースとは少しずれる。
自分の場合は:
- アクセス元がチャット(Claude.ai)と CLI(Claude Code)の両方
- プロジェクトが 20 以上ある
- 書き込みの8割はAIで、人間もWeb UIでたまに確認・編集する
LLM Wikiが「読んだものを蓄積する図書館」だとすると、自分が必要だったのは「進行中のプロジェクトをAIと一緒に管理する作業場のホワイトボード」のようなものだった。
取得の粒度を選べるようにした
ContextMixerの設計で最初に考えたのは、AIが「どこまで読むか」を選べるようにすることだった。
NotionのMCPだとページを指定したら中身が全部返ってくる。でもAIがまずやりたいのは「このドキュメント、今の作業に関係あるか?」の判断であって、それにはタイトルと概要の数十トークンがあれば十分だ。
なので取得モードを 4 段階に分けた。
| モード | 返る内容 | トークン目安 |
|---|---|---|
meta |
タイトル + 概要 | 数十 |
outline |
見出し構造 | 数百 |
section |
指定セクションだけ | 数百〜数千 |
full |
全文 | 全量 |
実際の取得の流れはこうなる。たとえば「認証の設計方針を確認して」と指示した場合:
1. list_docs(collection_id) → ドキュメント一覧(各 meta 付き)
2. "spec" が関係ありそう → get_doc(doc_id, view=outline)
3. 「認証」セクションを発見 → get_doc(doc_id, view=section, section="認証")
4. 必要な情報だけ取得完了
Notionなら「specページ丸ごと取得」の 1 ステップで、ページが長ければ数千トークン消費する。ContextMixer だと 3 回の API コールになるけど、合計トークンは数百で済む。
厳密に計測したわけではないが、全文取得前提のNotion MCPと比べるとトークン消費はかなり軽くなるはず。meta → section の2段階で済むケースが大半なので、読む量自体がかなり小さくなる。地味な仕組みだけど、毎日使うものなのでこの差がじわじわ効いてくる。
セッション引き継ぎの構造: AI Cortex
取得の粒度を分けたら、次は「何をどう保存するか」のルールを考える必要があった。
ContextMixer自体はコレクションとドキュメントという汎用的な入れ物で何をどう入れるかはシステムが決めるのではなく、使う側がルールとして決める。自分が作った運用ルールを「AI Cortex」と呼んでいる。
具体的には、各プロジェクトのコレクションに4つのドキュメントを置くルールにした。
- context — 現在のフェーズ、直近の作業、未解決事項、次のセッションへの引き継ぎ
- spec — ゴール、要件、技術構成。確定事項だけ
- decisions — 設計判断の理由と経緯。却下した選択肢も書く
- notes — ライブラリの罠、バグ回避策、実装 Tips
この4ドキュメントを作って、CLAUDE.mdやskillsに「作業開始時はcontextを読め、終了時に更新しろ」と書く。次のセッションのエージェントはそれを読んで続きから始める。
一番効果を感じるのはClaude Codeでの開発で、「前回どこまでやったか」を人間が説明しなくて済む。エージェントがcontextを読んで勝手に作業を再開してくれる。decisionsも地味に役立っていて、「なぜVueをやめたのか」をエージェントが自分で読めるから同じ議論が繰り返されなくなった。
AI に書かせることの難しさ
ただ、AIに書き込みを任せることには難しさもある。
放っておくとAIが勝手に判断をdecisionsに書き込んで、確定事項と検討中の話が混ざることがある。「ユーザー確認なしにdecisionsを作成しない」「specに検討中の内容を書かない」といったルールをCLAUDE.mdで指定して対処しているが、完璧ではない。
似たテーマのドキュメントが重複して作られることもある。書き込み前に検索で重複チェックさせるとか、いろいろ試しているがまだ試行錯誤中。AIにナレッジベースを書かせるなら、書き込み権限より書き込みルールの設計の方が重要だというのが今のところの実感だ。
やってみてわかったこと
この仕組みを運用してきて、ContextMixer 固有の話を離れても言えることが 2 つある。
AI には全文ではなく、読む順番を渡した方がいい
まず、AI への情報提供は段階的にした方がいい。全文を毎回渡す必要はなくて、概要を見せて関係ありそうなら深掘りさせる。この考え方は自前のナレッジベースに限らず、RAG のチャンク設計でもプロンプトの組み立て方でも使える。
セッション引き継ぎは、チャット履歴の要約だけでは足りない
もうひとつは、セッション引き継ぎにはチャット履歴の要約では足りないということ。「前回の判断の理由」や「次にやるべきこと」を正確に渡すには、役割別に構造化されたドキュメントがいる。この考え方自体は Notion でも Obsidian でも使えるが、AI が軽い粒度で探索できて、チャットからも CLI からも同じ場所にアクセスできる環境を最初から前提に設計したのが ContextMixer。
ContextMixerはOSSとして公開しています。
自分がほしかったのは、AI に全部を覚えさせることではなく、AI が必要な時に自分で読みに行ける場所だった。セッションが切れても、エージェントが変わっても、知識がそこにある。今のところ、それが一番現実的な「AI の記憶」の作り方かなと思っている。
Cloudflare の無料枠で動くのでランニングコストはほぼゼロ。セッション引き継ぎに困っている人は、試してみてほしい。
リンク