内容
# 智能代理记忆中心
> 🇧🇷 请在 [Português](README.pt-br.md) 中阅读。

持久的、**共享的 AI 编程代理内存**(Claude Code 及任何支持 MCP/REST 的工具),由 **您自己的 Supabase** 支持。每个会话都自动保存到 Postgres 表中,并在下一次会话开始时重新调用,跨越 **会话、工具实例和机器**。
与其他方案不同的一个立场:**您可以信任、解释和拥有的内存**。不是一个黑盒。
- **可解释的。** 回忆显示每个项目的来源(事实的置信度和年龄,会话的 `session_id`),并且事实的置信度会 **随时间衰减**,因此陈旧的内存会自动淡出。
- **人工控制的。** 跨项目开发者配置文件及其规则是 **提议的**,而不会自行应用。您可以批准或拒绝;不会有任何内容在未经您同意的情况下静默地重写您的代理的工作方式。
- **属于您。** Supabase 上的纯 Postgres。`pg_dump` 随时可用。中间没有 SaaS,也没有锁定。
## 为什么
Claude Code 每次会话都从零开始。像 claude-mem 或 mem0 这样的工具解决了这个问题,但它们要么存储在本地(不支持跨机器),要么通过托管服务运行,并且大多数会自动应用它们提取的内容。`agent-memory-hub` 是自有、可审计的版本:一个您拥有的 Supabase 表,可选的层,您可以根据需要切换它们(语义搜索、事实、跨项目开发者配置文件、备份),并且在内存更改代理行为的任何地方都需要人工干预。
- **跨会话/实例/机器:** 任何指向同一个 Supabase 的设置都共享所有内容。
- **提炼,而不是转储:** 回忆注入了紧凑的、排名的、可解释的上下文,而不是原始的转录。
- **自我改进,根据您的意愿:** 它了解您的工作方式,并根据项目提出规则;您可以决定。
## 功能
- **自动捕获** 每个会话,并带有每回合的检查点,生存期跨越崩溃。
- **回忆** 在会话开始时:每个相关会话的干净的一行摘要,以及当前项目的持久 **事实**。每个项目都带有其 **出处**(事实:置信度和自此时间;会话:`session_id`),因此回忆是可解释的。事实的置信度 **随时间衰减**(每种类型的半衰期),因此陈旧的事实会从回忆中淡出,而不会被删除。
- **搜索** 您的整个历史记录:**混合**(关键词 + 语义,通过 `pgvector`),带有可选的 LLM **`--rerank`** 第二步。
- **事实层**(可选,带自己的 LLM):持久的首选项/决策/配置,具有时间有效性,按含义去重。
- **开发者配置文件**(可选):提炼您在 **所有项目** 中的工作方式,并将您批准的模式转换为代理遵循的规则。自我改进的循环,由人工控制。
- **跨工具:** 通过钩子使用 Claude Code,通过适配器使用 Codex CLI,通过适配器模板使用任何工具。
- **MCP 服务器**(`scripts/mcp_server.py`,纯标准库):专用的工具 - `recall_relevant`、`recent_sessions`、`get_facts`、`get_session` - 因此任何 MCP 代理(Claude Code、Cursor、Codex)都可以在 **按需、结合任务** 的情况下查询内存,而不是仅仅在启动时被动地回忆。
- **内存控制台**(`scripts/memory.py`):从终端浏览、搜索和检查 - `stats`、`recent`、`search`、`facts`、`show`、`profile`,以及 `standup`(您今天/本周触及的内容)、`health` 和 `log`(如下)。
- **健康和可观察性**(`memory.py health` / `log`):将本地转录与 Supabase 协调,并监视捕获错误率,因此 **沉默的捕获失败会被发现**,而不是被忽略 - 您可以 **验证** 内存,而不是仅仅信任它。
- **每周摘要**(`scripts/weekly_digest.py`):所有项目(无 LLM)的 7 天摘要,具有进入您内容工作流的钩子。
- **您自己的备份:** 每天 `pg_dump` 到一个可移植的 `.sql`。没有锁定。
- **核心中没有 LLM**(“语义”部分使用嵌入式模型,而不是聊天 LLM);每个 LLM 支持的部分都是可选的,并且有免费选项。
## 工作原理
```mermaid
flowchart TD
subgraph S["AI 编程会话(Claude Code)"]
direction TB
SS["会话开始"] --> RECALL["recall_session.py<br/>注入相关过去会话的摘要"]
STOP["停止(每回合)"] --> CAP["capture_session.py<br/>连续检查点,后台,上载"]
SE["会话结束"] --> SAVE["capture_session.py<br/>最终保存"]
end
RECALL -.->|读取| DB[("Supabase,您的项目<br/>表 public.sessions")]
CAP -->|写入| DB
SAVE -->|写入| DB
DB -->|可选| DUMP["pg_dump<br/>cron 在一个始终在线的主机上"]
DUMP --> GZ([".sql.gz"])
GZ --> PULL["拉取到您的机器"]
```
- 捕获是 **幂等的**(通过 `session_id` 上载)。`停止` 检查点意味着即使突然终止,会议也会保持到其最后一回合。
- 回忆仅注入 **紧凑的摘要**(每个会话的一行提取摘要,而不是原始转录)。完整的转录可以通过 Supabase MCP 或 REST 按需查询。
- 摘要是 **确定性和无 LLM 的**:捕获钩子保留第一个实质性用户请求、最后一个请求和回合计数。运行 `sql/04-summary.sql` 以添加列。
## 需求和支持的工具
内存本身就是 Postgres,因此工具特定的只有自动捕获/回忆,它作为 Claude Code 钩子提供。
- **自动捕获 + 回忆(钩子):** [Claude Code](https://claude.com/claude-code)。钩子使用其 `SessionStart`、`Stop` 和 `SessionEnd` 事件。
- **读取和查询共享内存:** 任何支持 MCP 或 REST 的 AI 工具,例如 Cursor、Codex CLI、Gemini CLI 或 ChatGPT,通过 Supabase MCP 或 REST API。
- **从其他工具捕获:** 一个 **适配器** 扫描该工具的本地转录并上传新的转录(幂等),与 `backfill_sessions.py` 为 Claude Code 工作的方式相同。Codex CLI 随附 `scripts/adapters/codex.py`;请参阅 [从其他工具捕获](#从其他工具捕获适配器) 以添加更多。
还需要的:
- 一个免费的 [Supabase](https://supabase.com) 项目。
- `python3`(钩子和备份是纯标准库,不需要 pip)。
## 入门(也是如何在机器上设置)
> **快捷方式:** 克隆并填充 `.env` 后,运行 `./scripts/setup.sh`。它应用 SQL 迁移并在一步中安装 Claude Code 钩子(这是幂等的;它不会启用可选的事实层)。下面的手动步骤解释了它的作用。
### 1. 克隆
```bash
git clone https://github.com/carloshpdoc/agent-memory-hub.git
cd agent-memory-hub
```
### 2. 创建一个 Supabase 项目
在 [supabase.com](https://supabase.com):新建项目。启用 **数据 API** 和 **RLS**。从 **设置 > API** 获取:项目 URL、可公开的密钥、秘密密钥。
### 3. 应用模式
在 Supabase 中打开 **SQL 编辑器** 并运行 [`sql/01-schema.sql`](sql/01-schema.sql)。它创建 `sessions` 表、全文索引和 RLS。
### 4. 配置 `.env`
```bash
cp .env.example .env
# 使用您的 SUPABASE_URL 和 SUPABASE_SECRET_KEY(以及如果使用的备份变量)编辑 .env
```
`.env` 被 gitignore。钩子直接读取它。
### 5. 将钩子连接到 Claude Code
将以下内容添加到您的 Claude Code `settings.json`(`~/.claude/settings.json` 用于用户范围),使用您的克隆的 **绝对路径**:
```json
{
"hooks": {
"SessionStart": [
{ "matcher": "", "hooks": [
{ "type": "command", "command": "python3 /ABS/PATH/agent-memory-hub/hooks/recall_session.py", "timeout": 15 }
]}
],
"Stop": [
{ "matcher": "", "hooks": [
{ "type": "command", "command": "payload=$(cat); printf '%s' \"$payload\" | python3 /ABS/PATH/agent-memory-hub/hooks/capture_session.py >/dev/null 2>&1 &" }
]}
],
"SessionEnd": [
{ "matcher": "", "hooks": [
{ "type": "command", "command": "python3 /ABS/PATH/agent-memory-hub/hooks/capture_session.py", "timeout": 20 }
]}
]
}
}
```
> 如果您已经有这些事件的钩子,请将这些条目 **添加到** 现有数组中。
### 6. (可选)添加 Supabase MCP
让代理交互式地查询内存:
```bash
claude mcp add --scope user --transport http supabase \
"https://mcp.supabase.com/mcp?project_ref=<YOUR_PROJECT_REF>"
# 然后认证:/mcp > supabase
```
### 7. (可选)备份模块
在具有 `pg_dump` 的始终在线的主机上(版本高于或等于您的 Postgres 主要版本),并且克隆了存储库:
- 将您的连接凭证放入 `~/.pgpass`(chmod 600):
`HOST:5432:postgres:postgres.<PROJECT_REF>:PASSWORD`
- 在 `.env` 中填写 `PG_POOLER_*` 变量。
- Cron:`30 3 * * * /ABS/PATH/agent-memory-hub/scripts/backup.sh >> .../backup.log 2>&1`
- 使用 `scripts/pull-backups.sh` 将副本拉取到本地(在 `.env` 中设置 `REMOTE_SSH` 和 `SSH_KEY`)。
## 添加另一台机器
这就是重点,而且非常简单:
1. 在新机器上克隆存储库。
2. 复制相同的 `.env`(相同的 Supabase 凭证)。
3. 运行 `./scripts/setup.sh`。
完成。 该机器现在写入并读取 **相同的共享内存**。 迁移是幂等的(如果没有 DB 凭证,则跳过,因为模式是共享的)。 可选的事实层保持关闭,因此较弱的机器仅捕获和读取,而在您启用的地方运行重型事实提取。
要上传该机器的 **先前** Claude Code 历史记录(钩子之前的会话),请运行 `python3 scripts/backfill_sessions.py --dry-run` 进行预览,然后不带标志上传。它是幂等的(跳过已在 Supabase 中的会话)。
## 从其他工具捕获(适配器)
Claude Code 钩子是一种捕获路径。没有生命周期钩子的工具由 **适配器** 处理,该适配器扫描其本地转录并上传新的转录(幂等),与 `backfill_sessions.py` 为 Claude Code 工作的方式相同。适配器在 cron 上运行并写入 `tool=<name>`,因此回忆、搜索和事实统一处理所有工具。
- **Codex CLI** ([`scripts/adapters/codex.py`](scripts/adapters/codex.py)) 读取 `~/.codex/sessions/**/rollout-*.jsonl`。运行 `--dry-run` 进行预览,然后将其放到 cron 上。
- **添加工具:** 编写一个小型适配器,将工具的转录映射到 `(session_id, cwd, user/assistant turns)` 并使用 `tool=<name>` 上载。使用 `codex.py` 作为模板。Cursor(chat in SQLite)和 Gemini CLI 是很好的第一个贡献。
## 配置参考
| 变量 | 使用者 | 含义 |
| --- | --- | --- |
| `SUPABASE_URL` | hooks, backup.py | `https://<ref>.supabase.co` |
| `SUPABASE_SECRET_KEY` | hooks | 服务角色密钥(写入,绕过 RLS) |
| `PG_POOLER_HOST`, `PG_POOLER_USER` | backup.sh | 会话连接池主机,`postgres.<ref>` |
| `BACKUP_DIR`, `KEEP` | backup.sh, backup.py | 输出目录,保持数量 |
| `REMOTE_SSH`, `SSH_KEY` | pull-backups.sh | 始终在线的主机,SSH 密钥 |
| `EMBED_KEY` | embed_pending.py, search.py | 嵌入式函数(第 2 阶段)的保护 |
## 查询内存
- **控制台:** `python3 scripts/memory.py` 打开一个交互式提示,或使用子命令:`stats`、`recent [N]`、`search [--project P] "<q>"`、`facts [project]`、`show <id-prefix>`、`standup [today|yesterday|week]`、`health`、`log [N]`。纯标准库,无服务器,无浏览器中的密钥。`mem` 别名很方便:
`alias mem='python3 /ABS/PATH/agent-memory-hub/scripts/memory.py'`.
- **MCP 服务器(专用):** `scripts/mcp_server.py` 通过 stdio/JSON-RPC(纯标准库,无依赖项)公开 `recall_relevant`、`recent_sessions`、`get_facts`、`get_session`,因此任何代理都可以在 **按需、结合任务** 的情况下查询内存 - 而不仅仅是在启动时被动地回忆:
```bash
claude mcp add --scope user agent-memory-hub -- python3 /ABS/PATH/agent-memory-hub/scripts/mcp_server.py
```
- **Supabase MCP:** 代理通过 Supabase MCP 提问。它运行 SQL 通过 Supabase MCP。
- **REST 全文检索:** `GET /rest/v1/sessions?content_tsv=fts(simple).<term>` 使用秘密密钥。
- **过滤器:** 按 `project`、`machine`、`started_at`、`session_id`。
## 语义搜索(第 2 阶段)
可选。 在全文搜索之上添加基于含义的回忆,使用 `pgvector` 和在 Supabase Edge Function(免费,无外部 API)中运行的 `gte-small` 模型。
1. 运行 [`sql/02-phase2-pgvector.sql`](sql/02-phase2-pgvector.sql)。它添加了 `embedding` 列、HNSW 索引和 `match_sessions` RPC。还要运行 [`sql/03-hybrid-search.sql`](sql/03-hybrid-search.sql) 以获取 `hybrid_search` RPC。
2. 设置一个保护密钥并部署函数:
```bash
supabase secrets set EMBED_KEY=$(openssl rand -hex 24)
supabase functions deploy embed --no-verify-jwt # 新的 API 密钥不是 JWT
```
将相同的 `EMBED_KEY` 放在您的 `.env` 中。
3. 嵌入现有行:`python3 scripts/embed_pending.py`。在 cron 上运行它以保持新会话的嵌入(例如 `*/15 * * * *` 在您的始终在线的主机上)。
4. 搜索:`python3 scripts/search.py "如何设置备份"`。它运行 **混合搜索**(关键词 + 语义,通过 RRF 融合),因此精确的术语可能会被纯矢量搜索错过,而矢量搜索可能会错过其他术语。添加 `--rerank` 以获取一个可选的 LLM 第二步,该步骤根据相关性重新排序顶级候选者(需要设置 `FACTS_LLM`)。
边缘函数仅返回向量和计数,从不会话内容。
## 事实和偏好(可选,第 4 阶段)
所有上述内容均 **不需要 LLM**(“语义”部分使用嵌入式 `gte-small`,而不是聊天模型)。此可选层是唯一使用 LLM 的部分,并且它是 **自带 LLM,具有免费选项**,因此它永远不会强制成本或特定提供商。
启用后,可选的 cron 会将每个会话提炼成持久的原子事实(偏好、决策、配置),具有时间有效性,按含义去重。回忆然后在摘要开始时注入相关事实(当前项目 + 全局)。
1. 运行 [`sql/05-facts.sql`](sql/05-facts.sql)(事实表、有效性模型、`match_facts` RPC)。
2. 在 `.env` 中通过 `FACTS_LLM` 选择提供商:
- `ollama`:本地、免费、私有(需要 Ollama 运行)。
- `gemini`:Google AI Studio 免费层(`GEMINI_API_KEY`)。
- `openai`:OpenAI 或任何 OpenAI 兼容的端点(Groq、OpenRouter、本地)。
- `off`(默认):禁用;其他工具不受影响。
3. 运行 `python3 scripts/extract_facts.py`(将其放到 cron 中以处理新会话)。
**去重事实(可选,手动)。** 随着时间的推移,事实可能会重叠。`sql/06-find-fact-dupes.sql` 加上 `scripts/consolidate_facts.py` 让 LLM 判定近似重复对并取代冗余的事实(非破坏性,通过 `valid_until`)。用 `--dry-run` 运行并 **审查**:这是故意不自动化的,因为弱判定器可能会过度合并有用的特定细节,因此人类应该批准。一些冗余是可以的;只修剪您检查过的部分。
## 开发者配置文件和自我改进规则(可选,第 9 阶段)
大多数内存工具按项目存储事实。 由于此中心存储所有项目的所有会话,因此它可以执行其他工具无法执行的操作:提炼 **您的工作方式** 配置文件,并将高置信度模式转换为您的代理随后遵循的规则。 循环是:您使用它的次数越多,代理的自身指令就会变得更好, 由您作为门户。

> _示例运行,带有通用数据。循环:合成配置文件,审查每个模式,批准,然后批准的规则在您的 `CLAUDE.md` 导入的文件中生效。_
1. 运行 [`sql/07-profile.sql`](sql/07-profile.sql)(`profile_patterns` 表)。
2. 设置 `FACTS_LLM`(与上述相同的提供商),运行 `python3 scripts/synthesize_profile.py`。它读取您的持久事实,仅保留在 **2+ 不同项目** 中有证据的模式,并写入人类可读的 `PROFILE.md`。高置信度模式获得提议的规则。
3. 使用 `python3 scripts/memory.py profile` 审查并批准或拒绝每个模式(`profile approve <id>` / `profile reject <id>`)。管理是故意人为的。
4. 运行 `python3 scripts/apply_profile_rules.py`(干运行)然后 `--write`。它将批准的规则写入 **单独** 的文件(`~/.claude/profile-rules.md`),从不触及您的书面 `CLAUDE.md`。通过在 `CLAUDE.md` 中添加 `@~/.claude/profile-rules.md` 来加载它们一次。
- 添加 `--per-project` 以按项目编写一个文件(`~/.claude/profile-rules/<project>.md`),每个文件都包含其证据包括该项目的规则。在无关的会话中不要在该存储库的 `CLAUDE.md` 中加载相关规则。
回忆还会在会话开始时 **主动显示** 任何已检测但未审查的模式(及其置信度和项目计数),以便循环自行关闭,而不是等待您记住运行审查。
像事实层一样,这是可选的、自主 LLM 的,并且由人工审查控制:弱判断者可能会过度合并,而“更新”并不总是“更好”,因此如果没有您的确认,什么都不会被应用。
## 安全
- 机密信息仅存储在 `.env` 和 `~/.pgpass`(gitignored,chmod 600)中。永远不要提交它们。
- RLS 已启用。公共(匿名)密钥在没有策略的情况下无法读取。钩子使用秘密密钥。
- 秘密密钥功能强大。像密码一样对待它。
## 文件
```
scripts/setup.sh 一次性设置/更新:迁移 + 钩子(幂等)
scripts/migrate.py 将 sql/*.sql 应用于 Supabase
scripts/install_hooks.py 将钩子添加到 settings.json
scripts/backfill_sessions.py 上传此机器的先前 Claude Code 历史记录(一次性)
scripts/adapters/codex.py Codex CLI 的捕获适配器(其他工具的模板)
scripts/memory.py 内存控制台:浏览/搜索/检查/站立/健康(第 8 阶段)
scripts/memory_client.py 共享 Supabase 访问 + 读取查询(由控制台 + MCP 服务器使用)
scripts/mcp_server.py MCP 服务器(stdio/JSON-RPC,纯标准库):recall_relevant, get_facts, ...
scripts/weekly_digest.py 7 天跨项目摘要,无 LLM(第 10 阶段)
hooks/capture_session.py 捕获(停止 + 会话结束)
hooks/recall_session.py 回忆(会话开始)
sql/01-schema.sql 表 + 全文 + RLS
sql/02-phase2-pgvector.sql pgvector + match_sessions RPC(第 2 阶段)
sql/03-hybrid-search.sql 混合搜索 RPC:关键词 + 语义通过 RRF(第 3 阶段)
sql/04-summary.sql 摘要列(提取,无 LLM)
sql/05-facts.sql 事实/首选项层 + match_facts RPC(第 4 阶段,可选)
supabase/functions/embed/ gte-small 嵌入边缘函数(第 2 阶段)
scripts/backfill_summaries.py 填充现有行的摘要(一次性)
scripts/extract_facts.py 通过您的 LLM 将会话提炼成事实(第 4 阶段,可选)
scripts/consolidate_facts.py 通过 LLM 审查/合并重复事实(第 5 阶段,手动)
sql/06-find-fact-dupes.sql 查找近似重复事实对(第 5 阶段)
sql/07-profile.sql 开发者配置文件模式表(第 9 阶段,可选)
scripts/synthesize_profile.py 通过 LLM 提炼跨项目开发者配置文件(第 9 阶段,可选)
scripts/apply_profile_rules.py 将批准的配置文件规则写入 ~/.claude/profile-rules.md(第 9 阶段)
scripts/backup.sh pg_dump 备份(在始终在线的主机上 cron)
scripts/pull-backups.sh rsync 备份到此机器
scripts/backup.py 可移植的逻辑备份(REST/NDJSON,无 pg 客户端)
scripts/embed_pending.py 嵌入缺少向量的会话(第 2 阶段)
scripts/search.py 语义搜索 CLI(第 2 阶段)
docs/ 架构和设计决策
```
## 许可证
[MIT](LICENSE)
## 明星、分享、贡献
如果今天它帮助您避免为您的代理程序第十次解释您的项目,请给存储库一个星星。它真的帮助其他人找到它。
想法、粗糙边缘或您的工具的捕获适配器(Cursor、Gemini CLI...)?打开一个问题或拉取请求。如果您在此基础上构建某些内容,我很乐意看到它。
## 由
由 **[buildcomcarlos.com](https://buildcomcarlos.com)** 制作:有关 AI 代理、iOS 和独立开发软件的文章和开放工具。如果此项目对您有帮助,该网站是深入研究和后续实验的所在地。请打声招呼。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器