AI长期记忆架构

为IDE中的AI助手提供长期记忆架构,通过MCP协议实现记忆管理和检索功能。

  • by asromanychev
  • Ruby
  • 本地部署
  • 更新于
在 GitHub 查看 asromanychev/memcp

使用说明

MEMCP:IDE中AI的长期内存架构

MVP迭代1:IDE中AI长期内存体系结构的最低可行版本。

描述

该项目通过MCP(Model Context Protocol)为IDE(例如Cursor IDE)中的AI助理提供了长期内存架构。包括:

  • 轨道核心API:仅API内存管理应用程序(PostgreSQL+PgVector)
  • Sidekiq+Redis:使用Redis通过SideKiq异步处理任务
  • Ruby MCP服务器:通过MCP协议与IDE集成的STDIO服务器

快速启动

📘 INSALES项目: 见E/CN.4/Sub.2/2000/SR.1。详细说明 安装_INSALES.md 提供在Cursor IDE中安装和连接MCP服务器的分步说明。

选项A:Docker(推荐)

需要安装Docker和Docker Compose(插件) docker compose).
Compose文件使用 dev-收集的DockerFile层 一切 依赖(包括 development/test).

  1. 收集并运行所有服务(Rails API,PostgreSQL+PgVector,Redis):
    docker compose up --build
    
  2. 第一次运行后,不需要做任何额外的事情-容器将执行 bundle install 和 rails db:prepare 自动。
  3. API将在 http://localhost:3101数据库 localhost:15433Redis - 在 localhost:16380.

有用的命令:

  • 停止包围: docker compose down
  • 重新安装GEMS: docker compose run --rm web bundle install
  • 运行测试: docker compose run --rm web bundle exec rspec
  • 运行单个Rails命令: docker compose run --rm web ./bin/rails <command>
  • 连接到数据库: docker compose exec db psql -U postgres memcp_development
  • 加入Redis: docker compose exec redis redis-cli
  • 查看SideKiq日志: docker compose logs worker -f

服务端口是通过ENV指定的,默认情况下不会与标准值重叠:
•API: 3101 (MEMCP_WEB_PORT)
•PostgreSQL: 15433 (MEMCP_DB_PORT)
•Redis: 16380 (MEMCP_REDIS_PORT)
如有必要,在启动时重新定义它们,例如 MEMCP_WEB_PORT=3200 MEMCP_DB_PORT=25433 MEMCP_REDIS_PORT=26380 docker compose up.

Sidekiq Worker(任务队列)

默认情况下,SideKiq Worker不会启动。可以这样启动它:

docker compose --profile queue up

Worker使用Redis存储任务队列。Redis的配置在 config/database.yml (科 redis:(a)在国家、区域和国际各级建立数据库;

  • default (db:0)Redis的一般用途
  • sidekiq (db:1)-SideKiq队列

测试Redis和SideKiq:

# Проверка Redis
docker compose exec redis redis-cli ping

# Проверка через Rails console
docker compose run --rm web bundle exec rails runner 'puts $redis.ping; puts Sidekiq.redis { |c| c.ping }'

# Постановка тестовой джобы в очередь
docker compose run --rm web bundle exec rails runner 'TestJob.perform_async("test")'

选项B:本地安装

bundle install

# Создайте базу данных PostgreSQL
sudo -u postgres psql -c "CREATE DATABASE memcp_development;"
sudo -u postgres psql -d memcp_development -c "CREATE EXTENSION IF NOT EXISTS vector;"

# Запустите миграции
rails db:create
rails db:migrate

# Убедитесь, что Redis запущен локально или через Docker
# Запустите Sidekiq worker (в отдельном терминале)
bundle exec sidekiq -C config/sidekiq.yml

# Заполнить embeddings для существующих записей (опционально)
rails memories:generate_embeddings

# Запуск Rails API
rails server

API也将在 http://localhost:3001

本地Embeddings(QWEN3 0.6b,Matryoshka 1024d)

  • 默认提供程序: MEMORY_EMBEDDING_PROVIDER=local_1024.
  • QWEN3-embedding-0.6b模型(量化Q8u 0)从存储库下载 Qwen/Qwen3-包埋-0.6B-GGUF.
    推荐的文件: Qwen3-Embedding-0.6B-Q8_0.gguf (约1.2 GB)
  • 天平路径由变量指定。 MEMORY_EMBEDDING_MODEL_PATH默认使用 tmp/embeddings/Qwen3-Embedding-0.6B-Q8_0.gguf.
  • 设置matryoshka模式 MEMORY_EMBEDDING_OUTPUT_DIM=1024 (默认值与数据库布局相同)。
  • 本地服务的Endpoint MEMORY_EMBEDDING_ENDPOINT (默认) http://127.0.0.1:8081/embed).
  • 要下载模型,请使用 bin/setup_embeddings (支持) HF_TOKEN 通过SHA256验证 MEMORY_EMBEDDING_MODEL_SHA256).
  • 环境要求: python3 (支持) venv), pip, cmake编译器(build-essential/gcc)。脚本 bin/embedding_server 创建虚拟环境 tmp/embedding-venv 建立依赖关系 embeddings/requirements.txt (FastAPI、uvicorn、骆驼cpp-python)。
  • 开放源码软件(openai_1536(a)留待将来扩大;它需要 OPENAI_API_KEY.

快速启动(本地,包括Embeddings)

bin/setup          # устанавливает зависимости, миграции и очередь (запускает bin/dev автоматически)

bin/dev 启动Rails和Embeddings服务 Procfile.dev.要手动启动服务:

bin/setup_embeddings        # скачивает веса
MEMORY_EMBEDDING_PORT=8081 bin/embedding_server
bin/rails server
# Sidekiq: запуск воркера в отдельном терминале
# bundle exec sidekiq -C config/sidekiq.yml

### Atlas Adapter (зеркалирование insales_atlas)

- Сервис `Atlas::SyncService` копирует документы из `insales_atlas/` в `storage/atlas/`, вычисляет SHA256 и избавляется от дубликатов (один blob на несколько источников).
- Для запуска синхронизации:  
  ```bash
  bundle exec rails atlas:sync
  • 元数据可在 storage/atlas/index.json,内容在 storage/atlas/blobs/.
  • 重新启动更新索引并仅复制新的/修改的文件(SHA)。
  • 目录 storage/ 没有版本化:每个开发人员都在本地填充它(见下文)。 storage/README.md).清理环境时,可以删除内容。

### File Sync Adapter (локальные документы)

- `FileSync::WatcherService` синхронизирует `documents/` в `storage/documents/`, вычисляет SHA и обновляет индекс.
- Поддерживаются текстовые расширения `.md`, `.mdc`, `.txt`, `.rb`, `.js`, `.sql`, `.json`, `.yml`, `.yaml`.
- Запуск initial sync + watcher:
  ```bash
  bundle exec rails runner 'FileSync::WatcherService.call(params: { source_root: Rails.root.join("documents"), target_root: Rails.root.join("storage/documents") })'

(将进程保持在一个单独的终端中- listen 跟踪变化)。

  • 元数据位于 storage/documents/index.json删除源文件删除索引中的副本和条目。
  • 短烟:
    echo "# notes" > documents/sample.md
    bundle exec rails runner 'service = FileSync::WatcherService.call(params: { source_root: Rails.root.join("documents"), target_root: Rails.root.join("storage/documents") }); sleep 1'
    cat storage/documents/sample.md
    cat storage/documents/index.json | jq .
    
    检查停止手表组合后 Ctrl+C.

技能与规划师(MVP)

  • 技能通过 Skills::Registry;现在可用:
    • atlas_search(query:, limit: 10) 搜索镜子 storage/atlas/index.json.
    • documents_grep(pattern:, limit: 10) -文本搜索 storage/documents/.
  • 规划者 Planner::SimplePlanner 根据要求或接受技能 skill_id 显然
  • 实例:
    result = Planner::SimplePlanner.call(params: { query: "atlas adr short link" })
    puts result.result[:result][:matches]
    
    result = Planner::SimplePlanner.call(params: { skill_id: :documents_grep, skill_params: { pattern: "CartSessions" } })
    puts result.result[:result][:matches]
    
  • 错误的技能回归 result.result[:errors].

可观察性中心(推理-логи)

  • Observability::HubService 写事件规划者和技能 storage/logs/observability/current.jsonl格式:JSON,带标准字段(trace_id, event_id, operation, status, duration_ms, payload, extra, error).
  • 内置旋转:当您达到10‧MB时,文件将重命名为 current.jsonl.<timestamp>.jsonl.gz新文件将自动创建。
  • Smoke脚本:
    # 1. Подготовить временный источник Atlas
    mkdir -p tmp/atlas_demo/guides
    cat <<'EOF' > tmp/atlas_demo/guides/intro.md
    # Demo Guide
    Demo document for observability smoke.
    EOF
    
    bundle exec rails runner 'Atlas::SyncService.call(params: { source_root: Rails.root.join("tmp/atlas_demo") })'
    
    # 2. Вызвать планировщик с явным навыком
    bundle exec rails runner 'Planner::SimplePlanner.call(params: { query: "", skill_id: :atlas_search, skill_params: { query: "demo" } })'
    
    # 3. Проверить свежие события
    tail -n 5 storage/logs/observability/current.jsonl
    
    # 4. Очистить временные артефакты (опционально)
    rm -rf tmp/atlas_demo
    
  • 技能错误时 status 改为 error,附加上下文将进入 error 和 extra如果日志记录失败,业务逻辑将继续运行(排除在外)。

Embeddings服务验证:

curl -X POST http://127.0.0.1:8081/embed \
     -H "Content-Type: application/json" \
     -d '{"inputs":["embedding smoke test"]}'

答案必须包含数组 embeddings 长1024

形象

DockerFile的最后一层 production只有运行时依赖项和启用模式 RAILS_ENV=production.

docker build --target production -t memcp:latest .

最低运行示例(需要访问数据库和RAILS密钥的环境变量):

docker run --rm \
  -e RAILS_ENV=production \
  -e RAILS_MASTER_KEY=<ваш_rails_master_key> \
  -e DATABASE_URL=postgres://user:password@db:5432/memcp_production \
  -p 3001:3001 \
  memcp:latest

在生产环境中,确保数据库包含扩展名 vector并执行迁移:

docker run --rm \
  -e RAILS_ENV=production \
  -e RAILS_MASTER_KEY=<ваш_rails_master_key> \
  -e DATABASE_URL=postgres://user:password@db:5432/memcp_production \
  memcp:latest \
  bundle exec rails db:migrate

ℹ️ 对于生产部署,请确保数据库支持扩展 vector和钥匙 RAILS_MASTER_KEY 集装箱可用。

构建Docker映像之前的准备

DockerFile仅包含系统依赖项(python3, pip, cmake)因此,在构建或运行容器之前,开发人员需要手动准备模型:

# локально, до docker build
bin/setup_embeddings               # скачивает веса Qwen3 в tmp/embeddings
# опционально проверить сервис
MEMORY_EMBEDDING_PORT=8081 bin/embedding_server &
curl -s http://127.0.0.1:8081/embed \
     -H "Content-Type: application/json" \
     -d '{"inputs":["embedding smoke test"]}' \
     | jq '.embeddings[0] | length'
kill %1   # остановить сервер

然后可以收集图像(docker build ...).集装箱内的模型已经在 tmp/embeddings 卷/工作目录,和 bin/embedding_server 可以类似地启动。

4.在Cursor IDE中配置MCP服务器

将Cursor IDE添加到配置中(~/.cursor/mcp.json 或通过设置):

{
  "mcpServers": {
    "memcp": {
      "command": "ruby",
      "args": ["/Users/asromanychev/dev/memcp/mcp_server.rb"],
      "env": {
        "MEMCP_API_URL": "http://localhost:3101"
      }
    }
  }
}

重要:

  • 更换路径 /Users/asromanychev/dev/memcp/mcp_server.rb 在您的真实文件路径上
  • 验证服务器是否已启动: docker compose --profile queue up
  • API可用 http://localhost:3101 (端口可以更改) MEMCP_WEB_PORT)

配置后重新启动Cursor IDE。

项目结构

  • app/controllers/memory_controller.rb -带插头的API控制器 recall 和 save
  • app/models/ -模型 Project 和 MemoryRecord
  • app/jobs/ -SideKiq Job(基本类) BaseSidekiqJob, GenerateEmbeddingJob, TestJob)
  • db/migrate/ 表的迁移 projects 和 memory_records
  • config/database.yml PostgreSQL和Redis配置 redis:)
  • config/initializers/01_redis.rb 1.加入Redis($redis)
  • config/initializers/sidekiq.rb SideKiq配置(服务器和客户端)
  • config/sidekiq.yml SideKiq队列配置
  • mcp_server.rb -带工具的Ruby MCP STDIO服务器 recall 和 save

API终点

  • POST /recall 寻找记忆(封盖)
  • POST /save 保存记忆(封盖)

MCP工具

  • recall(query, project_path?) -根据要求搜索记忆
  • save(content, project_path, metadata?) -保存内存记录

详细文件

地位

当前状态(2025-11-11):

✅ 完成:

  • MVP-01:核心API服务对象(Memories::RecallService, Memories::SaveService)
  • 2.2.2.2.2.2.2.2.2.3.3.2.3.3.3.3.3.2.3.3.3.3.3.3.3.3.3.3.3.3.3.3.Memories::EmbeddingService,混合搜索 RecallService, GenerateEmbeddingJob)
  • Sidekiq+Redis:使用Redis(类似于Insales的配置,简化版本)通过SideKiq配置任务队列
    • Redis配置 config/database.yml 具有默认(DB:0)和SideKiq(DB:1)的单独数据库
    • 初始化 $redis 在 config/initializers/01_redis.rb
    • SideKiq配置 config/initializers/sidekiq.rb
    • 基类 BaseSidekiqJob 用于口袋
  • Atlas适配器(Atlas::SyncService)镜像INSALES_ATLAS
  • 文件同步适配器(FileSync::WatcherService•本地文件同步
  • 技能与规划师MVP(Skills::Registry, Planner::SimplePlanner, 技能 atlas_search 和 documents_grep)
  • Observability Hub(基本实现: Observability::HubService,jsonl-旋转日志,集成到调度程序中)

以下步骤:

第2阶段(进行中):

  • MVP-03:冗余(用于检测相似记录的Simhash/Minhash和Upsert逻辑)

第3阶段(推迟):

  • 扩展观察集线器:技能集合,导出到Prometheus/Clickhouse,警报
    • 必要时: 在实际负载下(几十个查询/分钟),需要监控生产,团队成长(需要Dashboard),自动诊断问题
  • Demo Playbooks(Resettable脚本)

许可证

麻省理工学院