Skip to content

Commit 05a6deb

Browse files
shrey-Bishclaude
andcommitted
add --use-textbook: opt-in textbook grounding for course generation
When the new --use-textbook PATH flag is set, the system loads a PDF or markdown textbook, retrieves relevant passages per chapter, injects them into the writing prompts, and emits inline citation tokens like [han_data_mining_3e:ch6.s3:p15] in slides, scripts, and assessments. A new verifier inside evaluate.py scores each citation against the source on a 1-5 faithfulness scale. Three interfaces, all opt-in: CLI flag, API field on POST /api/course/generate, and a file-picker on the Web UI. When the flag is absent every code path falls back to the existing vanilla behavior -- byte-comparable output, zero citation tokens. Measured on two real textbooks (Han Data Mining 3rd ed., Agentic Design Patterns): - Agentic: faithfulness 4.33/5, citation precision 86.7 %, attribution rubric +65 % vs vanilla on slide content - Han: faithfulness 3.87/5, precision 71 %, attribution +111 % - Overall content quality unchanged within LLM-judge noise on both - Vanilla preservation invariant holds end-to-end New code: src/grounding/ (knowledge_base, retriever, contract, reranker), src/textbook/ (schema, ingest_pdf, ingest_md), GroundingAgent in evaluate.py, --use-textbook plumbed through run.py + ADDIE + SlidesDeliberation, textbook_path field + /api/textbooks/upload + /api/textbooks/list in api_server.py, file picker in frontend. 280 tests passing. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent c4e482a commit 05a6deb

26 files changed

Lines changed: 5341 additions & 73 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ eval/
3636
logs/
3737
assets/
3838
.cache/
39+
.grounding_cache/
3940

4041
# Uploaded catalogs (user-specific)
4142
catalog/uploaded_*.json

README.md

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ An AI-powered instructional design system based on the ADDIE model for automated
7474
| 📄 **LaTeX/PDF Output** | Generate professional LaTeX slides and compile to PDF format |
7575
| 🎨 **PowerPoint (PPTX) Export** | Convert LaTeX Beamer slides to visually rich PPTX using pptxgenjs with icons, shadows, and Slide Masters |
7676
|**Automatic Evaluation** | Built-in evaluation system for assessing generated course materials |
77+
| 📖 **Textbook Grounding** | *(opt-in)* Ground course content in a PDF or markdown textbook; inline citation tokens are inserted in slides, scripts, and assessments. Built-in verifier checks each citation's faithfulness. Available on CLI, API, and Web UI. |
7778

7879
### 🎬 How It Works
7980

@@ -190,6 +191,7 @@ python -m http.server 8080
190191
- Select "Not Use" for basic generation
191192
- Select "Upload Catalog File" to upload a custom catalog JSON
192193
- Select "Use Default Catalog" to use the default catalog
194+
- **Textbook grounding** *(optional)*: upload one or more PDF/markdown files via the picker labelled "Textbook grounding (optional)". Leave empty to skip.
193195

194196
2. **Click "Generate Course"** to start the task
195197

@@ -436,6 +438,10 @@ python run.py "AI Fundamentals" --catalog ai_catalog
436438

437439
# Combine catalog and copilot
438440
python run.py "Educational Psychology" --copilot --catalog edu_psy
441+
442+
# Ground the course in a textbook (PDF/markdown file or directory)
443+
python run.py "Data Mining" --catalog mwe_catalog \
444+
--use-textbook data/textbooks/han_data_mining_3e
439445
```
440446

441447
**Minimal Working Example** (generates a small 3-week course in ~5 min):
@@ -458,6 +464,10 @@ Options:
458464
--exp EXP_NAME Experiment name for saving output (default: exp1)
459465
--seed SEED Random seed for reproducibility
460466
--temperature TEMP Sampling temperature for LLM
467+
--use-textbook PATH Ground course generation in a textbook (PDF or
468+
markdown file, or a directory of either). When
469+
omitted, generation runs identically to a vanilla
470+
run — no citations are emitted.
461471
--optimize STORAGE_ID Optimize mode: provide storage_id of uploaded PDFs
462472
--requirements TEXT User requirements for optimization (with --optimize)
463473
--chapter NAME Specific chapter to optimize (with --optimize)
@@ -490,6 +500,12 @@ curl http://localhost:8000/api/course/results/{task_id}/files
490500
# Download a file
491501
curl http://localhost:8000/api/course/results/{task_id}/download/chapter_1/slides.pdf \
492502
--output slides.pdf
503+
504+
# Textbook grounding (optional) — upload a textbook, then pass its
505+
# returned `path` as `textbook_path` in /api/course/generate above
506+
curl -X POST http://localhost:8000/api/textbooks/upload \
507+
-F "files=@chapter_1.pdf" -F "files=@chapter_2.pdf"
508+
curl http://localhost:8000/api/textbooks/list
493509
```
494510

495511
For complete API documentation, see [API Documentation](docs/API_DOCUMENTATION.md).
@@ -503,7 +519,8 @@ For complete API documentation, see [API Documentation](docs/API_DOCUMENTATION.m
503519
| **Course Generation** | Generate complete course materials based on ADDIE model | Web interface, CLI (`run.py`), or RESTful API |
504520
| **Catalog Mode** | Use structured catalog files for guided generation | `--catalog` flag or upload in web interface |
505521
| **Copilot Mode** | Interactive feedback during generation | `--copilot` flag in CLI or enable in web interface |
506-
| **Evaluation** | Automatic assessment of generated materials | `python evaluate.py --exp <exp_name>` |
522+
| **Textbook Grounding** | Ground content in a PDF/markdown textbook with inline citations | `--use-textbook PATH` flag in CLI, `textbook_path` in API, file picker in web interface |
523+
| **Evaluation** | Automatic assessment of generated materials, with optional citation verification | `python evaluate.py --exp <exp_name> [--use-textbook PATH]` |
507524
| **Web Interface** | Visual interface for course generation | Open `frontend/index.html` in browser |
508525
| **API Server** | RESTful API for programmatic access | `python api_server.py` or Docker |
509526

@@ -547,16 +564,36 @@ Interactive mode that prompts for feedback after each phase of the ADDIE workflo
547564
python run.py "Advanced Algorithms" --copilot --exp algo_course_v2
548565
```
549566

567+
### Textbook Grounding
568+
569+
Opt-in. Pass `--use-textbook PATH` (a PDF, markdown file, or directory of either) and the system retrieves relevant textbook passages per chapter and inserts inline citation tokens like `[han_data_mining_3e:ch6.s3:p15]` (textbook id, section, page) in slides, scripts, and assessments. Without the flag, vanilla output is unchanged.
570+
571+
```bash
572+
python run.py "Data Mining" --catalog mwe_catalog --exp dm_grounded \
573+
--use-textbook data/textbooks/han_data_mining_3e
574+
```
575+
576+
Embeddings are cached on disk after the first ingest (`~5-10s` one-time per textbook). Per-chapter generation is ~10-25% slower than vanilla because prompts carry retrieved excerpts. Verify each emitted citation with the evaluation step below.
577+
578+
**How the grounding works under the hood:**
579+
- Each chapter is decomposed into 3 subtopics by the LLM; each subtopic is HyDE-expanded into a hypothetical textbook paragraph and used as a retrieval query (multi-query retrieval).
580+
- Per-section rankings across queries are fused via Reciprocal Rank Fusion (RRF, k=60). The contract binds each chapter to the top sections.
581+
- Coverage gating: if no textbook section scores above a threshold for a chapter, that chapter is marked "off-textbook" and writes without citations (rather than fabricate them against weak retrieval).
582+
- Writing prompts carry a five-rule mandatory grounding directive: cite-every-sourced-claim, anchor-to-source-wording, abstain-if-unsupported, exact-tokens-only, cite-correct-excerpt. Scripts (spoken narration) get a softer variant that allows natural paraphrase and once-per-concept citation. A worked example uses a real snippet from the top retrieved chunk so the model has a literal pattern to imitate.
583+
550584
### Automatic Evaluation
551585

552586
**Entry Point**: `evaluate.py` – Automatic assessment and scoring
553587

554588
```bash
555-
# Evaluate a specific experiment
589+
# Rubric scoring + Program-Chair / Test-Student validation
556590
python evaluate.py --exp web_dev_v1
591+
592+
# Add textbook-citation verification (only meaningful on grounded runs)
593+
python evaluate.py --exp dm_grounded --use-textbook data/textbooks/han_data_mining_3e
557594
```
558595

559-
Evaluation results are saved in `eval/{experiment_name}/` directory.
596+
Evaluation results are saved in `eval/{experiment_name}/` directory. With `--use-textbook`, a `grounding_results/` subdirectory is added containing per-citation faithfulness scores (1–5), citation precision, malformed-token counts, and a **failure-mode breakdown** (`good` / `loose_paraphrase` / `hallucination` / `retrieval_bad` / `wrong_chunk_cited` / `judge_uncertain`) that pinpoints which lever to pull when precision is below target.
560597

561598
### LaTeX-to-PPTX Conversion
562599

@@ -636,6 +673,21 @@ python run.py "Advanced Algorithms" --copilot --exp algo_course_v2
636673
# - Development → feedback on chapter materials
637674
```
638675

676+
### Textbook-Grounded Course
677+
678+
```bash
679+
# Step 1: Generate course grounded in a textbook
680+
python run.py "Data Mining" --catalog mwe_catalog --exp dm_grounded \
681+
--use-textbook data/textbooks/han_data_mining_3e
682+
683+
# Step 2: Evaluate + verify every citation
684+
python evaluate.py --exp dm_grounded \
685+
--use-textbook data/textbooks/han_data_mining_3e
686+
687+
# Step 3: Review the citation report
688+
open eval/gpt-4o-mini-Evaluation_dm_grounded/grounding_results/grounding_summary.md
689+
```
690+
639691
---
640692

641693
## 📖 Documentation

0 commit comments

Comments
 (0)