Great let’s do an implementation status review.
And talk about maybe improving our OpenAI prompts.
So I was thinking about:
Core levers we use to influence outputs
Step context → each step has its own short system prompt + output format (JSON/TSX/JSON-Patch).
Versioned state → instructionsVersion (tokens, classApi, directives, selectionPlan, stencils, budgets).
Page context → {page, template, stencil, pageDirectives}.
Constraints → guardrails (no carousels), legal/AA requirements, copySpec limits, token-only utilities.
Cache key → hash(minimal inputs) to avoid repeat calls.
Step-by-step: prompt inputs & knobs
R1 — Attribute Extractor
Goal: numbers/colors only.
System: sys.extract.attrs@v1 → “extract machine-typed attributes; JSON only.”
User JSON: { finalPrompt, requiredKeys[], typeMap, rules[] }
Variables: finalPrompt (merged user ask), requiredKeys (from schema), typeMap (color/number/string).
Knobs: temp=0.1, max_tokens small.
Cache key: attrs:v{schema}:hash(finalPrompt)
R2 — Directive Extractor
Goal: tone/dos/don’ts/microcopy/SEO/imagery/page intents.
System: sys.extract.directives@v1.
User JSON: { finalPrompt, directiveSchema, rules[] }
Variables: directiveSchema (fields we allow).
Knobs: temp=0.2.
Cache key: dir:v{schema}:hash(finalPrompt)
R3 — Chooser (top-K)
Goal: pick TokenSet + LayoutPreset + Snippet bundle.
System: sys.choose.combo@v1.
User JSON: { page, directives, candidates[rank,score,ids], hardConstraints[], classApi }
Variables: page, directives (from R2), filtered+scored candidates (local), classApi.
Knobs: temp=0.2, only top-K=3 sent.
Cache key: choose:{version}:{page}:hash(cands+dir)
R4 — Instructions Getter
Goal: freeze instructionsVersion JSON.
System: sys.instructions@v1.
User JSON: { attributes, directives:{userDirectives,pageDirectives}, classApi, selectionPlan, placeholderPolicy, budgets, provenance }
Variables: outputs of R1, R2, R3 + static budgets.
Knobs: temp=0.1.
Cache key: {sessionId}:instructions
Page Pass 1 — Structure (TSX)
Goal: semantic skeleton bound to stencil slots (no styles).
System: sys.page.structure@v1 with literal context:
“You are designing a WordPress <template> (e.g., home.php).”
User JSON: { template, page, stencil, instructions:{version,userDirectives,pageDirectives} }
Variables: template (WP file), stencil.blocks/guardrails, pageDirectives.
Knobs: temp=0.3.
Cache key: {version}:{page}:structure:{stencilId}
Page Pass 2 — Page Copy (JSON)
Goal: fill stencil.copySpec fields.
System: sys.page.copy@v1 (WordPress literal).
User JSON: { page, template, stencil, directives, constraints:{readability} }
Variables: stencil.copySpec (maxChars, mustInclude), userDirectives.microcopy, legal reqs.
Knobs: temp=0.3.
Cache key: copy:{version}:{page}:hash(stencil+directives)
Page Pass 3 — Style (TSX)
Goal: apply token-mapped Tailwind + classApi variants.
System: sys.page.style@v1.
User JSON: { tsxStructure, tokens, classApi, layoutSystem }
Variables: designTokens, classApi, spacing scale, container/gutter.
Knobs: temp=0.3.
Cache key: {version}:{page}:style:{hash(tokens)}
Page Pass 4 — Conformance (JSON Patch)
Goal: minimal patch to fix a11y/spacing/heading/directive issues.
System: sys.page.conformance@v1.
User JSON: { tsx, reports:{a11y,designLint,directive}, budgets }
Variables: lint reports + budgets (AA, LCP/CLS/TBT).
Knobs: temp=0.2, max_tokens tiny.
Cache key: {version}:{page}:conf:{hash(reports)}
What variables change per step (the “switchboard”)
Global (most steps):
instructionsVersion.version
classApi, placeholderPolicy, budgets
Extractor steps: finalPrompt, requiredKeys, directiveSchema
Chooser: directives, candidates, hardConstraints, classApi
Structure: template, stencil.blocks, guardrails, pageDirectives
Copy: stencil.copySpec, userDirectives.microcopy, compliance.mustInclude
Style: designTokens, layoutSystem, classApi
Conformance: reports (axe/design-lint/directive), budgets
——————-
Simple rules:
Change prompt variables only when the step needs them.
Keep system prompts short, role-specific, versioned.
Pass the smallest JSON that fully constrains the step.
Literal page context (“You are designing home.php…”) only for Structure/Copy passes.
Tokens/classApi flow only into Style (and into Conformance checks), not into extractors.
Directives flow into Chooser, Structure, Copy; not into Style directly (Style uses tokens/variants).
Budgets/guardrails flow into Conformance (and restrict Chooser candidates up front).
———————
System prompts live in the prompt registry.
Prompt Registry (repo): prompts/registry.json (or prompts/*.json).
Keys are id@version (e.g., sys.page.copy@v1).
Each entry stores: system text, intended output format (json/tsx/json-patch), optional schema ref, and default temperature/max_tokens.
Optional DB mirror: a PromptRegistry table if you want live edits; the build always pins a specific version.
How they’re used
A central PromptBuilder loads the registry entry by id@version, injects step context (e.g., “You are designing a WordPress home.php”), and attaches a minimal JSON user payload for that step.
Every OpenAI call passes:
system = registry system prompt
user = compact JSON for that step
cache key = hash(systemId + user JSON) → skip re-calls if unchanged
idempotency (our side) for any follow-up writes
Do we use tool calls in OpenAI requests?
Yes for JSON outputs (function/tool calling or JSON-schema mode): extractors, chooser, instructions, page-copy, conformance.
No for TSX outputs (plain text): structure and style passes return TSX strings (we validate with AST/lint afterward).
Quick map (step → use tools?)
Step Uses tool/function call? Output
R1 Attributes Extractor ✅ Yes (JSON schema) JSON object of keys/values
R2 Directives Extractor ✅ Yes (JSON schema) JSON directives
R3 Chooser ✅ Yes (JSON schema) JSON with selected IDs + rationale
R4 Instructions Getter ✅ Yes (JSON schema) ThemeInstructions JSON
Page Structure ❌ No TSX (unstyled)
Page Copy ✅ Yes (JSON schema) pageCopy JSON (stencil slots)
Page Style ❌ No TSX (styled via tokens/classApi)
Conformance ✅ Yes (JSON schema) JSON Patch
———————
What do you think of this plan?
Am I overcomplicating the process?
What can we improve on?
Where do we have gaps in the current system?
Leave a Reply