Files
HomeAgent/scripts/capability-bench/PLAN.md
JianFeeeee f256098c9f refactor: 全面改名为 HologramAgent + 提示词技术内容下沉到 skill/工具描述 + 修 21 处乱码
## ① 全面改名 HomeAgent → HologramAgent

仓库已改名,但代码与文档里仍有大量旧名。本次按"用户能看到的优先"全量替换:

- 用户可见:登录页标题/页脚、默认人格第一句、CLI 状态输出、启动日志、
  plugin_install 的工具描述、AI 图片插件的 User-Agent
- 文档与脚本:README、assets/docs、docs/zh、deploy/*.sh、.github/workflows
- 鸿蒙工程:cmd/ohos/HomeAgent → cmd/ohos/HologramAgent(git mv)
  目录内的 module/app 描述同步;**证书路径原样保留**
  (default_HomeAgent_xxx.cer/p7b/p12 是签名材料的实际文件名,改了会找不到证书)
- 插件元数据:plugin.json 的 author

★ 必须保持原样的两处(改了会坏):
  · legacySeededPromptSignature = "你是 HomeAgent 的看板娘「小宅」…"
    —— 那是识别历史播种人格卡的**原文锚点**,改了就识别不出旧数据
  · 公开 SDK 的 ProxyAuthHomeAgent = "homeagent"
    —— 那是 SDK 契约里的值,属独立仓库,本仓不改

## ② 修 21 处乱码(U+FFFD)

这些是历史编辑留下的编码破坏,全在注释里,例如:
  「赌注重下���遍」→「赌注重下一遍」
  「「不��滤」」  →「「不过滤」」
  「**待��退场**」→「**待退场**」

★ 保留 providers/chineseclip/tokenizer.go 里的 2 处:那是**故意**用
  U+FFFD 演示"非法 UTF-8 字节被归一成 U+FFFD",不是乱码。

## ③ 提示词技术内容下沉(用户:技术性内容应该收敛到 skill 与 -help 中)

实测系统提示词 2309 字,其中两段几乎全是**模型无法据以行动的实现细节**:

  【工具执行顺序】1272 字(ParallelSafe 声明、批内降级、batchRunnable 判据…)
  【三层记忆】   1069 字(L1/L2/L3 编号、消费式删除、向量空间、指纹…)

收敛后 **2309 → 1723 字(-25%)**,保留的全是"模型据此做什么不同的事":

  工具顺序:默认并行 / 不要依赖先后 / 同通道保序 / 写类工具可能串行
  三层记忆:时序里能看最近 / doc_query 把历史事件按原始时间戳插回时序 /
           关系用 memory_recall / 成文知识用 knowledge_search

判断口径写进判据:新加一段提示词前先问"模型会据此做什么不同的事",
答不上来就该进 skill 或工具描述。

## 判据

prompt_memory_test.go 新增 2 条:
- TestSystemPromptHasNoImplementationJargon
  黑名单:ParallelSafe / batchRunnable / 消费式 / DenseCosine / fingerprint /
  向量空间 / 批内降级 / 自激
- TestSystemPromptStaysCompact:上限 2000 字(当前 1723)

变异:把 "ParallelSafe 声明、批内降级" 加回工具顺序段 ⇒ 第一条立刻红。

## 验证

- go build ./... / go vet ./... 干净
- go test ./... -count=1:58 包 0 失败
- make check-client-versions:客户端与内核版本一致
2026-10-22 20:49:44 +08:00

253 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 跑分计划
> 本文原为根目录 `benchmark.md`,随仓库清理归位到此处
> (与同目录 `README.md`「能力标定台」是两份不同文档,勿混)。
>
> **本机路径已脱敏**:脚本里出现的 `/home/<user>`、`/var/tmp/...` 均为占位示例,
> 实际跑请按本机环境替换,或改用 `spawn-instance.sh` 的参数。
> 交接文档:供新会话执行。旧会话的测试**已全部停止**,本文件是从头开始的唯一依据。
> 新会话开始时:**先验证本文件每一条「前置事实」再执行**,不要凭记忆或信任旧会话输出。
## 0. 前置事实(新会话必须先逐条重验)
| # | 事实 | 验证命令 | 期望 |
| --- | --- | --- | --- |
| 1 | 跑分工具已就位 | `ls scripts/capability-bench/` | bench.py pi_bench.py compare.py memory_recall.py tasks.example.json tasks.zerobasis.json spawn-instance.sh README.md |
| 2 | 代码提交已完成 | `git log --oneline -8` | 见 §5 提交清单 |
| 3 | 工作区干净 | `git status --short` | 空 |
| 4 | 生产实例未受影响 | `ps -p $(pgrep -f 'homed -data ${HA_DATA}' \| head -1) -o pid,etime` | 存活 |
| 5 | 测试进程已清 | `pgrep -f 'memory_recall\|pi_bench\|bench.py'` | 空 |
| 6 | llmsproxy 可用 | `curl -s -o /dev/null -w '%{http_code}' -H "Authorization: Bearer $(sqlite3 ${HA_DATA}/config.db \"SELECT value FROM config WHERE key='core.llm.api_key'\")" http://127.0.0.1:8081/v1/models` | 200 |
| 7 | pi 可用且版本 | `pi --version`(如 EADDRINUSE 用 `env -u PI_A2A_PORT -u PI_ACP_PORT`) | 0.85.1 |
| 8 | pi 的 llmsproxy provider | `python3 -c "import json;d=json.load(open('${PI_MODELS}'));print(d['providers']['llmsproxy']['baseUrl'])"` | <http://127.0.0.1:8081/v1> |
## 1. 已知的关键教训(不重犯)
1. **两侧 usage 同名不同义**(已归一,勿改回去):
- HologramAgent:`prompt_tokens` **含**缓存(OpenAI 口径)
- pi:`input` 是**未命中侧**,`totalTokens = input + cacheRead + output`(Anthropic 口径,受控实验实证)
- ⇒ 两侧各自过归一函数(pi_bench.py `_usage_of` / memory_recall.py `_norm_ha_usage`+`_norm_pi_usage`),汇总只认归一后的键
2. **缓存命中率恒 100% 的假绿已修**(`59c0689`):上游只报命中侧时 `miss = prompt - read`。修复前 100.0% → 修复后 87.6%。
3. **cli.sock 按行读**:消息含换行 = 拆成多条独立消息(历史全乱,表现为 BrokenPipe)。memory_recall.py 已有 `assert "\n" not in text`。
4. **内核会 dedupe 完全相同的输入**(`skipped:true`):多轮/重跑必须让每条文本不同。
5. **pi 必须隔离配置目录 + 端口**:`PI_CODING_AGENT_DIR=${PI_ISO}` + `PI_A2A_PORT`/`PI_ACP_PORT` 给空闲端口。隔离后无扩展 ⇒ `pi -p` 跑完自己退出。
6. **pi 的工具事件**:事件名 `tool_execution_start`、字段 `toolName`(写错只是静默为空)。
7. **★ 超窗校验是判据的前提,不是可选项**:旧 200k 跑分因实例窗口(HologramAgent 1M / pi 600k)大于灌入量 253k,实际测的是「窗口内召回」—— 跑 19 分钟、数字漂亮、完全无效。memory_recall.py 已加 `--expect-window` 校验(对无效配置直接拒跑);新会话用它,并先实测两侧真实窗口。
8. **改 LLM 配置必须重启实例**:provider 启动时构建,`/settings set` 落库但不生效。
9. **不要用 `pkill -f`**:会匹配到自己这条 shell 命令行。用 pid 文件或 `pgrep` 精确 pid。
10. **面板懒渲染**:WebUI 的 `#chat-panel-chat` 只在 `switchTab('chat')` 后存在;浏览器验证先切页。
11. **本机 diff 是坏的**(PATH 首位对任何输入返回 0):用 `/usr/bin/diff` 或 Python difflib。
## 2. 测试 A:零基础认知对比(质量,可多实例并行)
**目的**:同模型、同一份材料,只变 harness,测认知而非"翻自己的库"。
(旧版硬伤:knowledge-stats 让 pi 读 HologramAgent 自己的 graph.db ⇒ pi 97s/317k token 全是权限差异,不是能力差异。)
材料:`${BENCH_MATERIAL}/{incident-2026-08.md, config-notes.md}`(若不存在,按 git 历史里的任务集重建;材料必须含:512 连接池上限、4200 峰值、v2.30.4、87 订单、"600" **不在**材料里须自己算 200+400、ttl=0=永不过期、N+1、对账批处理)。
任务集:`scripts/capability-bench/tasks.zerobasis.json`(6 任务:检索/算术/推断/抗干扰/综合/多跳,全部带显式 check)。
执行:
```bash
# ① 起隔离实例(窗口两侧都配 200000)
BIN=${REPO}/build/homed \
bash scripts/capability-bench/spawn-instance.sh a 18082 200000
# ② HologramAgent 侧
python3 scripts/capability-bench/bench.py --socket ${INSTANCE_A}/cli.sock \
--api-key "$(cat "${INSTANCE_A}/apikey")" # 由 spawn-instance.sh 写入 \
--tasks scripts/capability-bench/tasks.zerobasis.json --out ${OUT_DIR}/ha --timeout 300
# ③ pi 侧(同一任务文件 ⇒ 提示词逐字相同)
python3 scripts/capability-bench/pi_bench.py \
--tasks scripts/capability-bench/tasks.zerobasis.json --out ${OUT_DIR}/pi --timeout 300
# ④ 对比
python3 scripts/capability-bench/compare.py --a ${OUT_DIR}/ha --b ${OUT_DIR}/pi \
--label-a HologramAgent --label-b pi --out ${OUT_DIR}
```
验收:两侧任务集一致(compare.py 会检查);逐任务看通过与 token;失败原因必须留在 compare.md。
## 3. 测试 B:200k 超窗记忆召回(性能敏感 ⇒ 独占实例,串行跑)
**目的**:多轮对话超出窗口后,早期内容的召回率(HologramAgent 向量裁剪 vs pi 压缩)。
**★ v3 填充模型(`95224eb`,当前唯一有效版本)**
| 版本 | 填充 | 结论 |
| --- | --- | --- |
| v1 | 显式强调针 + 语义空转 | 两例 4/4 满分零区分度 |
| v2 | 端口同构干扰 + **废话流**(天气/树叶/墨盒) | **作废**:废话被压缩直接丢弃 ⇒ 偶发针成填充里唯一的价值内容 ⇒ pi 跑分虚高 |
| v3 | **高密度叙事**(order-gw 运维主线) | 当前版本 |
v3 主线:`上线准备 → 灰度事故 → 修复验证 → 版本发布 → 交接收尾`,
每轮 5 片段、每片段 2-4 条有信息增量的工作项(数值、因果、决策、变更)、
含跨轮引用。针全部嵌在价值信息流里:
- **偶发针** = 服务依赖清单条目(同构干扰 = 其它服务的**真实**端口,同样有意义,只是不是针)
- **覆盖针** = 值班安排改号(`4379 → 4324`,真实变更场景;反向哨兵验证不塌回)
- **多跳** = 交接流程本身(团队→门禁→申请表)
实测证据支持「废话填充虚高」:v3 第 1 轮 HA 模型就同时调用
`memory_recall / doc_query / config_list_plugins / cmd_run` 四个工具,
而 v2 废话填充下只调 `doc_commit` —— 高密度负载才考得出 harness 的工具选择与
循环管理能力。
**★ 踩坑:锚点 frac 必须落在对应 phase 区间内**(生成器自证时抓到)
`narrative_block` 的 phase 由 `frac` 切分,而针锚点也用 `frac`。写
`i == int(total*0.50)` 想在 release 阶段插针,但 `0.50 < 0.61` 实际落在
verify 分支 ⇒ **永不触发**(表现为「覆盖新值找不到」,不报错)。同理
`0.63` 距边界 `0.61` 太近,浮点除法下可能仍在相邻区间。改法:把每个锚点
推到所属区间**内部**(0.52/0.66/0.70/0.76/0.85/0.92),并写落位自证。
**★ 先把两侧窗口真实配成一致(这是上次翻车点)**:
- HologramAgent:`core.llm.sources.deepseek.context_window = 200000`(spawn-instance.sh 第 3 参传 200000),起后 `sqlite3 ... "SELECT value FROM config WHERE key LIKE '%context_window%'"` 验证 = 200000
- pi:把隔离目录 `${PI_ISO}/models.json` 的 AUTO 模型 `contextWindow` 改成 200000,并用 python3 读回验证
执行(串行,先 A 后 pi;v3 填充实测 `overshoot` 需给 1.45 才能达到 1.23×):
```bash
python3 scripts/capability-bench/memory_recall.py --harness homeagent \
--socket ${INSTANCE_C}/cli.sock --api-key "$(cat ${INSTANCE_C}/apikey)" \
--window 200000 --expect-window 200000 --overshoot 1.45 \
--out ${OUT_DIR}/v3-ha
python3 scripts/capability-bench/memory_recall.py --harness pi \
--window 200000 --expect-window 200000 --overshoot 1.45 \
--out ${OUT_DIR}/v3-pi
```
验收:工具打印「✓ 超窗校验通过」(否则结果无效,删掉重跑);报告 recall_rate 按针分层;两侧灌入量同级(v3 = 143 轮 / 245k / 1.23×)。
注意:143 轮/侧,高密度叙事下单轮 ~25-50s,单侧约 1.5-2 小时;用 bg_run 跑且**不要** `| tail`(会缓冲到看不见进度),输出落文件。实时轮数看实例 `run.log` 的 `grep -ac 'text from cli'`(脚本 stdout 重定向后块缓冲滞后)。
## 4. 测试 C:多实例并行吞吐(可选,性能)
spawn-instance.sh 可起多实例(18082/18083/…;pluginmgr 9876 / remotedevice 9890 / kbtree 9892 写死会 bind 失败属预期降级,不影响 cli.sock 标定)。质量类测试可并行;性能类必须独占。
## 5. 提交清单(已在本地 main,未推送)
```
9ca7e34 feat(bench): 能力标定台 —— 经 cli.sock 驱动实例,记录结果与账目
59c0689 fix(usage): 缓存规则收成单一实现 —— 修掉「命中率恒 100%」的结构性假绿
07e15dc feat(context): 上下文阈值接入配置系统 —— 消除 0.8 与 600000 合成的隐形断层
52c2aae feat(webui): 对话页展示缓存命中率与 token 用量
(更早:73a6359 54ba3ff 2f898a6 6d537ca afeba70 a8ed3a8 —— usage 全链路 + 估算器校准)
```
待提交:本文件(benchmark.md)+ capability-bench 新增的 pi_bench.py / compare.py / memory_recall.py / tasks.zerobasis.json / spawn-instance.sh / README 增补。
## 6. 推送与部署(人工确认后才做)
- 推送:`git push origin main`(8+ 提交在本地)
- 部署:`deploy-plan.sh check`(已预检过:onnxruntime ✓ libonnxruntime ✓)→ backup → deploy;deploy 前需人工确认
- 生产适配器:`${HA_DATA}/adapters/` 有 9/10 与 .bundled 清单不符(openai.lua 实测仅版本落后、无用户修改);部署前逐个核对后清掉让内核重解包(backup 会带走)
## v4 跑分(2026-10-04,新内核 657ccd7)
### ★ 先说一个必须记的操作错误
跑之前先核对了内核版本:
```
build/homed Oct 1 21:18 ← 3 天前的二进制
今天的 memory 层提交 19 个
```
**如果直接跑,测的就是三天前的内核。** 而今天改的
全部是 memory 层(融合召回 / 拒答判据 / 仲裁 / schema 退场)——
跑分会完全测不到今天的工作。
⇒ **跑分前必须核对 `vcs.revision` == `git rev-parse HEAD`。**
这一条应该进 `spawn-instance.sh`,让它自动拒绝版本不符的实例。
(另外两次操作失误:`cp` 取快照在 WAL 模式下不一致;
`${VAR:0:8}` 在 `/bin/sh` 里报 Bad substitution。)
### 能力标定(tasks.zerobasis,6 任务)
| 指标 | 值 |
|---|---|
| 任务数 / 通过 | **6 / 6(100%)** |
| 总墙钟 | 159.17s |
| 工具调用 | 8 |
| 合计 token | 281971 |
| 缓存命中率 | 42.7% |
| 超时任务 | 0 |
分项:检索 3.85s / 算术 43.44s(算出 600)/ 推断 42.66s /
抗干扰 6.57s(答出「永不过期」)/ 综合 5.36s(命中 4200)/ 多跳 57.30s
### 与今天的记忆侧改动的关系
这一轮 6/6 **验证的是「今天没把主干跑坏」**,不是「今天的改动带来了提升」。
记忆召回质量另有专项(`memory_recall.py`,36 探针),
它的结论已经单独记录在 `production-recall-validation.md`:
| | 测试库 ha-c | 生产快照 1391 块 |
|---|---|---|
| 端到端 | 7/7 | 4/9 |
| abstention | — | 0/3(纯中文编造) |
★ **两个库的可拆率差 7.5 倍**(83% vs 11%),
ha-c 的分数不能推广到生产。
## v4 跑分结果汇总(2026-10-04)
### 能力标定
```
tasks.zerobasis 6/6(100%) 墙钟 159.17s
token 281971 缓存命中 42.7% 超时 0
```
### 端到端记忆召回
```
仲裁前 6/7 → 仲裁后 7/7
casual 3/3 overwrite 2/2 confusable 2/2
```
### ★ `memory_recall.py` 专项跑不完(不是慢,是必然失败)
36 轮 = 填充 26 + 探针 10。填充轮耗时实测:
```
[1/36] 30.9s
[2/36] 131.5s
[3/36] 392.0s ← 递增比 2.98×
```
外推:**第 6 轮就超过单轮超时(900s)**,26 轮累计 12.9 小时。
★ 慢的原因是 `memory_commit` 在填充期间持续写库
(entities 188 → 220),每轮检索的数据量与召回量都在涨。
⇒ **改走等价路径**:用探针判据(`TestProbe_端到端召回`)直接测,
数据仍是真实内核跑过的迁移库,结果 7/7。
⇒ **这个专项需要重新设计**:26 轮逐条填充的做法在
「写入会改变检索集」的系统上不成立。
正确做法应是**批量预填**(一次写入全部填充内容),
再跑探针轮 —— 否则填充本身就是被测对象的一部分。
### 本轮跑分的三个操作失误(已在 `421c1d7` 固化防护)
```
① 未核对内核版本 → 差点测三天前的二进制(已加自动拒绝)
② ${VAR:0:8} → /bin/sh 报 Bad substitution
③ 改错二进制路径 → ${INSTANCE_C}/homed 不存在,实际是 build/homed
```
### 实战数据印证的三件事
```
exact 14 / text 24 / symbol 0 标签分布(symbol 是今天新增的)
拒答 2 次(第8批/第9批,精确串库里没有 ⇒ 判据正确触发)
overflow 32 / preempt 6 / 裁剪 3 L4 超页处理真实触发
entities 188 → 220 memory_commit 仍在写旧表
```
详见 `live-run-evidence-2026-10-04.md`。