共享代理内存
AI代理团队的自我更新RAG。共享代理内存为Claude Code、Codex、Cursor和其他MCP客户端提供了一个由Qdrant支持的通用、可搜索的项目内存,然后推动代理在工作时保持该内存的最新状态。
团队获得了一个随着时间的推移而改进的共享检索层,而不是每个代理都重新发现相同的仓库模式、基础设施细节和故障排除历史。代理在深入文件之前搜索内存存储,只加载相关的完整笔记,并在对话揭示值得保留的内容时存储或更新持久的学习。
特性
- 团队RAG层 --跨项目、存储库和代理的共享检索增强上下文
- 自我更新工作流程 --Claude Code、Codex和Cursor插件附带了停止钩子,每五次助理转动就会提示内存管理
- 项目意识写作 --新内存默认为当前git项目;除非经过筛选,否则搜索将覆盖所有可访问的项目
- 混合搜索 --密集向量相似性(全MiniLM-L6-v2)+BM25关键字匹配,与往复式秩融合融合
- 艾宾浩斯遗忘曲线 --记忆会随着时间的推移而衰退;频繁访问的记忆会持续存在,未使用的记忆会在大约6个月后褪色并被刻上墓碑
- 秘密过滤 -四层检测(已知的令牌前缀、高熵字符串、证书分配、关键字接近)拒绝包含API密钥、令牌或证书的内存
- REST API --使用Swagger UI对Fastify服务器进行身份验证;MCP客户端也使用此API
- 内存浏览器 -独立的web用户界面,可通过Qdrant的REST API直接浏览、搜索、编辑和删除内存
- 多代理存储器 -多个人工智能代理通过一个API共享相同的内存存储
- 两步搜索 --首先返回标题以提高上下文效率,然后按需加载全文
- 本地嵌入 -全MiniLM-L6-v2在本地运行,外部API成本为零
- API支持的MCP -MCP工具直接调用REST API;无后台MCP守护进程
运作原理
- 客服电话
search_memory从团队记忆存储中检索紧凑的标题和ID。 - 客服电话
load_memories仅适用于相关点击,保持低上下文使用率。 - 客服电话
store_memory新的持久学习和update_memory当现有知识发生变化时。 - 代理插件每五个助手回合注入一次规范的内存捕获提示,提醒活动代理先搜索,更新过时的内存,并存储新的架构/工作流/故障排除学习。
钩子是故意基于提示的。它在正常的代理插件环境中工作,不需要单独的后台模型进程或直接的Qdrant访问。REST API仍然对每次写入强制执行身份验证、项目访问、审核元数据和秘密过滤。
Claude代码设置
市场安装
安装克劳德代码市场和插件:
curl -fsSL https://raw.githubusercontent.com/rbrcurtis/shared-agent-memory/main/install.sh | bash项目范围:
curl -fsSL https://raw.githubusercontent.com/rbrcurtis/shared-agent-memory/main/install.sh | SCOPE=project bash或者从结账处:
git clone https://github.com/rbrcurtis/shared-agent-memory.git
cd shared-agent-memory
scripts/setup-claude-code.shClaude Code将提示:
| 选项 | 描述 | 默认值 |
|---|---|---|
memory_api_url | 共享内存API基本URL | http://localhost:3100 |
memory_api_key | 需要内存API | 的承载令牌 |
default_agent | 代理存储在新内存中 | claude-code |
default_project | 新内存的可选项目覆盖 | 自动检测 |
对于此结账处的本地市场测试:
scripts/setup-claude-code.sh --local对于具有共享团队配置的项目级设置:
scripts/setup-claude-code.sh \
--scope project \
--memory-api-url https://memory.example.com \
--memory-api-key TEAM_API_KEY \
--default-agent claude-code \
--default-project my-project这将写入插件启用和 pluginConfigs 值到 .claude/settings.json 在目标仓库中。只有当API密钥有意与团队共享时,才提交该文件。
对于内部叉子或镜子:
curl -fsSL https://raw.githubusercontent.com/rbrcurtis/shared-agent-memory/main/install.sh | SOURCE=github-org/shared-agent-memory bash手动CLI等效工具:
claude plugin marketplace add rbrcurtis/shared-agent-memory
claude plugin install shared-agent-memory@shared-agent-memory安装范围
| 范围 | 标志 | 配置文件 | 用例 |
|---|---|---|---|
| 用户 | --scope user | Claude用户设置 | 所有项目的共享内存API |
| 项目 | --scope project | Project Claude设置 | 团队/项目安装 |
| 本地 | --scope local | 本地Claude设置 | 机器本地测试安装 |
安装脚本默认为用户作用域。通过 --scope project 或 --scope local 需要时:
scripts/setup-claude-code.sh --scope project直接MCP回退
首选市场插件。对于一次性直接安装MCP:
git clone https://github.com/rbrcurtis/shared-agent-memory.git
cd
npm install
npm run build
claude mcp add-json shared-memory '{
"type": "stdio",
"command": "node",
"args": ["
/dist/index.js"],
"env": {
"MEMORY_API_URL": "http://localhost:3100",
"MEMORY_API_KEY": "your-bearer-token",
"DEFAULT_AGENT": "claude-code"
}
}'MCP服务器与REST API对话。它不会启动Qdrant,也不会运行后台守护进程。
Codex设置
Codex支持以本地插件清单和本地回购市场的形式提供:
.codex-plugin/plugin.json-Codex插件元数据.agents/plugins/marketplace.json-此回购的市场准入.mcp.codex.json-绑定MCP服务器配置hooks/hooks.json-食品法典委员会Stop内存捕获挂钩
将此仓库添加为Codex市场:
codex plugin marketplace add rbrcurtis/shared-agent-memory对于本次结账的本地测试:
codex plugin marketplace add "$(pwd)"然后打开 /plugins 在Codex中,安装 共享代理内存,并启动一个新线程。捆绑的插件挂钩需要:
codex features enable plugin_hooks默认情况下,Codex挂钩处于启用状态。如果它们在本地被禁用,请重新启用它们:
codex features enable hooksCodex MCP配置转发 MEMORY_API_URL, MEMORY_API_KEY, DEFAULT_AGENT,以及 DEFAULT_PROJECT 来自Codex的当地环境。如果您更喜欢显式用户配置,请在中保留一个直接的MCP条目 ~/.codex/config.toml:
[mcp_servers.shared-memory]
command = "/path/to/shared-agent-memory/bin/shared-agent-memory"
startup_timeout_sec = 60
[mcp_servers.shared-memory.env]
MEMORY_API_URL = "http://localhost:3100"
MEMORY_API_KEY = "your-bearer-token"
DEFAULT_AGENT = "codex"
DEFAULT_PROJECT = ""光标设置
Cursor支持与官方Cursor市场具有相同的插件形状:
.cursor-plugin/marketplace.json-回购市场准入.cursor-plugin/plugin.json-游标插件元数据.mcp.cursor.json-绑定MCP服务器配置hooks/hooks.cursor.json-光标stop内存捕获挂钩
对于本地测试,将此签出作为本地Cursor插件公开并重新加载Cursor:
mkdir -p ~/.cursor/plugins/local
ln -s "$(pwd)" ~/.cursor/plugins/local/shared-agent-memory对于团队推出,请导入 rbrcurtis/shared-agent-memory 作为Cursor团队市场,并启用自动刷新。市场更新是由回购驱动的;新的推送会被重新索引,客户端会在刷新/重启时接收它们。
Cursor MCP配置启动 bin/shared-agent-memory 通过 CURSOR_PLUGIN_ROOT 和违约 DEFAULT_AGENT 到 cursor。在Cursor的环境或部署包装器中设置这些:
export MEMORY_API_URL=http://localhost:3100
export MEMORY_API_KEY=your-bearer-token
export DEFAULT_AGENT=cursor仅当您需要插件市场之外的机器本地凭据时,才使用直接游标MCP条目。
项目范围界定
主控程序 store_memory 在检测到的当前项目中存储新内存 project 省略。代理人可以通过 project 只有当故意将知识保存到另一个相关的仓库时。MCP服务器通过以下方式确定默认项目:
- Git远程 (首选):摘自
git remote get-url origin
- https://github.com/user/my-app.git → my-app - git@bitbucket.org:team/backend.git → backend
- 文件夹名称 (回退):不在git仓库中时使用
搜索和最近列表默认为API键可以访问的所有项目。通过 project 到 search_memory, list_recent,或REST API端点以筛选到单个项目。搜索结果包括项目名称,以便调用者可以看到每个内存的来源。
代理说明
Claude Code、Codex和Cursor插件会自动注册一个停止钩子。助手转动后,钩子运行共享包装器:
bin/shared-agent-memory --memory-turn-hook钩子在可用时从客户端转录中计算助手的轮次,回退到每个会话的插件数据,并每五个助手轮次注入一次规范的内存捕获提示。提示告诉活动代理:
- 回顾对话以获得持久的学习
- 写作前搜索现有记忆
- 更新过时的记忆,而不是创建重复的记忆
- 存储新的架构、工作流程、故障排除、代码库、基础设施和用户偏好学习
- 每个内存保留一个概念
为了保持内存使用的一致性,还可以添加持久指令 ~/.claude/CLAUDE.md 或回购 CLAUDE.md/AGENTS.md:
## Shared Memory
- **ALWAYS search_memory BEFORE searching files** when tasks need project context
- **ALWAYS store_memory** when you learn: workflows, troubleshooting, codebase patterns, user preferences, infrastructure
- **ALWAYS update_memory** when information changes - no stale duplicates
- One concept per memory, descriptive text for semantic search配置
环境变量
| 变量 | 描述 | 默认值 |
|---|---|---|
MEMORY_API_URL | MCP客户端的内存API基本URL | http://localhost:3100 |
MEMORY_API_KEY | MCP客户端的承载令牌 | 必填 |
DEFAULT_AGENT | 默认代理标识符 | unknown |
DEFAULT_PROJECT | 覆盖自动检测到的项目 | git仓库名称或文件夹 |
CLI参数
node dist/index.js \
--memory-api-url http://localhost:3100 \
--memory-api-key YOUR_KEY \
--agent claude-codeMCP工具
| 工具 | 说明 |
|---|---|
store_memory | 存储带有标题的文本,自动生成嵌入 |
search_memory | 默认情况下,在所有可访问的项目中进行语义搜索——返回标题、ID、项目和分数 |
load_memories | 按ID加载全文,强化加载的记忆 |
list_recent | 默认情况下,列出所有可访问项目的最近内存——返回标题、ID和项目 |
update_memory | 用新的文本和标题更新现有内存 |
delete_memory | 按ID删除内存 |
get_config | 显示当前MCP/neneneba API配置 |
两步搜索
搜索是为了提高上下文效率而设计的。它不会为每个结果转储全文,而是返回紧凑的标题,以便代理可以选择实际读取哪些记忆:
search_memory--返回带有ID和相关性得分的标题列表- 代理人审查标题,选择相关标题
load_memories--获取所选ID的全文
这很重要,因为AI代理的上下文窗口有限。返回10个完整的记忆可能会消耗数千个令牌,其中大多数是无关紧要的。头衔让经纪人有选择性。
混合搜索
搜索使用交互秩融合(RRF)结合了两种检索策略:
- 密集向量:语义相似性通过
all-MiniLM-L6-v2嵌入(384个维度) - BM25稀疏向量:通过Qdrant内置的BM25模型进行关键字匹配
这意味着搜索“Docker compose”会找到提到容器和编排(语义)的记忆,以及那些字面上说“Docker composer”(关键字)的记忆。这两种策略都融合到一个排名结果列表中。
REST API
基于Fastify的HTTP服务器,适用于非MCP客户端,具有OpenAPI规范和Swagger UI。
设置
# Run directly
PORT=3100 QDRANT_URL=http://localhost:6333 node dist/api/server.js
# Or via Docker
docker build -t shared-agent-memory .
docker run -p 3100:3100 \
-e QDRANT_URL=http://your-qdrant:6333 \
-e QDRANT_API_KEY=optional \
-e API_KEYS='[{"key":"your-bearer-token","name":"my-service","projects":null}]' \
shared-agent-memorySwagger用户界面可在 http://localhost:3100/docs.
认证
通过 API_KEYS 环境变量(JSON数组):
[
{
"key": "your-secret-token",
"name": "my-service",
"projects": ["project-a", "project-b"]
}
]projects: null--完全访问所有项目projects: ["a", "b"]--仅限于上市项目
端点
| 方法 | 端点 | 描述 |
|---|---|---|
| 得到 | /health | 健康检查(无身份验证) |
| 职位 | /api/v1/memories | 存储内存 |
| 得到 | /api/v1/memories/search | 搜索保留率重新排名 |
| 得到 | /api/v1/memories/load | 按ID加载全文,加强 |
| 得到 | /api/v1/memories/recent | 按创建日期列出最近的 |
| 得到 | /api/v1/memories/:id/audit | 列出内存的审核事件 |
| PUT | /api/v1/memories/:id | 更新内存 |
| 删除 | /api/v1/memories/:id | 删除内存 |
| 得到 | /api/v1/config | 服务器配置和型号状态 |
| 得到 | /docs | Swagger用户界面(无身份验证) |
审核元数据
每个内存在其有效载荷中存储当前审计元数据:
createdAt/updatedAtcreatedBy/updatedBy
actor字段使用匹配的API键 name。创建、更新和删除操作还将只追加审计事件写入名为的配套Qdrant集合 _audit.
艾宾浩斯遗忘曲线
使用受 艾宾浩斯遗忘曲线这确保了未使用的记忆会自然褪色,而频繁访问的记忆会持续存在。
运作原理
每个内存跟踪三个字段:
last_accessed--上次加载内存的时间戳access_count--它被加载了多少次stability--从access_count派生,控制内存衰减的速度
当时的留存率(召回概率) t 自上次访问以来的天数为:
retention = e^(-t / (BASE_HALF_LIFE * stability / ln(2)))随着 BASE_HALF_LIFE = 27 days,从未访问过的内存(稳定性=1.0)在27天后保留率降至50%。频繁访问的内存衰减得慢得多,因为它们的稳定性呈对数增长:
| 访问次数 | 稳定性 | 有效半衰期 |
|---|---|---|
| 0 | 1.0 | 27天 |
| 1 | 1.69 | 46天 |
| 5 | 2.79 | 75天 |
| 10 | 3.40 | 92天 |
| 20 | 4.04 | 109天 |
通过加载而非搜索进行加固
关键设计选择: 搜索不会强化记忆.只有 load_memories (显式获取全文)算作访问。这意味着:
- 出现在搜索结果中但从未加载的内存将自然衰减
- 只有特工发现足够有用的记忆才能被强化
- 系统通过实际使用而不仅仅是语义接近来学习哪些记忆是重要的
跳崖跳水
当内存的保留率降至1%以下时(TOMBSTONE_THRESHOLD = 0.01),通过设置a将其软删除 tombstoned_at 时间戳。墓碑记忆被排除在所有未来的查询之外,但仍保留在Qdrant中以进行潜在的恢复。
从未访问过的内存在大约 180天(约6个月).即使加载几次的记忆也会持续更长时间——加载5次的记忆在一年多的时间里都不会成为墓碑。
墓碑检查在搜索过程中发生得很慢——当搜索返回一个腐烂的记忆时,它会被作为副作用而被墓碑。
搜索重新排名
在搜索过程中,Qdrant的原始相似性得分乘以保留值。这意味着最近频繁使用的记忆的排名高于陈旧的记忆,即使陈旧的记忆在语义上稍好一些。为了补偿过滤,在对最终结果集应用保留重新排名和修剪之前,搜索会获得请求限制的3倍。
秘密过滤
记忆在储存前会被扫描以寻找秘密。如果检测到秘密,内存将被拒绝,并显示一个错误,描述发现的内容——然后调用代理可以编辑并重试。
四个检测层,按顺序应用:
- 已知前缀模式 --约24种已知令牌格式(GitHub PAT、AWS密钥、Slack令牌、JWT、私钥、Webhook等)的正则表达式规则
- 高熵长串 --十六进制字符串≥32个字符或base64字符串≥17个字符,香农熵>3.0
- 凭证分配 --直接分配模式(
token=value,api_key: value)其中值包含数字或特殊字符 - 关键字邻近度 --关键字50个字符以内的高熵字符串(>8个字符,熵>3.2),如
token,password,api_key,secret,bearer
误报过滤跳过代码标识符(camelCase)、文件路径、烤肉串大小写字符串和MongoDB ObjectID。
适用于两者 store_memory 和 update_memory API级别,涵盖所有客户。
内存浏览器
用于浏览、搜索、编辑和删除记忆的独立web UI。单个HTML文件(web/index.html)使用内联CSS/JS——没有构建步骤,没有框架,没有服务器。
- 直接与Qdrant的REST API对话(需要在Qdrant上启用CORS)
- 通过Qdrant内置的稀疏向量查询进行BM25关键字搜索
- 显示内存衰减状态的保留条
- 按项目、代理、标签过滤;切换墓碑记忆
- 编辑标题、文本和标签;墓碑删除记忆
本地打开:
file:///path/to/web/index.html?url=http://localhost:6333&key=YOUR_KEY有关Kubernetes部署,请参阅 k8s/ 目录(nginx通过ConfigMap提供静态文件)。
建筑
Agent 1 (Claude Code) ──┐
├── MCP Wrapper ── REST API (Fastify) ── Qdrant
Agent 2 (Codex) ──┤ localhost:3100
Agent 3 (Cursor) ──┘
External Service ────── REST API (Fastify) ── Qdrant
localhost:3100API过程将嵌入模型加载到内存中,以便快速响应:
- MCP包装器 (
index.ts):暴露内存工具的精简stdio服务器 - 客户 (
client.ts):用于REST API的HTTP客户端 - REST API (
api/server.ts):加速服务器的内存操作和嵌入生成
使用本地生成的嵌入 all-MiniLM-L6-v2 (384个维度)。API外部成本为零。
码头工人
docker build -t shared-agent-memory .
docker run -p 3100:3100 \
-e QDRANT_URL=http://host.docker.internal:6333 \
-e API_KEYS='[{"key":"your-token","name":"default","projects":null}]' \
shared-agent-memoryDocker镜像运行REST API服务器。对于MCP服务器,运行 node dist/index.js 直接;它使用stdio进行MCP,使用HTTP进行内存操作。
许可证
麻省理工学院
