Hindsight.md 13 KB

Hindsight 记忆系统

整理日期:2026-09-28 服务端:mac mini(10.10.10.25) 客户端:MacBook 上的 DeepSeek Harness 🔴 2026-09-28:MacBook 上的自托管部署已彻底删除 —— Apple Container 数据目录(容器 hindsight-local + 卷 hindsight-pg0data + 快照 + 镜像层,共 12 G)已移除,运行时由 /usr/local/bin/uninstall-container.sh -d 卸载; 本机只留客户端三件套(~/.hindsight/coding-agent.json → http://10.10.10.25:8888,外加 local-hindsight-api.key / local-hindsight-cp.key)。现役架构见 ~/Documents/MacBook/claude.md §8;本地部署全章存档见 ~/Documents/MacBook/hindsight-history.md §26(旧 hindsight-local-ops.md 已移入 _archive-hindsight-local-20260928/)。

0. 结论速览

  • 最新版 支持第三方记忆系统 —— Hindsight 是 9 个内置 provider 之一,随 Starter 默认安装。
  • 本机其实有两条独立链路写入 Hindsight,排障时先分清是哪一条:
    1. dsh-mnemon(可组合记忆) —— Memory Spaces provider,配置在 ~/.mnemon/state/memory-providers.json;
    2. hindsight-coding-agents 插件 —— 每个仓库一个 bank,会话结束自动回写,配置在 ~/.hindsight/coding-agent.json。
  • 两条链路 互补、不冲突(2026-09-28 实测结论):
    • hindsight-coding-agents = 采集器 —— git 种子 / 代码库普查 / 会话 transcript 自动回写 / 知识页面按小时刷新 → 让库自己长大,所以打开控制台总能看到「整合中」。
    • dsh-mnemon = 检索 + 管理台 + 热记忆 —— 15 个 bank 映射成记忆空间、跨库检索、MEMORY.md / USER.md 每轮注入、文档层、9 个 provider 可换 → 让库里的东西被用起来、管起来。
    • 证据:一次 mnemon_recall 同时命中 coding-agent::MacBook 和 hermes 两个库,返回的 4 条全部是别人写进去的(source: external)→ 读侧读的确实是同一条链路的共享库。
    • 唯一注意点:互补的是职责,重叠的是目标(mnemon 的 memory body 就是 coding-agents 建的同一批 bank)。分工定为「coding-agents 负责写,dsh-mnemon 负责读 / 管 / 热记忆」即可 —— 既不冲突也不重复。
  • 「整合」是 Hindsight 服务端的 worker 任务(hindsight_api.engine.consolidation.consolidator),不是插件在跑;两个插件都只是投喂方。控制台那个进度条 = 该 bank 的事实总数与 last_consolidated_at,dsh-mnemon 只装不写时队列永远是空的,不是坏了,是没有燃料。
  • 当前遗留 3 项:DSH UI 里 endpoint 端口填错、Hermes 未启用 hindsight、插件 v4 补丁属于本地临时改动。
  • 已处理(2026-09-28):插件 reflect 超时 → 改为 "autoInject": "pages"(跳过 hook 里注定失败的 20s reflect,不是调大超时;见问题 5);服务端 mental model refresh 偶发失败 → 只观察。

1. 问题清单

问题 1:最新版是否还支持第三方记忆系统(Hindsight)?

结论:支持。

  • dsh-mnemon 0.5.17 通过 Memory Spaces provider 机制支持 9 种外部引擎。
  • Hindsight 适配器 dsh-mnemon-provider-hindsight 0.5.5 随 Starter 默认安装。
  • 配置入口:设置 → 插件 →「可组合记忆」页面(不在「记忆系统」标签页里)。

问题 2:Hindsight 显示「服务就绪 · 尚无已激活记忆空间」

状态:⚠️ 待修(在 UI 改一个字段即可)

  • 根因:端口填错。 实际落盘配置 ~/.mnemon/state/memory-providers.json 里是 http://10.10.10.25:9999 —— 9999 是控制台 Web UI 端口,所有 API 请求都被重定向到登录页。
  • 为什么还显示「就绪」:探活只测 /health/live,登录页也算响应 → 假就绪;随后发现 banks 时拿到的是 HTML → 0 个记忆空间。
  • 验证:同一 key + 8888 端口实测 200 OK,能正常列出 banks(含 coding-agent::ZLSH-数字化管理系统,23697 facts)→ key 和服务本身都没问题。
  • 修复:UI 里把 endpoint 改成 http://10.10.10.25:8888,保存即同步。

问题 3:Hermes 看不到自己的记忆空间

状态:⚠️ 待修

  • 根因:config.yaml 里 plugins.enabled 和 plugins.disabled 同时列了 hindsight,其中 disabled 生效;且没有配任何连接参数。
  • 证据:errors.log 每轮警告 Memory provider 'hindsight' is disabled。Hermes 从未连过 Hindsight,服务器上现有的 bank 全是 mini 上 coding agent 写的。
  • 修复:hermes plugins enable hindsight + 配 local_external 模式(endpoint 8888 + 现有 key),然后重启 gateway。

问题 4:装 hindsight-coding-agents 后每轮报 format v4 message requires a producer-owned source kind

状态:✅ 已用官方临时补丁修复(等上游发版前有效)

  • 根因:插件 0.7.0 注入 recall 消息时用了 v3 旧写法 kind:"plugin",被 dsh 0.1.7-rc.2 的 v4 会话格式准入校验拒绝 → 整轮失败。
  • 上游:已有 3 个重复 issue(#4626 / #4701 / #4818);修复 PR #4639 已合并 main,但 npm 未发版(#4779 催发中)—— 所有安装渠道拿到的都是坏的。
  • 已完成的修复:
    1. 备份原文件 dist/dsh.js.bak-20260928;
    2. 按 issue #4779 的官方临时补丁改一行(18446):kind:"plugin", plugin:HINDSIGHT_PLUGIN → kind: HINDSIGHT_PLUGIN;
    3. 用 dsh 本体真实校验函数 assertV4RowAdmission 实测:补丁后的 shape PASS、旧 shape FAIL(精确复现原始报错);
    4. 重启 3080(dsh 0.1.7-rc.2),监听正常。
  • 注意:补丁会被插件重装/升级覆盖;等上游 0.7.1 发布后正常升级即可,不要长期依赖这个改动。

问题 5:每轮 reflect failed — reflect timed out after 20000ms

状态:✅ 已处理(2026-09-28,改为 autoInject: "pages",不是调大超时)

  • 发现于 2026-09-28 复查日志(问题 1–4 之外的新发现)。
  • 现象:~/.hindsight/coding-agents-logs/plugin.log 里 reflect failed 共 76 次;diag.jsonl 事件统计 reflect_failed 76 / reflect_fallback_pages 72 / reflect_ok 5 —— 即约 5 / 81 成功。09-28 当天的 4 次全是 reflect timed out after 20000ms: This operation was aborted (20)。
  • 根因:插件自动注入用的 reflect 客户端超时默认只有 20000ms(dist/dsh.js:1446 DEFAULT_REFLECT_TIMEOUT_MS = 2e4),而 ~/.hindsight/coding-agent.json 里没有配 reflectTimeoutMs。服务端给的是 HINDSIGHT_API_REFLECT_LLM_TIMEOUT=180、HINDSIGHT_API_REFLECT_WALL_TIMEOUT=1200;实测一次成功的 reflect 要 ~12.5s(4 iterations)—— 对大库(几千 fact)确实不够。
  • 影响:不致命 —— 失败后自动降级为知识页面检索(reflect_fallback_pages,72 次)。代价是「为什么这么改」那层深度记忆(reflect 结果)基本没进库。
  • 最终采用的处理:~/.hindsight/coding-agent.json 加 "autoInject": "pages" —— 跳过每次注定失败的 20s reflect,直接注入知识页面(失败后本来也是走它)。效果:每次会话启动省下约 20s,76 条 WARN 噪音消失。备份:~/.hindsight/coding-agent.json.bak-20260928-130203。
  • 为什么不调大 reflectTimeoutMs(这是最关键的一点,最初判断错了):
    • 那 20s 是插件故意给自动 hook 封的上限 —— dist/dsh.js:1515-1517 注释原文:"a short window is set to bound the automatic hook, not to cut off a call the agent is waiting on."
    • 自动 reflect 跑在会话启动的 hook 窗口里,且用低预算 budget: "low"(dist/dsh.js:18028);失败后的降级注入另有一个 7s 预算(:17951 HOOK_FALLBACK_BUDGET_MS = 7e3)。
    • agent 主动调的 MCP 工具 hindsight_reflect 本来就是 330s + high budget(:1447 DEFAULT_REFLECT_TOOL_TIMEOUT_MS = 33e4,:17192)—— 深路径一直都在,只是按需。
    • 所以把 hook 窗口抬到 120s = 用「每次启动最多卡 2 分钟」换一个低预算调用,不划算。
  • 代价与回退:自动的 "why" 综述不再注入,需要时由 agent 显式调 hindsight_reflect(这正是设计意图)。autoInject 可选值:none / pages / recall / reflect;想回退就删掉这行或恢复备份。
  • 另有两条服务端侧的报错,与本项不同源:
    • MentalModelRefreshError … ReflectNoAnswerError: Reflect's done tool returned no answer (iteration 4, 3 tool call(s) made)(mental_model mm-445d66d3558e462f838de381cbb758e3)—— 服务端 LLM 没把 answer 写进 done tool,疑似被 HINDSIGHT_API_REFLECT_MAX_COMPLETION_TOKENS=8000 截断;旧内容保留在 DB 并自动重试。
    • delta operations did not reach the document … refresh_skipped == 'delta_ops_failed' —— delta 更新没落到文档上,同样走"保留旧内容 + 重试",所以部分知识页面会偏旧。
  • 历史旁证:2026-09-27T17:25Z 那两次报的是 connect ECONNREFUSED 127.0.0.1:8888 —— 插件走了 localhost 默认回退路径(dist/dsh.js:1492 的 daemon 分支)而不是配置里的 10.10.10.25:8888;现在已不再出现,但复发时优先查这条。

2. 遗留待办

  • DSH UI:把 Hindsight endpoint 改为 http://10.10.10.25:8888
  • Hermes:plugins enable hindsight + 配 local_external,重启 gateway
  • 关注 hindsight-coding-agents 0.7.1 发版,升级后撤掉本地补丁
  • 插件 reflect 超时(2026-09-28 已处理):改为 "autoInject": "pages",跳过 hook 里注定失败的 20s reflect(不是调大 reflectTimeoutMs,理由见问题 5)
  • 服务端排查 mental model refresh 的 ReflectNoAnswerError / delta_ops_failed(mm-445d66d3558e462f838de381cbb758e3)

3. 同一条链路上的历史问题(2026-09-28 更早排查,已修)

  • mac mini 断网(无默认路由 + 无 DNS):容器所有云端嵌入/LLM 调用失败 → recall 返回 500 Failed to generate batch embeddings: Connection error.,09-28 凌晨 01:37 之后各记忆空间的写入全面停摆。 修复:networksetup -setmanual Wi-Fi 10.10.10.25 255.255.255.0 10.10.10.252 + -setdnsservers Wi-Fi 114.114.114.114 223.5.5.5(该机现为静态 IP,换网络时记得 -setdhcp 改回 DHCP)。
  • 远程重启 mac mini:用 sudo fdesetup authrestart(可一次性解锁 FileVault,SSH 约 40 秒后自动恢复);普通重启会锁在 FileVault 登录界面,SSH 再也连不上。FileVault 开启时 macOS 不允许自动登录(sysadminctl -autologin 直接报错),所以重启后若无人登录图形界面,容器不会自启。
  • DSH 运行时记忆为空:~/.dsh/profiles/web/cordis.patch.yml 里 mnemon-strategy-scoped 的 sourceKeys/writableSourceKeys 只留了 mnemon-source-memory-spaces,导致 runtime/mutate、documents/search 不被 View 提供(会话里报 Source Action is not offered by the current View: runtime/mutate)→ MEMORY.md / USER.md 永远为空。 修复:恢复为 runtime(working-context)+ documents(narrative)+ memory-spaces(durable-evidence),重启 dsh web 后验证写入成功。

4. 关键路径速查

用途 路径 / 命令
DSH mnemon 配置补丁 ~/.dsh/profiles/web/cordis.patch.yml
Mnemon provider 落盘状态(endpoint / apiKey / 记忆空间清单) ~/.mnemon/state/memory-providers.json
热记忆文件 ~/.mnemon/runtime/MEMORY.md、~/.mnemon/runtime/USER.md
DSH ↔ Hindsight 插件配置 ~/.hindsight/coding-agent.json
插件日志与诊断 ~/.hindsight/coding-agents-logs/plugin.log、diag.jsonl、usage.jsonl
插件状态脚本 node ~/.dsh/profiles/web/node_modules/@vectorize-io/hindsight-coding-agents/dist/status.js --repo <路径>
mac mini 容器操作 export PATH=/usr/local/bin:$PATH 后用 container(容器名 hindsight-local)

5. 已知坑

  • 8888 = API,9999 = 控制台。DSH / Hermes / 插件连 Hindsight 一律填 8888;填 9999 会「看起来就绪、实际 0 个空间」。
  • 控制台登录接口是 POST /api/auth/login,body {"key":"<控制台 access key>"}(Authorization: Bearer、X-Api-Key、Cookie 全部 401);access key 来自容器的 HINDSIGHT_CP_ACCESS_KEY 环境变量。
  • Mnemon 设置页的「参与 Source / 记录目标」改的就是 cordis.patch.yml;把它收窄成只有记忆空间,会让热记忆与文档层一起失效,且改完必须重启 dsh web 才生效。
  • hindsight-coding-agents 0.7.0 的 v4 修复是本地打补丁,插件重装/升级即丢。
  • hindsight-coding-agents 的 自动注入 reflect 超时默认只有 20 秒(DEFAULT_REFLECT_TIMEOUT_MS = 2e4)—— 这是故意给会话启动 hook 封的顶,不是给 agent 用的;agent 的 hindsight_reflect 工具超时是 330s(DEFAULT_REFLECT_TOOL_TIMEOUT_MS = 33e4)。所以别用调大 reflectTimeoutMs 去"修"它,那只会让每次会话启动变慢;要快就把 autoInject 设成 "pages"(本机已设)。
  • 「整合」是服务端的活(worker 的 consolidation 任务),客户端插件不参与;控制台进度条不动 ≠ 故障,要看有没有人往里写。