Writing an InferenceX whitepaper
SkillDocs & knowledgeProduce an InferenceX whitepaper end to end - the numbers, the executive-summary PDF in the SemiAnalysis house style, the dashboard-matched figures, the transparent hardware render, and the /whitepaper/[slug] landing page entry in the registry. Use when asked to write, scaffold, redesign, or update a whitepaper, an executive summary, a research paper landing page, or a /whitepaper route.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Writing an InferenceX whitepaper skill
What this skill tells your AI
The instructions your AI receives, as published by semianalysisai/inferencex-app in .claude/skills/write-inferencex-whitepaper/SKILL.md and read by ahel’s review.
A whitepaper is a short research paper (cover + two pages) that anchors one headline economic claim to the live benchmark, and a landing page at /whitepaper/<slug> that presents the same claim with three KPI tiles, two figure cards, the method, the assumptions, and a PDF download. The first paper, amd-mi355x-32b-revenue-per-gigawatt-kimi-k3, is the reference for every rule below; open it before starting.
Everything is driven by two sources of truth:
| Artifact | Source of truth |
|---|---|
Landing page, index card, sitemap, llms.txt, JSON-LD, metadata | one entry in packages/app/src/lib/whitepapers.ts (WHITEPAPERS) |
| PDF cover, pages, charts | one spec JSON consumed by pipeline/ (example: examples/mi355x-kimi-k3.json) |
Both carry the same numbers, so compute the numbers once, write them to the spec, and copy them into the registry from there.
Step 0: What the user must supply
Ask for whichever of these are missing; do not invent them.
- The claim: a headline number and the scenario it holds under (model, SKU, framework, operating point). Example: "MI355X on Kimi K3 2.8T can generate up to $32B of revenue per GW-year at P90 45 tok/s/user".
- The scope boundaries. The reference paper was vLLM only, MI355X only, no vendor-vs-vendor and no framework-vs-framework comparison. Respect whatever boundary the user sets; do not add a competitor bar "for context".
- Cost profiles. The estimator's cost tiers (Owning Hyperscaler, Neocloud, and the SKU's TCO $/chip/hr) or a Custom $/GPU/hr with its provenance (e.g. "August 2026 3-year MI355X rental pricing, $3.00"). Two scenarios fit the fixed page plan; more need a layout change (see Pipeline).
- A hardware render for the cover and hero, ideally a clean product shot on white (2560x1440 or larger).
pipeline/cutout.pymakes it transparent. - Whether disclosures apply. Default: none, and no "commissioned by" line. Authors are always
SemiAnalysis InferenceX Team(WHITEPAPER_AUTHORS), never an individual.
Step 1: Compute and verify the numbers
Reproduce the number the estimator shows at /profit-estimator-per-gigawatt; the paper must match what a reader sees when they open the dashboard link.
- Pull the AgentX rows for the exact configuration with the
inferencex-dataskill (latest run per config, correct ISL/OSL/trace, P90 interactivity, tok/s/GPU, input/output split, cache hit rate, avg power). - Interpolate the operating point on the upper-left Pareto frontier with the Steffen monotone cubic Hermite spline, never linear. Use
.claude/skills/write-inferencex-blog/iso_interactivity.py; it is the Python port ofpackages/app/src/components/calculator/profit-estimator.tsand the chart code, and it refuses to extrapolate. - Apply the estimator formulas (
profit-estimator.ts):- GPU-hours per GW-year = 1,000,000 kW / all-in kW per GPU x 8,760 h (
gpuHoursPerGwYear). All-in kW comes from the TCO model (2.09 kW for MI355X), not the board TDP. - Gross $/GPU/hr = tok/s/GPU x 3,600 x blended $/M tok, where the blended price weights input share, cache hit rate (cached input billed at the cached price) and output share at the interpolated point.
- Revenue = gross $/GPU/hr x GPU-hours x utilization (default 60%,
DEFAULT_UTILIZATION_PCT). - Compute expense = cost tier $/GPU/hr x GPU-hours (every provisioned hour, busy or idle).
- License fee = revenue x 30% (
DEFAULT_LAB_CUT_PCT). - Profit = revenue - compute - license fee; margin = profit / revenue; per chip-hour values divide by GPU-hours.
- GPU-hours per GW-year = 1,000,000 kW / all-in kW per GPU x 8,760 h (
- Token prices come from the model's public OpenRouter page at the data date; record input, cached input, and output per million tokens and the URL.
- Sanity checks before writing a word: recompute revenue per GW-year in a fresh Python shell from tok/s/GPU, blended price, GPU count, and utilization; confirm the headline rounds the same way everywhere ($32.6B in body copy, "$32B" only in the title); compute the break-even utilization for each cost profile (compute / (revenue at 100% x 0.7)) because reviewers ask.
- Save every derived value to the spec JSON (
operating_point,scenarios). Body copy quotes those fields; no number appears in prose that is not in the spec or the registry.
Common mistakes: using board TDP instead of all-in kW; forgetting that cached input is billed at the cached price; quoting $/M tok at 100% utilization then revenue at 60%; stating the rental scenario's compute as "double" when the tiers are not exactly 2x.
Step 2: Write the copy
Length discipline is the main quality lever. The PDF is an executive summary: one Summary paragraph, one bold callout, two figures, four method bullets, one source line. The landing page carries the longer material (abstract, five key findings, seven method steps, assumptions table).
Prose rules (load ai-isms-writing-style if available and run its pre-send check):
- Lead with the number and the condition it holds under. "$32.6B of revenue per GW-year at P90 45 tok/s/user and 60% utilization."
- Name the mechanism behind each finding (cache hit rate, input share, utilization break-even), not its importance.
- No "delve", "robust", "seamless", "landscape", "leverage", "underscore", "pivotal", no "not just X but Y", no em-dash chains, no closing recap.
- Do not compare against vendors, frameworks, or firms the user excluded. Do not name any third-party research firm.
- Titles:
<Vendor> <SKU> <Model> Can Generate Up to $<N>B of Revenue per GigaWatt per Year. No "White Paper" in the title. Subtitle:Executive Summary - <Topic> Analysis(plain hyphen, not an em dash). Cover line:Published by SemiAnalysis InferenceX Team - <Month YYYY>. - Figure card title mirrors the estimator title verbatim:
<Model> Agentic Revenue & Profit Estimates per GigaWatt Per Year at P90 <N> tok/s/user Interactivity. Cost tier strings mirror the estimator'sCost Tiervalues (Owning Hyperscaler,Custom $/GPU/hr (...)). - Captions state what changed between figures and the resulting profit per chip-hour.
- Chinese copy is a real translation of every field (title, subtitle, description, abstract, findings, KPI labels and captions, comparison, method, assumptions, sources, figure captions, alt text). Load
review-zh-copybefore the PR.
Step 3: Build the assets with pipeline/
Everything lives in this skill directory. The pipeline reproduces the shipped PDF byte-for-text from examples/mi355x-kimi-k3.json, so copy that file as the starting spec and edit the fields.
SKILL=.claude/skills/write-inferencex-whitepaper
OUT=/tmp/wp-<slug>
python3 $SKILL/pipeline/cutout.py render.png $OUT/<sku>-transparent.png # prints WxH for the registry
python3 $SKILL/pipeline/make_charts.py $SKILL/examples/<slug>.json $OUT # chart-<id>-{light,dark}.{svg,png}
python3 $SKILL/pipeline/build_pdf.py $SKILL/examples/<slug>.json $OUT # paper.html
NODE_PATH=$(npm root -g) node $SKILL/pipeline/render_pdf.js $OUT # paper.pdf + overflow report
pdftoppm -r 60 -png $OUT/paper.pdf $OUT/pg # look at every page
Dependencies: Python 3 with matplotlib, numpy, Pillow, scipy; Playwright (Chromium) on the global npm path; poppler for pdftoppm. DM Sans TTFs and the OFL notice are in pipeline/fonts/.
Spec fields (examples/mi355x-kimi-k3.json):
title,subtitle,publisher_line,meta_line: cover and page-1 header strings.cover.hardware_image: transparent PNG, path relative to the spec file. Placed at right 0.45in / top 3.45in / width 3.7in with a drop shadow, no caption.chart:title,x_label(<SKU> (<framework>)),sku,y_max/y_step(billions; choose so the tallest bar sits at roughly 70% of the axis),utilization,license_fee,updated,source,tco_source_title/tco_source_href,selling_prices,model_logo_svg(frompackages/app/public/logos/),vendor_mark(PNG mark drawn above the bar;pipeline/assets/amd_mark.pngships, add annvidia_mark.pngbeside it for NVIDIA papers).scenarios[2]:id,cost_tier,tco_badge(the estimator pill text after the SKU,1.5or3),cost_per_gpu_hr,revenue,compute,license,profit,margin,profit_per_chip_hr,kpi_profit_note,caption(HTML allowed).kpi_notes.revenue,kpi_notes.margin: tile captions shared by both scenarios.summary[](HTML paragraphs),callout,method_heading,method[](HTML list items),sources[](label,href),footnote.
House style the pipeline enforces (from the ClusterMAX GPU Cloud Rentals paper):
- Letter pages, zero print margin, content box 0.75in sides, 1.0in top, 0.95in bottom.
- Cover: black, circuit mosaic band across the top 5.15in (
assets/cover_mosaic.png), hardware render right, title block at 6.2in, 25pt bold title with 16pt regular subtitle. - Content pages: circuit trace artwork top-right with the SemiAnalysis badge (
assets/trace.png,assets/badge.png), the same trace mirrored bottom-left, "Page N" bottom-right. - Palette: near-black ink on white; tiles and figure cards on
#eaebec(the site's light--background); KPI values and the profit segment in the estimator red#ba534b; no yellow anywhere in the PDF. - Charts: 7.0x2.7in, one stacked bar (compute
#dfc6c4, license#d09792, profit#ba534b, edge#c26962, width 1.08 on xlim(-1,1)), grid#d9dce0, vendor mark above the total, "% margin" under the total, two-line y label. The dark variant swaps background/grid/ink to the site dark tokens and turns the vendor mark white; the two pink segments keep dark labels in both themes.
The render script prints {pageH, bodyH, bodyBox} per page. bodyH must equal bodyBox (868.8) on the content pages; a larger bodyH means clipped text. Cut copy first, then shorten a caption, then reduce chart height. Do not shrink type below the sizes in build_pdf.py.
Review the rasterised pages before shipping: title wraps, KPI tiles aligned, chart labels not colliding (segment labels switch to one line automatically under 0.42in), header trace not overlapping the doc title, footer trace not under the page number.
Step 4: Install the assets in the app
packages/app/public/whitepaper/<slug>/
pdf/SemiAnalysis-InferenceX-Executive-Summary_<Topic>.pdf paper.pdf
cover.webp page 1 of the PDF at 150 dpi, 1275x1650
<sku>-transparent.png cutout output
figure-1-<scenario>-light.png / -dark.png chart-<id>-{light,dark}.png (2100x810)
figure-2-<scenario>-light.png / -dark.png
pdftoppm -r 150 -f 1 -l 1 -png $OUT/paper.pdf $OUT/cover && python3 -c "from PIL import Image; Image.open('$OUT/cover-1.png').save('cover.webp', quality=88)"
Delete any asset a previous revision no longer references; whitepapers.test.ts checks that every path under the slug exists.
Step 5: Register the paper
Add one object to WHITEPAPERS in packages/app/src/lib/whitepapers.ts. The type doc comments describe every field; the important ones:
slug(URL-safe, unique),publishedDate,dataDate(benchmark snapshot),pageCount(content pages, cover excluded),tags.pdfPath,coverImagePath(alsoheroImagePath; used by the sitemap and JSON-LD image),chipImagePathwithchipImageWidth/chipImageHeightfromcutout.py.figures[]:id,srcLight,srcDark,width,height,tcoBadge(same string as the PDF pill).chart:modelLogoPath,utilization,licenseFee,source,tcoSourceTitle,tcoSourceHref,sellingPrices{input, cached, output, source}.enandzh(WhitepaperCopy):typeLabel,title,subtitle,description(meta, under 160 chars),abstract,keyFindings[5],kpis[3](value, label, caption, icondollar|trending|percent),comparison(secondary scenario lead + three items),methodSteps,assumptions[],sources[],authors(WHITEPAPER_AUTHORS/WHITEPAPER_AUTHORS_ZH),figureTitle,figures[]copy (costTier,caption,alt),coverAlt,chipAlt.
The registry feeds everything else automatically: /whitepaper index cards, /whitepaper/[slug] and /zh/whitepaper/[slug] (static params), sitemap entries with the cover image, llms.txt, Report + Breadcrumb + Collection JSON-LD, and metadata. /whitepaper is already in ZH_MIRRORED_ROUTES and the footer; nothing to add there for a new paper.
Landing page anatomy (packages/app/src/components/whitepaper/), so you know what each field renders:
whitepaper-detail-content.tsx: dark hero (also in light theme) with CSS grid texture, back link,typeLabeleyebrow, title, subtitle, meta row (authors, date, pages, tags),WhitepaperPdfButton placement="hero"+WhitepaperEstimatorLink, and the transparent hardware render overlaid on the right (hidden belowmd); three KPI tiles + comparison bar; two figure cards reproducing the estimator header (model mark,figureTitle, cost tier, utilization, license fee, updated, source, TCO badge pill, TCO source link, selling prices) with the light/dark PNG swap; two-column body (abstract, key findings as numbered cards, method as numbered list, assumptions table, sources) with a sticky sidebar (cover thumbnail +placement="sidebar"PDF button + on-this-page links) and a closing PDF card.whitepaper-index-content.tsx: eyebrow, H1, description, one card per paper (cover thumbnail, type label, title, subtitle, date, pages, three KPI values, tags, read + PDF links).whitepaper-links.tsx: every outbound click tracks awhitepaper_*event (pdf_download_clickedwithplacement,estimator_clicked,back_clicked,source_clicked,card_clicked,read_clicked). Use these components for links; do not add bare anchors.- Page chrome strings (eyebrows, section headings, button labels) live in
WHITEPAPER_COPY[locale]; per-paper strings live in the registry entry. Never hardcode a number in JSX.
Design rules for any change to these components: site tokens only (--background, --card, --border, --primary), plus the estimator red for KPI values; Heading/Eyebrow/Card/Badge primitives from components/ui; hero render hidden below md; screenshot dark and light at 1440 and 390 with Playwright and inspect for overflow, clipped text, and low contrast before committing.
Step 6: Tests and checks
Update or extend, never delete:
packages/app/src/lib/whitepapers.test.ts: unique slugs, asset paths exist, en/zh parity (same array lengths for findings, kpis, method, assumptions, sources, figures), headline numbers for the new paper, metadata and JSON-LD per locale.packages/app/src/components/whitepaper/whitepaper-content.test.tsx: KPI tiles, figure cards, sidebar, index card render from the registry.packages/app/src/app/sitemap.test.tsandsrc/lib/i18n.test.tsif a route or mirrored path changes.
PATH=$HOME/.bun/bin:$PATH bun run lint && bun run check:typography && bunx oxfmt --check
cd packages/app && bunx vitest run src/lib/whitepapers.test.ts src/components/whitepaper src/app/sitemap.test.ts src/lib/i18n.test.ts
bunx tsc --noEmit -p tsconfig.json 2>&1 | rg -i whitepaper # must print nothing
The repo formats with oxfmt, not prettier. Commit messages are bilingual (English line, then a 中文 paragraph). PR descriptions describe the paper, the pages, the assets, and the checks; they never name third-party firms or link to competitor reports, and neither does any commit or code comment.
Checklist before opening the PR
- Headline number matches
/profit-estimator-per-gigawattfor the same model, SKU, framework, interactivity, utilization, and cost tier. - Title without "White Paper", subtitle in the
Executive Summary - ... Analysisform, publisher line with month and year, authorsSemiAnalysis InferenceX Team. - PDF: cover + two pages,
bodyH == bodyBoxon both content pages, two figures only, three KPI tiles per page, no yellow, header/footer artwork positioned as in the reference. - Landing page: hero render present above
md, KPI values equal the PDF tiles, both figure cards swap light/dark PNGs, PDF button in hero, sidebar, and closing card. - Registry: en and zh complete,
chipImageWidth/Heightmatch the PNG, every asset path resolves, old assets removed. - Copy passed the AI-isms pre-send check; zh copy passed
review-zh-copy. - No disclosures or "commissioned by" text unless the user asked for them.
Signals
- GitHub stars
- 45
- Forks
- 19
- Last commit
- Sep 2026
ahel review
K6low
bundled executables the agent is told to run
Automated review, not a security audit. Ruleset v1+k2.
Advanced
- Catalog kind
- skill
- Gateway key
write-inferencex-whitepaper- Source
- github.com/semianalysisai/inferencex-app