research-paper-writing-e7303d — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited research-paper-writing-e7303d (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
End-to-end pipeline for producing publication-ready ML/AI research papers targeting NeurIPS, ICML, ICLR, ACL, AAAI, and COLM. This skill covers the full research lifecycle: experiment design, execution, monitoring, analysis, paper writing, review, revision, and submission.
This is not a linear pipeline — it is an iterative loop. Results trigger new experiments. Reviews trigger new analysis. The agent must handle these feedback loops.
<!-- ascii-guard-ignore -->
┌─────────────────────────────────────────────────────────────┐
│ RESEARCH PAPER PIPELINE │
│ │
│ Phase 0: Project Setup ──► Phase 1: Literature Review │
│ │ │ │
│ ▼ ▼ │
│ Phase 2: Experiment Phase 5: Paper Drafting ◄──┐ │
│ Design │ │ │
│ │ ▼ │ │
│ ▼ Phase 6: Self-Review │ │
│ Phase 3: Execution & & Revision ──────────┘ │
│ Monitoring │ │
│ │ ▼ │
│ ▼ Phase 7: Submission │
│ Phase 4: Analysis ─────► (feeds back to Phase 2 or 5) │
│ │
└─────────────────────────────────────────────────────────────┘<!-- ascii-guard-ignore-end -->
Use this skill when:
[CITATION NEEDED].Default: Be proactive. Draft first, ask with the draft.
| Confidence Level | Action |
|---|---|
| High (clear repo, obvious contribution) | Write full draft, deliver, iterate on feedback |
| Medium (some ambiguity) | Write draft with flagged uncertainties, continue |
| Low (major unknowns) | Ask 1-2 targeted questions via clarify, then draft |
| Section | Draft Autonomously? | Flag With Draft |
|---|---|---|
| Abstract | Yes | "Framed contribution as X — adjust if needed" |
| Introduction | Yes | "Emphasized problem Y — correct if wrong" |
| Methods | Yes | "Included details A, B, C — add missing pieces" |
| Experiments | Yes | "Highlighted results 1, 2, 3 — reorder if needed" |
| Related Work | Yes | "Cited papers X, Y, Z — add any I missed" |
Block for input only when: target venue unclear, multiple contradictory framings, results seem incomplete, explicit request to review first.
Goal: Establish the workspace, understand existing work, identify the contribution.
# Understand project structure
ls -la
find . -name "*.py" | head -30
find . -name "*.md" -o -name "*.txt" | xargs grep -l -i "result\|conclusion\|finding"Look for:
README.md — project overview and claimsresults/, outputs/, experiments/ — existing findingsconfigs/ — experimental settings.bib files — existing citationsEstablish a consistent workspace structure:
workspace/
paper/ # LaTeX source, figures, compiled PDFs
experiments/ # Experiment runner scripts
code/ # Core method implementation
results/ # Raw experiment results (auto-generated)
tasks/ # Task/benchmark definitions
human_eval/ # Human evaluation materials (if needed)git init # if not already
git remote add origin <repo-url>
git checkout -b paper-draft # or mainGit discipline: Every completed experiment batch gets committed with a descriptive message. Example:
Add Monte Carlo constrained results (5 runs, Sonnet 4.6, policy memo task)
Add Haiku baseline comparison: autoreason vs refinement baselines at cheap model tierBefore writing anything, articulate:
Propose to the scientist: "Based on my understanding, the main contribution is: [one sentence]. The key results show [Y]. Is this the framing you want?"
Use the todo tool to create a structured project plan:
Research Paper TODO:
- [ ] Define one-sentence contribution
- [ ] Literature review (related work + baselines)
- [ ] Design core experiments
- [ ] Run experiments
- [ ] Analyze results
- [ ] Write first draft
- [ ] Self-review (simulate reviewers)
- [ ] Revise based on review
- [ ] Submission prepUpdate this throughout the project. It serves as the persistent state across sessions.
Before running experiments, estimate total cost and time:
Compute Budget Checklist:
- [ ] API costs: (model price per token) × (estimated tokens per run) × (number of runs)
- [ ] GPU hours: (time per experiment) × (number of experiments) × (number of seeds)
- [ ] Human evaluation costs: (annotators) × (hours) × (hourly rate)
- [ ] Total budget ceiling and contingency (add 30-50% for reruns)Track actual spend as experiments run:
# Simple cost tracker pattern
import json, os
from datetime import datetime
COST_LOG = "results/cost_log.jsonl"
def log_cost(experiment: str, model: str, input_tokens: int, output_tokens: int, cost_usd: float):
entry = {
"timestamp": datetime.now().isoformat(),
"experiment": experiment,
"model": model,
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"cost_usd": cost_usd,
}
with open(COST_LOG, "a") as f:
f.write(json.dumps(entry) + "\n")When budget is tight: Run pilot experiments (1-2 seeds, subset of tasks) before committing to full sweeps. Use cheaper models for debugging pipelines, then switch to target models for final runs.
Most papers have 3-10 authors. Establish workflows early:
| Workflow | Tool | When to Use |
|---|---|---|
| Overleaf | Browser-based | Multiple authors editing simultaneously, no git experience |
| Git + LaTeX | git with .gitignore for aux files | Technical teams, need branch-based review |
| Overleaf + Git sync | Overleaf premium | Best of both — live collab with version history |
Section ownership: Assign each section to one primary author. Others comment but don't edit directly. Prevents merge conflicts and style inconsistency.
Author Coordination Checklist:
- [ ] Agree on section ownership (who writes what)
- [ ] Set up shared workspace (Overleaf or git repo)
- [ ] Establish notation conventions (before anyone writes)
- [ ] Schedule internal review rounds (not just at the end)
- [ ] Designate one person for final formatting pass
- [ ] Agree on figure style (colors, fonts, sizes) before creating figuresLaTeX conventions to agree on early:
\method{} macro for consistent method naming\citet{} vs \citep{} usageGoal: Find related work, identify baselines, gather citations.
Start from papers already referenced in the codebase:
# Via terminal:
grep -r "arxiv\|doi\|cite" --include="*.md" --include="*.bib" --include="*.py"
find . -name "*.bib"Load the `arxiv` skill for structured paper discovery: skill_view("arxiv"). It provides arXiv REST API search, Semantic Scholar citation graphs, author profiles, and BibTeX generation.
Use web_search for broad discovery, web_extract for fetching specific papers:
# Via web_search:
web_search("[main technique] + [application domain] site:arxiv.org")
web_search("[baseline method] comparison ICML NeurIPS 2024")
# Via web_extract (for specific papers):
web_extract("https://arxiv.org/abs/2303.17651")Additional search queries to try:
Search queries:
- "[main technique] + [application domain]"
- "[baseline method] comparison"
- "[problem name] state-of-the-art"
- Author names from existing citationsRecommended: Install Exa MCP for real-time academic search:
claude mcp add exa -- npx -y mcp-remote "https://mcp.exa.ai/mcp"A flat search (one round of queries) typically misses important related work. Use an iterative breadth-then-depth pattern inspired by deep research pipelines:
Iterative Literature Search:
Round 1 (Breadth): 4-6 parallel queries covering different angles
- "[method] + [domain]"
- "[problem name] state-of-the-art 2024 2025"
- "[baseline method] comparison"
- "[alternative approach] vs [your approach]"
→ Collect papers, extract key concepts and terminology
Round 2 (Depth): Generate follow-up queries from Round 1 learnings
- New terminology discovered in Round 1 papers
- Papers cited by the most relevant Round 1 results
- Contradictory findings that need investigation
→ Collect papers, identify remaining gaps
Round 3 (Targeted): Fill specific gaps
- Missing baselines identified in Rounds 1-2
- Concurrent work (last 6 months, same problem)
- Key negative results or failed approaches
→ Stop when new queries return mostly papers you've already seenWhen to stop: If a round returns >80% papers already in your collection, the search is saturated. Typically 2-3 rounds suffice. For survey papers, expect 4-5 rounds.
For agent-based workflows: Delegate each round's queries in parallel via delegate_task. Collect results, deduplicate, then generate the next round's queries from the combined learnings.
NEVER generate BibTeX from memory. ALWAYS fetch programmatically.
For each citation, follow the mandatory 5-step process:
Citation Verification (MANDATORY per citation):
1. SEARCH → Query Semantic Scholar or Exa MCP with specific keywords
2. VERIFY → Confirm paper exists in 2+ sources (Semantic Scholar + arXiv/CrossRef)
3. RETRIEVE → Get BibTeX via DOI content negotiation (programmatically, not from memory)
4. VALIDATE → Confirm the claim you're citing actually appears in the paper
5. ADD → Add verified BibTeX to bibliography
If ANY step fails → mark as [CITATION NEEDED], inform scientist# Fetch BibTeX via DOI
import requests
def doi_to_bibtex(doi: str) -> str:
response = requests.get(
f"https://doi.org/{doi}",
headers={"Accept": "application/x-bibtex"}
)
response.raise_for_status()
return response.textIf you cannot verify a citation:
\cite{PLACEHOLDER_author2024_verify_this} % TODO: Verify this citation existsAlways tell the scientist: "I've marked [X] citations as placeholders that need verification."
See references/citation-workflow.md for complete API documentation and the full CitationManager class.
Group papers by methodology, not paper-by-paper:
Good: "One line of work uses X's assumption [refs] whereas we use Y's assumption because..." Bad: "Smith et al. introduced X. Jones et al. introduced Y. We combine both."
Goal: Design experiments that directly support paper claims. Every experiment must answer a specific question.
Create an explicit mapping:
| Claim | Experiment | Expected Evidence |
|---|---|---|
| "Our method outperforms baselines" | Main comparison (Table 1) | Win rate, statistical significance |
| "Effect is larger for weaker models" | Model scaling study | Monotonic improvement curve |
| "Convergence requires scope constraints" | Constrained vs unconstrained | Convergence rate comparison |
Rule: If an experiment doesn't map to a claim, don't run it.
Strong baselines are what separates accepted papers from rejected ones. Reviewers will ask: "Did they compare against X?"
Standard baseline categories:
Before running anything, specify:
Follow these patterns from successful research pipelines:
Incremental saving — save results after each step for crash recovery:
# Save after each problem/task
result_path = f"results/{task}/{strategy}/result.json"
if os.path.exists(result_path):
continue # Skip already-completed work
# ... run experiment ...
with open(result_path, 'w') as f:
json.dump(result, f, indent=2)Artifact preservation — save all intermediate outputs:
results/<experiment>/
<task>/
<strategy>/
final_output.md # Final result
history.json # Full trajectory
pass_01/ # Per-iteration artifacts
version_a.md
version_b.md
critic.mdSeparation of concerns — keep generation, evaluation, and visualization separate:
run_experiment.py # Core experiment runner
run_baselines.py # Baseline comparison
run_comparison_judge.py # Blind evaluation
analyze_results.py # Statistical analysis
make_charts.py # VisualizationSee references/experiment-patterns.md for complete design patterns, cron monitoring, and error recovery.
Many NLP, HCI, and alignment papers require human evaluation as primary or complementary evidence. Design this before running automated experiments — human eval often has longer lead times (IRB approval, annotator recruitment).
When human evaluation is needed:
Key design decisions:
| Decision | Options | Guidance |
|---|---|---|
| Annotator type | Expert, crowdworker, end-user | Match to what your claims require |
| Scale | Likert (1-5), pairwise comparison, ranking | Pairwise is more reliable than Likert for LLM outputs |
| Sample size | Per annotator and total items | Power analysis or minimum 100 items, 3+ annotators |
| Agreement metric | Cohen's kappa, Krippendorff's alpha, ICC | Krippendorff's alpha for >2 annotators; report raw agreement too |
| Platform | Prolific, MTurk, internal team | Prolific for quality; MTurk for scale; internal for domain expertise |
Annotation guideline checklist:
- [ ] Clear task description with examples (good AND bad)
- [ ] Decision criteria for ambiguous cases
- [ ] At least 2 worked examples per category
- [ ] Attention checks / gold standard items (10-15% of total)
- [ ] Qualification task or screening round
- [ ] Estimated time per item and fair compensation (>= local minimum wage)
- [ ] IRB/ethics review if required by your institutionReporting requirements (reviewers check all of these):
See references/human-evaluation.md for complete guide including statistical tests for human eval data, crowdsourcing quality control patterns, and IRB guidance.
Goal: Run experiments reliably, monitor progress, recover from failures.
Use nohup for long-running experiments:
nohup python run_experiment.py --config config.yaml > logs/experiment_01.log 2>&1 &
echo $! # Record the PIDParallel execution: Run independent experiments simultaneously, but be aware of API rate limits. 4+ concurrent experiments on the same API will slow each down.
For long-running experiments, set up periodic status checks. The cron prompt should follow this template:
Monitor Prompt Template:
1. Check if process is still running: ps aux | grep <pattern>
2. Read last 30 lines of log: tail -30 <logfile>
3. Check for completed results: ls <result_dir>
4. If results exist, read and report: cat <result_file>
5. If all done, commit: git add -A && git commit -m "<descriptive message>" && git push
6. Report in structured format (tables with key metrics)
7. Answer the key analytical question for this experimentSilent mode: If nothing has changed since the last check, respond with [SILENT] to suppress notification to the user. Only report when there's news.
Common failure modes and recovery:
| Failure | Detection | Recovery |
|---|---|---|
| API rate limit / credit exhaustion | 402/429 errors in logs | Wait, then re-run (scripts skip completed work) |
| Process crash | PID gone, incomplete results | Re-run from last checkpoint |
| Timeout on hard problems | Process stuck, no log progress | Kill and skip, note in results |
| Wrong model ID | Errors referencing model name | Fix ID and re-run |
Key: Scripts should always check for existing results and skip completed work. This makes re-runs safe and efficient.
After each experiment batch completes:
git add -A
git commit -m "Add <experiment name>: <key finding in 1 line>"
git pushGit commits track what happened, but not the exploration tree — the decisions about what to try next based on what you learned. Maintain a structured experiment journal that captures this tree:
// experiment_journal.jsonl — append one entry per experiment attempt
{
"id": "exp_003",
"parent": "exp_001",
"timestamp": "2025-05-10T14:30:00Z",
"hypothesis": "Adding scope constraints will fix convergence failure from exp_001",
"plan": "Re-run autoreason with max_tokens=2000 and fixed structure template",
"config": {"model": "haiku", "strategy": "autoreason", "max_tokens": 2000},
"status": "completed",
"result_path": "results/exp_003/",
"key_metrics": {"win_rate": 0.85, "convergence_rounds": 3},
"analysis": "Scope constraints fixed convergence. Win rate jumped from 0.42 to 0.85.",
"next_steps": ["Try same constraints on Sonnet", "Test without structure template"],
"figures": ["figures/exp003_convergence.pdf"]
}Why a journal, not just git? Git tracks file changes. The journal tracks the reasoning: why you tried X, what you learned, and what that implies for the next experiment. When writing the paper, this tree is invaluable for the Methods section ("we observed X, which motivated Y") and for honest failure reporting.
Selecting the best path: When the journal shows a branching tree (exp_001 → exp_002a, exp_002b, exp_003), identify the path that best supports the paper's claims. Document dead-end branches in the appendix as ablations or negative results.
Snapshot code per experiment: Copy the experiment script after each run:
cp experiment.py results/exp_003/experiment_snapshot.pyThis enables exact reproduction even after subsequent code changes.
Goal: Extract findings, compute statistics, identify the story.
Write analysis scripts that:
# Standard analysis pattern
import json, os
from pathlib import Path
results = {}
for result_file in Path("results/").rglob("result.json"):
data = json.loads(result_file.read_text())
strategy = result_file.parent.name
task = result_file.parent.parent.name
results.setdefault(strategy, {})[task] = data
# Compute aggregate metrics
for strategy, tasks in results.items():
scores = [t["score"] for t in tasks.values()]
print(f"{strategy}: mean={np.mean(scores):.1f}, std={np.std(scores):.1f}")Always compute:
See references/experiment-patterns.md for complete implementations of McNemar's test, bootstrapped CIs, and Cohen's h.
After analysis, explicitly answer:
#### Handling Negative or Null Results
When your hypothesis was wrong or results are inconclusive, you have three options:
| Situation | Action | Venue Fit |
|---|---|---|
| Hypothesis wrong but why is informative | Frame paper around the analysis of why | NeurIPS, ICML (if analysis is rigorous) |
| Method doesn't beat baselines but reveals something new | Reframe contribution as understanding/analysis | ICLR (values understanding), workshop papers |
| Clean negative result on popular claim | Write it up — the field needs to know | NeurIPS Datasets & Benchmarks, TMLR, workshops |
| Results inconclusive, no clear story | Pivot — run different experiments or reframe | Don't force a paper that isn't there |
How to write a negative results paper:
Venues that explicitly welcome negative results: NeurIPS (Datasets & Benchmarks track), TMLR, ML Reproducibility Challenge, workshops at major conferences. Some workshops specifically call for negative results.
Figures:
plt.savefig('fig.pdf')Tables:
booktabs LaTeX package\usepackage{booktabs}
\begin{tabular}{lcc}
\toprule
Method & Accuracy $\uparrow$ & Latency $\downarrow$ \\
\midrule
Baseline & 85.2 & 45ms \\
\textbf{Ours} & \textbf{92.1} & 38ms \\
\bottomrule
\end{tabular}| Situation | Action |
|---|---|
| Core claims supported, results significant | Move to Phase 5 (writing) |
| Results inconclusive, need more data | Back to Phase 2 (design) |
| Unexpected finding suggests new direction | Back to Phase 2 (design) |
| Missing one ablation reviewers will ask for | Run it, then Phase 5 |
| All experiments done but some failed | Note failures, move to Phase 5 |
Before moving to paper writing, create a structured experiment log that bridges results to prose. This is the single most important connective tissue between experiments and the writeup — without it, the writing agent has to re-derive the story from raw result files.
Create `experiment_log.md` with the following structure:
# Experiment Log
## Contribution (one sentence)
[The paper's main claim]
## Experiments Run
### Experiment 1: [Name]
- **Claim tested**: [Which paper claim this supports]
- **Setup**: [Model, dataset, config, number of runs]
- **Key result**: [One sentence with the number]
- **Result files**: results/exp1/final_info.json
- **Figures generated**: figures/exp1_comparison.pdf
- **Surprising findings**: [Anything unexpected]
### Experiment 2: [Name]
...
## Figures
| Filename | Description | Which section it belongs in |
|----------|-------------|---------------------------|
| figures/main_comparison.pdf | Bar chart comparing all methods on benchmark X | Results, Figure 2 |
| figures/ablation.pdf | Ablation removing components A, B, C | Results, Figure 3 |
...
## Failed Experiments (document for honesty)
- [What was tried, why it failed, what it tells us]
## Open Questions
- [Anything the results raised that the paper should address]Why this matters: When drafting, the agent (or a delegated sub-agent) can load experiment_log.md alongside the LaTeX template and produce a first draft grounded in actual results. Without this bridge, the writing agent must parse raw JSON/CSV files and infer the story — a common source of hallucinated or misreported numbers.
Git discipline: Commit this log alongside the results it describes.
Any output in this pipeline — paper drafts, experiment scripts, analysis — can be iteratively refined. The autoreason research provides empirical evidence for when each refinement strategy works and when it fails. Use this section to choose the right approach.
| Your Situation | Strategy | Why |
|---|---|---|
| Mid-tier model + constrained task | Autoreason | Sweet spot. Generation-evaluation gap is widest. Baselines actively destroy weak model outputs. |
| Mid-tier model + open task | Autoreason with scope constraints added | Add fixed facts, structure, or deliverable to bound the improvement space. |
| Frontier model + constrained task | Autoreason | Wins 2/3 constrained tasks even at frontier. |
| Frontier model + unconstrained task | Critique-and-revise or single pass | Autoreason comes last. Model self-evaluates well enough. |
| Concrete technical task (system design) | Critique-and-revise | Direct find-and-fix loop is more efficient. |
| Template-filling task (one correct structure) | Single pass or conservative | Minimal decision space. Iteration adds no value. |
| Code with test cases | Autoreason (code variant) | Structured analysis of why it failed before fixing. Recovery rate 62% vs 43%. |
| Very weak model (Llama 8B class) | Single pass | Model too weak for diverse candidates. Invest in generation quality. |
Core insight: Autoreason's value depends on the gap between a model's generation capability and its self-evaluation capability.
Model Tier │ Generation │ Self-Eval │ Gap │ Autoreason Value
──────────────────┼────────────┼───────────┼────────┼─────────────────
Weak (Llama 8B) │ Poor │ Poor │ Small │ None — can't generate diverse candidates
Mid (Haiku 3.5) │ Decent │ Poor │ LARGE │ MAXIMUM — 42/42 perfect Borda
Mid (Gemini Flash)│ Decent │ Moderate │ Large │ High — wins 2/3
Strong (Sonnet 4) │ Good │ Decent │ Medium │ Moderate — wins 3/5
Frontier (S4.6) │ Excellent │ Good │ Small │ Only with constraintsThis gap is structural, not temporary. As costs drop, today's frontier becomes tomorrow's mid-tier. The sweet spot moves but never disappears.
Each pass produces three candidates from fresh, isolated agents:
Key parameters:
When refining the paper itself through autoreason:
| Failure | Detection | Fix |
|---|---|---|
| No convergence (A never wins) | A wins <15% over 20+ passes | Add scope constraints to the task |
| Synthesis drift | Word counts grow unboundedly | Constrain structure and deliverable |
| Degradation below single pass | Baselines score higher than iterated output | Switch to single pass; model may be too weak |
| Overfitting (code) | High public-test pass, low private-test pass | Use structured analysis, not just test feedback |
| Broken judges | Parsing failures reduce panel below 3 | Fix parser before continuing |
See references/autoreason-methodology.md for complete prompts, Borda scoring details, model selection guide, scope constraint design patterns, and compute budget reference.
Goal: Write a complete, publication-ready paper.
A paper project with 50+ experiment files, multiple result directories, and extensive literature notes can easily exceed the agent's context window. Manage this proactively:
What to load into context per drafting task:
| Drafting Task | Load Into Context | Do NOT Load |
|---|---|---|
| Writing Introduction | experiment_log.md, contribution statement, 5-10 most relevant paper abstracts | Raw result JSONs, full experiment scripts, all literature notes |
| Writing Methods | Experiment configs, pseudocode, architecture description | Raw logs, results from other experiments |
| Writing Results | experiment_log.md, result summary tables, figure list | Full analysis scripts, intermediate data |
| Writing Related Work | Organized citation notes (Step 1.4 output), .bib file | Experiment files, raw PDFs |
| Revision pass | Full paper draft, specific reviewer concerns | Everything else |
Principles:
context/ directory with pre-compressed summaries: context/
contribution.md # 1 sentence
experiment_summary.md # Key results table (from experiment_log.md)
literature_map.md # Organized citation notes
figure_inventory.md # List of figures with descriptionsThe single most critical insight: Your paper is not a collection of experiments — it's a story with one clear contribution supported by evidence.
Every successful ML paper centers on what Neel Nanda calls "the narrative": a short, rigorous, evidence-based technical story with a takeaway readers care about.
Three Pillars (must be crystal clear by end of introduction):
| Pillar | Description | Test |
|---|---|---|
| The What | 1-3 specific novel claims | Can you state them in one sentence? |
| The Why | Rigorous empirical evidence | Do experiments distinguish your hypothesis from alternatives? |
| The So What | Why readers should care | Does this connect to a recognized community problem? |
If you cannot state your contribution in one sentence, you don't yet have a paper.
This skill synthesizes writing philosophy from researchers who have published extensively at top venues. The writing philosophy layer was originally compiled by Orchestra Research as the ml-paper-writing skill.
| Source | Key Contribution | Link |
|---|---|---|
| Neel Nanda (Google DeepMind) | The Narrative Principle, What/Why/So What framework | How to Write ML Papers |
| Sebastian Farquhar (DeepMind) | 5-sentence abstract formula | How to Write ML Papers |
| Gopen & Swan | 7 principles of reader expectations | Science of Scientific Writing |
| Zachary Lipton | Word choice, eliminating hedging | Heuristics for Scientific Writing |
| Jacob Steinhardt (UC Berkeley) | Precision, consistent terminology | Writing Tips |
| Ethan Perez (Anthropic) | Micro-level clarity tips | Easy Paper Writing Tips |
| Andrej Karpathy | Single contribution focus | Various lectures |
For deeper dives into any of these, see:
Spend approximately equal time on each of:
Why? Most reviewers form judgments before reaching your methods. Readers encounter your paper as: title → abstract → introduction → figures → maybe the rest.
Paper Writing Checklist:
- [ ] Step 1: Define the one-sentence contribution
- [ ] Step 2: Draft Figure 1 (core idea or most compelling result)
- [ ] Step 3: Draft abstract (5-sentence formula)
- [ ] Step 4: Draft introduction (1-1.5 pages max)
- [ ] Step 5: Draft methods
- [ ] Step 6: Draft experiments & results
- [ ] Step 7: Draft related work
- [ ] Step 8: Draft conclusion & discussion
- [ ] Step 9: Draft limitations (REQUIRED by all venues)
- [ ] Step 10: Plan appendix (proofs, extra experiments, details)
- [ ] Step 11: Complete paper checklist
- [ ] Step 12: Final reviewWhen drafting with an AI agent, use a two-pass approach (proven effective in SakanaAI's AI-Scientist pipeline):
Pass 1 — Write + immediate refine per section: For each section, write a complete draft, then immediately refine it in the same context. This catches local issues (clarity, flow, completeness) while the section is fresh.
Pass 2 — Global refinement with full-paper context: After all sections are drafted, revisit each section with awareness of the complete paper. This catches cross-section issues: redundancy, inconsistent terminology, narrative flow, and gaps where one section promises something another doesn't deliver.
Second-pass refinement prompt (per section):
"Review the [SECTION] in the context of the complete paper.
- Does it fit with the rest of the paper? Are there redundancies with other sections?
- Is terminology consistent with Introduction and Methods?
- Can anything be cut without weakening the message?
- Does the narrative flow from the previous section and into the next?
Make minimal, targeted edits. Do not rewrite from scratch."Append this checklist to every refinement prompt. These are the most common errors when LLMs write LaTeX:
LaTeX Quality Checklist (verify after every edit):
- [ ] No unenclosed math symbols ($ signs balanced)
- [ ] Only reference figures/tables that exist (\ref matches \label)
- [ ] No fabricated citations (\cite matches entries in .bib)
- [ ] Every \begin{env} has matching \end{env} (especially figure, table, algorithm)
- [ ] No HTML contamination (</end{figure}> instead of \end{figure})
- [ ] No unescaped underscores outside math mode (use \_ in text)
- [ ] No duplicate \label definitions
- [ ] No duplicate section headers
- [ ] Numbers in text match actual experimental results
- [ ] All figures have captions and labels
- [ ] No overly long lines that cause overfull hbox warningsThe title is the single most-read element of the paper. It determines whether anyone clicks through to the abstract.
Good titles:
Bad titles:
Rules:
From Sebastian Farquhar (DeepMind):
1. What you achieved: "We introduce...", "We prove...", "We demonstrate..."
2. Why this is hard and important
3. How you do it (with specialist keywords for discoverability)
4. What evidence you have
5. Your most remarkable number/resultDelete generic openings like "Large language models have achieved remarkable success..."
Figure 1 is the second thing most readers look at (after abstract). Draft it before writing the introduction — it forces you to clarify the core idea.
| Figure 1 Type | When to Use | Example |
|---|---|---|
| Method diagram | New architecture or pipeline | TikZ flowchart showing your system |
| Results teaser | One compelling result tells the whole story | Bar chart: "Ours vs baselines" with clear gap |
| Problem illustration | The problem is unintuitive | Before/after showing failure mode you fix |
| Conceptual diagram | Abstract contribution needs visual grounding | 2x2 matrix of method properties |
Rules: Figure 1 must be understandable without reading any text. The caption alone should communicate the core idea. Use color purposefully — don't just decorate.
Must include:
Enable reimplementation:
For each experiment, explicitly state:
Requirements:
Organize methodologically, not paper-by-paper. Cite generously — reviewers likely authored relevant papers.
All major conferences require this. Honesty helps:
Conclusion (required, 0.5-1 page):
Discussion (optional, sometimes combined with conclusion):
Do NOT introduce new results or claims in the conclusion.
Appendices are unlimited at all major venues and are essential for reproducibility. Structure:
| Appendix Section | What Goes Here |
|---|---|
| Proofs & Derivations | Full proofs too long for main text. Main text can state theorems with "proof in Appendix A." |
| Additional Experiments | Ablations, scaling curves, per-dataset breakdowns, hyperparameter sensitivity |
| Implementation Details | Full hyperparameter tables, training details, hardware specs, random seeds |
| Dataset Documentation | Data collection process, annotation guidelines, licensing, preprocessing |
| Prompts & Templates | Exact prompts used (for LLM-based methods), evaluation templates |
| Human Evaluation | Annotation interface screenshots, instructions given to annotators, IRB details |
| Additional Figures | Per-task breakdowns, trajectory visualizations, failure case examples |
Rules:
\appendix command, then \section{A: Proofs} etc.When over the page limit:
| Cut Strategy | Saves | Risk |
|---|---|---|
| Move proofs to appendix | 0.5-2 pages | Low — standard practice |
| Condense related work | 0.5-1 page | Medium — may miss key citations |
| Combine tables with subfigures | 0.25-0.5 page | Low — often improves readability |
Use \vspace{-Xpt} sparingly | 0.1-0.3 page | Low if subtle, high if obvious |
| Remove qualitative examples | 0.5-1 page | Medium — reviewers like examples |
| Reduce figure sizes | 0.25-0.5 page | High — figures must remain readable |
Do NOT: reduce font size, change margins, remove required sections (limitations, broader impact), or use \small/\footnotesize for main text.
Most venues now require or strongly encourage an ethics/broader impact statement. This is not boilerplate — reviewers read it and can flag ethics concerns that trigger desk rejection.
What to include:
| Component | Content | Required By |
|---|---|---|
| Positive societal impact | How your work benefits society | NeurIPS, ICML |
| Potential negative impact | Misuse risks, dual-use concerns, failure modes | NeurIPS, ICML |
| Fairness & bias | Does your method/data have known biases? | All venues (implicitly) |
| Environmental impact | Compute carbon footprint for large-scale training | ICML, increasingly NeurIPS |
| Privacy | Does your work use or enable processing of personal data? | ACL, NeurIPS |
| LLM disclosure | Was AI used in writing or experiments? | ICLR (mandatory), ACL |
Writing the statement:
\section*{Broader Impact Statement}
% NeurIPS/ICML: after conclusion, does not count toward page limit
% 1. Positive applications (1-2 sentences)
This work enables [specific application] which may benefit [specific group].
% 2. Risks and mitigations (1-3 sentences, be specific)
[Method/model] could potentially be misused for [specific risk]. We mitigate
this by [specific mitigation, e.g., releasing only model weights above size X,
including safety filters, documenting failure modes].
% 3. Limitations of impact claims (1 sentence)
Our evaluation is limited to [specific domain]; broader deployment would
require [specific additional work].Common mistakes:
Compute carbon footprint (for training-heavy papers):
# Estimate using ML CO2 Impact tool methodology
gpu_hours = 1000 # total GPU hours
gpu_tdp_watts = 400 # e.g., A100 = 400W
pue = 1.1 # Power Usage Effectiveness (data center overhead)
carbon_intensity = 0.429 # kg CO2/kWh (US average; varies by region)
energy_kwh = (gpu_hours * gpu_tdp_watts * pue) / 1000
carbon_kg = energy_kwh * carbon_intensity
print(f"Energy: {energy_kwh:.0f} kWh, Carbon: {carbon_kg:.0f} kg CO2eq")If your paper introduces a new dataset or releases a model, include structured documentation. Reviewers increasingly expect this, and NeurIPS Datasets & Benchmarks track requires it.
Datasheets for Datasets (Gebru et al., 2021) — include in appendix:
Dataset Documentation (Appendix):
- Motivation: Why was this dataset created? What task does it support?
- Composition: What are the instances? How many? What data types?
- Collection: How was data collected? What was the source?
- Preprocessing: What cleaning/filtering was applied?
- Distribution: How is the dataset distributed? Under what license?
- Maintenance: Who maintains it? How to report issues?
- Ethical considerations: Contains personal data? Consent obtained?
Potential for harm? Known biases?Model Cards (Mitchell et al., 2019) — include in appendix for model releases:
Model Card (Appendix):
- Model details: Architecture, training data, training procedure
- Intended use: Primary use cases, out-of-scope uses
- Metrics: Evaluation metrics and results on benchmarks
- Ethical considerations: Known biases, fairness evaluations
- Limitations: Known failure modes, domains where model underperformsSentence-level clarity (Gopen & Swan's 7 Principles):
| Principle | Rule |
|---|---|
| Subject-verb proximity | Keep subject and verb close |
| Stress position | Place emphasis at sentence ends |
| Topic position | Put context first, new info after |
| Old before new | Familiar info → unfamiliar info |
| One unit, one function | Each paragraph makes one point |
| Action in verb | Use verbs, not nominalizations |
| Context before new | Set stage before presenting |
Word choice (Lipton, Steinhardt):
Full writing guide with examples: See references/writing-guide.md
Always copy the entire template directory first, then write within it.
Template Setup Checklist:
- [ ] Step 1: Copy entire template directory to new project
- [ ] Step 2: Verify template compiles as-is (before any changes)
- [ ] Step 3: Read the template's example content to understand structure
- [ ] Step 4: Replace example content section by section
- [ ] Step 5: Use template macros (check preamble for \newcommand definitions)
- [ ] Step 6: Clean up template artifacts only at the endStep 1: Copy the Full Template
cp -r templates/neurips2025/ ~/papers/my-paper/
cd ~/papers/my-paper/
ls -la # Should see: main.tex, neurips.sty, Makefile, etc.Copy the ENTIRE directory, not just the .tex file. Templates include style files (.sty), bibliography styles (.bst), example content, and Makefiles.
Step 2: Verify Template Compiles First
Before making ANY changes:
latexmk -pdf main.tex
# Or manual: pdflatex main.tex && bibtex main && pdflatex main.tex && pdflatex main.texIf the unmodified template doesn't compile, fix that first (usually missing TeX packages — install via tlmgr install <package>).
Step 3: Keep Template Content as Reference
Don't immediately delete example content. Comment it out and use as formatting reference:
% Template example (keep for reference):
% \begin{figure}[t]
% \centering
% \includegraphics[width=0.8\linewidth]{example-image}
% \caption{Template shows caption style}
% \end{figure}
% Your actual figure:
\begin{figure}[t]
\centering
\includegraphics[width=0.8\linewidth]{your-figure.pdf}
\caption{Your caption following the same style.}
\end{figure}Step 4: Replace Content Section by Section
Work through systematically: title/authors → abstract → introduction → methods → experiments → related work → conclusion → references → appendix. Compile after each section.
Step 5: Use Template Macros
\newcommand{\method}{YourMethodName} % Consistent method naming
\newcommand{\eg}{e.g.,\xspace} % Proper abbreviations
\newcommand{\ie}{i.e.,\xspace}| Pitfall | Problem | Solution |
|---|---|---|
Copying only .tex file | Missing .sty, won't compile | Copy entire directory |
Modifying .sty files | Breaks conference formatting | Never edit style files |
| Adding random packages | Conflicts, breaks template | Only add if necessary |
| Deleting template content early | Lose formatting reference | Keep as comments until done |
| Not compiling frequently | Errors accumulate | Compile after each section |
| Raster PNGs for figures | Blurry in paper | Always use vector PDF via savefig('fig.pdf') |
| Conference | Main File | Style File | Page Limit |
|---|---|---|---|
| NeurIPS 2025 | main.tex | neurips.sty | 9 pages |
| ICML 2026 | example_paper.tex | icml2026.sty | 8 pages |
| ICLR 2026 | iclr2026_conference.tex | iclr2026_conference.sty | 9 pages |
| ACL 2025 | acl_latex.tex | acl.sty | 8 pages (long) |
| AAAI 2026 | aaai2026-unified-template.tex | aaai2026.sty | 7 pages |
| COLM 2025 | colm2025_conference.tex | colm2025_conference.sty | 9 pages |
Universal: Double-blind, references don't count, appendices unlimited, LaTeX required.
Templates in templates/ directory. See templates/README.md for compilation setup (VS Code, CLI, Overleaf, other IDEs).
Tables — use booktabs for professional formatting:
\usepackage{booktabs}
\begin{tabular}{lcc}
\toprule
Method & Accuracy $\uparrow$ & Latency $\downarrow$ \\
\midrule
Baseline & 85.2 & 45ms \\
\textbf{Ours} & \textbf{92.1} & 38ms \\
\bottomrule
\end{tabular}Rules:
Figures:
plt.savefig('fig.pdf')For converting between venues, see Phase 7 (Submission Preparation) — it covers the full conversion workflow, page-change table, and post-rejection guidance.
Add these packages to any paper for professional quality. They are compatible with all major conference style files:
% --- Professional Packages (add after conference style file) ---
% Typography
\usepackage{microtype} % Microtypographic improvements (protrusion, expansion)
% Makes text noticeably more polished — always include
% Tables
\usepackage{booktabs} % Professional table rules (\toprule, \midrule, \bottomrule)
\usepackage{siunitx} % Consistent number formatting, decimal alignment
% Usage: \num{12345} → 12,345; \SI{3.5}{GHz} → 3.5 GHz
% Table alignment: S column type for decimal-aligned numbers
% Figures
\usepackage{graphicx} % Include graphics (\includegraphics)
\usepackage{subcaption} % Subfigures with (a), (b), (c) labels
% Usage: \begin{subfigure}{0.48\textwidth} ... \end{subfigure}
% Diagrams and Algorithms
\usepackage{tikz} % Programmable vector diagrams
\usetikzlibrary{arrows.meta, positioning, shapes.geometric, calc, fit, backgrounds}
\usepackage[ruled,vlined]{algorithm2e} % Professional pseudocode
% Alternative: \usepackage{algorithmicx} if template bundles it
% Cross-references
\usepackage{cleveref} % Smart references: \cref{fig:x} → "Figure 1"
% MUST be loaded AFTER hyperref
% Handles: figures, tables, sections, equations, algorithms
% Math (usually included by conference .sty, but verify)
\usepackage{amsmath,amssymb} % AMS math environments and symbols
\usepackage{mathtools} % Extends amsmath (dcases, coloneqq, etc.)
% Colors (for figures and diagrams)
\usepackage{xcolor} % Color management
% Okabe-Ito colorblind-safe palette:
\definecolor{okblue}{HTML}{0072B2}
\definecolor{okorange}{HTML}{E69F00}
\definecolor{okgreen}{HTML}{009E73}
\definecolor{okred}{HTML}{D55E00}
\definecolor{okpurple}{HTML}{CC79A7}
\definecolor{okcyan}{HTML}{56B4E9}
\definecolor{okyellow}{HTML}{F0E442}Notes:
microtype is the single highest-impact package for visual quality. It adjusts character spacing at a sub-pixel level. Always include it.siunitx handles decimal alignment in tables via the S column type — eliminates manual spacing.cleveref must be loaded after hyperref. Most conference .sty files load hyperref, so put cleveref last.algorithm, amsmath, graphicx). Don't double-load.siunitx makes number-heavy tables significantly more readable:
\begin{tabular}{l S[table-format=2.1] S[table-format=2.1] S[table-format=2.1]}
\toprule
Method & {Accuracy $\uparrow$} & {F1 $\uparrow$} & {Latency (ms) $\downarrow$} \\
\midrule
Baseline & 85.2 & 83.7 & 45.3 \\
Ablation (no X) & 87.1 & 85.4 & 42.1 \\
\textbf{Ours} & \textbf{92.1} & \textbf{90.8} & \textbf{38.7} \\
\bottomrule
\end{tabular}The S column type auto-aligns on the decimal point. Headers in {} escape the alignment.
Standard pattern for side-by-side figures:
\begin{figure}[t]
\centering
\begin{subfigure}[b]{0.48\textwidth}
\centering
\includegraphics[width=\textwidth]{fig_results_a.pdf}
\caption{Results on Dataset A.}
\label{fig:results-a}
\end{subfigure}
\hfill
\begin{subfigure}[b]{0.48\textwidth}
\centering
\includegraphics[width=\textwidth]{fig_results_b.pdf}
\caption{Results on Dataset B.}
\label{fig:results-b}
\end{subfigure}
\caption{Comparison of our method across two datasets. (a) shows the scaling
behavior and (b) shows the ablation results. Both use 5 random seeds.}
\label{fig:results}
\end{figure}Use \cref{fig:results} → "Figure 1", \cref{fig:results-a} → "Figure 1a".
\begin{algorithm}[t]
\caption{Iterative Refinement with Judge Panel}
\label{alg:method}
\KwIn{Task $T$, model $M$, judges $J_1 \ldots J_n$, convergence threshold $k$}
\KwOut{Final output $A^*$}
$A \gets M(T)$ \tcp*{Initial generation}
$\text{streak} \gets 0$\;
\While{$\text{streak} < k$}{
$C \gets \text{Critic}(A, T)$ \tcp*{Identify weaknesses}
$B \gets M(T, C)$ \tcp*{Revised version addressing critique}
$AB \gets \text{Synthesize}(A, B)$ \tcp*{Merge best elements}
\ForEach{judge $J_i$}{
$\text{rank}_i \gets J_i(\text{shuffle}(A, B, AB))$ \tcp*{Blind ranking}
}
$\text{winner} \gets \text{BordaCount}(\text{ranks})$\;
\eIf{$\text{winner} = A$}{
$\text{streak} \gets \text{streak} + 1$\;
}{
$A \gets \text{winner}$; $\text{streak} \gets 0$\;
}
}
\Return{$A$}\;
\end{algorithm}TikZ is the standard for method diagrams in ML papers. Common patterns:
Pipeline/Flow Diagram (most common in ML papers):
\begin{figure}[t]
\centering
\begin{tikzpicture}[
node distance=1.8cm,
box/.style={rectangle, draw, rounded corners, minimum height=1cm,
minimum width=2cm, align=center, font=\small},
arrow/.style={-{Stealth[length=3mm]}, thick},
]
\node[box, fill=okcyan!20] (input) {Input\\$x$};
\node[box, fill=okblue!20, right of=input] (encoder) {Encoder\\$f_\theta$};
\node[box, fill=okgreen!20, right of=encoder] (latent) {Latent\\$z$};
\node[box, fill=okorange!20, right of=latent] (decoder) {Decoder\\$g_\phi$};
\node[box, fill=okred!20, right of=decoder] (output) {Output\\$\hat{x}$};
\draw[arrow] (input) -- (encoder);
\draw[arrow] (encoder) -- (latent);
\draw[arrow] (latent) -- (decoder);
\draw[arrow] (decoder) -- (output);
\end{tikzpicture}
\caption{Architecture overview. The encoder maps input $x$ to latent
representation $z$, which the decoder reconstructs.}
\label{fig:architecture}
\end{figure}Comparison/Matrix Diagram (for showing method variants):
\begin{tikzpicture}[
cell/.style={rectangle, draw, minimum width=2.5cm, minimum height=1cm,
align=center, font=\small},
header/.style={cell, fill=gray!20, font=\small\bfseries},
]
% Headers
\node[header] at (0, 0) {Method};
\node[header] at (3, 0) {Converges?};
\node[header] at (6, 0) {Quality?};
% Rows
\node[cell] at (0, -1) {Single Pass};
\node[cell, fill=okgreen!15] at (3, -1) {N/A};
\node[cell, fill=okorange!15] at (6, -1) {Baseline};
\node[cell] at (0, -2) {Critique+Revise};
\node[cell, fill=okred!15] at (3, -2) {No};
\node[cell, fill=okred!15] at (6, -2) {Degrades};
\node[cell] at (0, -3) {Ours};
\node[cell, fill=okgreen!15] at (3, -3) {Yes ($k$=2)};
\node[cell, fill=okgreen!15] at (6, -3) {Improves};
\end{tikzpicture}Iterative Loop Diagram (for methods with feedback):
\begin{tikzpicture}[
node distance=2cm,
box/.style={rectangle, draw, rounded corners, minimum height=0.8cm,
minimum width=1.8cm, align=center, font=\small},
arrow/.style={-{Stealth[length=3mm]}, thick},
label/.style={font=\scriptsize, midway, above},
]
\node[box, fill=okblue!20] (gen) {Generator};
\node[box, fill=okred!20, right=2.5cm of gen] (critic) {Critic};
\node[box, fill=okgreen!20, below=1.5cm of $(gen)!0.5!(critic)$] (judge) {Judge Panel};
\draw[arrow] (gen) -- node[label] {output $A$} (critic);
\draw[arrow] (critic) -- node[label, right] {critique $C$} (judge);
\draw[arrow] (judge) -| node[label, left, pos=0.3] {winner} (gen);
\end{tikzpicture}Essential for rebuttals — generates a marked-up PDF showing changes between versions:
# Install
# macOS: brew install latexdiff (or comes with TeX Live)
# Linux: sudo apt install latexdiff
# Generate diff
latexdiff paper_v1.tex paper_v2.tex > paper_diff.tex
pdflatex paper_diff.tex
# For multi-file projects (with \input{} or \include{})
latexdiff --flatten paper_v1.tex paper_v2.tex > paper_diff.texThis produces a PDF with deletions in red strikethrough and additions in blue — standard format for rebuttal supplements.
Install and use for publication-quality plots:
pip install SciencePlotsimport matplotlib.pyplot as plt
import scienceplots # registers styles
# Use science style (IEEE-like, clean)
with plt.style.context(['science', 'no-latex']):
fig, ax = plt.subplots(figsize=(3.5, 2.5)) # Single-column width
ax.plot(x, y, label='Ours', color='#0072B2')
ax.plot(x, y2, label='Baseline', color='#D55E00', linestyle='--')
ax.set_xlabel('Training Steps')
ax.set_ylabel('Accuracy')
ax.legend()
fig.savefig('paper/fig_results.pdf', bbox_inches='tight')
# Available styles: 'science', 'ieee', 'nature', 'science+ieee'
# Add 'no-latex' if LaTeX is not installed on the machine generating plotsStandard figure sizes (two-column format):
figsize=(3.5, 2.5) — fits in one columnfigsize=(7.0, 3.0) — spans both columnsfigsize=(3.5, 3.5) — for heatmaps, confusion matricesGoal: Simulate the review process before submission. Catch weaknesses early.
Generate reviews from multiple perspectives. The key insight from automated research pipelines (notably SakanaAI's AI-Scientist): ensemble reviewing with a meta-reviewer produces far more calibrated feedback than a single review pass.
Step 1: Generate N independent reviews (N=3-5)
Use different models or temperature settings. Each reviewer sees only the paper, not other reviews. Default to negative bias — LLMs have well-documented positiv
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.