内容
align="center">
<img src="docs/assets/banner.svg" alt="智能代理内存引擎 — 面向编程代理的本地优先持久化内存" width="100%" />
</p>
<p align="center">
<strong>面向编程代理的本地优先持久化内存和项目知识运行时。</strong>
</p>
<p align="center">
<a href="https://github.com/uudam42/agent-memory-engine/actions/workflows/ci.yml">
</a>
<a href="https://github.com/uudam42/agent-memory-engine/blob/main/LICENSE">
<img src="https://img.shields.io/github/license/uudam42/agent-memory-engine?style=for-the-badge" alt="MIT 许可证" />
</p>
<p align="center">
<a href="README.md">English</a> | <a href="README.zh-CN.md">中文</a>
</p>
---
# 智能代理内存引擎
**一种本地优先的 MCP 运行时,为编程代理提供持久化、基于证据的项目内存和扎实的项目跨越多个会话。**
---
## 为什么存在
编程代理面临一个基本问题:每个会话都从零开始。
- 代理在会话之间忘记项目上下文。
- 代理重复扫描仓库以重新学习模块的作用。
- 代理丢失调试经验和历史决策。
- 平面 RAG 无法区分稳定约束、过去事件、架构决策和原始代码证据。
- 即使大上下文窗口仍然需要智能优先级和令牌预算。
内存引擎通过在索引项目知识库的同时维护结构化的、基于证据的内存树来解决这个问题 — 两者都是本地的、自动的,不需要基础设施。
---
## 核心能力
| 能力 | 详情 |
|---|---|
| **持久化内存树** | MemoryNode 层次结构:约束、架构、模块、决策、事件、程序 |
| **基于证据的内存** | 每个节点链接到源证据条目(测试输出、代码引用、审查笔记) |
| **候选暂存** | 反思在提升到实时树之前生成 MemoryCandidates |
| **置信度感知提升** | 创建/更新/合并/取代/丢弃/需要审查 |
| **冲突检测** | 高风险区域(身份验证、模式、状态机、重试)标记为审查 |
| **祖先合并** | 父节点摘要在每次提升后自动更新 |
| **代理原生召回** | 编码任务前的意图感知检索 — 无需手动查询 |
| **渐进** | 深入节点、其子节点证据 |
| **后反思** | 代理报告结果 → 系统决定如何保留知识 |
| **知识摄入** | Markdown、代码、ADR、测试报告、运行时日志、git 差异 |
| **本地 FTS5 搜索** | SQLite FTS5,带有波特分词器;无需外部搜索引擎 |
| **可选向量检索** | InMemoryVectorIndex(临时)或未来的持久后端 |
| **词汇结构备用** | 无向量后端或 Docker 的完整检索 |
| **统一上下文包** | 内存 + 知识合并、重复数据删除、令牌预算 |
| **检索可追溯性** | 每个信号的得分明细在每个响应中 |
| **本地优先隐私** | 所有数据保留在 `.memory-engine/` 中;无遥测,无云调用 |
| **Python MCP 服务器** | stdio 传输;无 TypeScript,无 Docker,无外部守护进程 |
| **零触摸引导** | 在第一个 MCP 连接时自动初始化 |
| **增量索引** | JSON 清单;仅在后续运行中重新索引 |
---
## 快速入门
### 前提条件:一次性安装 `uv`
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
### 1. 克隆内存引擎
```bash
git clone https://github.com/your-org/memory-engine
```
### 2. 复制 MCP 配置块
**选项 A — 显式项目根目录:**
```json
{
"mcpServers": {
"memory-engine": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/memory-engine",
"memory-engine-mcp",
"--project-root",
"/absolute/path/to/your-project"
]
}
}
}
```
**选项 B — 通过环境变量获取项目根目录:**
```json
{
"mcpServers": {
"memory-engine": {
"command": "uv",
"args": [
"run",
"--directory",
"/absolute/path/to/memory-engine",
"memory-engine-mcp"
],
"env": {
"MEMORY_ENGINE_PROJECT_ROOT": "/absolute/path/to/your-project"
}
}
}
}
```
> **注意:** 将所有 `/absolute/path/to/...` 替换为机器上的实际路径。
> 配置文件位置和工作区变量支持因客户端而异:
> - **Cursor:** `.cursor/mcp.json` 或全局 Cursor MCP 设置
> - **Claude Code:** `~/.claude.json` 或项目级配置
> - 参阅客户端的 MCP 文档以获取确切的位置。
### 3. 打开目标项目并开始编码
就这样。内存引擎会自动启动并处理其他所有事情。
---
## 自动发生的事情
```
用户打开项目
│
▼
MCP 客户端通过 stdio 启动 memory-engine-mcp
│
项目根目录解析(.git / py / package.json 标记)
│
▼
.memory-engine/ 创建(如果首次使用)
│
▼
README、ADR、架构文档、约束被索引
│
▼
更广泛的源文件在后台增量索引
│
▼
代理开始非琐碎的编码任务
│
▼ [自动]
retrieve_agent_context 调用
│ → 相关约束、事件、决策、程序、源引用
│
▼
代理实现并验证
│
▼ [自动,成功后]
reflect_and_write 调用
│ → 系统评估保留门
│ → 如果值得则创建 MemoryCandidates
│ → 提升到内存树
│ → 合并祖先摘要
│
▼
memory_status 显示更新的计数---
## ```mermaid
graph TD
A[用户 / 编程代理] -->CP 客户端]
B -->|stdio| C[Python MCP 服务器]
C --> D[]
C --> E[服务层]
C --> F[知识层 D -->|召 / 反思
E -->|内存生命周期| G[(内存树\nSQLite)]
F -->|摄入 / 搜索| H[(知识库\nSQLite + FTS5)]
F --> I[可选向量后端]
E --> G
F --> H
C -->引导和增量 J --> K-engine/\n项目本地存储]
G --> H --> K
```
---
## 代理调用链
```mermaid
sequenceDiagram
participant 代理
participant MCP as MCP 服务器
participant 技能 as 代理技能
participant 服务 as 服务层
participant 数据库 / FTS5
代理->>MCP: retrieve_agent_context(任务, 文件, 符号)
MCP->>技能: QueryAnalyzer.analyze()
技能->: MemoryNode(意图加)
技能->>数据库: 知识搜索S5 + 向量 RRF)
技能->>技能: 排名、合成、重复数据删除、令牌修剪
MCP-->>代理: 上下文包(内存 + 知识 + 跟踪)
Note over 代理: 实现并验证
代理->>MCP: reflect_and_write(任务, 结果, 验证状态)
MCP->>技能: ReflectionSkill.analyze() — 门控检查
技能->>服务: PostTaskService.reflect_and_write()
服务->>服务: PromotionService.promote()
服务->>服务: ConsolidationService.update_ancestors()
服务->>数据库: 持久化 MemoryNode 更新
MCP-->>代理: {结果: "已持久化", 已提升候选: 2}
```
---
## 内存生命周期
```
任务结果
│
▼
ReflectionSkill.analyze()
│ 门控:结果 ≠ 失败/恢复,验证状态,置信度 ≥ 阈值,
│ 摘要字数,己知平凡模式
│
├─ 跳过 → 返回 {skip_reason}
│
└─ 通过 ▼
│
MemoryCandidate 生成
├─ 约束 (重要性 0.92)
├─ 程序 (重要性 0.72)
├─ 事件/调试 (重要性 0.85)
├─ 模块 (重要性 0.62)
└─ 决策 ( 0.82)
│
▼
PromotionService.promote()
├─ 创建 — 新节点
├─ 更新 — 相同标题,内容刷新
├─ 合并 — 近似重复(Jaccard ≥ 0.80)
├─ 取代 — 现有节点确认错误
├─ 丢弃 — 低价值 / 已知
└─ 需要审查 — 与高置信度现有节点冲突
│
▼
ConsolidationService.update_ancestors()
│ 父节点摘要 = concat(子节点摘要)
▼
缓存失效 + 内存修订号增加
```
### 节点状态
| 状态 | 含义 |
|---|---|
| `candidate` | 已暂存,待提升决策 |
| `active` | 实时,返回召回 |
| `stale` | 过时;保留历史 |
| `superseded` | 被更新节点取代 |
| `needs_review` | 标记冲突;建议人工审查 |
---
## 知识生命周期
```
文档 / 代码 / ADR / 测试 / 日志 / 差异
│
▼
redact() ← 8 种模式:API 密钥、令牌、密码、私钥、
│ 连接字符串、JWT、AWS 密钥、Slack 令牌
▼
SHA-256 内容哈希 → 重复数据删除检查
│
▼
源类型分块器
├─ Markdown → 基于标题的章节(≤1200 令牌)
├─ 代码 → 类/函数块 (≤1000 令牌)
├─ 测试报告 → 结果窗口
├─ 日志 → 滑动窗口 (≤600 令牌)
└─ 差异/补丁 → 基于块的块
│
▼
KnowledgeDocument + KnowledgeChunk (SQLite)
│
├─ FTS5 插入 (词汇 — 始终可用)
└─ 向量更新 (可选 — InMemoryVectorIndex 或 Qdrant)
│
▼
混合检索 → RRF 融合 → 源质量 │
▼
UnifiedContextPack (令牌预算的 40%)
```
---
## 目录结构
```
memory_engine/
├── main.py ← FastAPI 应用(开发 / 直接 API 使用)
├── cli.py ← 调试 CLI
├── config.py ← Pydantic 设置
│
├── agent/ ← 阶段 8 命名空间(重新导出)
│ ├── skills/ → memory_engine.skills
│ ├── policies/ → 反射门控常量
│ └── contracts/ → 代理 I/O 领域模型
│
├── skills/ ← 代理面对的行为(召回、检查、反射)
├── services/ ← 领域编排(提升、合并)
├── knowledge/ ← 摄入、切分、FTS5、向量、搜索、融合、缓存
├── repositories/ ← 持久化抽象(memory_node, candidate, evidence)
├── models/ ← Pydantic 领域 + SQLAlchemy ORM
│
├── bootstrap/ ← 本地运行时(project_root, 存储, 安全, 状态)
├── runtime/ ← 阶段 8 命名空间(重新导出 bootstrap + 缓存 + 配置)
│
├── mcp/ ← MCP 适配器(工具、资源、服务器、项目上下文)
├── api/ ← FastAPI 路由
└── db/ ← SQLite 会话 + 初始化
docs/
├── architecture/ ← 系统概述、内存生命周期、知识管道、
│ 检索管道、MCP 集成、本地运行时
└── guides/ ← 快速入门、配置、隐私和安全
tests/
├── test_phase4.py – test_phase7.py ← 阶段集成测试
└── test_*.py ← 单元和组件测试
```
---
## MCP 工具
| 工具 | 用途 |
|---|---|
| `retrieve_agent_context` | 在编码任务前检索内存 + 知识 |
| `inspect_memory` | 深入 MemoryNode、其子节点和证据 |
| `inspect_knowledge` | 检查 KnowledgeChunk 或源文件范围(已编辑) |
| `reflect_and_write` | 将验证的工作报告给反射管道 |
| `memory_status` | 项目健康状况、检索模式、索引计数、修订 |
| `refresh_project_knowledge` | 触发增量重新扫描(仅显式使用) |
## MCP 资源
| 资源 | 内容 |
|---|---|
| `memory://project/current/constraints` | 活动项目约束 |
| `memory://project/current` | 架构和模块摘要 |
| `memory://project/current/status` |状态、检索模式、健康状况 |
| `memory://project/current-incidents` | 最近的调试事件 |
| `memory://project/current/memory-tree-summary` | 内存树大纲 |
memory://project/current/agent-policy` | 生成的代理策略 |
---
## 本地存储
```
your-project/.memory-engine/
├── config.yaml ← 编辑以自定义;绝不会被覆盖
├── project_state.json ← 引导状态,修订
├── memory.db ← 所有数据(内存,知识,候选)
├── indexes/manifests/ ← 增量索引文件清单
├── generated/
│ └── AGENT_MEMORY_POLICY.md
├── bootstrap/bootstrap_report.json
├── constraints.md ← 人工编写;安全提交
├── team-rules.md ← 人工编写;安全提交
└── decisions.md ← 人工编写;安全提交
```
将 `./` 添加到 `.gitignore`(第一次引导时的提示)。
三个手动编写的 `.md` 文件可以选择性地提交。
**重置:** `rm -rf your-project/.memory-engine/`
---
## 人工编写的种子知识
创建这些文件以提供无法单独从代码中安全推断的稳定项目知识:
**`.memory-engine/constraints.md`**
```markdown
# 项目约束
## 身份验证
不允许绕过 JWT 验证。所有路由都需要 Bearer 令牌。
## 数据库
绝不能使用原始 SQL。仅限 SQLAlchemy ORM。
```
**`.memory-engine/team-rules.md`**
```markdown
# 团队规则
- 合并前,PR 需要 2 次批准
- 所有公共 API 必须有 OpenAPI 文档
- 仅记录结构化 JSON(生产代码中无打印语句)
```
这些文件在引导时作为高优先级知识被索引,并在相关任务之前返回上下文。
---
## 检索模式
### 默认本地模式:`lexical_structured_fallback`
在没有持久化向量后端可用时激活(本地使用的默认模式)。
用于排名的信号:
- SQLite FTS5 词汇匹配(BM25)
- 当前任务文件与模块路径重叠
- 当前任务符号与符号重叠
- 内存树邻近度
- 节点重要性和置信度
- 新鲜度(最近权重)
- 项目范围 TTL
### 增强模式:`hybrid_lexical_vector`
在持久化向量后端健康时激活。
通过 RRF 融合在块嵌入上添加余弦相似度。
**向量检索是可选的。** 默认本地模式在没有 Qdrant、Docker 或任何外部服务的情况下工作。
---
## 隐私和安全
- **本地存储:** 所有数据保留在 `.memory-engine/` 中;机器上没有数据离开
- **无遥测:** 无使用数据发送到任何地方
- **无云嵌入:** 默认情况下无外部 API 调用
- **无 Docker:** 不需要任何功能
- **路径边界:** 所有文件读取限制在解析的项目根目录内
- **符号链接保护:** 链接超出项目根目录的链接被拒绝
- **机密编辑:** 在持久化和 MCP 输出之前运行
- **默认排除:** `.env`, `secrets/`, `*.pem`, `*.key`, `node_modules/`, `.git/`, 二进制文件,超过 5 MB 的文件
- **无自动 Git 提交:** 绝不
- **不写入 `.memory-engine/` 之外:** 保证
---
## 配置
在第一次引导时生成于 `.memory-engine/config.yaml`:
```yaml
project:
name: auto
root_path: auto
runtime:
auto_bootstrap: true
auto_recall: true
auto_reflect: true
auto_index_on_start: true
incremental_indexing: true
privacy:
mode: local
redact_secrets: true
allow_network_embedding: false
knowledge:
include:
- README.md
- docs/**
- src/**
- app/**
- lib/**
- tests/**
exclude:
- node_modules/**
- .git/**
- .venv/**
- dist/**
- build/**
- .env
- secrets/**
max_file_size_mb: 5
retrieval:
default_token_budget: 6000
cache_enabled: true
vector_backend: auto
allow_degraded_fallback: true
```
用户编辑在重新引导时被保留。
---
## 演示场景
**调度项目。任务:** 在不破坏终端任务状态语义的情况下添加指数级重试回退。
1. 代理调用 `retrieve_agent_context`:
```json
{
"constraints": [
{
"title": "终端状态不可变性 "summary": "COMPLETED, FAILED, CANCELLED 是终端状态。任何将终端状态转换出去的操作都是严重错误。",
"importance": 0.95
}
],
"incidents": [
{
"title": "重试循环重新进入终端任务",
"summary": "在 v0.8.2 中,重试竞争条件重新进入 COMPLETED 任务。根本原因:重试检查在重新排队前未验证终端状态。",
"importance": 0.88 }
],
"knowledge_chunks": [
{
"source_path": "docs/adr/003-retry-policy.md",
"preview": "决策:使用指数退避和抖动 5 次重试..."
}
],
"retrieval_trace": [...],
"meta": {
"retrieval_mode": "lexical_structured_fallback",
"vector_backend": "ephemeral",
"warnings": ["语义向量检索不可用..."]
}
}
```
2. 代理实现重试逻辑与终端。
3. 测试通过。代理调用 `reflect_and_write`:
```json
{
"outcome": "persisted",
"oted": 2,
"consolidation_notes": ["父节点 '调度核心' 摘要已更新"]
}
```
---
## 调试 CLI
仅限维护人员、演示和故障排除使用。不是正常工作流。
```bash
memory-engine debug status --project-root /path/to/project
memory-engine debug bootstrap --project-root /path/to/project
memory-engine debug index --project-root /path/to/project
memory-engine debug recall "添加重试回退" --project-root /path/to/project
memory-engine debug inspect <node-id>
memory-engine debug reset-project --project-root /path/to/project
```
---
## 测试
```bash
# 运行所有测试
pytest -v
# 运行聚焦测试
pytest tests/test_phase7pytest tests/test_phase6v
pytest -k "recall" -v
```
目前有 215 个测试通过。全部确定。无需外部服务## 限制和未来工作
- **持久化本地向量后端** — 当前的 InMemoryVectorIndex 在进程重启后不幸存
- **可选 Qdrant 后端** — 接口存在;默认不安装客户端
- **PyPI 发布** — `pip install memory-engine-mcp` 尚未可用
- **二进制打包**尚无二进制安装程序
- **客户端特定安装程序** — 尚无 Cursor/VS Code 扩展
- **可流式 HTTP 远程模式** — stdio 仅限;尚无团队共享的 HTTP 传输
- **团队共享内存** — 每个项目都有独立的本地存储;尚无团队共享内存
- **身份验证和权限** — 尚无每用户或每团队访问控制
- **更丰富的代码解析** — 切分基于行范围;基于 AST 的解析是未来工作
- **更大的仓库基准** — 尚未在 monorepo 规模上验证
---
## 贡献
1. 先阅读 [`docs/architecture/system-overview.md`](docs/architecture/system-overview.md)。
2. 保持服务层边界:MCP/API 层保持薄。
3. 将业务逻辑保留在 `skills/`、`services/`、`knowledge/` 中。
4. 新的知识源类型 → `knowledge/chunkers.py` + 新的 `SourceType` 枚举值。
5. 新的 MCP 工具 → `mcp/tools.py`,仅限薄包装;委托给服务。
6. 新的领域模型 → `models/domain.py` 或 `models/knowledge_domain.py`。
7. 为所有新行为添加测试。
8. 绝不削弱项目根目录安全边界。
9. 在打开 PR 之前运行 `pytest -v` 并确认所有测试通过。
---
## 开发
```bash
# 安装开发依赖
pip install -e ".[dev]"
# 运行测试
pytest -v
# 启动 FastAPI 服务(开发 / 直接 API 使用)
uvicorn memory_engine.main:app --reload
# API 文档位于 http://localhost:8000/docs
# 直接运行 MCP 服务器
uv run memory-engine-mcp --project-root /path/to/project --log-level DEBUG
```
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器