# 记忆与审查规则(功能说明) 本文档说明 dsh-memory-evolve-suite 的**行为与规则**——记忆系统如何分层、回合内审查如何触发与产出、哪些内容会进入记忆/技能、需要用户确认什么。不含实现细节;若你想了解内部机制,直接看代码或 README 的配置表。 --- ## 1. 记忆系统:五层轨道 插件维护五层互不污染的记忆,各层的"写入方式"与"注入方式"不同: | 轨道 | 存什么 | 谁能写入 | 是否注入会话 | |---|---|---|---| | **用户档案 `user`** | 用户是谁、偏好、沟通方式、工作习惯 | 只有用户**确认后**才能写入(建议确认制) | ✅ 每个会话注入 | | **全局事实 `memory`** | 环境事实、工具要点、技术惯例 | 只有用户**确认后**才能写入 | ✅ 每个会话注入 | | **项目关键记忆 `key`** | 当前项目的**长期事实**(约定/决策/架构/踩坑) | **模型写入需用户确认**(每回合按重要性判断提交建议→进队列→采纳后生效)+ 记忆 Tab 手动添加(直写) | ✅ 当前项目会话注入(按 cwd 隔离;**按 git 分支过滤**,当前分支名随 key 注入) | | **项目日志 `project`** | 当前项目的约定、进展、关键决策 | 模型**每回合主动写入**(无需确认) | ❌ 不注入,按需读取 | | **今日日志 `daily`** | 今天做了什么、重要进展 | 模型**每回合主动写入** | ❌ 不注入,按需读取 | ### 1.1 写入方式 - **user / memory(全局轨)**:suggest 模式下,模型(含回合内审查)和子代理都**不能直接写**。只能通过"建议"进入待确认队列,由你在会话页记忆 Tab(或 `/memory_review` 命令)逐条确认后才真正写入。这是为了防止无人把关的自我修改——全局轨内容每个会话都注入,写错影响最大。 - **key(项目关键记忆)**:快照提示行要求模型每轮收尾**判断**本轮是否出现**重要项目事实**——长期约定、决策、架构、踩坑结论(会跨会话长期有效的),有则向 target=key **提交建议**(进待确认队列,**用户采纳后**才写入并注入,与全局轨同待遇),没有就跳过(**不是流水账**,不必每轮都写)。也可以在会话页记忆 Tab 的「项目关键记忆 KEY.md」里用输入框手动添加(用户即确认者,直写)。key 归档到该项目的 `KEY-archive.md`(随项目走),归档/转正保留分支标记; - **project / daily(日志轨)**:快照提示行要求模型**在输出最终回复的那条消息中,先输出完整回复文本,然后在同一条消息的文本之后附带工具调用**(严禁先调工具再写回复)——**每轮收尾必须**用 memory 工具向 daily 与 project **各写入 1 条**本回合进展(1-2 行具体内容;内容不要自带时间/日期前缀,程序自动盖准确时间戳),并调用 `memory_review_status`(action=check)检查审查是否到期。写入无需确认;它们不注入会话,即使内容质量一般也只是占用文件空间,风险低。 - 该行为由三个独立开关控制(「Memory Evolve 设置」Tab「配置」子页签,默认都开):关闭某一轨后,快照提示行不再要求写入该轨(仅保留按需读取提示),模型仍可在你明确要求时写入。 - 你也可以直接对 agent 说"记住 XXX",agent 会按目标轨规则写入。 ### 1.2 注入与缓存 - **只注入低频变化的轨道**:user / memory(内容需确认才会变)+ key(只在出现重要项目事实时写,低频稳定)。快照末尾有一行固定提示,要求模型"每轮收尾向 project/daily 各写入 1 条、按重要性判断是否写 key 并检查审查",但 project/daily 的**内容不注入**。 - 原因:DSH 的上下文快照是追加式的,注入内容一变就会追加新快照、降低 LLM 前缀缓存命中率。project/daily 随每回合主动写入而变化,注入会每轮破坏缓存,所以它们按需读取。**key 与全局轨一样低频**,用"实时读取 + 变更检测"注入——内容变化(工具写入或 Tab 手动添加)后下一轮快照文本变化、自动重新注入,与全局轨机制完全一致。**提示行本身是固定文本**(不随内容变化),不产生新的快照。 - 已知局限:即使只有低频轨,**任何确认写入**(或直接 `memory add`)仍会触发一次快照更新,前缀缓存相应截断。写入越频繁,缓存收益越小。这是 DSH 核心机制的固有行为。 ### 1.3 记忆条目格式 - 每条记忆带时间前缀:全局轨与项目关键记忆 `[YYYY-MM-DD]`、项目日志 `[YYYY-MM-DD HH:MM]`、今日日志 `[HH:MM] [项目]`(文件名已含日期;`[项目]` 由程序取自会话工作目录自动标注,无需模型书写)。**git 仓库中,项目日志与今日日志还会自动带分支 tag**:`[HH:MM] [git main] [项目] 内容`、`[YYYY-MM-DD HH:MM] [git main] 内容`——分支由程序实时获取(`git branch --show-current`),非 git 仓库/获取失败则不标注;手写的前缀(日期或 `[git …]`)都会被程序剥离——tag 是程序专属标注,保证日志可溯源到分支、跨分支记忆可靠。 - 项目记忆(key 与 project)按**工作目录**隔离:每个目录一组独立文件,A 项目会话看不到 B 项目的记忆(key 只注入自己目录的会话,project 只能按需读取自己目录的那份)。 ### 1.4 让模型主动读取与写入项目/今日记忆 快照中的「按需记忆」提示行**已内建触发条件**:明确告诉模型"任务涉及项目上下文/对项目情况不确定 → 先读 target=project;用户问今天做了什么/需要当天信息 → 读 target=daily;不要凭猜测回答。项目关键记忆(target=key)已注入上下文,无需读取"。同时要求模型**每个回合收尾调用 memory 工具写入**本回合产出、**按重要性判断是否写 key**(详见 1.1)。所以**不需要**额外写使用指引,插件默认就能让模型主动读取与记录。 写入的**时间戳由程序生成**:模型不被告知当前日期、也不允许手写日期前缀(提示行明确禁止,程序层还会剥离手写前缀再盖标准戳),保证每日日志 `[HH:MM] [项目]`、项目日志 `[YYYY-MM-DD HH:MM]`、项目关键记忆 `[YYYY-MM-DD]` 格式统一准确。 `memory list` 支持查询:`filter`(关键词)、`since`/`until`(日期范围,daily 可跨文件查历史日志)、`recent`(最新在前)、`limit`(条数上限)。**查不到匹配或存在日期无法解析的旧格式条目时,返回会提醒模型去掉过滤条件读取全文核对**——旧格式条目不参与日期过滤但会被原样返回,不会误删。 「每回合主动写入」可按轨关闭(「Memory Evolve 设置」Tab「配置」三个开关,默认都开):关闭后该轨回到纯按需读取(key 关闭后仅保留手动添加与读取),模型不再被要求每轮写入。 可选补充:若希望模型额外知道"已安装该插件"或加个性化说明,可在全局记忆(MEMORY.md)放一条简短说明(非必需)。 ### 1.5 git 分支与记忆 同一项目(同一工作目录)的不同 git 分支可能逻辑完全不同,插件的项目级记忆**全程感知当前分支**,避免跨分支记忆串味: - **当前分支识别**:程序实时执行 `git branch --show-current`(与 DSH TUI 同款,1s 超时兜底)。**非 git 仓库 / 获取失败 / detached HEAD(无分支名)一律视为"无分支"**——所有分支行为自动退化为"全部",绝不丢记忆。 - **key 按分支范围注入**:key 条目可带 `[branch:main,dev]` 标记限定可见分支;**无标记 = 全部**(所有分支可见,历史条目天然如此)。注入时只注入「无标记」+「标记覆盖当前分支」的条目;**当前分支名随 key 一起注入**(key 小节标题「当前分支:main」+ 提示行「当前 git 分支:**main**」),模型明确知道自己所在分支。 - **范围语义**:「全部」与具体分支**互斥且全部权重最大**(勾"全部"清空分支选择);多选为逗号列表(A 和 B);分支改名/删除后旧标记条目成为死数据(永不注入),可手动改/删。 - **范围管理入口**: - 记忆 Tab KEY 页签:每条 key 显示「分支: 全部 ▾ / 分支: main,dev ▾」徽标,点击展开多选(保存后经 `/api/key/scope` 精确改写标记,「全部」=移除标记);手动添加时可同时选择分支范围;非 git 仓库只显示「全部」。 - LLM 工具:`memory add target=key … branches=main,dev`(缺省=全部;**不存在的分支只警告、照常写入**——分支以后可能创建);`memory list target=key branch=main` 查询该分支可见条目。 - **日志分支 tag(来源溯源)**:项目日志/每日日志每条记录**自动带来源分支 tag** `[git main]`(daily 形如 `[HH:MM] [git main] [项目] 内容`;project 形如 `[YYYY-MM-DD HH:MM] [git main] 内容`)。程序实时标注、**模型无法手写**(手写 `[git …]` 前缀会被剥离),日志可溯源到分支,跨分支回顾不会张冠李戴。 - **开关**:`keyBranchFilter`(默认 `true`,仅 config.yaml)关闭后 key 不过滤注入(全部注入、不注入分支名)。 --- ## 2. 回合内记忆审查 > **职责边界**:project / daily 的写入由**主会话每回合主动完成**、key 由主会话**按重要性判断写入**(见 §1.1),**审查不处理它们**。审查只专注**全局轨(user/memory)建议**与**技能创建/优化**——"提炼与进化"的事,与"日志流水"分离。 ### 2.1 触发与执行 | 环节 | 说明 | |---|---| | **回合计数** | 插件统计每个会话的用户回合数(`agent/settled`,仅 message 回合;重试/系统注入/子代理会话不计)。计数**只增不清** | | **到期** | 计数达到 `reviewInterval`(默认 5)后,一次审查被标记为**到期**。到期状态保持到模型真正完成审查——漏一轮不会丢,下回合仍到期 | | **查询** | 快照携带固定提示段,要求模型每个回合结束前调用 `memory_review_status`(action=check)——**到期判断以工具返回的 `due` 为准**(间隔不写死在提示里,改配置不破坏缓存);**到期时快照末尾出现醒目警告**,模型收尾必须执行审查并 complete。注:警告随到期状态出现/消失,`complete` 后快照文本变化会触发一次额外的上下文重新注入(每周期共 2 次)——**特性而非缺陷**,保证弱遵循模型也能收到到期提醒;建议内容未确认前只存在于待确认队列,不会进入注入 | | **执行** | 到期时模型在**自己的回合内静默执行**审查(全部为工具操作,不写进最终回复):全局轨建议 → 技能操作 → `memory_review_status complete` 复位计数 | | **复位** | 只有 `complete` 才清零计数;未到期时调用 `complete` 无意义(不重置) | ### 2.2 审查基于完整上下文 - 审查由**主 LLM 直接执行**——它拥有本会话全部上下文(对话、工具输出、推理、细节),**不需要**摘要转录、不需要子代理、不需要深读接口;信息零损耗。 - 全局记忆(MEMORY.md/USER.md)本来就注入在快照中,审查对照快照**直接查重**,无需另附全文。 ### 2.3 审查使用哪些工具 - `memory_review_status`:查询到期 / 完成审查后复位; - `memory_suggest`(suggest 模式):提交全局轨建议(不会直接修改记忆); - `memory`(auto 模式):直接写入全局轨; - `skill_manage`:技能创建/优化(create 默认进待确认队列)。 ### 2.4 依赖与代价 - 审查是**提示词驱动**的:插件负责计数与到期标记,**执行依赖模型的指令遵循能力**——弱遵循模型可能到期不查、查了不执行(后果见 §7 已知局限); - 审查在回合内同步执行:到期回合的响应会略慢(一次查询 + 若干工具调用),用纪律控制规模(≤2 条建议 + ≤1 次技能操作)。 --- ## 3. 审查产出规则(什么该记、什么不该记) > 审查只处理**全局轨建议**与**技能**(project/daily 由主会话每回合主动写入、key 按重要性判断写入,见 §1.1,不在审查职责内)。 ### 3.1 全局轨 user / memory(严格,宁缺毋滥) 只有以下内容才允许提建议(且进入队列后仍需你确认): - 用户透露的**稳定**个人信息、偏好、沟通/工作方式(需跨会话可复用;**单次出现的行为不算偏好**,需至少 2 次独立信号); - 非平凡、**稳定**的环境/技术事实。 **明确不建议的内容**: - 与**已有记忆重复**的内容(全局记忆已注入在快照中,审查直接对照查重); - **可复用的操作方法**——这类知识应进入**技能**,而不是全局记忆; - 转录中对代码/配置**现状的描述**——代码演进快,描述容易过时(未来会话拿到的是过时"事实"); - 一次性任务叙事、瞬时错误、对工具的负面断言、密钥等敏感信息、重试即好的临时状态。 同一偏好多轮出现时**合并为一条建议**,不拆分。 ### 3.2 技能(严格创建 + 用户确认) 技能会注入**每个会话**的系统提示词(技能目录全量注入),每多一个技能都会增加上下文并影响缓存,因此: - **创建门槛**:只有同时满足 ① 多次尝试仍难解决(反复踩坑)② 难度大、非显而易见 ③ 后续可能多次复用,才允许创建技能。**一次性任务、简单任务不创建**;想不出类级名称说明不该创建。 - **优化已有技能不受此限**:发现已有技能缺步骤或过时,随时可以改进(但需先读取过该技能)。 - **确认制**:默认情况下,审查创建的新技能先进**待确认队列**(`pending-skills`),不会注入任何会话;你在会话页记忆 Tab「待确认技能建议」中**采纳**后,技能才进入技能库生效(采纳 = 移动文件,立即实现),**拒绝**则删除。 - 技能命名必须是 kebab-case 的类级名称(如 `systematic-debugging`),禁止一次性任务名(如 `fix-pr-123`)。 --- ## 4. 确认机制一览 | 内容 | 队列 | 确认方式 | 生效方式 | |---|---|---|---| | 全局记忆建议(user/memory) | `SUGGESTIONS.jsonl` | 记忆 Tab 逐条采纳/归档/拒绝,或 `/memory_review` 命令 | 采纳后写入对应记忆文件,下个请求随快照注入 | | 新技能(默认) | `pending-skills/` 目录 | 记忆 Tab「待确认技能建议」采纳/拒绝 | 采纳 = 移动进技能库,立即被所有会话加载 | | 待办建议(todo-life/work/project/daily) | `SUGGESTIONS.jsonl`(target=todo-*) | 记忆 Tab「待确认记忆建议」采纳/归档/拒绝 | 采纳后写入对应待办轨 MD 文件(用户口述的待办直写,不经队列) | 一些辅助机制: - **建议频次**:同一内容被多次建议时,队列中只保留一条并累计"已建议 N 次"(列表按频次排序、高频置顶)——反复出现的信号说明它很可能真的值得确认。 - **归档(第三级存储)**:不够格进主记忆但丢了可惜的建议可**归档**至 `MEMORY-archive.md` / `USER-archive.md`(§ 格式、按原 target 分文件、含建议理由)——**不注入任何会话**,记忆 Tab 归档页签(或 `/memory_review archive`)可**移回主记忆**(转正写入对应主轨)或删除;归档过的内容若再次被审查建议会重新进入队列(自动唤醒)。 - **采纳前可编辑**:全局记忆建议在采纳前可以修改文本,修改后的内容才会写入。 - **自动沉淀开关**:`reviewMode=auto`(全局记忆直接写入,不逐条确认)与 `skillReviewEnabled`(技能自动创建,不经确认)**默认都是关**(suggest + 确认制),需要你显式开启——开启后审查产出直接生效,注意提示注入风险。 --- ## 5. 待办(dtodo) 会话页记忆 Tab 的「待办」子 Tab 与 `dtodo` 工具提供四轨待办管理,与记忆同构: - **四轨**:`life` 生活(`TODOS-life.md`)· `work` 工作(`TODOS-work.md`,跨项目)· `project` 项目(`projects//TODOS.md`,**按工作目录隔离**,A 项目会话看不到 B 项目)· `daily` 每日(`daily/YYYY-MM-DD.todo.md`,按天分文件,与日志文件分离); - **存储格式**:§ 分隔的 MD 文件(与记忆完全同构,任何编辑器/模型可直接读取),**文件头是 HTML 注释格式说明**(tag 语法自描述,解析时剥离);每条待办首行是元数据 tag:创建时间(程序盖戳)、`[id: xxxxxxxx]`(唯一标识,工具按 id 操作)、`[q1]`~`[q4]`(四象限:重要×紧急,缺省=未分类)、`[due: YYYY-MM-DD]`(截止,缺省=不限)、`[status: pending|doing|done|blocked|cancelled]`(缺省 pending)、`[done: …]`(完成时间,程序盖戳)、`[cat: …]`(可选分类);正文可多行写详情; - **dtodo 工具**:`add`(用户口述直写;target 缺省=project,无 cwd 用 work;quadrant/important/urgent/due/cat 可选)· `list`(**默认智能视图**:逾期 + 今日到期 + 当前项目未完成 + 全局 Q1/Q2 未完成,排序后最多 8 条——模型只能读到"该关心的",全量需显式 `all=true` 或 status/quadrant/due 筛选;`date=` 查每日某天;**`past=true` 查每日过往**(今天之前的 daily 文件,条目带日期、排最后),默认**不返回已过期的遗留**(未完成且无未来截止),`expired=true` 才全部显示——过往默认不出现,不增加模型负担;**`cwd=路径` 跨项目查询**:在别的会话里查指定项目的 `target=project` 待办,project 轨按该路径定位,缺省=当前会话目录)· `done` / `update` / `remove`(按 `id` 精确操作,杜绝文本匹配误删;**过往条目的 id 同样可操作**,写回对应日期的文件); - **写入权限**:你**口述的待办直写**(你是确认者);模型**自建待办进待确认队列**(`memory_suggest target=todo-*`),采纳后写入对应轨——模型不能自作主张给你派活; - **快照提示**:只注入一条**固定提示行**(文本永不变,缓存友好)——收尾时 `dtodo list` 检查到期,有到期的在回复末尾提醒用户,不要主动展开全部清单;查每日过往待办用 `dtodo list past=true`(默认不含,不增加信息负担);**待办内容永不注入**(与 project/daily 同待遇,状态变化不产生任何尾部注入); - **归档**:待办建议可归档到 `TODO-archive.md`(条目带「原轨」标记,转正时写回对应待办轨);已完成待办保留在文件里(`[status: done]` + 完成时间),可随时在 UI 查看/恢复。 --- ## 6. 会话页记忆 / 技能 / 待办 / 设置 Tab(唯一管理入口) 会话页顶部有 **记忆 / 技能 / 待办 / Memory Evolve 设置** 四个标签页(`memoryTabEnabled` **默认开启**,可在「Memory Evolve 设置」Tab 的「配置」之外通过 config.yaml 关闭——它不是运行时可改项,Tab 关闭后无法从 UI 找回),是插件的**唯一管理入口**(原设置面板「记忆管理」已移除,功能全部并入这些 Tab)。有未确认的记忆/技能/待办时,对应标签显示 **🔴 小红点 + 计数** 提醒处理。每个 Tab 都有「指南」子 Tab:设置 Tab 的指南是**整个插件所有功能的简单介绍**,其余 Tab 的指南是**各自功能的详细介绍**。记忆 Tab 顶部是功能子 Tab + 文件页签(竖线分隔): - **功能 Tab(记忆 Tab:指南 / 待确认记忆建议)**:与文件页签同一行(竖线分隔);「指南」是记忆功能的详细介绍;「待确认记忆建议」是建议队列(采纳/归档/拒绝、批量处理、编辑后采纳)。整体指南与运行时配置已移入「Memory Evolve 设置」Tab(指南=全插件简介;配置=原运行时配置表单,保存即生效并持久化); - **技能 Tab(指南 / 待确认技能建议 / 技能管理)**:「技能管理」是合并自原 dsh-skill-browser 的完整技能管理器(浏览/搜索/禁用启用/自定义目录/文件编辑,见 README); - **待办 Tab(指南 / 待确认待办管理 / 待办)**:「待办」是四轨待办管理(见第 5 节); - **查看文件**:全局规则、长期记忆、用户档案、项目关键记忆、项目日志、今日日志与归档文件(只读预览,含文件路径与截断提示);§ 分隔的结构化条目默认以美观卡片视图展示(时间徽标 + 内容 + 项目标签,支持关键词搜索),可切换纯文本视图;**每个页签顶部有一行小字说明该记忆的作用与机制**; - **手动添加项目关键记忆**:在「项目关键记忆 KEY.md」页签下可用输入框手动输入一条长期项目事实(程序盖时间戳、保持 § 格式),可**选择分支范围**(全部 / 具体分支多选,互斥且「全部」权重最大;非 git 仓库只有「全部」),下一轮自动注入上下文; - **分支范围(git 仓库)**:key 条目可带 `[branch:main,dev]` 标记限定可见分支(无标记=全部)。会话注入时只注入无标记或覆盖**当前分支**的条目,当前分支名随 key 一起注入让模型知道自己所在分支;每条 key 的**分支徽标**可点击修改范围(`/api/key/scope` 精确改写标记,「全部」= 移除标记);LLM 写 key 可用 `branches=main,dev` 参数(缺省=全部,不存在分支警告但照常写入),`memory list target=key branch=main` 查询指定分支可见条目;`keyBranchFilter=false`(config.yaml)可关闭过滤; - **删除记忆条目**:美观视图每条目带「删除」按钮,点击后弹出确认(删除不可恢复);确认后宿主按**完整条目文本精确匹配**删除(`removeExact`,整条相等——不用子串匹配,杜绝删除短条目时误删包含它的长条目);文件被外部修改导致无法解析时拒绝删除并备份;条目已不存在时报错提示刷新; - **主记忆 ↔ 归档双向打通**:用户档案/长期记忆页签的条目可**「归档」**(确认后从主轨移入归档文件、不再注入会话,内容原样保留);归档页签的条目可**「移回主记忆」转正**(重新注入会话)或删除——记忆 Tab 内即可完成完整生命周期管理; - **不提供其他编辑**:其余记忆文件是 § 分隔的结构化条目,在页面上随意改写容易破坏格式、导致 memory 工具读取错乱;修改请用 memory 工具(project/daily/key 可直接写,全局轨经确认制),或「打开文件」用系统编辑器手工编辑; - 每行都有"用系统工具打开"按钮。 --- ## 7. 常见问题 **Q:为什么我确认了一条建议,会话里的记忆没立刻变?** A:写入立即完成,但注入发生在下一个请求的上下文快照中;当前已渲染的快照不会回改。 **Q:项目记忆不注入,模型怎么会知道项目的事?** A:项目**关键记忆**(key)本来就注入当前项目会话的上下文(快照中有「项目关键记忆」小节)。快照中还有固定提示行要求模型每个回合检查:任务涉及项目上下文时主动用 `memory` 工具读取(target=project / daily),每回合产生值得记录的新事实时主动写入(key 按重要性判断)。读取与写入都由模型主动完成,无需审查回合。 **Q:技能创建为什么还要确认?** A:技能注入所有会话且会长期存在,相当于修改"系统提示词"。默认进待确认队列,确保只有你认可的经验成为全局技能。 **Q:审查会看到我的敏感信息吗?** A:审查由主会话模型自己执行——它本来就拥有全部上下文(密钥等敏感内容不会比正常对话多暴露);同时"禁止沉淀"清单禁止把敏感内容写入记忆。 **Q:为什么审查是"到期"而不是"每 N 回合自动跑"?** A:审查改由主 LLM 在自己回合内执行(信息零损耗,不再派生子代理)。插件只计数与标记到期;到期状态保持到模型用 `memory_review_status complete` 真正完成,漏一轮不会丢。 ## 8. 已知局限:指令遵循依赖 「每回合写入 project/daily、按重要性写入 key」与「回合内记忆审查」都由**快照提示段**驱动,执行依赖模型的指令遵循能力: - 弱遵循模型可能跳过每回合检查、到期后不查询或不执行审查——插件无法强制(这是提示词机制的本质代价,换取的是信息完整性与架构简化); - **到期不清零**缓解"漏一轮"(下回合仍到期),但救不了"从不查"; - 若发现模型不执行:可调低 `reviewInterval` 提高到期频率,或在「Memory Evolve 设置」Tab「配置」关闭「每回合写入」减少噪音。