Paper Writer, Critic and Iteration
Schedule experiments with UCB, iterate a draft with a five-score critic, and emit LaTeX, BibTeX and a manifest.
- Concepts and terms
- Tasks and commands
- Annotated code
- Diagrams
- Defaults and numbers
- Troubleshooting
- Questions and tips
End-to-end research demo#
Run the lessons#
| Command | What it does |
|---|---|
python3 code/main.py (54) | Writes paper.tex, references.bib, manifest.json to a temp dir |
python3 code/main.py (55) | Prints the critic loop result and per-round trace |
python3 code/main.py (56) | Prints stop_reason, paper triggers and branch stats |
python3 code/main.py (57) | Prints best branch, critic status and paper sections |
Calls in code#
| Task | Code |
|---|---|
| Figures from experiment outputs | figs = |
| Render LaTeX only | render_latex(paper) |
| Fill prose and write three files | manifest = |
| Pair critic and reviser | critic, |
| Iterate a draft | CriticLoop(critic= |
| Mock experiments | make_deterministic_runner(base_rewards, |
| Schedule and wait | report = |
| Pick and promote | pick_best_branch(sched_report), then mini_to_full_paper(critic_result.paper, branch) |
Declare the paper skeleton#
paper = Paper( title="<title>", authors=["Lab Bot"], abstract="<abstract>", sections=[ Section(id="method", title="Method", cites=["jones2021"], figure_refs=[figs[0].id]),label sec:method ], figures=figs,label fig:<id> bibliography=[ BibEntry(key="jones2021", entry_type="article", fields={"title": "On loops", "author": "Jones", "year": "2021"}), ],)prose = MockProseGenerator(outlines={"method": "<outline>"})writer = PaperWriter(prose=prose)gates run before any fileQuestions#
- Why a skeleton first?
- Gates check figures, cites and sections before any prose.
- What does the critic read?
manifest.json. It does not parse LaTeX.- Why UCB?
- Greedy never explores. Uniform never exploits.
- Why import, not copy?
- The demo adjusts
sys.pathand composes the earlier lessons.
Run the UCB scheduler#
seed = [Hypothesis(id="h-a-1", branch="branch-a"), Hypothesis(id="h-b-1", branch="branch-b")]runner = make_deterministic_runner( base_rewards={"branch-a": 0.85, "branch-b": 0.55}, seed=7, delay_ms=2.0,)reward is base + N(0, noise)sched = IterationScheduler( runner=runner, slots=3, max_experiments=20, paper_threshold=0.7, prune_floor=0.25, prune_after_runs=3, expander=deterministic_expander,two follow-ups per high reward)report = asyncio.run(sched.run(seed))SchedulerReportreport.to_dict()stop_reason, paper_triggersCritic round and stop rules#
Formulas and scores#
- UCB1
- mean reward + c times sqrt(ln(total_runs) / runs).
- Untried branch
ucb_scorereturnsfloat("inf"), so it runs first.- Prune
- mean below
prune_floorafterprune_after_runstrials. - Paper trigger
- branch mean at or above
paper_threshold, once per branch. - Clarity
min(10.0, 3.0 + avg_body / 50.0).- Evidence
min(10.0, 2.0 + 2.0 * fig_refs + 1.5 * cites).- Novelty
- 9.0 for high, 6.0 for medium, 3.0 for low
originality_tag. - Demo originality
- high at reward 0.8 or more, medium at 0.6 or more.
Loop defaults#
| Setting | Default | Note |
|---|---|---|
max_rounds | 5 | Critic budget. Below 1 raises ValueError |
target_score | 8.0 | Every dimension, not the mean |
plateau_epsilon | 0.1 | For plateau_window 2 rounds |
slots | 3 | Parallel asyncio tasks |
max_experiments | 50 | max_seconds is 30.0 |
exploration_c | sqrt(2) | UCB exploration weight |
paper_threshold | 0.7 | Fires paper.trigger |
prune_floor | 0.2 | After prune_after_runs 3 trials |
Errors and fixes#
| Symptom | Cause | Fix |
|---|---|---|
PaperValidationError: cites unknown bibliography key | Section cite has no BibEntry | Add the entry to bibliography |
PaperValidationError: references unknown figure id | figure_refs names a missing figure | Add the figure first |
NoTriggerError | No branch reached paper_threshold | Check branch rewards against the threshold |
| Five flat rounds, verdict budget | Suggestions never raise the score | Fix the critic, not the draft |
| Branch never scheduled again | Branch is pruned | Check prune_floor and prune_after_runs |
| Trace event kind error | Runner task raised | Read the repr of the exception in the trace |