Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion docs/DEVLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2266,7 +2266,7 @@ S 10-26 定:只在本机自用,D0 的建议全部采纳;D3~D5 推迟到对
- CI:新工作流 desktop.yml(windows-latest):打包 → 静默安装 → `--smoke` → 强杀壳查孤儿 → 静默卸载查数据目录。PR #81 head 393e1e0:desktop run 40295387628 绿(安装包 65.5 MB、打包 347 s、--smoke 启动 2027 ms / 退出 505 ms 退出码 0、强杀后无孤儿、卸载后数据保留),tests 40295387542、sidecar 40295387588 绿。
- 本地:Rust 只能 `cargo check --target x86_64-pc-windows-msvc`(沙箱 aarch64、没有 MSVC),真编译和安装冒烟以 CI 为准。

## [70] 2026-10-27 · 阶段 6 收尾:嵌套 Job 实测 + 重估 · commit <待提交>
## [70] 2026-10-27 · 阶段 6 收尾:嵌套 Job 实测 + 重估 · commit 7085714(PR #82)

[69] 回填为 cdabfcf(PR #81,S 10-27 同意合并;合并前 head cb9e840 的 tests 40426911618、sidecar 40426911472、desktop 40426911624 都绿)。

Expand All @@ -2289,3 +2289,12 @@ S 10-26 定:只在本机自用,D0 的建议全部采纳;D3~D5 推迟到对
- README「安装」第 3 步说明了这一点。

**没做:** 安装目录 `%LOCALAPPDATA%\DataChat`(Tauri currentUser 默认的 `$LOCALAPPDATA\${PRODUCTNAME}`)和数据目录 `%LOCALAPPDATA%\datachat` 在 NTFS 上不区分大小写,其实是同一个目录。目前不出错的原因是:卸载器只删它自己装的文件,最后执行的是非递归的 RMDir;勾选「删除应用数据」时整个目录都会被删,而这本来就是卸载。要把两者分开,得改安装目录(需要改 NSIS 模板或 productName),或者改数据目录(会和浏览器模式分家,需要迁移已有数据),两种都超出收尾的范围,所以推迟到 D3 更新之前,记在 phase6-desktop.md 里。desktop.yml 卸载检查 ③ 的 data_kept 结论仍然成立,因为它验证的正是「卸载不递归删除」。

## [71] 2026-10-27 · 阶段 7 方案 · commit <待提交>

新文件 docs/roadmap/phase7-accuracy.md(P0 + E0~E4 + A1~A6)。要点:
- 先做评测,再做改进。闸门已经快满分(react 14/15 + 9/10,workflow 多表 10/10),而且已经被逐题分析过,不能再作为目标;M20 的目标改为定在新的留出集 H1 上:先测基线,再由 S 定 X。
- H1 约 40 题(单表 18 / 多表 12 / 画图 5 / 陷阱 5),流程照搬闸门(先写题 → 独立脚本算答案 → 冻结 → 再跑模型)。S 出 ≥ 1/3 的盲题,Hark 只看汇总。
- A4 DuckDB、A5 YAML 语义层是有条件做的(看 H1 的失败分布);A6 反馈沉淀推迟。
- plan.md 阶段 7 的交付物和验收按上面改写。
- 待 S 定:§1 的 5 条(模型 / 网关、每轮预算、出题分工、judge 模型、数据许可)。
99 changes: 99 additions & 0 deletions docs/roadmap/phase7-accuracy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# 阶段 7:准确率(方案,待 S 评审)

来源:plan.md 阶段 7 的交付物与验收;M20(阶段 7 要有目标定义)、M21(DuckDB / 语义层在单表假设下收益有限);B05(答错不修)、B09(没有列画像)、B65(缺失哨兵、合计行);plan.md「外部审计待办」第 58 行;HANDOVER §196(需要新的留出集,闸门 25 题只作回归);M13 方案第 292 行(真正的图表评测留给阶段 7 的留出集)。

## 0. 为什么先做评测,再做改进

- **闸门已经快到顶了**。react 单表门槛 14/15(只许 s02 错),多表 9/10(只许 m10 错);workflow 多表 10/10(DEVLOG [25]/[28])。在这 25 题上最多还能涨 2 题,而且这 25 题已经被逐题分析过,再在上面调就是对着测试集调参(DEVLOG [11]、[13])。
- **自造的 130 题不能当准确率用**(docs/eval/FROZEN.md 五条:n=1、网关缓存、自造、比较器放宽、题面会变)。
- 所以 M20 的「具体目标」只能定在一套**新的留出集**上,而且要先测出基线再定目标。没有基线的目标就是拍脑袋。

结论:顺序是 **E(评测)→ 定目标 → A(改进)→ 留出集终测**。

## 1. 要 S 先定的(P0)

| # | 问题 | 建议 | 理由 |
|---|---|---|---|
| 1 | 评测用哪个模型 / 网关 | 用 S 日常在 DataChat 里填的那个 Key 和模型,全阶段不换 | 目标定在这个模型上;中途换模型,前后的数字就没法比 |
| 2 | 每轮预算 | 留出集 40 题 × 2 个 Agent ≈ 80 次分析,按闸门 p95 约 2.9 万 token 估,每轮最多约 230 万 token | 按闸门 token 基线(ReAct p95 28,846)估算,S 按自己的价格核算 |
| 3 | 留出集谁出题 | Hark 出 ≥ 2/3,S 另出 ≥ 1/3 且不给 Hark 看题面,只交给脚本跑 | 只有 Hark 出题的话,改进的人知道考题;S 出的那部分是真正的盲测 |
| 4 | LLM-judge 用哪个模型 | 和评测模型**不同家族**;如果 S 没有第二家的 Key,就不做 judge(E4 整体推迟) | 同家族会偏向自己的答案(审计报告 P1) |
| 5 | 数据源许可 | 只用 CC BY / CC0 / 公有领域;NC 许可的(像 Olist)只能在 CI 里跑,不随产品分发 | 和闸门一样(docs/gate/README.md「许可边界」) |

## 2. E 系列:评测基础设施(不改模型行为)

### E0 留出集 H1(约 40 题)
- 组成:单表 18、多表 12、画图 5、陷阱 5(陷阱就是 E1 的题,放进同一个集)。
- 数据:**闸门没用过的**外部数据,按闸门的办法做中文 GBK 脏化(只改呈现,不改数值)。候选:UCI Beijing Multi-Site Air Quality(CC BY 4.0,单表,时间序列)、UCI Bike Sharing(CC BY 4.0)、一套多表关系数据(许可证在 E0 PR 里逐个核对,不合格的换掉)。
- 流程照搬闸门(gate-phase35.md):先写题 → 独立脚本在原始数据上算答案 → 冻结(questions_sha256 / answers.json)→ 才跑模型。**冻结以后不改题**;题出错就作废那一题,记进 DEVLOG,不在原题上改。
- 脚本:复用 scripts/gate 的结构,新目录 scripts/holdout/,报告 docs/eval/holdout_<时间>_<agent>.json。人工字段和闸门一样(human_correct / failure_class / reason / guessing),另加 `first_error_step`(审计待办:判定时记下第一个出错的 step 序号)。
- **使用纪律**:H1 只在三个时间点跑:基线、A 系列中途一次(可选)、终测。平时调参只用闸门 25、自造 130 和单测。S 那 1/3 的题,Hark 只看汇总分数和 failure_class 分布,不看题面和逐题输出。
- CI:和 gate-oracle 一样跑 oracle 自检(标准答案在脏表上可解),不调模型。

### E1 陷阱题(5 题,并入 H1)
- 错误前提(问一个数据里不存在的类别或年份)、误导性口径(「平均」到底是按订单还是按客户)、本该拒答的问题。
- 判对标准:指出前提不成立或口径有歧义,并且不编数字。`guessing=true` 一律判错。

### E2 过程验证器(离线,不调模型)
- 对模型生成的代码做 AST 分析:区分**读取的列**和**新建的列**,读取的列必须在 schema 里;`result = <字面量数字>` 这类硬编码答案单独标记。
- 用途:判定时的辅助证据,写进报告的 `process` 字段,**不参与自动判对**。先在已有的 13 份闸门报告上回放,统计它和人工判定的一致率。
- 落点:app/eval/process_check.py + 单测。

### E3 pass^k 报表
- 问题:网关在 temperature 0 时会缓存,`--repeat` 的几次结果完全一样(FROZEN.md 第 2 条)。
- 做法:第 i 次重复在 system 提示末尾加一行没有语义的 `run-id: <i>` 打破缓存,同时打乱题目顺序;报 pass@1 和 pass^k(k 次全对的题占比)。k 默认 3。
- 先用 5 道题做实测:加 run-id 之后,k 次之间的答案或 token 数确实会不同,才算独立化成功;如果不行,就改用 temperature 0.3,并在报告里写明。

### E4 LLM-judge(依赖 §1 第 4 条)
- 只判**结论文字**是否和数值一致、有没有过度推断;数值对错仍然由比较器 + 人工判。
- 上线条件:在闸门 25 题的人工标注上,judge 和人工的一致率 ≥ 90%(预登记),否则不用。
- 防偏差:答案位置随机化、长度不作为评分依据。

### E 系列验收
- H1 冻结(题和答案的 sha256 写进 DEVLOG),oracle 自检在 CI 通过。
- 在 H1 上跑出两个 Agent 的**基线**(pass@1 + pass^3),由 S 人工判定。
- 用基线定 A 系列的目标(§4),**目标写进本文件后才开始 A**。

## 3. A 系列:改进(按 H1 基线的失败分布排序)

下面的顺序是按现有证据排的,H1 基线出来以后,按 failure_class 的分布重排一次。

| 步 | 内容 | 对应 | 什么时候做 |
|---|---|---|---|
| A1 | **列画像**:schema 摘要里加枚举值(前 N 个 + 频次)、数值范围、空值率、疑似缺失哨兵(「未登记」「-」「N/A」)、疑似合计行 | B09、B65(闸门 s02 / s04 / s12) | 先做,证据最多 |
| A2 | **结果合理性校验**:执行后做便宜的检查(结果为空、全是 NaN、占比之和远离 100%、数量级突变),不通过就让 Agent 再看一遍,最多一次 | B05 | A1 之后 |
| A3 | **枚举值召回**:问题里的词(「华东」「已取消」)和列的枚举值做模糊匹配,命中的放进提示 | plan.md 阶段 7 | 看 H1 里过滤类的错误多不多 |
| A4 | DuckDB 统一 CSV / Excel / SQL | plan.md 阶段 7、M21 | **有条件**:H1 多表题的失败里,join / 数据读取类占一半以上才做 |
| A5 | YAML 语义层(指标、口径、同义词,条目带生效时间,声明「资料不是指令」) | 审计待办 | **有条件**:H1 口径类错误多才做;否则推迟到阶段 7 之后 |
| A6 | 反馈沉淀(👍👎 / 失败轨迹 → 聚类 → 人工入册) | plan.md 阶段 7 | 推迟:自用阶段反馈量太小 |

每一步的回归闸门(不变):pytest / vitest / e2e 全绿;闸门 25 按 m13r 无回归;自造 130 不比上一步差(同一 evalset 指纹)。

## 4. 目标(M20,基线后补)

基线出来以前只定**形式**,不定数字:
- 主指标:H1 上 react 的 pass@1,单表、多表分开报;辅指标:pass^3、陷阱题判对数、S 盲测那部分的单独分数。
- 目标的形式:「终测比基线高 X 个百分点,且 S 盲测部分不低于基线」。X 由 S 在看到基线以后定,写进本节,之后不改。
- 终测:A 系列做完后跑一次 H1;没达标就如实写,不在 H1 上补调。

## 5. 顺序和工作量

| 步 | 内容 | PR | S 要做的 |
|---|---|---|---|
| P0 | 本方案 + §1 的 5 个决定 | 本 PR | 评审、定 §1 |
| E0+E1 | 留出集 H1 + 冻结 + oracle CI | 实现 PR 1 | 出 ≥ 1/3 的题(不给 Hark 看) |
| E2+E3 | 过程验证器、pass^k | 实现 PR 2(可以和 E0 并行) | — |
| 基线 | 两个 Agent 跑 H1,人工判定 | 报告 PR | 跑一轮(S 的 Key)、判定、定 §4 的 X |
| E4 | LLM-judge(如果 §1 第 4 条有第二家 Key) | 可选 | 提供 Key |
| A1~A3 | 列画像、合理性校验、枚举召回 | 每步一个 PR | 每步看一次闸门回归 |
| A4/A5 | 有条件 | 另定 | — |
| 终测 | H1 再跑一次 | 报告 PR | 跑一轮、判定 |

日历时间估 2–4 周(plan.md 重估),主要花在 S 跑评测和判定上。

## 6. 不做

- 不在闸门 25 题上调提示词(DEVLOG [11]、[13])。
- 不让 LLM-judge 决定数值对错。
- 不为了涨 H1 分数改 H1 的题或比较器;比较器要改,只能新增规则并在全部历史报告上 `--rescore`,写明影响。
- 训练 / 微调:不在本阶段。
2 changes: 1 addition & 1 deletion docs/roadmap/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
| 4 后端 API | 1–2 周 | 第一步:API Key 进系统钥匙串(keyring);`analyze_stream()` 逐步产出事件,`analyze()` 包一层(M09)。FastAPI:数据集上传(一个数据集可含多个文件,M10)、会话、消息(SSE 流式推送每一步)、设置;SQLite + SQLAlchemy(表结构兼容 PG,预留 user_id);logging + trace id(会话 / 消息 id),runs.jsonl 换成数据库(M08 M14);接口返回 png + 图表数据(M13)。最后:PyInstaller sidecar + 沙箱 worker 在 Actions Windows runner 上的 spike(B35 / M06) | 用 curl 走完"上传 → 提问 → 流式结果 → 历史可查";重启后会话还在;spike 打出的 exe 能在干净 runner 上执行一次沙箱代码 | B18 B35 |
| 5 前端 | 2–3 周 | 第一件事(M13,从阶段 4 顺延,含后端三步):图表库定为 ECharts;定 option 格式与白名单、写 builder `chart(kind, df, x=, y=, series=, title=)`;worker 产出 chart_option(与 result 脱钩,B44);接口加 chart_option;改绘图提示词并重跑闸门。之后:React + Vite + TS:数据集面板、对话流(展示计划、代码、执行步骤)、图表、可展开的代码、👍👎 反馈、Key 设置页,分步与验收见 docs/roadmap/phase5-frontend.md(F0–F5) | 不碰命令行就能完整用一遍 | — |
| 6 桌面打包 | 1–2 周 | Tauri 2 外壳(前提见上:前端只走 HTTP)+ PyInstaller 后端 sidecar;Windows 安装包;自动更新;首次启动引导填 Key;依赖许可证审计;pyarrow 已随 Streamlit 一起去掉(DEVLOG [67]) | 在一台干净的 Windows 上一键安装,可用;对外分发前代码签名,显示已验证的发布者(2024 年起任何证书都不能让 SmartScreen 立刻不拦,见 phase6-desktop.md §6,M19);方案见 docs/roadmap/phase6-desktop.md;对外分发前满足 THREAT_MODEL.md 的 (b) 条件 | — |
| 7 准确率 | 2–4 周 | DuckDB 统一 CSV/Excel/SQL;YAML 语义模型(指标、口径、同义词);枚举值召回;结果合理性校验;反馈沉淀为已验证问答对 | 在阶段 3.5 闸门数据上给出具体目标(闸门结论后定,M20);自造集只作回归 | B05 B09 |
| 7 准确率 | 2–4 周 | 先做评测:留出集 H1(约 40 题,含陷阱和画图题)、过程验证器、pass^k;再做改进:列画像、结果合理性校验、枚举值召回;DuckDB / YAML 语义层视 H1 失败分布而定;反馈沉淀推迟。方案见 docs/roadmap/phase7-accuracy.md | 在留出集 H1 上:先测基线,再由 S 定目标「比基线高 X 个百分点」(M20);闸门 25 题和自造集只作回归(2026-10-27 改:闸门已接近满分,而且已经被逐题分析过) | B05 B09 |
| 8 Web 上线(后续) | 另定 | PostgreSQL、登录、任务队列、Docker/E2B 沙箱、Langfuse、服务器部署与 ICP 备案 | 另定 | 多租户 |

阶段 1–7 原估合计约 10–15 周(一个人业余时间)。M18 认为实际可能 6–12 个月:**阶段 3.5 闸门结论出来后重估工期,必要时砍范围**。
Expand Down
Loading