内容
# 代理内存引擎
**所有编码代理共享的内存 - Claude Code、Codex CLI、Cursor - 通过MCP,具有按令牌预算的召回功能,因此它不会淹没上下文窗口。**
每个编码代理在会话之间都会忘记所有内容,并且没有一个代理能够读取另一个代理的笔记:Claude Code关于代码库的学习内容对Codex是不可见的,反之亦然。通常的解决方法 - 加载到每个提示中的一堆Markdown内存文件 - 有相反的问题:随着文件堆的增长,每周消耗的令牌越来越多。
这个引擎是两者之间的关键部分。代理将原子事实、决策和交接写入一个存储;在任务开始时,任何代理都只会回忆起与该任务相关的记忆,并且是在您设置的硬令牌预算下运行的。它作为一个[模型上下文协议](https://modelcontextprotocol.io)服务器运行,因此每个支持MCP的代理都共享相同的内存 - 每个记忆都记录了写入它的代理。
> 这个引擎是Markdown记忆*约定*的演进版本,这个仓库最初托管的约定仍然包含并可用在[`scaffold/`](scaffold/)中 - 变成了一个有测量的检索*系统*。
## 结果
在一个代理跨多个会话在一个代码库上工作的标记基准测试中(14个持久记忆,7个新鲜会话任务,top-k = 3):
| 组别 | 平均上下文令牌 | 召回率 | 精确度 | 节省令牌 vs 基线 |
| --- | ---: | ---: | ---: | ---: |
| 无记忆(对照组) | 0 | 0.00 | 0.00 | 100% |
| 完整上下文(基线 - 加载每个记忆) | 550 | 1.00 | 0.10 | 0% |
| **语义召回(此引擎)** | **120** | **0.93** | **0.43** | **78%** |
| **预算召回(≤ 120令牌,硬上限)** | **113** | **0.93** | **0.43** | **80%** |
**语义召回检索了93%的相关记忆,同时加载的上下文令牌减少了78%**,与加载每个记忆文件相比 - 而在**硬120令牌上限下,召回率保持不变**,因此记忆的成本随着存储的增长而保持固定。数字通过`python eval/run_eval.py`复制,并在CI中再生,使用确定性的离线嵌入器,因此它们是字节稳定的。
## 跨代理循环
```mermaid
sequenceDiagram
participant CC as Claude Code
participant M as 记忆存储 (MCP)
participant CX as Codex CLI
CC->>M: memory_write("预订存储在UTC", 决策)
CC->>M: memory_handoff(完成, 下一步骤, 警告)
Note over CC: 会话结束
CX->>M: memory_boot("继续预订错误修复")
M-->>CX: 最后交接 + 相关事实, ≤ 300令牌
Note over CX: 精确地从Claude Code停止的地方继续
```
三个习惯,三个工具:
- **`memory_boot(task, budget_tokens)`** - 在会话开始时调用:从*前一个代理*(无论哪个工具)的最新交接,加上与任务最相关的记忆,在一个令牌预算下打包。
- **`memory_write(text, type)`** - 持久保存一个事实、决策或问题,一旦它被学习。近似重复项会自动删除。
- **`memory_handoff(done, next_steps, warnings)`** - 在会话结束时调用,以便下一个代理继续而不是重新发现。
工具输出故意紧凑 - 没有分数,没有时间戳 - 因为记忆工具返回的所有内容都会在调用代理的上下文窗口中再次付费。
## 连接到您的代理
```bash
pip install -e ".[mcp]"
```
将每个代理指向**相同的存储路径**,并给每个代理自己的名称:
**Claude Code**
```bash
claude mcp add agent-memory -e AGENT_MEMORY_PATH=~/.agent_memory/store.json \
-e AGENT_MEMORY_AGENT=claude-code -- agent-memory-mcp
```
**Codex CLI** (`~/.codex/config.toml`)
```toml
[mcp_servers.agent-memory]
command = "agent-memory-mcp"
env = { AGENT_MEMORY_PATH = "~/.agent_memory/store.json", AGENT_MEMORY_AGENT = "codex" }
```
**Cursor** (`.cursor/mcp.json`)
```json
{
"mcpServers": {
"agent-memory": {
"command": "agent-memory-mcp",
"env": {
"AGENT_MEMORY_PATH": "~/.agent_memory/store.json",
"AGENT_MEMORY_AGENT": "cursor"
}
}
}
}
```
每个记忆现在都带有其来源( `[决策 · claude-code]` , `[交接 · codex]` ),并且在一个工具中写入的交接通过`memory_boot`被下一个工具拾取。
## 工作原理
- **可插拔嵌入器** ([embeddings.py](src/agent_memory/embeddings.py)) - 一个小型`Embedder`协议,带有两个后端:一个依赖关系免费的确定性`HashingEmbedder`(默认;离线运行和CI)和一个用于真实语义嵌入的`SentenceTransformerEmbedder`。相同的API,通过安装一个包进行交换。
- **矢量存储** ([store.py](src/agent_memory/store.py)) - 在numpy矩阵上精确的强力余弦,JSON持久性,写入时近似重复抑制和贪婪**预算打包**:召回按照相关性顺序遍历结果,并跳过任何可能溢出调用者令牌预算的项目。代理的记忆是数百条记录,而不是数百万条,因此这是瞬时和精确的; FAISS/Chroma可以在相同的API后面插槽。
- **MCP服务器** ([mcp_server.py](src/agent_memory/mcp_server.py)) - 将`memory_boot`、`memory_recall`、`memory_write`、`memory_handoff`、`memory_stats`公开为代理工具。
- **评估框架** ([run_eval.py](eval/run_eval.py)) - 在标记数据集上测量令牌成本和检索精度/召回率,包含四个组别。
## 快速开始(60秒)
```bash
pip install -e . # 核心引擎 + CLI(仅限numpy)
python eval/run_eval.py # 重现上表的结果
agent-memory --agent claude-code write "预订存储在UTC." --type 决策
agent-memory --agent claude-code handoff --done "修复双重电子邮件." --next "添加速率限制."
agent-memory boot "继续速率限制工作" --budget 200
```
在Python中:
```python
from agent_memory import MemoryStore
store = MemoryStore(path="~/.agent_memory/store.json")
store.write("聊天机器人使用Google Gemini在server/gemini-chat.ts。",
type="决策", agent="claude-code")
for hit in store.recall("聊天机器人配置在哪里", k=3, budget_tokens=150):
print(hit.score, hit.entry.text)
```
## 真实的语义嵌入
```bash
pip install -e ".[real]" # 句子转换器 + tiktoken
```
`default_embedder()`在安装时自动优先使用真实模型。 在任何地方强制使用离线嵌入器,并使用`AGENT_MEMORY_EMBEDDER=hashing`(CI执行此操作以获取稳定数字)。
## 迁移现有的Markdown脚手架
```bash
python scripts/ingest_markdown.py path/to/agent-memory/ # 每个文件/部分一个记忆
```
## 开发
```bash
pip install -e ".[dev]"
pytest -q
```
## 设计笔记
- **故意小巧。** 一个本身消耗上下文的记忆层会适得其反。 回忆输出紧凑,预算上限,无评分; 整个引擎只有几百行代码,只有一个必需依赖(numpy)。
- **默认离线安全。** 无需模型下载或网络即可运行、测试或评估 - 重型后端是可选额外项。 这保持CI的确定性,并且存储库可以在一步中克隆和运行。
- **诚实的评估。** 基准测试很小,由手标记; 漏掉的记忆(`task_1`)被报告而不是调整。 框架包括无记忆对照组和完整上下文基线,以便比较公平。
- **在需要的地方保持枯燥。** 强力精确搜索而不是ANN索引,JSON而不是数据库 - 故意选择实际规模,可在相同API后面交换。
## 路线图
- 基于LLM的压缩:总结/重复`state`和`worklog`记忆,从原始会话记录中提取持久事实。
- 基于时间和类型的排名感知(衰减旧`state`,永不丢弃`decision`)。
- 在CI中发布`sentence-transformers`数字与哈希基线。
- 用于大型存储的FAISS后端。
## 许可证
MIT