Skip to main content
Glama

firm-memory

このファームがどのようにソフトウェアを組み立てているのかをAIコーディングエージェントに覚えさせるためのメモリレイヤーです。どの呼び出しでも同じことを学び直す、という無駄がなくなります。

CodeGraph は 「このコードは何をしているのか?」 に答えます。 Firm Memory は 「なぜこういう作りにするのか?」 に答えます。

CodeGraph は、現在のコードの振舞いについて、常に正とみなされる情報源です。Firm Memory は、背景となるエンジニアリング知識を保持しますが、古くなる可能性があります。ですので、メモリと現在のコードが矛盾するとき、コードが優先されます。


そのかたち

  OpenCode        On-call        Future agent
      └───────────────┼───────────────┘
                      │  MCP
             ┌────────▼─────────┐
             │  Firm Memory MCP │   thin transport adapter
             └────────┬─────────┘
                      │
             ┌────────▼─────────┐
             │   Firm Memory    │   taxonomy · scope · provenance · lifecycle
             └────────┬─────────┘
                      │  MemoryProvider
             ┌────────▼─────────┐
             │      mem0        │   embeddings · vector search · ranking
             └──────────────────┘

プラットフォームは、ファームメモリが何を意味するかを定義します。プロバイダーは、その保存と取り出しをどう行うかを実装します。MCP は、エージェントがどうアクセスするかを担います。この分離こそがポイントです。OpenCode や MCP の取り決めを変えることなく、第二のプロバイダーを導入できます。


Related MCP server: Agent Memory Control Plane

クイックスタート

pip install -e '.[mem0,pgvector,rerank,mcp,dev]'
export FIRM_MEM0_PG_DSN='postgresql://mem0:pw@db.internal:5432/mem0'
export FIRM_MEMORY_DOMAINS='execution,mcx'      # this repo's domains
export FIRM_MEMORY_CANDIDATES_PATH='.firm-memory/candidates.json'
from firm_memory import FirmMemory, MemoryScope, MemoryType

memory = FirmMemory.from_env()          # scoped to this checkout + its domains + the firm

for hit in memory.search("why does OMS reject orders after 15:20"):
    print(hit.id, hit.content, hit.provenance.reference)

proposal = memory.propose(
    "Cash strategies stop sending at 15:20 because the exchange rejects after that.",
    type=MemoryType.BUSINESS_RULE,
    scope=MemoryScope(domains=("execution",), repos=("oms", "gateway")),
    reference="mr-4821",
)
# Not stored as knowledge yet — it is queued for a human:
print(proposal.accepted, proposal.candidate_id, proposal.decision.reason)

memory.approvals.approve(proposal.candidate_id, approver="ashish")

エージェント向けにMCPサーバーを起動します:

firm-memory-mcp        # stdio; exposes memory_search / memory_get / memory_propose / memory_correct

このパッケージが受け持つ五つのこと

1. 分類体系

プロバイダーが標準で備える抽出処理は、一般消費者向けアシスタント(食べ物、趣味、音楽)向けに調整されています。ここでは、取引システム向けに調整しています。13種類のそれぞれに、抽出を促す説明が付いています。

ARCHITECTURE_DECISION · REJECTED_APPROACH · CONVENTION · REVIEW_PATTERN · BUG_FIX · TASK_LEARNING · TOOLING_SETUP · DEPENDENCY_DECISION · PERFORMANCE_FINDING · BUSINESS_RULE · PRODUCTION_ISSUE · OWNERSHIP · TERMINOLOGY

この分類は、何らかのデータがプロバイダーに到達する前に強制されます。メンバー名である BUSINESS_RULE と、安定したワイヤースラグである business_rules のどちらの表記でも解決されます。

同じくらい大切なのは除外事項です。ソースコード、diff、スタックトレースは保存しない。秘密情報も保存しない。個々のエンジニアに関する事実は保存しない。一時的な状態も保存しない、ということです。

2. スコープ

独立した属性であり、階層ではありません。ファームの知識は、ツリー構造には収まらないからです:

{"firm": true, "domains": ["execution"], "repos": ["oms", "gateway"]}

3つのリポジトリにまたがるメモリは、一度だけ保存され、それぞれのリポジトリから参照できます。意図的にエンジニアレベルもチームレベルもスコープにはしていません。誰がたずねても、同じ質問には同じファーム知識を返さなければなりません。IDの軸を入れると、ひとつの事実が、やがて食い違ってくるコピーへと分裂してしまうからです。

3. ティア

承認の状況とは直交した、再利用期間の軸です。

Tier

内容

タスクスコープ?

EPISODIC

個別MR向けの作業メモリ。発見されたことと、それへの判断

はい(必須)

DURABLE

承認のゲートをくぐって書き出された、蒸留済みの知識

対象外

INDEX

クローズしたissue/MRごとに、原文のままのカードを1枚、ドキュメントの形体で保持する

対象外

検索はデフォルトで EPISODIC を除外します。このデフォルト設定には重みがあります。ベクトルストアにとって、タスクフィルタが存在しないことは 「気にしない」 を意味し、「未設定」 を意味しません。つまり、このデフォルトがないと、あらゆるMRの作業途中の状態が通常の検索結果に混ざってしまいます。この動作を検証する契約テストがあります。

4. 来歴とライフサイクル

すべてのメモリは、どこから生じたのかを保持しています。エンジニアは、その引用の根拠を、背後にあるMR・issue・インタビューまで辿って確認でき、そして修正もできます。

Candidate ─► taxonomy / scope / provenance checks ─► human approval ─► provider.insert()

初版はすべて人の承認が必要です。信頼度は最初から記録されるため、後で自動化を有効にしても、マイグレーションは不要です。ビジネスルール、アーキテクチャ決定、社内の慣習、本番に重大な知識は、信頼度にかかわらず常に人の承認が必要です。

何も削除されません。 修正は、メモリを降格させ、フラグを付けます。後継があるときは、その置き換わる対象を明示します。決定がなされたこと、そしてそれが取り消されたこと自体の記録は残り続けます。

5. 信頼性

メモリはベストエフォートです。読み出しは例外を投げません。プロバイダーの障害や制限時間の超過があった場合は、空の結果と記録済みのメトリックを返すだけで、呼び出しの失敗がコードレビューを失敗させることはありません。書き込みは例外を投げます。承認したばかりのメモリを黙って捨てるのは、エラーにするより悪いからです。


設定

プラットフォームの設定はプロバイダー非依存であり、プロバイダーの設定はプロバイダー自身が読み取ります。この分離があるからこそ、プロバイダーの切り替えが単なる設定変更で済みます。

変数

デフォルト

意味

FIRM_MEMORY_PROVIDER

mem0

使用するプロバイダー

FIRM_MEMORY_LIMIT

5

1回の検索で返す結果数

FIRM_MEMORY_MIN_SCORE

0.3

関連度の下限

FIRM_MEMORY_TIMEOUT_SECONDS

2.0

諦めるまでの制限待機時間

FIRM_MEMORY_DOMAINS

—

このチェックアウトが属するドメイン

FIRM_MEMORY_REPO

(git remote)

リポジトリのスラグを上書きする

FIRM_MEMORY_CANDIDATES_PATH

(プロセス内)

提案が人の承認を待つ場所

FIRM_MEMORY_AUTO_APPROVE

off

信頼度に基づく自動承認

FIRM_MEM0_PG_DSN

必須

pgvector の接続文字列

FIRM_MEM0_COLLECTION

mem0_firm

コレクション名

FIRM_MEM0_POOL_OWNER

firm

プールを指す user_id

FIRM_MEM0_RERANK

on

ローカルcross-encoderによる再ランク付け

FIRM_MEM0_REPO、FIRM_MEM0_TOP_K、FIRM_MEM0_THRESHOLD、そして FIRM_MEM0_FIRM_OWNER は、既存環境を変えない配慮で引き続き尊重されます。

デプロイは自己完結となり、外部への送出はありません。"MCX注文は常にRisk Engine Aを経由する" のようなビジネスルールは、コードのコメントというよりも戦略的財産に近いものです。このプールには、そこへデータを送るすべてのリポジトリのアクセス制御の合集合が継承されます。


レイアウト

src/firm_memory/
├── models.py          canonical Memory · status · tier
├── taxonomy.py        the firm's vocabulary and its exclusions
├── scope.py           firm / domains / repos
├── provenance.py      where a memory came from
├── lifecycle.py       approval policy and status transitions
├── memory.py          the API agents and applications import
├── config.py          platform settings
├── metrics.py         failure and latency counters
├── repo.py            deterministic repo identity
├── providers/
│   ├── base.py        the interface: insert · search · get · update
│   ├── registry.py    configuration-driven selection
│   ├── inmemory.py    dependency-free provider for tests and local use
│   └── mem0/          namespace · filters · mapping · settings · provider
├── ingestion/
│   ├── approval.py    the human gate
│   └── store.py       where candidates wait
└── mcp/
    ├── tools.py       the four tools (no SDK dependency)
    └── server.py      thin transport adapter

tests/
├── unit/          modules in isolation
├── integration/   the API across layers, incl. provider swap
├── contract/      against the real mem0 filter pipeline
└── mcp/           the agent-facing surface

開発

.venv/bin/python -m pytest -q                       # 261 tests (1 skipped without the mcp extra)
.venv/bin/python -m pytest --cov --cov-report=term   # 94% coverage
.venv/bin/python -m ruff check src tests

契約テストは特に注目してください。それらは、mem0 の実際の前処理と pgvector の SQL ビルダーを通してフィルタを実行し、そのソースコードの読み書きで判明した制約を決定づけます。フラットな OR 分岐、フラットなメタデータキー、そのうちの一つ を表すリスト値、そして Memory.search が必要とするトップレベルのエンティティキーです。mem0 のアップグレードによってこれらが壊れたら、プールが静かにからになることはなく、テストが声高に失敗します。

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to capture, store, and retrieve durable learnings from projects via MCP tools, providing a queryable memory of product and technical lessons across repos.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides coding agents with governed semantic memory and code-graph context via MCP, enabling code-linked recall, blast-radius impact analysis, and lifecycle-aware memory management.
    3
    Apache 2.0