Assemble Tool Prompts Dynamically per Environment
Stop shipping one static mega-prompt: generate tool prompts from environment conditions, inject blocks only when features are on, and dedupe config to save tokens.
The route
4 steps to Done
- 01
Identify conditional blocks
Find what only sometimes belongs in the prompt.
Preview prompt + verify gate ▾ Hide ▴
List every section of your current tool/system prompt and mark its activation condition: ALWAYS (core tool description), FEATURE-GATED (sandbox instructions only if sandboxing is enabled; background-task instructions only if background execution is allowed; git safety protocol only in repos), ENVIRONMENT-DERIVED (allowed paths, network hosts, resource limits - values that come from live config), and AUDIENCE (internal power users may get short skill references where external users need full inline instructions). For each block record: condition, source of truth for its values, and current token cost. This map is the spec for the generator.
- ✓ Every section has an explicit condition
- ✓ Value sources identified for derived blocks
- ✓ Token cost recorded per block
- 02
Build the prompt generator
Prompts become code with inputs, not strings.
Preview prompt + verify gate ▾ Hide ▴
Implement a generator function that takes the environment (feature flags, config objects, user class) and returns the assembled prompt. Structure: an ordered list of block builders, each returning either its text or nothing based on its condition; join the included blocks. Pull live values (allowed paths, hosts) directly from the same config objects the ENFORCEMENT code reads - never a hand-copied list - so prompt and enforcement cannot drift. Make assembly deterministic: stable ordering, stable formatting, no timestamps, so identical environments produce byte-identical prompts (this also preserves prompt-cache hits). Unit-test each block: condition on -> text present; condition off -> text absent.
- ✓ Blocks read conditions from real flags/config
- ✓ Values sourced from the enforcing code's config
- ✓ Byte-determinism verified for fixed inputs
- 03
Dedupe and budget every block
Every injected token must earn its place.
Preview prompt + verify gate ▾ Hide ▴
Add hygiene passes to the generator: dedupe list values before injection (configs merged from multiple sources often repeat entries - deduping alone can save 150-200 tokens per request), collapse redundant whitespace, and cap list lengths with a 'plus N more' summary where full enumeration adds nothing. Instrument the generator to log token counts total and per block on every assembly. Set a budget per tool prompt and alert when exceeded. Review the biggest blocks: can a table become a sentence, can an example be cut, can an audience variant use a shorter form? Re-run your behavior tests after each cut to confirm nothing regressed.
- ✓ Dedup pass on all injected lists
- ✓ Token counts logged per block
- ✓ Budget alert wired and behavior re-verified after cuts
- 04
Verify against live environments
The generator must be right in every configuration, not just the default.
Preview prompt + verify gate ▾ Hide ▴
Test the assembled prompt across your real configuration matrix: sandbox on/off, background tasks enabled/disabled, inside/outside a git repo, each user class. For each configuration assert: no block describes a disabled feature, injected values equal the enforcing config's values (compare programmatically, not by eye), and the model behaves correctly on a smoke task. Add a regression test that snapshots the assembled prompt per configuration so unintended diffs show up in code review. Ship with a version identifier embedded in logs (not the prompt) so production transcripts can be traced to the exact prompt build.
- ✓ All configurations tested for false capability claims
- ✓ Prompt values programmatically compared to enforcement values
- ✓ Snapshot tests catch unintended prompt diffs
Research-backed