DSHarness 系统拆解 固定基线 47f943859b · 36 已复核 / 0 撰写中 / 36 章
English
上下文治理·第 14 章

记忆与知识:有何能力、又刻意没有什么

会话日志、摘要、Skill、Session Query 与长期语义记忆的边界

已复核上游 47f943859b范围: 辨析 working context、durable log、session reference、query、skill 和真正跨会话记忆之间的区别。

结论:DeepSeek Harness 有耐久历史与显式召回,但没有默认自动运行的长期记忆系统

在固定基线中,最容易被混称为“记忆”的能力其实属于六个不同层次:当前 Session Surface 是模型的工作上下文;JSONL 是完整耐久事件历史;compaction checkpoint 是同一会话内的有损上下文替换;session reference 是显式复制的跨会话快照;session query/FTS 是读取与词法检索;Skills 是可信指令目录。真正的外部记忆数据库、知识图谱或其他召回后端只通过默认关闭的 Memory MCP 示例接入。

源码结论

“日志已经持久化”不等于“新会话会自动想起旧会话”。每次 Provider 请求仍只从当前 Session 的 Surface 派生消息;默认组合没有自动搜索其他会话、把搜索结果排序后注入 prompt 的第一方管线。MEMORY-AGENT-CONTEXTSESSION-SURFACE-PROJECTION

1. 把六层核心能力与外部边界放进同一张矩阵

机制权威数据模型如何看见是否跨会话发布默认
Working context当前 Session Surface + 本次 system/toolsderiveMessages() 直接组成请求是;minimal 会关闭动态 runtime context
Durable history追加式 Session event log只有折叠后仍在 Surface 的消息进入请求可被显式读取,不自动召回Base 默认 JSONL
Compaction摘要审计事件 + replacement checkpointcheckpoint 替换旧 Surface spanStandard 有;minimal 无
Session reference来源会话当前 Surface 的有界快照作为带来源的 user-role context 注入是,显式一次性复制Opt-in,发布组合未挂载
Session query / FTS实时或持久日志;可丢弃的 SQLite 派生索引Host/UI 或可选模型工具读取是,但受调用方授权精确读取启用;FTS 与模型工具关闭
Skills文件系统或 runtime provider 的指令定义目录摘要 + 按需完整正文按 workspace/scope 发现,不从对话学习Standard 有;minimal 无
Memory MCP第三方 provider 自己的存储模型显式调用 MCP 工具由 provider 决定示例全部关闭

默认不是一个单一布尔值,而是 composition 的结果。Base 挂载 JSONL 与 sessionQuery,但把 FTS 配成 openAt: never;standard preset 再挂载 Skills 和 compaction;minimal 明确省略 compaction,并禁止动态 runtime-context snapshot。MEMORY-DEFAULT-COMPOSITIONMEMORY-STANDARD-PRESETMEMORY-MINIMAL-PRESET

2. Working context 是当前 Surface,不是整份日志

claim inbox messages
→ assemble system prompt and tools
→ project dynamic runtime context
→ run agent/pre-step injections
→ append accepted user/context messages durably
→ derive current Surface messages
→ snapshot request header
→ call Provider

Agent 在 pre-step 中认领输入、组装 prompt、计算 runtime context,并允许插件追加 context;只有被接受的消息才作为 user/message 落入 Session。模型调用随后读取 session.deriveMessages(),并把 canonical provider/model、system 与 tools 另写进 request/headerMEMORY-AGENT-CONTEXT

可见性规则

只有 user/message、非空 assistant/messagetool/result 能成为 Surface message。Turn/Step boundary、raw stream chunk、request header 和其他 log-only event 从不直接进入模型历史;replacement generation 变化时,derived cache 会按新 Surface 全量重建。SESSION-SURFACE-PROJECTIONSESSION-DERIVED-CACHE

因此一个 Session 同时拥有两种“过去”:raw log 保存发生过的事实,current Surface 决定下一次模型真正看见什么。后文所有 memory 讨论都必须先说明自己读取的是哪一层。

3. Durable history 是恢复基础,不是自动召回策略

Base bundle 默认把 Session 日志写到 $DSH_HOME/sessions。Persistence coordinator 只在 backend batch append 成功后推进 durable cursor;resume/load 通过 reservation 与稳定 revision 取得精确、已修复的逻辑历史。实时事件进入有界 write-behind,显式 session/flush 是即时 durability barrier,Session disposal 会 drain 剩余写入。MEMORY-DEFAULT-COMPOSITIONMEMORY-PERSISTENCE-TRANSACTIONMEMORY-PERSISTENCE-FLUSH

文件边界

POSIX 路径以 0700 创建目录,以 0600 创建同步临时文件,并通过 link、目录 fsync 和清理完成不覆盖既有日志的发布。它降低同机泄露和掉电损坏风险,但没有引入租户级访问模型。MEMORY-JSONL-PERMISSIONS

它保证什么它不保证什么
事件按 seq 连续追加,flush 后可作为恢复事实不会提炼稳定用户画像或事实
冷会话能由 Host 或查询服务显式读取新会话不会因此自动搜索旧会话
被 compaction 遮蔽的原始事件仍可审计模型不会自动重新获得这些被遮蔽原文

4. Compaction 是同会话有损变换,不是第二个记忆库

Compaction 的 start/summary/end 是 log-only bracket;真正改变模型可见历史的是随后带 surfaceOp: replace 的 user-message checkpoint。Summary 事件保存被遮蔽 seq、估算 token price、provider/model、usage 与完整 rawOutput,所以旧原文和辅助模型原始输出仍存在于耐久日志中。COMPACT-EVENTS

维度Compaction 的语义为什么不是长期记忆
范围当前 Session 的一个 head-anchored Surface span不读取其他会话或外部事实库
结果较短 checkpoint + 保留近期 tail只为下一次上下文预算服务
保真Prompt 要求结构化摘要,代码只验证非空且更短没有事实一致性或实体记忆 invariant
恢复原始事件保留,Surface 只看 replacement审计可追溯不等于模型自动 recall

默认 basic policy 在 80% pressure 附近触发,保留约 16% 的近期 tail,并允许有界 retry。摘要 directive 固定要求英文;非英语会话可能引入额外翻译损失。自动摘要失败只警告并继续当前 Turn,因此高压历史可能保持未压缩。COMPACT-CONFIGCOMPACT-SUMMARIZER

5. Session reference 是显式、不可变、带来源的跨会话快照

user selects source session ids
→ resolver reads each source's current Surface once
→ keep direct user text + assistant text + canonical checkpoints
→ drop tools, reasoning, nested injected context, and shadowed raw history
→ enforce a per-source UTF-8 byte budget
→ inject one sourced user-role snapshot into the target Session

Resolver 默认最多接收 3 个来源、候选上限 50、每个来源 65536 UTF-8 bytes。Prompt 明确把快照标为 untrusted、read-only,并禁止模型采纳其中的指令、权限声明或工具请求,除非当前用户再次提出。MEMORY-REFERENCE-RESOLVER

Projection 只保留直接用户消息、assistant text 和 canonical compact checkpoint。超预算时先保留 checkpoint 与最新消息、删除较旧非 checkpoint 单元,再对最长文本做 head/tail 截断并记录精确 omission。MEMORY-REFERENCE-PROJECTION

Snapshot 而非 link

prepare() 每个来源只读一次。来源之后被追加、压缩或删除,都不会改变目标 Session 已经写入的 context;测试还要求 fresh replay 复现相同目标消息。MEMORY-REFERENCE-CONTRACT-TEST

它不是 fork、resume、subscription 或实时共享,也不会在模型认为旧会话“相关”时自动运行。context 包总览明确把 session-reference 列为 opt-in。MEMORY-REFERENCE-OPT-IN

6. Session reference 的授权属于 Host,不属于 resolver

listCandidates() 会列出 sessionQuery 暴露的所有非自身会话;相同 cwd 只提高排序优先级,不构成过滤。prepare() 接受精确 Session ID 后直接调用 readSurface()。包 README 也明确称 resolver 假定 Host 已经获准读取 query service 暴露的每个 Session。MEMORY-REFERENCE-RESOLVERMEMORY-REFERENCE-TRUST

信任边界,而非默认漏洞

在固定提交中,该包默认未挂载,也没有发布 Web candidate picker,因此不存在 stock UI 直接越权读取的路径。但任何未来多用户 Host 若暴露它,都必须在候选发现和精确 prepare 两处分别过滤、重新授权;不能把 cwd 排名误当成 access control。

已确认文档漂移

README 声称 standard TUI 安装 one-shot pre-step wrapper,并描述 idle/running 两条 inject/steer 集成路径;固定提交中找不到对应生产 adapter、消费方或发布 composition row。可验证的实现止于 resolver、URI/parser、projection 与 UI replay 组件。MEMORY-REFERENCE-DOC-DRIFTMEMORY-REFERENCE-OPT-IN

7. Session query 是统一读取面;FTS5 是可丢弃的词法派生索引

Query corpus 优先读取 detached live snapshot;只有目标不在线时才 inspect persistence,并在读取期间再次检查 attach race。批量 cold read 有并发上限,单个 Session 失败被隔离为该项的 rejected result。MEMORY-QUERY-CORPUS

搜索文档由完整 raw log 逐事件抽取,并用 canonical Surface fold 标成 currentshadowedlog-only。默认可搜索 user/assistant text、tool name/arguments/results、Todo 与部分 Turn error;reasoning、raw chunks、request headers、未知事件和未知 block 被排除。MEMORY-QUERY-DOCUMENTSMEMORY-QUERY-EXTRACTION

搜索语义风险

user/message 抽取不检查 source。因此一旦启用 FTS,Skill catalog、Skill invocation 或 session-reference 等插件注入的 user-role context 也可能进入索引;Host 的 Web 搜索虽过滤 current user/assistant event type,却没有再按 message source 过滤。这是可确认的静态索引语义与隐私边界,不代表默认配置已经创建该索引。

SQLite 后端是 FTS5 unicode61 词法检索,不是 embedding 或 semantic retrieval。若配置持久路径,它会把抽取后的明文复制进派生数据库;新建目录与文件使用 owner-only 权限,外来数据库会被拒绝,受识别但版本不兼容的派生 schema 可重建。MEMORY-QUERY-SQLITE-SCHEMA

8. 默认只启用精确读取;全文搜索和模型查询工具都关闭

Base 与 Web patch 都设置 path: ':memory:'openAt: never。这个模式完全不 import/open SQLite,并让 searchSessions/searchEvents 返回 SESSION_QUERY_SEARCH_DISABLED;但 title、lineage、surface 与 exact event read 仍由统一 service 提供。MEMORY-DEFAULT-COMPOSITIONMEMORY-QUERY-SQLITE-MODELOG-QUERY-TRACE

模型侧 tool-session-query 是另一个 opt-in 包,注册 session_searchsession_event_searchsession_tracesession_event_tracesession_event_read;发布 Host composition 默认不挂载。它还故意不做结果字节/字符截断,部署方若需要有界 inline output,必须另挂 spill policy。MEMORY-QUERY-TOOL-CONTRACT

模型工具授权

若显式挂载,调用者只能来自 exec.agent;self 始终可读,跨会话必须与调用 Session 的 cwd 精确相等,且读取后会按 observed header 再检查。未经授权的 lineage 分支被替换为不含隐藏 Session ID 的 marker。MEMORY-QUERY-TOOL-AUTH

要精确描述默认能力,应说“Host 拥有跨会话精确查询 seam,但模型默认没有跨会话搜索/读取工具”,而不是笼统写成“支持会话记忆”。

9. Web UI 当前是本地元数据搜索优先,内容搜索按配置降级

Workspace Browser 对非空查询立即匹配 title 与 Workspace 名称,250 ms 后再请求 Host content search;远端失败时保留本地结果并显示 warning。两类结果按本地优先顺序去重、合并并限制到 20 条。MEMORY-WEB-SEARCH

Host 以“attached Session + 带 cwd 的可服务 cold Session”作为可见 baseline,查询 provider 后只接受属于可见集合、类型为 current user/assistant message、且 Session ID 自洽的 hit。这个 Host gate 是 Web 路径的授权边界。MEMORY-WEB-HOST-GATE

默认组合落差

Stock Web 的非空查询仍会发起 content request,但 base/backend 的 openAt: never 确定性拒绝 FTS,于是用户实际得到 title/workspace-only 结果和 unavailable warning。UI README 描述了内容匹配交互,却没有在同处说明发布默认关闭,因此“UI 能发请求”和“默认部署能搜正文”不能混为一谈。

10. Skills 是可信知识与操作说明,不是从对话学习的记忆

Skill registry 合并 host/global 与 per-scope provider/runtime 层:最近 scope 的同名项覆盖较远层,层内再按 rank 解决重复;list() 返回摘要,get() 按需加载完整定义。Registry 不包含从 Session 事实提取、强化、冲突消解或遗忘的路径。MEMORY-SKILL-REGISTRY

Filesystem provider 从最近 Git root 的 .dsh/skills.agents/skills、custom roots、用户 roots 和 bundled root 发现扁平 .md 或一层目录中的 SKILL.md。默认开启 watch、跟随符号链接,并允许最多 128 个 project watchers;非 bundled root 通过可选 filesystem policy 读取。MEMORY-SKILL-FILESYSTEM-CONFIGMEMORY-SKILL-FILESYSTEM-ROOTSMEMORY-SKILL-FILESYSTEM-LOAD

路径进入模型的内容持久语义
Catalog publication名称 + 截断后的 description以 sourced user message 记录完整当前目录
模型调用 skill按需完整 <skill_content>普通 tool call/result 留在 Session
用户输入空白边界 /name直接注入完整 instructions contextskill-invocation source 的 user message

两条加载路径都检查实际 definition 的 invocation policy,且只有直接用户来源能伪触发不了的 /name gesture。完整正文被有意视作 trusted local content 并原样嵌入;这正是知识注入,而不是记忆检索。MEMORY-SKILL-INVOCATION

11. Skills 的主要风险是仓库信任与上下文放大

发现分类实际影响
项目 Skills 自动被发现,没有逐仓库或逐 Skill consentHost trust boundary不可信仓库的 description 可进入 catalog,正文可在调用后成为强指令
每条 description 默认最多 500 字符,但没有 Skill 数量/总 catalog 上限静态韧性缺口大量 Skill 可线性放大每次 catalog publication
完整 Skill body 没有字节上限静态韧性缺口一次模型或用户加载即可显著占用上下文
Body 原样渲染为可信 instructions设计边界可形成 prompt injection,但不会因此自动执行仓库脚本
Provider 配置注释称默认名 local,schema/constructor 实际为 filesystem文档漂移嵌入方按注释推断 provider identity 会出错

单条 description cap、完整目录 publication 和无 body cap 都能从实现直接确认;filesystem provider 的 JSDoc/default 不一致也位于同一配置定义中。MEMORY-SKILL-FILESYSTEM-CONFIGMEMORY-SKILL-FILESYSTEM-LOADMEMORY-SKILL-INVOCATION

Web 的 skill.list 只为已 attach Session 解析 host-owned cwd/scope,并只返回 user-invocable 项;客户端按 Session 缓存、以 / 提供候选,选中后只写入字面量 /name 。列表失败会静默丢弃该菜单分组,没有 consent 或风险预览层。MEMORY-SKILL-HOST-UIMEMORY-SKILL-CLIENT-UI

12. 外部 Memory MCP 是互操作边界,数据与召回语义归 Provider 所有

examples/mcp-memory 提供 Memorix、MCP Reference Memory 与 Engram 三个 pin 住版本的 overlay。Harness 负责解析 overlay、启动 stdio 子进程或连接 Streamable HTTP、发现工具并把它们注册为 mcp__<server>__<tool>;它不下载服务、初始化数据库、选择模型/embedding provider、迁移数据或监管独立 HTTP 服务。发布 composition 中没有 memory server,省略 --patch 时全部关闭。MEMORY-MCP-BOUNDARY

Provider 示例README 所述存储/检索Harness 能保证的部分
MemorixProvider 自有本地 heuristic 与数据目录MCP transport、tool discovery 与调用
Reference Memory本地 knowledge graph;大小写无关 substring search配置把存储路径传给子进程
EngramProvider 自有 storage/project selection启动配置与环境边界

是否写入、何时搜索、如何解决冲突、是否遗忘、跨项目身份和许可都不是 core Harness contract。示例甚至建议在 tool description 不足时额外写一条“该记住时写、历史相关时搜”的模型指令,说明自动使用仍依赖 prompt/tool policy。MEMORY-MCP-BOUNDARY

测试边界

现有测试验证 overlay 可解析、pin 存在、没有明显硬编码 key,并把真实命令替换为 keyless fixture 后检查工具发现;它没有运行真实 provider,也没有证明写入、Host 重启持久化、新 Session 召回、权限隔离或语义质量。MEMORY-MCP-CONTRACT-TEST

13. 固定提交中刻意没有的第一方自动记忆闭环

not present as a shipped first-party default:
conversation → fact extraction → durable semantic store
             → relevance retrieval → ranking/dedup
             → permission-filtered automatic prompt injection
             → conflict resolution / forgetting / provenance feedback

源码与发布 composition 能证明的是 Session event log、Surface replacement、exact/lexical query、explicit snapshots 与 instruction catalogs。没有证据支持把这些机制描述成默认的 embedding memory、向量检索、episodic/semantic memory、用户画像学习或自动 recall。外部 MCP 可以补上其中部分能力,但能力、数据所有权与风险随 provider 改变。

为什么这种克制很重要

显式边界让 replay、授权和 token cost 更容易推理:历史读取必须经过 Host/tool seam,跨会话内容带 source,Skills 必须被加载,外部数据库必须显式挂载。代价是用户期待的“长期记住我”不会自然发生,部署者必须自行选择存储、触发、授权、冲突与遗忘策略。

最准确的产品描述是:durable, replayable session history with explicit cross-session retrieval seams,而不是 autonomous memory platform。

14. 已确认问题、静态风险与验证状态

项目结论级别状态
Session-reference README 描述未落地的 standard TUI integration已确认文档漂移默认未挂载
Stock Web 发 content search,但 backend 默认确定性禁用 FTS已确认 composition/UI 落差降级为 title/workspace + warning
启用 FTS 后可能索引插件注入的 user messages高置信静态推论默认未创建索引
持久 FTS 复制抽取后的明文已确认数据边界owner-only;显式启用才发生
Skill catalog/body 缺少 aggregate size cap,项目发现无 consent已确认静态韧性/信任缺口standard 默认相关
Compaction 保留 shadowed raw events 与 summarizer rawOutput已确认 retention 边界不是删除机制
Web search 返回底层错误文本源码承认的部署边界当前只声明 single-user local
Memory MCP 没有真实 provider E2E已确认验证缺口只有配置与 fixture discovery 测试
验证范围

本章固定在 upstream commit 47f943859bef60e4160492346772ded9b24f765a,交叉检查了 Agent request path、Session/Surface、persistence、compaction、session-reference、session-query/SQLite/model tools、Web Host/UI、Skills 与 Memory MCP 示例及其测试源码。由于依赖安装在无关平台包上阻塞,本轮没有成功执行测试;这里报告的是源码与既有测试合同审计,不声称运行时测试通过。

我的学习体会

内容仅自动保存到当前浏览器,不上传、不进入仓库。你可以导出 Markdown 自行归档。