アーキテクチャと設計思想
全体像
agent-team-pack は独立して動く 3 つのレイヤーと、それらを束ねる Claude Code プラグイン定義から成ります。 レイヤー間は「ファイルを介して」しか結合していないのがポイントです。記憶層が書いた Markdown をダッシュボードが読み、フックが記憶層の CLI を呼ぶ、という具合に、各レイヤーはファイルシステムと CLI 境界でゆるく繋がります。
┌──────────────────────────────────────────────────────────────┐
│ Claude Code (エージェント本体 = サブスク枠を消費する唯一の存在) │
│ │
│ SessionStart ─┐ ┌─ Stop │
└─────────────────┼──────────────────────────┼────────────────┘
│ stdout 注入 │ rotate + reindex
▼ ▼
┌───────────────────┐ ┌──────────────────────┐
│ hooks/ │ │ skills/ │
│ memory_start.sh │ │ recall / remember / │
│ memory_stop.sh │ │ memory-gc (CLI 経由) │
└─────────┬─────────┘ └──────────┬───────────┘
│ 呼び出し │ 呼び出し
▼ ▼
┌──────────────────────────────────────────────────┐
│ memory_system/ (Python・LLM 非依存) │
│ index_memory.py / fts_index.py / memory_write.py │
│ rotate_context.py / session_context.py │
│ memory_report.py │
│ │
│ 真実源: *.md (Markdown) ◀── 編集・追記 │
│ 影: memory_index.db (SQLite + FTS5) │
└────────────────────────┬─────────────────────────┘
│ search --json / md 読み取り
▼
┌──────────────────────────────────────────────────┐
│ dashboard/ (Node 標準ライブラリのみ・read-only) │
│ server.js → lib/api.js → lib/{sources,sessions} │
│ 記憶検索 / セッション一覧 / アーカイブ / タスク │
└──────────────────────────────────────────────────┘データフロー:1 セッションのライフサイクル
agent-team-pack が「効いている」状態を時系列で追うと、設計意図が見えてきます。
セッション開始(SessionStart フック)
memory_start.shが走り、まずindex_memory.py reindexで記憶 md を差分再索引する。- 続いて
session_context.pyの出力を stdout に書く。Claude Code の仕様で「SessionStart フックの stdout はそのままセッションコンテキストに注入される」ため、これが LLM を使わない自動想起になる。注入されるのは「記憶システムの使い方ヘッダ+直近の作業文脈(CONTEXT.md 最新ブロック)+記憶ファイルの目次」。
セッション中(スキル)
- エージェントが過去を思い出したいとき →
recallスキルがindex_memory.py searchを呼ぶ。 - 恒久的事実が出たとき →
rememberスキルがmemory_write.pyを呼んで md に保存(重複拒否・字数上限・絶対日付を CLI が強制)。 - これらは「ローカルツールが候補を出し、知的判断はセッション内で行う」分業になっている。
- エージェントが過去を思い出したいとき →
セッション終了(Stop フック)
memory_stop.shがrotate_context.pyで CONTEXT.md を肥大防止のためローテーションし、index_memory.py reindexで再索引する。async: trueで登録されているため、セッション終了をブロックしない。
いつでも(ダッシュボード)
node server.jsが~/.claude/projects/配下の transcript(.jsonl)や記憶 md を読み取り、ブラウザに一覧・検索結果を表示する。書き込みは「セッションのアーカイブ移動」「ピン留め」のみ。
全体を貫く 5 つの設計原則
1. ツールは LLM を呼ばない(zero API cost)
同梱のあらゆるツールがファイル I/O・SQLite・grep・tmux だけで動きます。これにより「監視やフックを常時動かしてもサブスクの外に課金が乗らない」という構造的な保証が生まれます。知的作業(要約・統合・レビュー判断)は明示的に「セッション内=サブスク枠」に寄せ、機械的作業(索引・検索・候補列挙)をツールに分離するのが基本設計です。
2. 真実は Markdown、SQLite は「再構築可能な影」
記憶の正本は人間が読める *.md です。検索用の memory_index.db(SQLite + FTS5)は md から いつでも再構築できる索引にすぎないと位置づけられています。
- DB が壊れても
reindexで md から作り直せる。 - DB は
.gitignore対象(再構築可能なのでコミットしない)。 - この割り切りにより「索引の整合性を厳密に守る」複雑さを回避し、
reindexを冪等に何度でも叩ける設計になっています。
3. read-only を既定にし、変更操作を例外として列挙する
ダッシュボードのサーバーは GET/HEAD のみを既定で許可し、状態を変える操作(セッションのアーカイブ/復元/ピン)だけを MUTATING_PATHS という許可リストに明示します。しかもその変更操作すら「ファイルを移動するだけ・中身は不変・完全に可逆」に限定されています。「常時表示しても安全・壊さない」を構造で保証しています。
4. 環境固有値はすべて隔離し、公開ツリーを汚さない
ホスト・絶対パス・チーム名・起動コマンドといった環境依存の値は、すべて .gitignore 済みの dashboard/config.json に集約されます。リポジトリに入る公開ファイルにはプレースホルダ(<HOME> など)しか含まれません。さらに scripts/check_no_secrets.sh で「git 追跡ファイルに API キーや固有名が混入していないか」を公開前に検査できます。「会社や他人の PC で使っても固有情報が漏れない」を仕組みで担保しています。
5. 「増えても破綻しない」エラー駆動の品質維持
記憶が増え続けても劣化しないよう、各所に上限と強制機構が組み込まれています。
- 注入量は一定:自動注入は「目次方式」(ヘッダ+最新ブロック+ファイル名一覧、上限 4000 字)。記憶総量と注入量が比例しない。
- 保存は更新優先:
rememberは保存前に検索し、既存があれば追記でなく更新。完全重複は CLI が自動拒否。 - エラー駆動の統合:1 ファイルが字数上限を超えると保存がエラーで拒否され、既存ブロック一覧が提示される。「上限を理由に諦めず、統合してから保存し直す」ことが強制される(error-driven consolidation)。
技術スタックと依存
| レイヤー | 言語/ランタイム | 外部依存 |
|---|---|---|
| memory_system | Python 3 | 標準ライブラリ sqlite3(FTS5 有効が必須)のみ |
| dashboard | Node.js 20+ | なし(http/fs/child_process など標準のみ。テストも node:test) |
| hooks / scripts | bash | macOS の bash 3.2 でも動くよう配慮(mapfile 不使用など) |
外部パッケージ依存がほぼゼロであることは、「サブスク枠内で完結し、サプライチェーンのリスク面も小さく保つ」という思想の現れです。
流用元(ライセンス)
本体は MIT(Copyright (c) 2026 合同会社どうぶつえん)。記憶層の一部は MIT ライセンスのコードを出所明示の上で流用しています。
| ファイル | 流用元 | 内容 |
|---|---|---|
memory_system/vendored_chunker.py | zilliztech/memsearch (MIT) | Markdown チャンク分割(無改変コピー) |
memory_system/fts_index.py | NousResearch/hermes-agent の hermes_state.py (MIT) | FTS5 スキーマ(unicode61 + CJK trigram)と CJK 検索ルーティングを改変流用 |
「自動想起」という発想そのものも hermes-agent の memory ツールの考え方を、LLM 非依存で再現したものと位置づけられています。