## Before
用户问:`这里有外卖/配送字眼的 session 有多少,比例?顺便看解决率,再给整个商品领域占比。`
手工做法容易变成三轮返工:
| 问题 | 典型失败 |
|---|---|
| HTML 解析 | 直接截 `const DATA =` 后面的文本,把后续脚本也带进去,触发 `JSON extra data` |
| ID 字段 | 猜 `sessionId/session_id`,但页面真实字段是 `sessid` |
| 关键词口径 | 全字段命中、对话正文命中、用户原话命中混在一起,无法解释真实用户诉求 |
| 输出口径 | 先给 case 数,用户追问后再补解决率、商品域占比和导出清单 |
## After
一次命令固定解析和口径:
```bash
python /Users/bytedance/Documents/job-bu/data-analysis-workspace/tools/review_html_keyword_metrics.py \
/Users/bytedance/Documents/job-bu/data-analysis-workspace/projects/2026-05-09-商品领域意图体系迭代/output/review_pages/商品域最终体系_用户版层级_session复核_2026-05-25_v31_客服Skill命中.html \
--keywords 外卖 配送 \
--scopes all_fields,messages_readable,user_text,metadata \
--id-field sessid \
--product-total 9335 \
--global-total 77328 \
--export-ids \
--export-formats xlsx,csv,txt \
--out-dir output/keyword_metrics/外卖配送_2026-05-25_v31
```
标准输出先给可复核摘要:
| scope | case 数 | 已解决 | 未解决 | 解决率 | 商品域占比 | 大盘占比 | 解读 |
|---|---:|---:|---:|---:|---:|---:|---|
| all_fields | 490 | `<tool计算>` | `<tool计算>` | `<tool计算>` | 5.25% | 0.63% | 全记录字段命中,适合最大召回 |
| messages_readable | 313 | `<tool计算>` | `<tool计算>` | `<tool计算>` | 3.35% | 0.40% | 对话正文命中,排除部分结构化标签噪音 |
| user_text | 122 | `<tool计算>` | `<tool计算>` | `<tool计算>` | 1.31% | 0.16% | 更接近真实用户主动诉求 |
| metadata | `<tool计算>` | `<tool计算>` | `<tool计算>` | `<tool计算>` | `<tool计算>` | `<tool计算>` | 标签、reason、命中 Skill 等辅助字段命中 |
同时写出:
- `metrics.json`:包含 `records=9335`、`unique_sessid=9335`、关键词、scope、分子分母和解决率。
- `metrics.md`:可直接贴给用户的结论版。
- `matched_sessions.csv`:每个命中 session 的 `sessid`、命中 scope、命中字段、是否解决、命中片段。
- `sessionId清单.xlsx/csv/txt`:按既有单列表头 `智能会话id` 导出。
验收信号:
- 解析成功:`DATA.total=9335`、`records=9335`、`unique_sessid=9335`。
- 口径透明:每个结果都带 `scope`,不把 `all_fields` 冒充真实用户诉求。
- 交付完整:用户继续追问占比、解决率、清单导出时,不需要重新写临时脚本。