记忆

记忆下发

记忆从服务端到 Daemon 节点缓存与沙箱只读投影的完整下发链路、L0/L1/L2 资产隔离过滤体系与 MEMORY.md 任务导航索引构建。

智能体处理任务时,相关的历史记忆是如何精准送达其运行环境的?MEMORY.md 是如何生成的?为什么环境事实不会互相污染?

本文详细揭秘 Mopheus 记忆系统的下发构建、传输协商、节点缓存与沙箱投影全链路。


下发前动态构建链路(Server 端)

当智能体认领(Claim)一个任务,或者调度器启动后台自动化 Job 时,服务端会为该任务动态准备记忆上下文。整个过程严格按照分层过滤原则进行:

                      [任务上下文输入]
           (工单标题/描述、发起人用户ID、关联 asset_id、标签等)
                                │
                                ▼
┌───────────────────────────────────────────────────────────────┐
│                 三层保底过滤体系 (RecallMemories)             │
├───────────────────────────────────────────────────────────────┤
│                                                               │
│  [L0: 工作区通用底座] (Zero Scope Binding)                    │
│   • 严格条件: asset_id IS NULL AND user_id IS NULL            │
│   • 仅放全局静态环境事实、全局架构偏好与通用手册              │
│                                                               │
│  [L1: 任务发起人偏好] (Origin User Preference)                │
│   • 严格条件: context_tags->>'user_id' = origin_user_id       │
│   • 仅激活当前发起人的个人工作流偏好                          │
│                                                               │
│  [L2: 资产专属规格与动态候选] (Asset & Context Recall)        │
│   • 若工单绑定 asset_id: 精准召回该资产专属的 environment_fact│
│   • 若工单出现错误码或技术栈标签: 动态匹配对应上下文记忆      │
│                                                               │
└───────────────────────────────┬───────────────────────────────┘
                                │
                                ▼
               [动态合成任务私有 MEMORY.md 索引表]
                                │
                                ▼
               [计算 ETag 清单并下发至 Daemon 节点]

1. 核心边界:资产隔离与三层过滤

Mopheus 的环境事实与资产(asset_id)深度挂钩,并不会全量注入,而是通过三层过滤机制进行精准的确定性分发,确保特定资产的数据库或系统参数只在关联任务中生效:

L0:工作区纯通用底座(Zero Scope Binding)

  • SQL 过滤条件:
    WHERE workspace_id = $1
      AND memory_type IN (3, 5, 6)
      AND enabled = TRUE
      AND superseded_by IS NULL
      AND (context_tags->>'asset_id' IS NULL OR context_tags->>'asset_id' = '')
      AND (context_tags->>'user_id' IS NULL OR context_tags->>'user_id' = '')
  • 注入内容:真正属于整个工作区共享的持久条件(如容器只读路径规范、公共代理配置)。
  • 硬性排除:任何打了 asset_id 的卡片,坚决不进入 L0!

L1:任务发起人个人偏好(Origin User Preference)

  • 仅当任务携带明确的 origin_user_id 时,激活该用户显式保存的个人偏好(memory_type = 5 AND context_tags->>'user_id' = $userID)。
  • 其他成员发起任务时,不会被此人的个人偏好干扰。

L2:资产专属规格与动态候选(Asset & Context Candidates)

  • 资产专属事实定向激活:当工单元数据中指定了目标资产(asset_id),系统通过 JSON 包含匹配(context_tags @> {"asset_id": "..."})精准拉取属于该资产的专属环境事实(如某台特定物理机的 CPU/内存、指定 PostgreSQL 实例的只读副本拓扑)。
  • 动态上下文匹配:自动提取工单扫描文本中的错误码(如 ORA-01555、42P01)与标签,精准挂载对应的报错排障记录。

动态生成 MEMORY.md 任务索引

在确定了当前任务所需的记忆卡片集合后,服务端会动态生成一个任务专用的 Markdown 导航索引——MEMORY.md。

索引文件结构

# Task Memory Navigation Index

This is the workspace memory repository index for the current task. Skim primary anchors and matched recommendations first, then navigate to detailed cards via relative paths.

## Primary Anchors
- [API 错误码必须使用 errx 定义](conventions/preferences/1528fa6d-2786-4c33-9e4e-a2e4e84ca7d7.md) (preference)
- [Monorepo 与落地页分仓解析规则](conventions/corrections/2fa85f64-0000-0000-0000-000000000002.md) (human_correction)

## Knowledge Map (OKF Topology)
- `runbooks/`: Operational SOPs and disaster recovery (`errors/`), pitfalls & incident postmortems (`pitfalls/`), verified execution playbooks (`playbooks/`).
- `facts/`: IT asset topology and configuration baselines (`specs/`).
- `conventions/`: Human corrections (`corrections/`) and user/operational preferences (`preferences/`).
- `docs/`: Ingested system architecture manuals and long-form official reference documentation.

## Top Matched Recommendations
> **Notice**: Showing top 10 prioritized recommendations of 12 locally mounted knowledge cards. Additional 2 cards are cataloged below.

| Type | Title | Description | Labels | Relative Path | Occurrence | Last Seen |
| :--- | :---- | :---------- | :----- | :------------ | :--------- | :-------- |
| fact | /src 与 /home/moclaw-dev/repos 为只读挂载 | 沙箱只读挂载拓扑说明 | sandbox, linux | [facts/specs/7ca47dae-9dab-4390-8fee-a8284d31f079.md](facts/specs/7ca47dae-9dab-4390-8fee-a8284d31f079.md) | 1 | 2026-10-10 |
| preference | API 错误码必须使用 errx 定义 | 后端错误码规范 | go, backend | [conventions/preferences/1528fa6d-2786-4c33-9e4e-a2e4e84ca7d7.md](conventions/preferences/1528fa6d-2786-4c33-9e4e-a2e4e84ca7d7.md) | 1 | 2026-10-10 |
| risk | save-images.sh 与 Docker 29 containerd 不兼容 | — | docker, release | [runbooks/pitfalls/c971377d-839b-43e8-bf11-4ff24de977ce.md](runbooks/pitfalls/c971377d-839b-43e8-bf11-4ff24de977ce.md) | 1 | 2026-10-10 |
| resolution | PostgreSQL JSONB CAST 类型转换修复 | JSONB 路径表达式显式转换 | postgres, sql | [runbooks/errors/b8fc3025-ceb6-4be9-a8a6-03898ae25e92.md](runbooks/errors/b8fc3025-ceb6-4be9-a8a6-03898ae25e92.md) | 3 | 2026-10-10 |

## Additional Mounted Cards (2)
The following background cards are also mounted in local OKF directories and can be inspected via your preferred file viewing tool or `grep`:
- [Nginx Gateway Timeout 排查](runbooks/errors/d1234567-0000-0000-0000-000000000001.md) (`error_resolution`)
- [通用开发规范手册](docs/e1234567-0000-0000-0000-000000000002.md) (`reference_doc`)

## Usage Guidelines
- **Verify Deeply**: Table summaries are triage hints, not conclusive evidence. Always inspect the full card via your preferred file viewing tool before relying on it.
- **Explore Local Cards**: In addition to the top recommendations, all mounted cards listed above are immediately available in the local directory tree.
- **Dynamic Retrieval**: If this index does not cover what you need, run `mop memory retrieve "<query>"` with descriptive natural language, or `mop memory get <id> --save` to fetch full docs into `.memory/`.
- **Durable Persistence**: This directory is an ephemeral read-only projection for this task run. Never write memory files directly to disk; use `mop memory store` to persist reusable facts into the workspace.

关键设计点:

  1. 确定性相对链接:表中的链接路径严格遵循 OKF 4 大支柱相对路径(facts/specs/、conventions/、runbooks/、docs/),使智能体可以直接调用 view_file 或 cat 读取。
  2. 初筛线索而非证据:标题和摘要只是快速分流的线索。系统在 System Prompt 中硬性约束:智能体在真正执行决策前,必须点开链接阅读完整卡片正文,绝不可仅凭索引标题臆测内容。

节点缓存与传输(Daemon 端)

为了避免每次任务启动时反复从中心数据库全量拉取卡片导致带宽浪费与 I/O 尖峰,Mopheus Daemon 实现了工作区级的共享缓存池。

              [Server 下发记忆清单与 ETag]
                           │
                           ▼
              ┌────────────────────────┐
              │ Daemon 校验本地 ETag   │
              └────────────┬───────────┘
                           │
             ┌─────────────┴─────────────┐
             ▼                           ▼
        [ETag 匹配]                [ETag 失效]
             │                           │
       (304 Not Modified)          (拉取差异卡片)
             │                           │
             ▼                           ▼
  [复用本地 Cache Pool]     [加 .lock 锁,原子写入并重命名]
             │                           │
             └─────────────┬─────────────┘
                           │
                           ▼
          [投影到沙箱工作区 .claude/memory/]
  1. ETag 弱校验协商:服务端根据当前工作区活跃记忆的版本与修改时间戳计算弱 ETag。Daemon 节点带有匹配的 ETag 时,服务端直接响应 304,实现零网络卡片传输。
  2. 工作区级 Cache Pool:Daemon 在宿主机本地维护共享缓存目录,同一工作区内的多个并发 Agent 任务共享相同的底层卡片文件缓存。
  3. 并发安全保障:多任务并发同步缓存时,通过跨进程文件排他锁(.lock)配合临时文件写入与原子重命名(atomic rename),彻底防止文件写入竞争与半损坏读(Torn read)。

沙箱安全投影与隔离守卫

这是保障知识库不被沙箱污染的核心防护层:

1. 物理只读投影

  • Linux 环境(Production):Daemon 借助 Linux 原生命名空间与 Bubblewrap,使用 --ro-bind 将宿主机 Cache Pool 挂载到沙箱容器内部的 .claude/memory/ 目录。
  • 跨平台 / 开发环境:通过文件系统相对符号链接(Symlink)投影。

2. 隔离防污染守卫(Strict Isolation Guard)

  • MEMORY.md 任务专属生成:MEMORY.md 绝不写入共享的 Cache Pool,而是仅写入当前任务专属的工作目录。这样既保证每个任务看到自己独有的索引视界,又防止跨任务索引相互覆盖。
  • 禁止本地文件逆向污染:由于沙箱内挂载为物理只读,智能体在沙箱内哪怕通过 Bash 尝试直接修改 .claude/memory/ 下的文件,也会收到 Read-only file system 错误;若在非隔离环境下直接修改,这些修改在沙箱销毁时也会立即清空,绝不会逆向同步至中心数据库。

智能体交互契约

系统在通用 System Prompt(writeSlimCommandsMemory)中对智能体注入了清晰的认知工作流指引:

  1. 第一步:通读索引
    在执行任何复杂排障或检索前,先查看 .claude/memory/MEMORY.md,快速扫描是否存在当前问题已知的前人经验。
  2. 第二步:按需阅读卡片全文
    根据索引给出的相对链接,读取目标卡片,了解完整的操作约束、前提条件与回滚步骤。
  3. 第三步:动态检索补充
    如果预置的 MEMORY.md 没有命中,智能体通过 mop memory retrieve "<query>" 主动向服务端发起动态加权全文检索。
  4. 第四步:受控持久化
    智能体在任务中总结出的新知识,必须调用 mop memory store --type ... 命令行提交至数据库持久化。