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
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* text=auto eol=lf
*.ps1 text eol=crlf
*.png binary
*.pdf binary
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev,llm]"
python -m pip install -e ".[dev,llm,gui]"

- name: Run test suite
run: python -m pytest
86 changes: 86 additions & 0 deletions P0_CHANGES.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# P0 修改说明(2026-10-06,2026-10-07 复核修订)

本包基于官方最新版 `SlideNote-main`(GitHub commit `3fca464`)制作,包含两部分工作:
移植旧版本里未同步的本地改进 + 落实 ROADMAP 的 P0 三项。全部改动已通过验证:
**354 个测试全绿(基线 337 + 新增 17)、无 API 冒烟通过、评测与排版工具实测跑通。**

## 一、从旧版本移植的改动(微信包里未提交的本地改进)

| 文件 | 改动 |
| --- | --- |
| `slidenote/notes/structure.py`(新) | 讲义结构契约评估:必备栏目(本讲目标/主题章节/本讲总结/章节自测)+ 推荐栏目(例子/易错点),检测"第 N 页"式逐页标题和重复模板栏目 |
| `slidenote/notes/document_frame.py`(新) | 确定性文档框架:从 deck brief 提取内容补齐缺失的全局栏目,幂等、不改章节正文、不新增课件外事实 |
| `slidenote/notes/prompt_templates.py` | 单页生成改为"中间证据卡"定位;weave/教学增强按上下文选择全文结构契约或自适应章节规则;收紧事实边界(禁止新增无依据数字/结论);新增结构修复 prompt |
| `slidenote/notes/repair.py` | 新增 `_repair_note_structure_once` 并接线到 finalize。复核版要求修订后契约通过、正文至少保留 80%、精确保留来源标记/图片目标、coverage 不回退且输出未截断;任一不满足即保留原稿 |
| `slidenote/notes/finalize.py` | lecture-weave 收尾时应用文档框架;契约仍不通过时触发一次结构修复(带守护) |
| `slidenote/notes/quality.py` | 质量报告新增 `structure_contract`、`human_note_structure_score`、`mechanical_structure_pass` 等字段与对应改进建议 |
| `slidenote/notes/versions.py` | prompt 版本号升级(page-lecture-v5 / weave-v5 / teaching-enrichment-v3 / structure-repair-v2),旧缓存自动失效 |
| `slidenote/notes/usage.py` | 用量报告增加 `repair_calls` 计数 |
| `slidenote/build/config.py`、`notes/__init__.py` | 默认 `temperature` 0.2→0.0(可复现评测)、`weave_dedup` soft→normal(配合新去重文案) |
| `tests/test_notes.py` | 断言适配新 prompt 文案 |
| `tests/test_note_structure.py`(新) | 结构契约/文档框架/结构修复守护/质量报告的 9 个测试,包含假阳性和严重截断回归测试 |

## 二、P0 三项落地(ROADMAP)

### P0-1 真实课件评测与内容核对

- `benchmarks/README.md`:样本集要求、评测流程、硬门槛与启发式/人工复核的边界。
- `benchmarks/samples.manifest.json`:固定样本清单(改动前后必须用同一份)。
- `benchmarks/rubric.template.json`:8 维度人工评分 rubric(1-5 分,含锚点)。
- `benchmarks/spot-check.template.md`:人工抽查模板(关键事实 10 条/漏项/图文对应/来源定位 10 处/耗时成本)。
- `scripts/make_sample_deck.py`:生成固定合成样例(文字密集页、表格、公式、折线图、扫描页、18 页),可重复构建、可提交仓库。
- `scripts/eval_decks.py`:评测 harness——按 manifest 逐例运行 build,记录耗时/阶段耗时/tokens/成本估算/coverage/启发式分数;硬门槛失败自动把 notes、coverage、质量报告留档到 `runs/<run>/failures/<case>/`;`--baseline` 与上次运行逐项对比。

用法:

```powershell
python scripts/make_sample_deck.py
python scripts/eval_decks.py benchmarks/samples.manifest.json --out benchmarks/runs/baseline
# 改动后:
python scripts/eval_decks.py benchmarks/samples.manifest.json --out benchmarks/runs/after --baseline benchmarks/runs/baseline
```

### P0-2 笔记阅读与导出排版验收

- `scripts/verify_note_layout.py`:三层检查,每个问题定位到样本/文件/页码。
- Markdown:标题跳级、多个 H1、空章节、图片无 alt/无邻近解释、超宽表格、行列不齐、代码围栏/公式未闭合、缺来源标记。
- Word(pandoc 导出):标题/表格/图片数量与 Markdown 对比、表格行列错位。
- PDF:文本溢出页边界、图片与文字重叠(图文错位)、空白页、页尾孤立标题。
- 缺 pandoc/LibreOffice 时对应层显示 skipped 并注明原因。

```powershell
python scripts/verify_note_layout.py outputs\你的输出目录
python scripts/verify_note_layout.py benchmarks\runs\after\outputs
```

### P0-3 来源与质量提示说清边界

- GUI Quality 标签页:新增三层信号说明(coverage=结构线索、quality_report=启发式、人工复核=最终结论),新增"建议人工复核"清单(合并 coverage 缺项、图片缺失、幻觉风险、结构契约失败,每行注明信号来源和查看位置)。
- `docs/quality-and-guard.zh-CN.md`:三层质量信号对照表(各自能回答/不能回答什么)、结构契约字段说明。
- `docs/benchmark.zh-CN.md`:新工具用法。
- `ROADMAP.zh-CN.md`:标注 P0 工具已就绪,真实课件样本与人工评分待收集。

## 三、验证结论

- `python -m pytest`:354 passed(完整安装 dev/llm/gui,0 skipped)。
- `python scripts/smoke_first_run.py`:通过。
- 评测 harness 实测:合成样例约 0.9s,仓库外绝对 `--out` 与 `--baseline` 正常;报告会明确显示 local 产物的逐页标题,但不把它作为 lecture 硬门槛。
- 排版验收:Markdown/docx/PDF 三层规则均有自动回归测试;当前合成运行只请求 markdown-zip,因此实际 docx/PDF 导出仍按环境显示 skipped。
- GUI 导入与复核面板冒烟通过。

## 四、2026-10-07 独立复核修复

- 阻止结构修复把长讲义截断成短提纲后仍被接受。
- 校验 manifest `case_id` 并证明输出目录位于评测根目录内,消除路径穿越删除风险。
- `coverage.json`、`quality_report.json`、`run_summary.json`、`export_report.json` 缺失或关键字段无效时评测失败,不再默认当作 0 漏项。
- Markdown 报告直接使用实际 `page_listing_hits`,不再把检测到的逐页标题显示成“无”。
- 收紧结构标题匹配,识别 `Slide 1 - Topic`,排除“这不是总结”“例子与应用被当作主题”等假阳性,并让重复模板信号参与机械结构判定。
- 支持仓库外绝对输出路径;CI 安装 GUI 依赖并执行全部测试。
- 新增 `.gitattributes`,已有文本统一为 LF,PowerShell 脚本保留 CRLF,避免全仓库伪 diff。
- 详细说明见 `REVIEW_FIXES.zh-CN.md`。

## 五、待你完成的事

1. 真实课件(文字密集/图表/表格/公式/扫描页/50 页以上)按 `benchmarks/README.md` 加入 manifest——合成样例不能替代真实课件。
2. 用 `spot-check.template.md` 对 lecture 产物做一次人工抽查(需要 API key)。
3. 本机安装 LibreOffice 后 PDF 导出与 PDF 层排版检查才可用(当前会优雅跳过)。
36 changes: 36 additions & 0 deletions REVIEW_FIXES.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# 2026-10-07 复核修复说明

本文件记录 `SlideNote-main-P0-reviewed-fixed` 相对初始 P0 修改包的第二轮独立复核修复。

## 已修复问题

1. **结构修复防截断**:全文修订必须通过结构契约,正文保留率不得低于 80%,并精确保留原来源标记、图片目标及既有 coverage;修订后重新修复图片链接并执行 figure grounding。
2. **评测路径安全**:`case_id` 使用白名单格式,所有 case 输出/失败目录在删除或写入前验证仍位于预期根目录内。
3. **评测失败关闭**:关键 artifact 缺失、JSON 无效或关键字段缺失时直接判定失败,不再把缺失值当作 0。
4. **报告一致性**:逐页标题列直接依据实际检测结果;local 模式显示“有(未作为硬门槛)”。
5. **结构契约误判**:支持 `Slide 1 - Topic` 等格式;全局结构栏目必须是 H2;“这不是总结”和单独“例子与应用”不再被误判为合格的 summary/topic;成组重复 H3 模板会使机械结构检查失败。
6. **路径兼容性**:`--out`、manifest 和 baseline 可位于仓库外,不再因 `relative_to()` 抛错。
7. **CI 完整性**:CI 安装 `gui` extra,Streamlit 测试不再被跳过。
8. **排版检查证据**:新增 Markdown、DOCX、PDF 三层自动回归测试。
9. **干净 Git diff**:文本统一 LF,新增 `.gitattributes`;PowerShell 脚本声明 CRLF。
10. **空章节误报**:父级标题下直接进入有正文的子标题不再被错误标记为空章节。

## 验证结果

- `python -m pytest -q`:354 passed。
- `python scripts/smoke_first_run.py`:通过。
- 合成样本 baseline/after:1/1 通过,绝对输出路径与 baseline 对比正常。
- 排版检查:当前 markdown-zip 运行 0 error、0 warning;docx/PDF 实际导出因该 manifest 未请求而跳过,但三层检测器均已有自动 fixture 覆盖。

## 仍需真实环境完成

合成 local 样本不能证明 LLM 讲义内容更准确。发布“质量已提升”的对外结论前,仍需使用固定模型和参数,对至少 3–5 份真实 lecture 课件完成修改前/修改后生成、双人独立 rubric、关键事实与来源抽查。该项需要真实课件和 API key,不应以合成测试替代。

## 2026-10-08 维护者复核修复

- 全文结构修复使用文档专用后处理,保留原 H1;只接受保留唯一、相同课程标题的候选。结构契约增加 `h1_count` / `title_pass`,缺失或重复主标题不再假通过。
- 文档框架和结构契约共用标题解析与栏目匹配,带主题后缀、编号或闭合井号的既有栏目不会被重复补齐。
- 结构、评测和排版检查忽略反引号或波浪号代码围栏里的伪标题。框架按真实 H1 定位插入位置,保留代码正文;排版检查仍报告未闭合围栏。
- 连续 Markdown 表格按相邻行分组,正常表格不会被误拆,列数不齐的行会准确报出行号。
- 文档级编织/增强 prompt 明确 H1 由系统添加,正文使用 H2;章节级 prompt 保持 H3。消除同时要求输出 H1/H2 和禁止输出这些标题的冲突,并更新相关缓存版本。
- 新增 41 个回归用例,完整测试 **395 passed**;无 API 首次运行冒烟通过;原 PR 的固定合成样本 local 评测 **1/1 通过**,严格 Markdown 排版检查 **0 error / 0 warning**。该样本未请求 DOCX/PDF,因此这两层实际导出仍未验收。
1 change: 1 addition & 0 deletions ROADMAP.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Ingest -> Understand -> Write -> Guard -> Export
- 已生成 `notes.md`、coverage、source map 和启发式质量报告。Coverage 能提示部分漏项和来源标记问题,不能证明解释准确或学习效果。
- 独立的 `study-pack` 命令可生成 review、exam、交互式 `exam.html`、结构化学习包与错题复盘提示词;答题记录尚未形成持久化闭环。
- 已有 GUI 查看与下载、进度报告,以及 Markdown、Word、PDF、LaTeX 等输出能力;导出排版仍需用真实课件系统验收。
- 已有固定样本评测脚手架(`benchmarks/` + `scripts/eval_decks.py`,记录耗时/tokens/成本/硬门槛并留档失败案例)、导出排版验收(`scripts/verify_note_layout.py`),以及 lecture 讲义结构契约与确定性文档框架(`structure_contract` / `document_frame`);真实课件样本与人工评分仍在收集。

## 建议优先级

Expand Down
102 changes: 102 additions & 0 deletions benchmarks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# SlideNote 固定样本集与评测流程(P0)

目的:让"单份课件的笔记可靠、好读"成为**可复核、可比较**的工程目标,而不是
只看 coverage 分数或单次人工感觉。本目录是 ROADMAP P0-1(真实课件评测与内容
核对)的落地工具。

## 目录结构

```text
benchmarks/
README.md 本文件
samples.manifest.json 固定样本清单(评测的输入,改动前后必须用同一份)
samples/ 样本课件
synthetic_course.pdf 固定合成样例(scripts/make_sample_deck.py 生成)
rubric.template.json 人工 1-5 分评分 rubric(结构/连贯/解释深度等 8 维度)
spot-check.template.md 人工抽查记录模板(关键事实/漏项/图文对应/来源定位)
runs/<run_id>/ 每次评测的输出(eval_report.json/md、outputs/、failures/)
```

## 固定样本集要求

按 ROADMAP P0 的特征矩阵收集,每类至少一份,真实课件优先:

| 特征 | 要求 | 记录在 manifest 的 `features` |
| --- | --- | --- |
| 文字密集页 | 定义/推理段落为主的课件 | `text-dense` |
| 图表 | 流程图、示意图,需要图文对应 | `chart` |
| 表格 | 有对比结论的表格 | `table` |
| 公式 | 含数学公式或代码推导 | `formula` |
| 扫描页 | 图片化、需要 OCR 的页面 | `scanned` |
| 长课件 | 50 页以上 | `long` |

加入真实课件时,在 `samples.manifest.json` 增加一个 case:

```json
{
"case_id": "cs168-lecture05",
"source": "samples/cs168-lecture05.pdf",
"description": "真实课件:xxx 课程第 5 讲",
"features": ["text-dense", "chart"],
"language": "zh",
"expected_pages": 42,
"source_origin": "user-provided",
"preset": "local",
"export": "markdown-zip",
"manual_notes": "samples/notes/cs168-lecture05.human-notes.md(如有,且允许作为参考时不进仓库)",
"allow_fewshot": false
}
```

规则:

- 真实课件与人工笔记**不要提交**到公共仓库(版权/隐私);`source_origin:
user-provided` 的 case 只保留本地路径并在 `manual_notes` 记录笔记位置。
- `allow_fewshot: true` 表示该笔记允许摘出去内容化的片段作为风格示例;
默认 `false`,避免内容泄漏进 prompt。
- `synthetic_course.pdf` 由 `scripts/make_sample_deck.py` 生成,内容固定,
覆盖六类特征,用于 CI 和无 API 冒烟;它不能替代真实课件的人工评分。

## 评测流程

1. **生成/确认样本**:`python scripts/make_sample_deck.py`(或放入真实课件并更新 manifest)。
2. **跑基线**:
```powershell
python scripts/eval_decks.py benchmarks/samples.manifest.json --out benchmarks/runs/<日期>-baseline
```
无 API 时用 manifest 里的 `preset: local`(离线,确定性指标);正式评测把
`preset` 设为 `lecture` 并配置 API key,运行时间和成本才有产品意义。
3. **改动后再跑同一 manifest**,并和基线比较:
```powershell
python scripts/eval_decks.py benchmarks/samples.manifest.json --out benchmarks/runs/<日期>-after --baseline benchmarks/runs/<日期>-baseline
```
`eval_report.md` 会给出每个用例的耗时/tokens/覆盖/启发式分数差值;注意
离线 `local` 预设不调用模型,耗时差值主要反映解析与导出。
4. **人工抽查**:对 lecture 运行结果使用 `spot-check.template.md`(关键事实
10 条、漏项、图文对应、来源定位 10 处)+ `rubric.template.json` 打分。
两位评审独立打分,不要共享。
5. **失败案例**:任何硬门槛失败(关键报告缺失或无效、必讲内容漏项 > 0、lecture
产物出现逐页标题、构建/导出失败、正文为空)会在 `runs/<run>/failures/<case_id>/` 留下 notes.md、
coverage、质量报告和命令记录,保证失败可复核、可进 issue。

## 硬门槛与启发式的边界

- **硬门槛(自动,失败即失败)**:关键构建/coverage/quality/export 报告存在且
关键字段有效、必讲内容漏项为 0、lecture 产物无"第 N 页"式正文标题、构建与
导出无阻塞错误。这是回归防线。local 预览允许逐页标题,但报告仍明确显示检测结果。
- **启发式分数(自动,仅用于比较)**:coherence、explanation_depth、结构契约
分数等只能发现明显回归,**不代表内容正确或好读**。
- **人工抽查(最终质量结论)**:内容是否讲对、漏了什么、图文是否对应,只能
通过对照原课件的人工抽查判断。三者不可互相替代,详见
[docs/quality-and-guard.zh-CN.md](../docs/quality-and-guard.zh-CN.md)。

## 排版验收

评测通过后,用排版验收工具检查阅读体验(标题层级、段落密度、长表格、图文
错位、断页/溢出),问题能定位到样本与页:

```powershell
python scripts/verify_note_layout.py benchmarks/runs/<日期>-after/outputs
```

详见该脚本 `--help` 与 [docs/benchmark.zh-CN.md](../docs/benchmark.zh-CN.md)。
Loading
Loading