feat: streamline conversational birth-time rectification

This commit is contained in:
Jesse_Chen
2026-07-22 17:39:11 +08:00
parent d40c16369d
commit 3069a7c8a0
30 changed files with 2059 additions and 590 deletions
@@ -0,0 +1,131 @@
# 对话式生时纠正修改方案与真实回放门槛
日期:2026-07-22
## 结论先行
当前系统可以改成普通 session 式的一问一答,但不能把“交互更顺”描述成“已经能准确到分钟”。现有公开开发案例的分钟评分仍不稳定;产品入口还会丢弃健康、事故、家庭类证据,并且实际只把最近 6 条事件送入评分。
本方案把修改拆成两个互不混淆的目标:
1. 让用户通过自然语言持续补充经历,系统每轮只问一个最有区分力的问题。
2. 用开发集和独立冻结盲测证明分钟排序是否真的收敛;没有通过门槛时只返回候选范围和证据缺口。
## 已确认的问题
### 1. 首轮正文被技术回执合同绑架
`narrative-agent.ts` 当前要求首轮正文复述所有稳定层、敏感层、具体值和领域映射。模型未满足时,fallback 又会输出同一份 D 层清单。技术包本身可以保留,但不应该成为用户正文。
### 2. 自然语言证据域不完整
`evidence-extractor.ts` 只显式识别事业、学业、迁移、关系、家庭、财富。疾病、手术、事故和丧亲会落到 `other``route.ts` 又会排除 `family``other`,所以 D30、家庭与部分重大人生事件无法参与评分。
日期正则还被限制为 1900–2099 年。公开历史人物案例中的 18xx 年事件会被保存成“日期未知”,无法评分;这也意味着现有历史 AA 开发案例并没有真正通过当前产品的自然语言入口。
### 3. 事件数量合同互相矛盾
- 会话收敛层:3 条开始排序,8 条停止继续取证。
- 路由评分层:只保留最近 6 条。
- Jyotish Skill:至少 5 条 dated events 才适合定框;高置信度通常需要 10–15 条多领域事件。
3 条可以产生早期候选反馈,但不得升级成准确分钟。停止条件也不能仅由事件数量触发。
### 4. 当前问题选择仍偏“让用户交材料”
系统应从候选差异中选择一个信息增益最高、用户容易回忆的问题,例如“第一次正式工作是哪年哪月”,而不是一次要求用户提交多个领域的事件。
## 最小实施方案
### 阶段 A:修正文合同,不改评分器
建议改动:
- `frontend/src/lib/conversational-rectification/narrative-agent.ts`
- 首轮正文只要求:当前范围、尚未确认边界、证据进度、一条具体问题。
- 取消首轮必须公开全部 stable/sensitive layer values 的校验。
- fallback 同样只输出一条问题。
- 技术层继续完整保存在 technical packet / receipt 中,在 UI 中放入可折叠“计算依据”。
- 用户消息区、输入框、滚动和留白完全复用普通 session 布局,不保留卡片式问卷。
验收:首轮正文不出现 D1/D9/D10 技术 dump;每轮只有一个问号和一个待回答主题。
### 阶段 B:补齐事件入口
建议改动:
- 在持久化和技术包域中新增 `health_pressure`,不要把它降级成 `other`
- 抽取器识别:确诊、住院、手术、事故、受伤、创伤、重大疾病、康复。
- 日期解析支持出生之后的合法公历年份,而不是写死 19xx/20xx;继续用 `asOfDate` 排除未来事件。
- 家庭事件不要整体丢弃;按父母、子女、生育、丧亲等映射到后端支持的主题证据,若评分器尚无对应合同则明确存储为 context-only,而不是静默消失。
- 移除 `.slice(-6)` 的隐式截断。建立一个共享常量;建议开发回放先测 5、8、10、12 条,再决定产品上限。
- UI 显示“已记录 / 可评分 / 需补日期 / 仅作背景”的数量,避免用户以为回答已评分。
验收:真实测试集中所有标记为可评分的自然语言回答都能保留正确日期、精度和领域;任何被排除的事件都有可见原因。
### 阶段 C:一次问一个高信息量问题
复用现有 `candidateDifferences``suggestedDomains` 和 fact difference opportunities
1. 过滤已经问过、用户表示不记得、或缺少后端支持的主题。
2. 优先选择能把当前候选分成最均衡分区的事件领域。
3. 将领域转成生活化问题,并要求“年份/月份 + 发生了什么”。
4. 用户回答后重新排序,再选择下一题。
问题模板必须具体,例如:
> 你第一次明显的工作转折发生在什么时候?可以是入职、离职、换行业、升职或创业。直接告诉我大约哪一年哪一月和发生了什么;记不清月份也可以先说年份。
### 阶段 D:安全收敛
每轮都可以展示“当前领先范围”,但只有同时满足以下条件才允许提示确认:
- 至少 5 条可评分事件,且至少 3 个领域;高置信度目标使用 10–15 条。
- 真实候选形成唯一分钟或预先规定的窄范围。
- ±1/2/5 分钟邻近稳定性通过。
- leave-one-event-out 通过,不能由单一事件决定结果。
- 没有缺失的强制计算层。
- 独立冻结盲测达到发布指标。
未满足时输出:候选范围、支持事件、冲突事件、未评分事件和下一条问题,不允许写“准确时间为”。
## 测试集分层
### 对话开发回放集
文件:`references/real_case_calibration/conversational_rectification_development_v1.json`
当前 v1 是入口 smoke fixture,不是分钟收敛 benchmarkTypeScript 测试验证 fixture 中自然语言在现有抽取器下的日期、精度和领域;Python 回放使用同一 fixture 的人工 `expected_route_scoreable` 标签模拟现有路由过滤,再测试逐轮排名。它不是自然语言到评分的端到端回放,且每例不足 5 条可评分事件,不能用于判断 Skill 级收敛。
下一版 development benchmark 必须把每例扩充至至少 5 条、目标 10–15 条多领域事件,并直接调用抽取器和路由投影,覆盖记不清、拒答、否定、纠正、重复和一条消息多事件。它引用仓库已有公开 AA 开发案例,永久排除在 holdout 之外,可以用于修 bug 和调问题排序。
### 独立冻结 holdout v4
开发集不能证明发布准确率。正式验证需要另一位 reviewer 收集至少 20 个未参与调参的公开 AA 案例,在评分前完成:出生来源复核、事件来源复核、假分钟承诺、manifest hash、实现 hash 和真值密封。只允许盲回放一次;失败后整批降为 development,下一版重新收集 fresh holdout。
## 指标
对话入口:
- 日期和精度提取准确率。
- 领域提取准确率。
- 应评分事件保留率。
- 每轮问题数必须等于 1。
- 不能回答、记不清、纠正旧答案时仍能继续。
分钟能力:
- 3、5、8、10 条事件时的 Top-1 / Top-3。
- 逐轮真实分钟排名和误差轨迹。
- 唯一分钟率、邻近稳定性、leave-one-out。并列范围未破时 `predicted_time` 必须为空;如保留确定性 tie-break,只能单列为诊断 MAE,不能当成分钟能力。
- false confirmation rate 和 confirmation coverage 必须同时报告。
建议继续沿用当前发布门槛:Top-1 ≥ 60%Top-3 ≥ 85%MAE ≤ 2 分钟,false confirmation ≤ 5%insufficient-evidence rejection ≥ 90%。confirmation coverage 不能为 0,否则只是“永不确认”而非可用收敛。
## 实施顺序
1. 先合并阶段 A 与入口可观测性,不改变“准确分钟”声明。
2. 用本开发回放集修阶段 B,确保事件没有在入口丢失。
3. 接入阶段 C 的单问题排序并做多轮 replay。
4. 当开发集达到稳定目标后,冻结实现并收集 fresh holdout v4。
5. 只有 holdout 通过后才开放分钟确认;否则产品始终停在候选范围。