Skip to main content
Glama

firm-memory

一个记忆层,让我们的 AI 编码智能体记住这家公司如何构建软件,从而不必在每次调用时重新学习同样的东西。

CodeGraph 回答 “代码在做什么?” Firm Memory 回答 “我们为什么要这样构建?”

CodeGraph 对当前代码行为保持权威。记忆(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. 分类法

提供方自带的分类抽取是为消费级助手(美食、爱好、音乐)调优的。我们的分类抽取是为交易系统调优的。十三个类型,每个都配有驱动抽取的描述:

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)和稳定的线上 slug(business_rules)。

同样重要的是排除项:不包含源代码、diff 或堆栈追踪;不包含秘密;不包含关于某位工程师的隐私事实;不包含瞬时状态。

2. 范围

独立的属性,而不是层级结构——因为公司知识并不顺从一棵树:

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

一条横跨三个仓库的记忆 只需存储一次,并且可以从其中任何一个仓库访问到。这里刻意不设工程师级和团队级范围:无论谁发问,同一个问题都必须返回同样的公司知识,否则身份轴会把引用的事实分裂成几个副本。

3. 层级

生命周期轴,与审批状态正交:

类型

保存内容

按任务限定?

EPISODIC

每个 MR 的临时工作记忆——发现及其处置

是,必需

DURABLE

经过审批门写入的提炼知识

从不

INDEX

每个关闭的 issue/MR 保留一张逐字卡片,保持文档形态

从不

搜索默认排除 EPISODIC。这个默认是承重(load-bearing)的:对于向量存储来说,缺少任务过滤器意味着 “不关心”,而不是 “未设置”,所以如果没有这个默认值,每个 MR 的草稿状态都会混入普通召回。它有契约测试保护。

4. 溯源与生命周期

每条记忆都携带来源,因此工程师能把一条引用追踪到背后的 MR、issue 或访谈——并对其纠错。

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

V1 是完全人工审批的;置信度从一开始就记录,所以日后开启自动化无需迁移修改。业务规则、架构决策、公司约定和生产相关的知识永远需要人工把关,无论置信度如何。

不删除任何东西。 一次更正会使原记录降级并标记;被取代则指明替代的新记录。那之前已做过决定已作废的事实,依然存活。

5. 可靠性

记忆是尽力而为的。读取永远不抛错:提供方挂机或超出有界超时,只会返回空的奖惩并记录指标,失败的召回不能让代码审查失败。写入会抛错——静默丢弃一条刚批通过的工程记忆,要比报错更糟。


配置

平台设置与提供方无关;提供方配置由提供方自己读取。这种拆法正是“更换提供方”只需要改配置项的地方。

变量

默认值

含义

FIRM_MEMORY_PROVIDER

mem0

使用哪个提供方

FIRM_MEMORY_LIMIT

5

每次搜索的结果数

FIRM_MEMORY_MIN_SCORE

0.3

相关性下限

FIRM_MEMORY_TIMEOUT_SECONDS

2.0

放弃前有界等待时间

FIRM_MEMORY_DOMAINS

—

这个 checkout 所属的域

FIRM_MEMORY_REPO

(git remote)

覆盖仓库 slug

FIRM_MEMORY_CANDIDATES_PATH

(进程内)

候选记录等待人工处理的地方

FIRM_MEMORY_AUTO_APPROVE

on

基于置信度的自动审批开关

FIRM_MEM0_PG_DSN

required

pgvector 连接字符串

FIRM_MEM0_COLLECTION

mem0_firm

collection 名称

FIRM_MEM0_POOL_OWNER

firm

命名该 pool 的 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 路由” 一样,比代码注释更接近与策略本身的地缘;它所在的 pool 会继承到合流,即每个提供数据的仓库所定义的访问权限共同上限。


布局

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 要求的顶层 entity_key。如果 mem0 升级破坏其中的某一条,这些测试会响亮失败,而不会让 pool 悄然变空。

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