How ChatGPT's Chart Tools Encode Rules in Tool Descriptions
2 min read
Originally from codex-tool-reference.simonw.chatgpt.site
View source
My notes
Summary
This is a captured tool reference showing the exact system-prompt-style instructions and TypeScript declarations behind a ChatGPT “Data Analytics” plugin’s chart and artifact rendering tools (render_chart, render_artifact, validate_artifact). It documents the precise rules the model is given for validating data before rendering, bounding payload size, and keeping chart titles and subtitles semantically distinct.
Key Insight
- Validate-then-render, never render-as-validator: the tool text explicitly forbids calling
render_artifactiteratively to “test” a manifest, because a failed render leaves a visible placeholder card in front of the user. The failure mode is spelled out in the tool description itself, not left to the model to infer. - Hard numeric bounds baked into prose, not just schema: artifact snapshots are capped at 50 datasets, 2,000 rows per dataset, 3MB total payload, and 200k inline source characters. These concrete limits are written directly into the tool’s natural-language instructions so the model self-limits before the schema would reject it.
- Runtime mode gating: a “Work Mode” flag disables the entire MCP widget-rendering path (
render_artifact,render_chart,render_table) and forces a fallback to Sites and HTML export instead. The model is told to “positively identify” this mode from context before choosing a tool, an example of routing logic embedded in the tool description rather than in code. - Title versus subtitle contract: titles must stay neutral and descriptive (metric, dimension, time scope) with no inferred narrative or headline; subtitles are reserved for the actual reader-facing insight. This split is enforced at the prompt level to stop the model from either being bland everywhere or inventing clickbait headlines everywhere.
- A
By <dimension>phrase is treated as a binding promise: if a chart title or subtitle says “revenue by segment,” the model must verify segment is actually encoded (axis, color, facet, or label). If not, it is instructed to strip the phrase rather than ship a chart that doesn’t deliver what its own title claims. - Deprecation notices live inside the tool description: legacy manifest fields (
xField,series) are explicitly flagged as rejected right in the instructions, so the model doesn’t need external migration docs to avoid using them. - Explicit ordered fallback chain: native widget, then Sites export package, then static image or file, then compact table. Each step only triggers after the previous one is rejected, fails, or is unavailable, preventing the model from skipping straight to the lowest-fidelity option.