Specify & Constrain
- ▸Define success before writing any prompt by listing inputs, outputs, format, and forbidden content
- ▸Apply four constraint techniques: delimiters, respond-with-only, stop sequences, and prefill
- ▸Rewrite a weak prompt into an engineered prompt using the specify-and-constrain pattern
Specify: define success first
A prompt cannot be well-engineered until you know what "correct" looks like. Before writing a single word of prompt copy, answer four questions.
- Inputs — what does the model receive? (free text, structured JSON, code snippet, ...)
- Outputs — what should the model produce? (one JSON object, a regex string, a Python function, ...)
- Format — exactly what format must the output obey? (UTF-8, double-quoted keys, no markdown fences, ...)
- Forbidden content — what must never appear? (preamble, apologies, backticks, extra keys, ...)
Constrain: four techniques
1. Delimiters
Wrap variable content in XML tags, triple-hashes, or markdown headings to separate instructions from data. The model is less likely to confuse injected content with your instructions when they are visually distinct.
2. "Respond with only..."
Explicit exclusion beats implicit expectation. "Emit only raw JSON content — no markdown code fences, no backticks, no preamble" leaves no room for ambiguity.
3. Stop sequences
Pass stop=["\n\n"] or another sentinel to the API to cut off generation as soon as the model would add unwanted trailing text. Useful for single-line outputs such as regex patterns.
4. Prefill
Some APIs allow you to inject the first token(s) of the assistant turn. Starting with { for JSON or def for Python steers the model immediately into the correct format and makes it structurally hard to emit a preamble.
Weak prompt vs engineered prompt
Here is the same AWS-task wrapper written two ways. The weak version relies on the model's good nature. The engineered version makes success structurally inevitable.
def wrap_user_weak(test_case):
return f"""Please help with this AWS-related request. Think briefly if helpful, then answer clearly.
{test_case["task"]}
You may explain your reasoning before giving the final answer."""def wrap_user_engineered(test_case):
fmt = test_case["format"]
crit = test_case.get("solution_criteria", "")
return f"""## Task
{test_case["task"]}
## Deliverable
Type: **{fmt}** (this case expects exactly one {fmt} artifact).
## Output rules
1. Emit **only** raw {fmt} content — no markdown code fences, no backticks, no preamble.
2. JSON: UTF-8, double-quoted keys/strings, no comments or trailing commas.
3. Python: minimal valid code that satisfies the task; no prints unless required.
4. Regex: one pattern string only.
## Rubric alignment
{crit}
"""- ✓Define inputs, outputs, format, and forbidden content before writing prompt copy
- ✓Delimiters separate instructions from variable data
- ✓"Respond with only" constraints beat implicit expectations
- ✓Stop sequences and prefill enforce format at the API level, not just the instruction level
- ✓The engineered wrapper exposes the rubric to the generator so both sides share the same success definition