0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Codeに記憶を持たせたらissue→PRが自走し始めた話

0
Posted at

Claude Codeに記憶を持たせたらissue→PRが自走し始めた話

はじめに — Claude Codeは、毎回忘れる

Claude Code は本当に優秀です。設計を相談して、実装させて、テストまで通してくれる。ところが、セッションを閉じた瞬間に全部忘れます

  • 毎朝、同じプロジェクト説明から始まる
  • 先週ハマった罠を、今週もう一度踏む
  • 「昨日のあの方針、なんでやめたんだっけ」が通じない
  • CLAUDE.md に書き溜めても、肥大化してメンテが追いつかない
  • 規模が大きめのプロジェクトだと誤解や瞑想がある
  • 同一セッションに縛られる

単発の作業なら困りません。問題は自動化を積み上げようとしたときです。issueを投げたらPRが返ってくる仕組みは作れても、前回の失敗から学ばない自動化は、同じ失敗を高速に繰り返すだけになります。

そこで、AIエージェント用の永続記憶基盤(Kagura Memory Cloud)を作り、その上に Plan / Build / Verify を分担するCLIツール群を載せました。この記事では、そのエコシステムの全体像と、開発中に起きた 「記憶が12分で蒸発していた」事件 (と修正)の話をします。

解決の核: Kagura Memory Cloud

memory-cloud は、AIエージェント向けのセルフホスト可能な記憶サーバーです(Apache-2.0)。MCPサーバーとして動くので、Claude Code はもちろん、MCP対応クライアントならどこからでも繋がります。

Claude Code ──MCP(45ツール)──▶ memory-cloud ──▶ PostgreSQL + Qdrant + ニューラルグラフ

中身は素朴な「ベクタDB + チャットラッパー」ではなく、使うほど賢くなることを狙った構成です。

機能 内容
remember / recall 知見・決定・失敗を保存し、意味検索で呼び出す
ハイブリッド検索 セマンティック + BM25キーワード(top-1精度 96%)
AIリランキング Ollama(ローカル・無料)/ Voyage / Cohere
Hebbianエッジ 一緒に想起された記憶同士の結合が自動で強化される
Sleep処理 定期的に記憶を整理・統合するバックグラウンド処理

ポイントは下2つです。「cells that fire together, wire together(共に発火する細胞は結合する)」という神経科学の Hebbian 則をそのまま実装していて、検索するたびに記憶グラフが学習します。Sleep処理は人間の睡眠中の記憶整理のメタファで、溜まった記憶の要約・統合・重要度の再評価を裏で回します。

既存アプローチとの位置づけはこうです。

アプローチ 保存 複利(使うほど良くなる) スケール
ベクタDB / RAG チャンク埋め込み なし(取り出すだけ) 任意
Karpathy の LLM Wiki Markdownファイル LLMがページを書き換え 個人(〜100ページ)
Kagura Memory Cloud Postgres + Qdrant + 神経グラフ Hebbian + Sleep チーム/組織

実際に自分のチームの開発で数ヶ月運用していて、現在の本番コーパスは 13ワークスペース、3,527記憶、4,868エッジ、Sleepレポート424件という規模です。この数字、後半の「事件」で重要になるので覚えておいてください。

エコシステム全体像

記憶基盤の上に、コーディング作業を分担するツール群を載せています。

設計思想はシンプルで、共通軸を2本だけに絞りました。

  • brain軸(kagura-brain): headless Claude Code(claude -p)を起動して結果のverdictを返す部分。標準ライブラリのみで実装
  • memory軸(kagura-memory SDK): recall / remember を叩く部分

その上に載る「三兄弟」はそれぞれ単機能です。

ツール 役割 一言で
kagura-planner Plan 過去の決定・既知の罠をrecallして、実装計画を立てて記憶に残す
kagura-engineer Build GitHub issueをPRまで自走させるハーネス
kagura-code-reviewer Verify コードレビュアー。JSON verdictを返す

「全部入りの巨大エージェント」を1個作るのではなく、Plan / Build / Verify を独立したCLIに分けて、記憶だけを共有させる。各ツールは単体でも使えますし、engineerがreviewerをsubprocessとして呼ぶような連携もします。

実例: issueがPRになるまで

一番動きがわかりやすい kagura-engineer の run を見てみます。

uv tool install "kagura-engineer[review]"
kagura-engineer doctor   # 依存チェック(git / claude / gh / ollama / memory)
kagura-engineer run 42   # issue #42 をPRまで自走

:notebook: kagura-plugins経由でskillを登録すればメインのチャットプロンプトから簡単に起動することができます。。基本、github issue drivenでの自走しますので、githubのレポジトリ内で run してください。

run 42 の内部はこういうループです。

guard(環境検証)
  → recall(関連する過去の作業・罠を記憶から取得)
  → worktree(作業ツリーを隔離)
  → start → implement → ship(headless claude -p で駆動)
       └─ レビュー: kagura-code-reviewer が JSON verdict を返す
            green/yellow → 続行、red → 停止して人間にエスカレーション
  → PR作成
  → remember(この run の結果・学びをsavepointとして記憶に保存)

記憶が効いているポイントを3つ挙げます。

1. 開始前に recall する。 過去に似たissueでどんな設計判断をしたか、どのテストが壊れやすいか、といった知見がプロンプトに注入されます。さらに実装フェーズ中も MCP 経由で recall / remember ツールが使えるので、Claude が作業の途中で「これ前にやったことあるか?」を自分で調べられます。

2. レビュワー kagura-code-reviewer は Ollamaにも対応しているので、返ってくるのはMarkdownの感想文ではなく機械可読のJSON verdictで、engineerはそれを見て続行/停止をゲートします。redなら止まって人間を呼ぶ、というHITL(Human-in-the-loop)設計です。

3. 終わったら remember する。 runの結果は記憶に保存され、次のrunのrecallの種になります。クラウド側に障害があっても、書き込みはローカルのwrite-aheadログに退避して次回再送されるので、進捗が消えません。

つまり1回のrunが「過去から学ぶ → 作る → 検証する → 未来に残す」のループになっていて、回すほど次のrunの初期コンテキストが賢くなる——はずでした。

戦記: 記憶が12分で蒸発していた

ここからが本題です。

「使うほど賢くなっているか」を確かめるため、本番コーパスを集計したことがあります。結果がこれでした。

エッジ種別 本数 割合
semantic(意味的類似で自動生成) 4,433 91%
declared(明示的に宣言) 375 8%
hebbian(使用から学習) 61 1.3%

「使うほど賢くなる」の心臓部である Hebbian エッジが、グラフ全体の 1.3% しかない。さらに調べると、もっと不穏な事実が出てきました。

  • 存在する Hebbian エッジは全部、直近33分以内に作られたもの。前日以前から生き残っているエッジが1本もない
  • 一番使い込んでいるコンテキスト(2,292記憶)の Hebbian エッジは 0本

数ヶ月使い込んだのに、学習の痕跡が30分ぶんしかない。記憶グラフの「学習した層」だけが、毎時間きれいに蒸発していたのです。

原因: decay が秒単位で適用されていた

記憶グラフには「使われないエッジは徐々に弱る」減衰(decay)処理があります。問題のコードは1行でした。

decay_factor = math.exp(-self.config.decay_rate * delta_seconds)

decay_rate = 0.001 という設定値を、経過秒数に掛けていました。バックグラウンド処理は1時間ごとに走るので、1回の処理で重みは

exp(-0.001 × 3600) = exp(-3.6) ≈ 0.027   # 毎時97.3%減

半減期に直すと ln(2) / 0.001 = 693秒 ≈ 11.6分。エッジが生き残るには数分以内に同じ記憶ペアが再想起され続ける必要があり、「一度調べて、先に進む」という普通の使い方では絶対に生存できません。

設計意図が日単位だったことは、すぐ隣の設定が物語っていました。

recency_tau_days: float = 14.0  # 2週間の半減期 — 時間の単位は「日」のつもり

おまけにもう1つ。減衰処理のマネージャがタスク実行のたびに作り直されていて、前回実行時刻が常に None。経過時間の計算は実質死んでいて、毎回固定の3600秒ぶん減衰していました。

修正と教訓

修正自体は素直で、「半減期を日単位で明示する」設定に変えました(0.5 ** (delta / half_life_days) の形)。修正後は Hebbian エッジが日をまたいで生存し、再想起のたびに重みが育つことを確認しています。

この事件の教訓は3つあります。

  1. 「賢くなる仕組み」は、入れただけでは動かない。 機能としては数ヶ月間「正常稼働」していました。蒸発に気づけたのは、本番の分布を集計するクエリを数本書いたからです。学習系の機能には「学習が蓄積しているか」のメトリクスが必須でした。
  2. 単位のない設定値は罠。 decay_rate = 0.001 は何も語りません。half_life_days = 14 なら、コードを読まなくても意図がわかるし、秒と日を取り違えようがありません。
  3. 派手なバグほど静かに死ぬ。 エラーは1件も出ていません。検索は正常、保存も正常。消えていたのは「将来の賢さ」だけでした。

学び: 記憶は「保存」ではなく「複利」

数ヶ月運用してみての一番の学びはこれです。

記憶を保存するだけなら簡単で、価値は複利からしか生まれない。

「使う → 結合が強まる → 想起が良くなる → もっと使える」というループが1箇所でも切れていると、どれだけ記憶を溜めても、それはただの検索可能なログです。今回の decay バグは、まさにこのループが切れていた実例でした。

正直に言えば、まだ道半ばです。Hebbian エッジの割合は修正直後でわずか1.3%からの再スタートで、「冷えた状態 vs 温まった状態」で実タスクの成績が変わることの定量証明はこれからです。ただ、測定 → 原因特定 → 修正のループは回り始めました。「AIが使うほど賢くなる」を構想で終わらせず、本番の数字で検証しながら育てていくつもりです。

リンク集

すべて Apache-2.0 / 公開リポジトリです。

質問・ツッコミ歓迎です。特に「記憶の複利」をどう測るかについて知見のある方、ぜひコメントください。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?