# Git 一致性优先的共享记忆检索系统 本项目在现有 QMD 基础上增加 `memory-gateway`,目标是让多 Agent 查询具备“查询前强制同步”的一致性,而不是只依赖后台轮询同步。 ## 1. 项目背景 在多 Agent 协作里,若“同步”和“查询”解耦为两个松散后台动作,会出现: - Agent A 读到旧记忆 - Agent B 读到新记忆 - 对任务目标、恢复点、执行上下文理解分叉 本项目的核心设计: - Git 是 source of truth - QMD 只做索引和检索 - memory-gateway 负责查询前同步与一致性协调 ## 2. 架构与一致性事务 ```mermaid flowchart LR C[Remote Client\nCodex/Claude/OpenClaw] --> G[memory-gateway\nHTTP :8787] G --> S[Sync Transaction\nfetch -> workspace sync -> qmd update/embed] S --> Q[qmd search/query\nper-workspace index] Q --> G G --> C G --> M[/data/git-mirror/repo.git] G --> W1[/data/workspaces/main] G --> W2[/data/workspaces/memory-2026-03] G --> W3[/data/workspaces/task-TASK-001] ``` `/query` 的主链路: 1. 解析 `branch / memory_profile / query_type / query` 2. 获取 workspace 锁(同 workspace 串行,不同 workspace 并行) 3. `git fetch` + workspace 对齐到目标 branch 最新 commit 4. `qmd update`(需要时 `embed`) 5. 执行检索 6. 返回结果 + `branch/commit_hash/synced_at/workspace` ## 3. 服务职责 ### qmd - 提供 MCP/HTTP 能力(`8181`) - 持久化 cache/config - 作为底层检索引擎,不作为远程客户端唯一入口 ### memory-gateway - 远程唯一入口(`8787`) - 提供 `GET /health`、`POST /query`、`POST /sync`、`GET /status` - 强制执行查询前同步 ### warmup(可选) - 定时轻量请求,降低冷启动抖动 - 仅优化项,不提供一致性保证 ## 4. 目录与关键路径 ### 仓库目录(Host) ```text . ├─ docker-compose.yml ├─ .env.example ├─ AGENTS.md ├─ README.md ├─ gateway/ │ ├─ app/ │ ├─ tests/ │ ├─ requirements.txt │ └─ Dockerfile ├─ scripts/ │ ├─ qmd-entrypoint.sh │ ├─ bootstrap.sh │ ├─ warmup.sh │ └─ smoke-test.sh └─ data/ ├─ git-mirror/ ├─ workspaces/ ├─ qmd-cache/ ├─ qmd-config/ └─ remote-memory.git/ # bootstrap 生成的本地 demo remote ``` ### 容器内路径 - Git mirror: `/data/git-mirror/repo.git` - Workspace 根目录: `/data/workspaces` - QMD cache: `/var/lib/qmd/cache`(qmd 容器)/ `/data/qmd-cache`(gateway 调 CLI) - QMD config: `/var/lib/qmd/config`(qmd 容器)/ `/data/qmd-config`(gateway 调 CLI) ### 查询返回路径映射(项目相对路径) 为方便你直接在项目目录定位,`/query` 与 `/sync` 返回的 `resolved_workspace` 使用项目相对路径,而不是容器绝对路径。 - `main` -> `data/workspaces/main` - `memory/2026-03` -> `data/workspaces/memory-2026-03` - `task/TASK-001` -> `data/workspaces/task-TASK-001` 内部容器路径仍是 `/data/workspaces/...`,网关会在响应时转换为相对路径表示。 ## 5. 分支与 profile 规则 优先级:`branch > memory_profile > main` - `stable` -> `main` - `monthly-YYYY-MM` -> `memory/YYYY-MM` - `task-` -> `task/` 建议分层: - 长期稳定:`main` - 月度滚动:`memory/YYYY-MM` - 任务临时:`task/` ## 6. 环境变量(关键配置) ### 必填 - `GIT_REMOTE_URL`:Git 真相源地址(ssh/https/file/path) ### 常用 - `DEFAULT_BRANCH`:默认分支(默认 `main`) - `QMD_TIMEOUT_SECONDS`:gateway 调 qmd CLI 超时秒数(默认 `300`) - `QMD_INDEX_PREFIX`:per-workspace 索引名前缀(默认 `ws`) - `QMD_UPDATE_ON_LATEST_QUERY`:`require_latest=true` 时是否强制 `qmd update`(默认 `true`) - `QMD_EMBED_ON_CHANGE`:HEAD 变化时是否尝试 embed(默认 `true`,可按性能改 `false`) ### GPU(qmd 容器) - `CUDA_DEVICE` - `CUDA_VISIBLE_DEVICES` - `NVIDIA_VISIBLE_DEVICES` ### 模型覆盖(可选) - `QMD_EMBED_MODEL_URI` - `QMD_RERANK_MODEL_URI` - `QMD_GENERATE_MODEL_URI` 示例:见 `[.env.example](/home/lingyuzeng/project/qmd-local/qmd-docker-http-mcp/.env.example)`。 ## 7. 快速开始 ### 7.1 初始化 demo remote 与目录 ```bash cd /home/lingyuzeng/project/qmd-local/qmd-docker-http-mcp ./scripts/bootstrap.sh ``` ### 7.2 启动 ```bash docker compose build docker compose up -d ``` ### 7.3 健康检查 ```bash curl http://127.0.0.1:8181/health curl http://127.0.0.1:8787/health ``` ## 8. API 使用 ### GET /health ```bash curl -fsS http://127.0.0.1:8787/health ``` ### POST /sync ```bash curl -fsS -X POST http://127.0.0.1:8787/sync \ -H 'content-type: application/json' \ -d '{"branch":"main","require_latest":true}' ``` ### POST /query(主入口) ```bash curl -fsS -X POST http://127.0.0.1:8787/query \ -H 'content-type: application/json' \ -d '{ "branch":"main", "query_type":"search", "query":"recovery strategy", "require_latest":true, "debug":true }' ``` 返回字段核心: - `ok` - `branch` - `resolved_workspace`(项目相对路径,例如 `data/workspaces/main`) - `commit_hash` - `synced_at` - `query_type` - `results` - `qmd_collection` - `debug`(可选) ### GET /status ```bash curl -fsS http://127.0.0.1:8787/status ``` ## 9. 查询策略说明 当前最小兼容实现中: - `query_type=search` -> `qmd search` - `query_type=vsearch` -> `qmd vsearch` - `query_type=query/deep_search` -> 为保证稳定与时延上界,默认走 `qmd search`(响应 `debug.qmd_command` 可追踪) ## 10. 测试与验收 ### 自动化测试 ```bash python3 -m venv .venv . .venv/bin/activate pip install -r gateway/requirements.txt pytest httpx PYTHONPATH=./gateway pytest -q gateway/tests ``` ### 手工验收(建议) 1. 构建与启动 2. 服务健康 3. 基础查询 4. 修改远端后立即查询(验证查询前同步) 5. 分支隔离 6. 默认分支 7. 并发查询 8. 重启恢复 ## 11. 常见问题 ### 首次请求慢 首次模型/索引准备、或首次分支激活会慢。可用: - `QMD_EMBED_ON_CHANGE=false`(降低请求阻塞) - warmup profile 预热 ### 本地路径 remote 被 git safe.directory 拦截 gateway 已对本地 `GIT_REMOTE_URL` 自动添加 `safe.directory`。 ## 12. 客户端接入建议 - 远程客户端只访问 `memory-gateway`,不要直连 qmd - 每次请求尽量显式传 `branch` 或 `memory_profile` - 记录响应中的 `branch + commit_hash` 用于审计与回放 ## 13. 关键文件 - 网关入口:[gateway/app/main.py](/home/lingyuzeng/project/qmd-local/qmd-docker-http-mcp/gateway/app/main.py) - 同步事务:[gateway/app/sync_service.py](/home/lingyuzeng/project/qmd-local/qmd-docker-http-mcp/gateway/app/sync_service.py) - Git 管理:[gateway/app/git_manager.py](/home/lingyuzeng/project/qmd-local/qmd-docker-http-mcp/gateway/app/git_manager.py) - QMD 调用:[gateway/app/qmd_client.py](/home/lingyuzeng/project/qmd-local/qmd-docker-http-mcp/gateway/app/qmd_client.py) - Compose 编排:[docker-compose.yml](/home/lingyuzeng/project/qmd-local/qmd-docker-http-mcp/docker-compose.yml) ## 14. 多 Agent 记忆仓库最佳实践 ### 14.1 子记忆仓库怎么放 建议把“记忆系统仓库”单独管理,并在本项目中通过 `.gitignore` 忽略运行态 clone/mirror/workspace。 - 推荐:独立 memory repo(独立 push/pull 生命周期) - 不推荐主方案:submodule(多 agent 高频写入时维护成本高、冲突处理复杂) ### 14.2 推荐目录结构(memory repo 内) ```text memory-repo/ ├─ shared/ │ ├─ announcements/ │ └─ sop/ ├─ agents/ │ ├─ agent-a/ │ │ ├─ AGENT-CARD.md │ │ ├─ MEMORY-LOG.md │ │ ├─ PROMPT-RULES.md │ │ ├─ inbox/ │ │ ├─ working/ │ │ ├─ handoff/ │ │ └─ checkpoints/ ├─ tasks/ │ └─ TASK-001/ └─ policies/ └─ WRITE-PERMISSIONS.yaml ``` ### 14.3 每个子 Agent 的脚手架 本仓库提供脚手架脚本:`scripts/scaffold-agent-memory.sh` 示例: ```bash ./scripts/scaffold-agent-memory.sh \ --repo /path/to/memory-repo \ --agent agent-a \ --default-branch main ``` 作用: - 生成 `agents//` 标准目录 - 生成 `AGENT-CARD.md`(身份与可写路径声明) - 生成 `PROMPT-RULES.md`(写前 pull、冲突处理规则) - 生成 `policies/WRITE-PERMISSIONS.yaml` ### 14.4 多 Agent 同步与冲突最小化策略 1. 写入前固定执行:`git pull --rebase origin ` 2. 尽量 append-only,减少多人改同一行 3. 原子小提交(按一次记忆动作提交) 4. 推送失败先 rebase,再自动合并一次;仍冲突则人工解决 5. 共享目录写权限建议通过 gateway 或服务端 hook 校验,避免越权路径写入 ### 14.5 与 QMD/gateway 的关系 - Git 仓库负责“真相源”和版本历史 - gateway 负责查询前同步和分支/工作区隔离 - qmd 负责本地索引与检索 这样可以同时满足: - 多 agent 共享记忆 - 查询一致性 - 冲突可控 - 结果可追溯(branch + commit)