2 次代碼提交 6372009b71 ... 19ebc8e77e

作者 SHA1 備註 提交日期
  zhensolid 19ebc8e77e vault backup: 2026-09-29 09:44:56 3 周之前
  zhensolid 6f9760d4b3 vault backup: 2026-09-28 12:53:53 3 周之前
共有 1 個文件被更改,包括 121 次插入 和 0 次删除
  1. 121 0
      01-AI与模型/DSH/Hindsight.md

+ 121 - 0
01-AI与模型/DSH/Hindsight.md

@@ -0,0 +1,121 @@
+# 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 发版,升级后撤掉本地补丁
+- [x] 插件 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 任务),客户端插件不参与;控制台进度条不动 ≠ 故障,要看有没有人往里写。