The builder joins five fixed sections in one order. Fixed order keeps diffs small when one section changes.
It calls no model. It assembles text and checks shape before anything is sent.
Section | Builder rule | Gate |
|---|---|---|
task | One verb phrase plus scope. | Non-empty. |
context | Facts that change the answer. | Non-empty. |
constraints | Limits and forbidden actions. | Names at least one bound. |
format | Keys and separator. | Mentions KEY: VALUE. |
examples | One normal case plus one edge. | Contains Example. |
Common tokenizers use subword units similar to BPE. A rough planning rule is about 4 characters per token for English prose with common tokenizers, with fewer characters per token for code, numbers, hex, and non-Latin text.
The rule is approximate and tokenizer-dependent. Behavior varies by model: measure it on real prompts before trusting a budget.
import sys
def estimate_tokens(text):
return (len(text) + 3) // 4
def build_prompt(sections):
order = ["task", "context", "constraints", "format", "examples"]
parts = []
for key in order:
parts.append(key.upper() + ":\n" + sections[key])
return "\n\n".join(parts)
def main():
sections = {
"task": "Explain what the FIFO block does in two sentences.",
"context": "8-deep FIFO, active-low reset, used between UART RX and core.",
"constraints": "No generic advice. Name signals. Stay under 120 words.",
"format": "Return lines as KEY: VALUE with keys FUNCTION, DEPTH, SIGNALS.",
"examples": "Example input: full flag high. Example output: FUNCTION: backpressure.",
}
budget = 500
for key in ["task", "context", "constraints", "format", "examples"]:
if key not in sections or sections[key].strip() == "":
print("FAIL: missing section text")
sys.exit(1)
prompt = build_prompt(sections)
for tag in ["TASK:", "CONTEXT:", "CONSTRAINTS:", "FORMAT:", "EXAMPLES:"]:
if tag not in prompt:
print("FAIL: section tag absent")
sys.exit(1)
if "KEY: VALUE" not in prompt:
print("FAIL: parseable marker absent")
sys.exit(1)
total = estimate_tokens(prompt)
if total <= 0 or total > budget:
print("FAIL: total outside budget")
sys.exit(1)
print("PASS: 5 sections assembled within 500 token budget")
main()The program prints one PASS line with its counts. The calc block below works the same arithmetic by hand on stated example sizes.
example budget check with stated section sizes
budget = 500 tokens at a planning rule of 4 characters per token
task 160 chars -> 40 tokens, context 640 chars -> 160 tokens
constraints 320 chars -> 80 tokens, format 160 chars -> 40 tokens
examples 480 chars -> 120 tokens
total chars = 160 + 640 + 320 + 160 + 480 = 1760
total tokens = 40 + 160 + 80 + 40 + 120 = 440 tokens
headroom = 500 - 440 = 60 tokens
headroom share = 60 / 500 = 0.12 = 12%
440 <= 500, so the prompt fits the budgetIn the basic attention form, cost grows with the square of the sequence length, and efficient variants exist. Long inputs are less reliable than short ones, with a reported tendency to use the start and end better than the middle.
Trimming context to the deciding facts therefore serves both budget and reliability. Measure hit rate on the task after each trim.
Shorten or drop the lowest-value section first, usually the longest example. Re-run the gate until the total fits.
60 tokens. That is 12% of the budget.