paper-banana — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited paper-banana (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
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.
Automates publication-ready academic illustrations via 5 specialized agents, each a separate call to the configured VLM or image model (Gemini by default): Retriever (categorize & select references) -> Planner (multimodal description) -> Stylist (polish) -> Visualizer (render) -> Critic (evaluate & refine).
Two output modes:
scripts/orchestrate.py for end-to-end execution.Requirements: Python 3.10+ with google-genai>=2, matplotlib, seaborn, numpy, pillow, and an API key for the provider in use (default Gemini: GOOGLE_API_KEY or GEMINI_API_KEY). Optional: openai (for openai/... and openrouter/... models), anthropic, pypdf (PDF input).
Models: named provider/model; unprefixed names are inferred. Defaults are gemini-3.5-flash (Retriever/Planner/Stylist/Critic) and gemini-3-pro-image (Visualizer, "Nano Banana Pro"). Override with PAPERBANANA_VLM_MODEL / PAPERBANANA_IMAGE_MODEL or the orchestrator's --vlm-model / --image-model flags.
| Provider | Key | Reasoning | Image | Examples |
|---|---|---|---|---|
| gemini (default) | GOOGLE_API_KEY | yes | yes | gemini-3.5-flash, gemini-3.1-flash-lite, gemini-3-pro-image, gemini-3.1-flash-image |
| openai | OPENAI_API_KEY | yes | yes | openai/gpt-5.5, openai/gpt-5.4-mini, openai/gpt-image-2, openai/gpt-image-1.5 |
| anthropic | ANTHROPIC_API_KEY | yes | no | anthropic/claude-opus-5, anthropic/claude-sonnet-5 |
| openrouter | OPENROUTER_API_KEY | yes | yes | openrouter/google/gemini-3.5-flash, openrouter/google/gemini-3-pro-image |
If the user names a provider or model, pass it via --vlm-model / --image-model. If a run fails with a missing-key or model error, run python scripts/validate_output.py --check-api and report which key or model is the problem.
Paper: PaperBanana: Automating Academic Illustration for AI Scientists (arXiv:2601.23265, Google/PKU). Official code: https://github.com/dwzhu-pku/PaperBanana
Decide which track to follow:
| Signal | Mode |
|---|---|
| User provides raw data, table, CSV + visual intent (bar chart, scatter, etc.) | PLOT MODE |
| User provides methodology text, description, or figure caption | DIAGRAM MODE |
| User provides existing figure to improve | Match original type |
Critical rule: PLOT MODE always generates Python code (never image generation for data visualizations). Code-based generation eliminates data hallucination errors that corrupt numerical accuracy in image-based approaches.
Primary entry point: Run the end-to-end orchestrator:
python scripts/orchestrate.py \
--methodology-file methodology.txt \
--caption "Figure 1: Overview of proposed framework" \
--mode diagram \
--output output/diagram.pngUseful flags (combine as needed):
| Flag | Use when |
|---|---|
--methodology-file paper.pdf --pages 3-5 | The user gives a PDF (or .tex); page ranges keep only the method section |
--venue icml --figure-width single | The user names a venue or column width. Venues: neurips (default), iclr, icml, cvpr, acl, aaai |
--num-candidates 4 | Quality matters more than cost: renders 4 images in parallel, the Critic keeps the best |
--input-image old_figure.png | The user wants an existing figure improved (Planner sees it, Visualizer edits it) |
--image-size 4K | Print-quality output (default 2K) |
--resume | Re-render after a failed or unsatisfying image step without re-running Retriever/Planner/Stylist |
--vlm-model / --image-model | The user asks for a specific provider or model |
Or with inline text:
python scripts/orchestrate.py \
--methodology "Our framework consists of three modules..." \
--caption "Figure 1: System overview" \
--mode diagram \
--output output/diagram.pngThe orchestrator chains all 5 agents automatically and handles the Critic's refinement loop (up to 3 iterations). Intermediate outputs, including every Visualizer attempt (diagram_iter{N}[_c{K}].png), are saved to output/work/; the best-scoring image is copied to --output. The run ends with a per-model token/image usage summary; relay it to the user.
#### Pipeline Details
Read references/DIAGRAM-PROMPTS.md for the actual Gemini prompt templates used by each agent.
Phase 1: RETRIEVER (scripts/retriever.py) — VLM call
references/DIAGRAM-CATEGORIES.mdassets/references/Phase 2: PLANNER (scripts/planner.py) — Multimodal VLM call
--input-image, the existing figure is attached too and the Planner must preserve its content while improving layout and legibilityPhase 3: STYLIST (scripts/stylist.py) — VLM call
--venue, --figure-width; data in assets/venues.json)Phase 4: VISUALIZER (scripts/generate_image.py) — Image model call
gemini-3-pro-image (Nano Banana Pro) by default; openai/gpt-image-2, gemini-3.1-flash-image, or an OpenRouter image model via --image-model--input-image, the existing figure is passed as the edit source instead of generating from scratch--num-candidates N, N images are rendered in parallel and all are scored by the Critic; the best is keptPhase 5: CRITIC (scripts/critic.py) — Multimodal VLM call
You can also run each agent individually for more control:
# Phase 1: Retriever
python scripts/retriever.py --methodology-file text.txt --output work/retriever.json
# Phase 2: Planner (add --input-image old.png to improve an existing figure)
python scripts/planner.py --methodology-file text.txt --caption "Figure 1: ..." \
--references work/retriever.json --output work/planner.json
# Phase 3: Stylist (venue defaults to neurips)
python scripts/stylist.py --description work/planner.json --venue icml --figure-width single \
--output work/stylist.json
# Phase 4: Visualizer (extract styled_description from JSON, pass to generate_image.py;
# add --reference-image old.png to edit an existing figure, --model openai/gpt-image-2 to switch renderer)
python scripts/generate_image.py --prompt-file work/styled_desc.txt --aspect-ratio 16:9 \
--image-size 2K --output output/diagram.png
# Phase 5: Critic
python scripts/critic.py --image output/diagram.png --methodology-file text.txt \
--description work/stylist.json --output work/critic.jsonRead references/PLOT-PROMPTS.md for detailed agent prompts. Read references/PLOT-STYLE-GUIDE.md for aesthetic rules.
Plot mode uses the host agent for reasoning and code generation — no image-model API calls are needed for plot generation itself.
#### Phase 1: CATEGORIZE (Retriever)
Match data characteristics and visual intent:
| Data Type | Plot Types |
|---|---|
| Categorical comparison | Bar chart, grouped bar, stacked bar |
| Continuous trends | Line chart, area chart |
| Correlation/distribution | Scatter plot, histogram, box plot, violin |
| Matrix/similarity | Heatmap, confusion matrix |
| Multi-dimensional | Radar/spider chart |
| Proportional | Pie/donut chart, treemap |
#### Phase 2: PLAN (Planner)
Create a detailed specification that explicitly enumerates:
#### Phase 3: STYLE (Stylist)
Read references/PLOT-STYLE-GUIDE.md for NeurIPS 2025 plot aesthetics.
Key styling rules:
assets/palettes/colorblind_safe.json)#### Phase 4: VISUALIZE (Visualizer — Code Generation)
Generate complete, self-contained Python matplotlib/seaborn code. Use scripts/plot_generator.py as a reference implementation or run it directly with a JSON config:
python scripts/plot_generator.py --config plot_config.json --venue icml --width single --output figure.pdf--venue and --width size the figure to the venue's column (single) or text (double) width from assets/venues.json; use the same widths for figsize when writing custom code.
Code requirements:
.mplstyle from assets/matplotlib_styles/academic_default.mplstyleOUTPUT_PATH variable for output file locationbbox_inches='tight'plt.show() — save onlyAfter generating the code, execute it to produce the plot image.
#### Phase 5: CRITIQUE (Critic)
Same rubric as diagram mode, plus plot-specific checks:
If code execution failed, analyze the error, simplify the approach, and regenerate.
Diagram (automated): Run scripts/orchestrate.py with your methodology text file and caption.
Diagram (via agent): "Generate a methodology diagram for my transformer architecture. Here is the methodology section: [paste text]. Caption: Overview of our proposed multi-head attention framework."
Plot: "Create a bar chart comparing model performance. Data: {BERT: 92.3, GPT-4: 88.1, Claude: 95.7, Gemini: 91.2}. Intent: F1 score comparison across language models."
Improve: "Improve this figure: [attach image] using this methodology: [paste text]" → run scripts/orchestrate.py --input-image figure.png --methodology-file text.txt.
From a paper: "Make the method figure for paper.pdf" → scripts/orchestrate.py --methodology-file paper.pdf --pages 3-5 (ask for or infer the method-section pages).
Other provider: "Use GPT Image for rendering" → add --image-model openai/gpt-image-2 (needs OPENAI_API_KEY).
| File | Purpose | When to Read |
|---|---|---|
scripts/orchestrate.py | End-to-end pipeline runner | Diagram mode primary entry point |
scripts/providers.py | Gemini / OpenAI / Anthropic / OpenRouter adapters, model routing, usage tracking | When a provider or key error needs diagnosing |
scripts/common.py | Input loading (.txt/.tex/.pdf), venue lookup, re-exports of providers | Imported by all diagram scripts |
scripts/retriever.py | VLM-based reference selection | Phase 1 (diagram mode) |
scripts/planner.py | Multimodal description generation | Phase 2 (diagram mode) |
scripts/stylist.py | VLM-based style application | Phase 3 (diagram mode) |
scripts/generate_image.py | Gemini Image API call | Phase 4 (diagram mode) |
scripts/critic.py | VLM-based image evaluation | Phase 5 (diagram mode) |
scripts/plot_generator.py | Template-based matplotlib generator | Phase 4 (plot mode) |
scripts/validate_output.py | Output validation and dependency check | Post-generation validation |
references/DIAGRAM-PROMPTS.md | Actual Gemini prompt templates for diagrams | All diagram phases |
references/PLOT-PROMPTS.md | Agent prompts for plots | All plot phases |
references/DIAGRAM-STYLE-GUIDE.md | NeurIPS 2025 diagram aesthetics | Phase 3 (Style) |
references/PLOT-STYLE-GUIDE.md | NeurIPS 2025 plot aesthetics | Phase 3 (Style) |
references/EVALUATION-RUBRIC.md | Critic scoring criteria (4 dimensions) | Phase 5 (Critique) |
references/DIAGRAM-CATEGORIES.md | 4 diagram categories with keywords | Phase 1 (Categorize) |
assets/references/index.json | 13 curated reference diagram metadata | Phase 1 (Retriever) |
assets/references/*.jpg | 13 curated reference diagram images | Phase 2 (Planner multimodal input) |
assets/venues.json | Column/text widths and style notes per venue | Phase 3 (Style) and plot sizing |
assets/palettes/*.json | Color palette definitions | Phase 3 (Style) |
assets/matplotlib_styles/*.mplstyle | Matplotlib style sheets | Phase 4 (plot mode) |
# Default provider (Gemini) for all agents
export GOOGLE_API_KEY="your-api-key-here" # GEMINI_API_KEY also works
# Optional: other providers (install with: pip install openai anthropic)
export OPENAI_API_KEY="..." # openai/gpt-5.5, openai/gpt-image-2, and openrouter/... via OPENROUTER_API_KEY
export ANTHROPIC_API_KEY="..." # anthropic/claude-opus-5 (reasoning agents only)
# Optional: swap models (defaults shown). Cheaper: gemini-3.1-flash-lite / gemini-3.1-flash-image
export PAPERBANANA_VLM_MODEL="gemini-3.5-flash"
export PAPERBANANA_IMAGE_MODEL="gemini-3-pro-image"
# Install dependencies (add pypdf for PDF input)
pip install "google-genai>=2" matplotlib seaborn numpy pillowVerify setup: python scripts/validate_output.py --check-deps --check-api (checks packages, the API keys, and that both configured models are reachable).
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.