| 1 | # Context Engine v2:指令、记忆与检索 |
| 2 | |
| 3 | Context Engine v2 为 Reasonix 提供两个权限不同的持久上下文层: |
| 4 | |
| 5 | - **常驻指令**定义智能体必须怎样工作。 |
| 6 | - **背景记忆**保存未来可能有用、但也可能过时的事实。 |
| 7 | |
| 8 | 把两者分开是最重要的设计原则:一个事实不应静默升级成命令;一条长期规则也不应依赖 |
| 9 | 检索是否恰好命中。 |
| 10 | |
| 11 | ## 选择正确的层 |
| 12 | |
| 13 | | 放在哪里 | 适合存放 | 示例 | |
| 14 | | --- | --- | --- | |
| 15 | | `AGENTS.md`、`REASONIX.md` 或 `CLAUDE.md` | 每个相关回合都必须存在的规则 | 必跑测试、仓库边界、评审约定 | |
| 16 | | 项目记忆 | 只适用于当前 workspace 的持久事实 | 发布分支、代码中看不出的服务约束、项目工单 URL | |
| 17 | | 全局记忆 | 明确需要在所有 workspace 可用的事实 | 用户显式选择为全局的偏好 | |
| 18 | | 会话历史 | 原始措辞、工具输出,或尚未沉淀为稳定事实的决定 | 昨天的报错、已放弃的方案 | |
| 19 | |
| 20 | 指令文件应保持简短。它们属于 cache-stable prompt prefix,多写的一段内容会被每个回合携带。 |
| 21 | 可以按需发现的事实应放进记忆。 |
| 22 | |
| 23 | 一个最小项目文件通常就够了: |
| 24 | |
| 25 | ```markdown |
| 26 | # Build and verify |
| 27 | |
| 28 | - Run `go test ./...` before reporting completion. |
| 29 | - Do not edit generated files under `desktop/frontend/wailsjs/`. |
| 30 | - Keep public API changes backward compatible. |
| 31 | ``` |
| 32 | |
| 33 | 在 CLI 中,`/remember <note>` 和 `# <note>` 会直接把内容追加到项目指令文档。它们是 |
| 34 | 常驻指导的快捷方式,不是 agent 用来创建背景事实的 `remember` tool。 |
| 35 | |
| 36 | ## 指令解析 |
| 37 | |
| 38 | Reasonix 识别 `REASONIX.md`、`AGENTS.md`、`CLAUDE.md`,以及对应的 `.local.md` |
| 39 | 变体。它先加载 Reasonix home 下的用户全局指令,再从 workspace root 逐级走到目标路径; |
| 40 | 在每个目录内,先加载普通文件,再加载该目录的 `.local.md`。 |
| 41 | |
| 42 | 更深目录高于更浅目录;同一目录内 local 变体高于普通文件,因此越靠后的条目冲突时优先。 |
| 43 | 用户当前请求始终是最高优先级的用户指令。展开后正文完全相同的文件会去重,并保留更具体 |
| 44 | 的来源。 |
| 45 | |
| 46 | 指令文件可用独占一行的相对路径导入另一个文件: |
| 47 | |
| 48 | ```markdown |
| 49 | @docs/agent-testing.md |
| 50 | ``` |
| 51 | |
| 52 | 导入按确定性顺序展开、去重,最多五层,并被限制在源指令文件拥有的目录内。绝对路径、 |
| 53 | 父目录逃逸、符号链接逃逸、不可读文件和循环引用都会被拒绝并形成诊断,不会被静默信任。 |
| 54 | |
| 55 | 用下面的命令查看真实解析结果: |
| 56 | |
| 57 | ```text |
| 58 | /memory instructions |
| 59 | ``` |
| 60 | |
| 61 | 它会显示加载优先级、scope、目标目录、imports 和 diagnostics。桌面 Context Center |
| 62 | 展示同一套 provenance。 |
| 63 | |
| 64 | ## 背景事实模型 |
| 65 | |
| 66 | 每条事实都是一个 Markdown 文件,包含: |
| 67 | |
| 68 | - 不变的 `id`; |
| 69 | - 单调递增的 `revision`; |
| 70 | - `created_at`、`updated_at` 时间; |
| 71 | - 便于阅读的 name、title 和 description; |
| 72 | - 相互独立的 `type` 与 `scope`; |
| 73 | - Markdown 正文。 |
| 74 | |
| 75 | `type` 表示内容类别: |
| 76 | |
| 77 | - `user`:用户身份或偏好; |
| 78 | - `feedback`:关于怎样工作以及原因的反馈; |
| 79 | - `project`:代码库本身无法直接得出的项目目标或约束; |
| 80 | - `reference`:URL、工单 ID 等外部资源。 |
| 81 | |
| 82 | `scope` 表示生效范围: |
| 83 | |
| 84 | - `project` 是安全默认值; |
| 85 | - `global` 必须显式选择。 |
| 86 | |
| 87 | type 不推导 scope。项目反馈仍只属于项目,全局 reference 仍然是 reference。 |
| 88 | |
| 89 | 当等价的项目事实和全局事实同时存在时,自动召回使用项目事实。Context Center 和 |
| 90 | `/memory` 仍展示两者,并解释覆盖关系,而不是删除或隐藏任何来源。 |
| 91 | |
| 92 | 为兼容旧数据并保证首轮可用性,全局 `user` 和 `feedback` 正文会在会话开始时快照到一个 |
| 93 | 低优先级稳定指导区。存在等价项目事实时,它会在稳定前缀构建前屏蔽对应的全局指导, |
| 94 | 因此“项目覆盖全局”不依赖后续查询是否恰好触发召回。其他事实正文只有在相关时才进入上下文。 |
| 95 | |
| 96 | ## 自动召回 |
| 97 | |
| 98 | 每个真实用户回合开始前,Reasonix 会用原始用户消息搜索 active facts。宿主追加给 provider |
| 99 | 的上下文不会反过来污染查询。选中的事实作为有预算、低权限的后缀追加到本轮 user turn, |
| 100 | 不会修改 system prompt 或工具 schema。 |
| 101 | |
| 102 | 召回策略刻意保守: |
| 103 | |
| 104 | - “继续”这类泛化回合不触发召回; |
| 105 | - 用 BM25 排序有区分度的词法命中; |
| 106 | - 项目事实有轻微相关性加权; |
| 107 | - 过期事实只降权,不静默删除; |
| 108 | - 本轮存在等价项目事实时,不再注入对应的全局 fallback; |
| 109 | - 已经作为稳定指导存在的全局 `user` / `feedback` 不会被自动召回重复注入; |
| 110 | - 默认最多四条事实、2,400 字符; |
| 111 | - provider 可见块不包含 fact storage path,snippet 中的 home directory 前缀会替换为 |
| 112 | `<local-home>`。 |
| 113 | |
| 114 | freshness 按事实类型计算: |
| 115 | |
| 116 | | 类型 | fresh | current | 超过多久为 stale | |
| 117 | | --- | ---: | ---: | ---: | |
| 118 | | `reference` | 14 天 | 45 天 | 45 天 | |
| 119 | | `project` | 30 天 | 180 天 | 180 天 | |
| 120 | | `user`、`feedback` | 90 天 | 365 天 | 365 天 | |
| 121 | |
| 122 | freshness 是提醒和排序信号,不代表事实真假。召回文本会明确告诉模型:内容可能错误或过期, |
| 123 | 不能覆盖当前请求和常驻指令。 |
| 124 | |
| 125 | 查看最近一次决定: |
| 126 | |
| 127 | ```text |
| 128 | /memory recall |
| 129 | ``` |
| 130 | |
| 131 | trace 包含 query、选中的 ID/revision、score、命中原因、freshness、预算使用量、 |
| 132 | omitted 数量和 suppressed 原因。 |
| 133 | |
| 134 | 需要更深检索时仍可使用只读 `memory` tool 的 `search`、`read`、`list`。需要原始措辞或 |
| 135 | 工具输出时,应使用 `history`。 |
| 136 | |
| 137 | ## 安全写入与确认 |
| 138 | |
| 139 | 普通路径零配置。只有同时满足以下条件时,Reasonix 才可以自动创建一条新记忆: |
| 140 | |
| 141 | - 当前父 controller 拥有本项目 memory store(可以是交互式,也可以是顶层 headless,但不能是子智能体); |
| 142 | - type 被显式标为 `project` 或 `reference`; |
| 143 | - scope 为 project 或省略; |
| 144 | - 操作是纯创建,不是更新; |
| 145 | - 正文不超过自动写入预算; |
| 146 | - 未检测到凭据、secret、私钥或邮箱; |
| 147 | - 不存在同名、同 title 或同 description 的事实。 |
| 148 | |
| 149 | 授权是一次性的,存储层还会强制 create-only,因此评估后并发出现的事实也不会被覆盖。 |
| 150 | |
| 151 | 其余情况仍需显式确认: |
| 152 | |
| 153 | - 全局事实; |
| 154 | - `user` 偏好和 `feedback`; |
| 155 | - 更新已有 ID 或 revision; |
| 156 | - 可能重复的内容; |
| 157 | - 敏感或超长内容; |
| 158 | - 所有 `forget` 操作。 |
| 159 | |
| 160 | Auto 和 Yolo 不会绕过这些确认。Guardian 和 permission hook 不能替用户批准。顶层 |
| 161 | headless controller 只能使用上述同一个一次性低风险创建路径;子智能体以及不拥有该作用域 |
| 162 | controller 的 headless surface 会 fail closed,其他记忆变更仍必须有交互式确认界面。 |
| 163 | |
| 164 | 用户直接在 Context Center、`/remember`、restore 或 recover 命令中发起的操作,本身就是 |
| 165 | 显式用户动作,不会再增加一次审批。 |
| 166 | |
| 167 | ## Revision、归档与恢复 |
| 168 | |
| 169 | 更新事实时,旧版本会先保存为不可变快照。过期的 `expected_revision` 会被拒绝,不会覆盖 |
| 170 | 更新后的内容。 |
| 171 | |
| 172 | 恢复旧 revision 不会原地倒退存储,而是把所选内容复制成一个更高的新 revision,保持 |
| 173 | 单调审计链: |
| 174 | |
| 175 | ```text |
| 176 | /memory revisions <id-or-name> |
| 177 | /memory restore <id-or-name> <revision> |
| 178 | ``` |
| 179 | |
| 180 | `forget` 会把事实移出 active recall 并放入 `.archive/`。恢复只接受当前 store 拥有的 |
| 181 | archive entry,拒绝符号链接和路径逃逸,拒绝 ID/name 冲突,也绝不覆盖 active file: |
| 182 | |
| 183 | ```text |
| 184 | /memory archived |
| 185 | /memory recover <archive-path> |
| 186 | ``` |
| 187 | |
| 188 | 恢复出的内容同样成为一个更高的新 revision。Restore 和 recover 会通过一次 turn-tail note |
| 189 | 立即作用于当前会话,并在下次会话自然进入稳定 prefix。 |
| 190 | |
| 191 | ## 零配置建议 |
| 192 | |
| 193 | 打开桌面端 Suggestions tab 时,会自动扫描近期本地用户回合,不需要设置开关。它会提出: |
| 194 | |
| 195 | - 从明确偏好、约束和项目约定中提取的长期记忆候选; |
| 196 | - 从重复工作流模式中提取的 Skill 候选。 |
| 197 | |
| 198 | 扫描使用原始用户内容,并与两个 scope 的 facts 和已加载指令正文去重;扫描本身绝不写入。 |
| 199 | 每个候选都展示 evidence,必须由用户显式接受。远程 workspace 会 fail closed:远端不提供 |
| 200 | 能力时,Reasonix 不会回退读取桌面机器的本地 session 或 memory。 |
| 201 | |
| 202 | ## 管理界面 |
| 203 | |
| 204 | 直接运行 `/memory` 会显示两个 scope 的全部 active facts,包括 ID、revision、type、 |
| 205 | scope、freshness 与存储来源。CLI、Desktop 和 remote workspace 都提供结构化补全。 |
| 206 | |
| 207 | | 命令 | 结果 | |
| 208 | | --- | --- | |
| 209 | | `/memory` | 指令、事实和 archive 综合摘要 | |
| 210 | | `/memory instructions` | precedence、目录、imports、diagnostics | |
| 211 | | `/memory recall` | 最近一次自动召回 trace | |
| 212 | | `/memory revisions <ref>` | active fact 与不可变历史 | |
| 213 | | `/memory restore <ref> <revision>` | 恢复为一个新 revision | |
| 214 | | `/memory archived` | archive facts 与路径 | |
| 215 | | `/memory recover <path>` | 把当前 store 拥有的 archive 恢复为新 revision | |
| 216 | |
| 217 | Context Center 用图形界面展示同一模型,还会显示冲突和 project-over-global 解释。 |
| 218 | |
| 219 | ## 升级兼容 |
| 220 | |
| 221 | Context Engine v2 会自动升级旧 store,不需要设置: |
| 222 | |
| 223 | - 没有 ID 的旧事实获得确定性的 `legacy-*` identity; |
| 224 | - 缺少 revision 的事实从 revision 1 开始; |
| 225 | - 缺少 scope 时,根据所在 project/global 目录推导; |
| 226 | - migration 幂等,只写入一次新 metadata; |
| 227 | - 新旧版本共享 state root 时,兼容路由字段可避免旧客户端把事实移错目录; |
| 228 | - 旧 `MEMORY.md` 作为派生数据处理,并根据事实文件重建; |
| 229 | - 旧 Memory v5 `<memory-compiler-execution>` transcript 仍可读取,退役的 |
| 230 | `[agent].memory_compiler` 设置会被移除。 |
| 231 | |
| 232 | 不需要 vector database、embedding service、setup wizard 或手动 re-index 命令。 |
| 233 | |
| 234 | ## Cache 与隐私契约 |
| 235 | |
| 236 | - 常驻指令和派生 memory index 在会话开始时进入稳定 prefix。 |
| 237 | - Provider 可见的指令 provenance 只使用稳定的 `workspace/...` 与 `user/...` 标签;绝对来源路径 |
| 238 | 和 store 路径仅保留在本地诊断中。 |
| 239 | - Provider 可见的 memory tool result 只使用稳定的 `project/<name>.md` 与 |
| 240 | `global/<name>.md` 引用。这些引用可直接用于 read、update、revision 和 archive;即使两个 |
| 241 | scope 中存在同名事实,也会精确定位;Context Center 和本地恢复诊断仍保留真实存储路径。 |
| 242 | - 动态召回和会话中途改动只追加到当前 user turn。 |
| 243 | - diagnostics 不进入 provider request。 |
| 244 | - 自动召回不暴露 fact storage path,并替换 snippet 中的 home directory 前缀。 |
| 245 | - 外部审批通知只收到工具名,不收到记忆正文。 |
| 246 | - 远程管理只使用远程 controller 的 memory catalog,绝不回退读取桌面本机 store。 |
| 247 | |
| 248 | 这样既保持 provider-visible prefix 稳定,也让动态上下文可解释、可恢复。 |
| 249 |