Constraint Setting
Tell the model what it may not do, how far it may go, and when to stop — constraints are how you make outputs predictable enough to ship.
Why constraints matter
A model with no constraints will reliably do something reasonable and occasionally do something that breaks your product. It will write a 600-word answer when you had room for two sentences. It will offer medical dosing advice your legal team never approved. It will call a search tool eleven times in a loop because nothing told it to stop. Constraint setting is how you convert a capable-but-unbounded generator into a component you can actually integrate.
This is the technique that separates a demo from a deployment. In a chat window, you tolerate variance — you just regenerate. In a pipeline, the output of one model call is the input to a parser, a UI slot, or another model. Variance there is not charming; it is an incident. Constraints are how you buy the predictability that downstream code assumes.
The four kinds of constraint
Most useful constraints fall into four buckets, and it helps to name them explicitly when you write a prompt:
- Length and format limits. "At most three sentences." "Return a single JSON object, no prose." "Each bullet under 15 words." These bound the size and shape of the output so it fits a UI element or a schema.
- Allowed and forbidden actions. "Answer only questions about our return policy." "Never quote a price; direct the user to the pricing page." "Do not generate code; describe the approach in English." These bound what the model is permitted to produce.
- Scope boundaries. "If the question is outside HR topics, reply exactly: 'I can only help with HR questions.'" These define the territory and, crucially, specify the behavior at the edge — the refusal path — rather than leaving it to the model's improvisation.
- Tool-call and step budgets. In agentic setups: "Use the search tool at most twice." "Plan before acting; do not exceed five tool calls before returning to the user." These bound cost, latency, and runaway loops, which is often the difference between a $0.02 request and a $4 one.
How to write them well
Be specific and checkable. "Be concise" is a wish; "respond in at most two sentences" is a constraint you can actually verify in a test. Whenever you can phrase a limit so that a human or a regex could grade pass/fail, do it — that same checkability is what lets you build an eval suite later.
Worked example. Suppose you are building a support assistant for a bank. A weak instruction is "Help the customer with their banking questions, but be careful about sensitive topics." Compare a constrained version:
You are a support assistant for Acme Bank. Rules:
1. Answer only questions about account access, transactions, and our published fee schedule.
2. Never state, estimate, or confirm an account balance or a specific transaction amount. If asked, reply: "For security, I can't view account details here — please sign in to online banking."
3. Never give tax, legal, or investment advice. Redirect to a licensed advisor.
4. Keep responses under four sentences.
5. If a request falls outside these topics, say so plainly and offer to connect a human agent.
The second version is longer, but every clause removes a class of failure. Rule 2 names the forbidden action and supplies the exact fallback, so the model is never left to invent a refusal. That pairing — forbid X, then specify what to do instead — is the single highest-leverage habit in constraint writing.
How production systems hard-code constraints
If you read the leaked or published system prompts of shipping assistants, you will notice they are largely constraint documents. They enumerate forbidden content, response-length norms, when to use which tool, how to behave when a tool fails, and what to refuse. The interesting behavior — the helpful answer — is left to the model's general capability. The system prompt's job is mostly to fence off the bad outcomes. This is a deliberate division of labor: trust the model for competence, but never trust it for boundaries you care about. Bake those into the system prompt where the user cannot easily override them.
Positive vs. negative framing
A long-standing piece of folklore is that models follow positive instructions ("respond in formal English") better than negative ones ("don't use slang"). There is real signal here — the empirical prompt-engineering literature, including Schulhoff's Prompt Report, generally finds that telling a model what to do is more reliable than a pile of prohibitions, partly because a forbidden token mentioned in the prompt can paradoxically make it more salient. But the evidence is mixed and task-dependent, not a law. The practical synthesis:
- Prefer to state the desired behavior positively when you can: "Use only the four categories listed above" beats "don't invent new categories."
- For genuine safety and compliance boundaries, keep the explicit prohibition anyway — the small risk of salience is worth the unambiguous instruction, and you should be testing it regardless.
- Where possible, replace a prohibition with a constrained mechanism: a JSON schema, an enum, a function signature, or a regex-validated format enforces the constraint structurally instead of relying on the model to remember a "don't."
Pitfalls
- Over-constraining. Twenty rules compete for attention and contradict each other; the model satisfies some and drops others. Keep the list short and ordered by importance.
- Unverifiable constraints. "Be professional" cannot be tested. If you cannot grade it, you cannot trust it across versions.
- Constraints without a fallback. Forbidding an action without specifying the alternative produces awkward, off-distribution refusals.
- Trusting the prompt for hard guarantees. A length limit in a prompt is a strong suggestion, not a hard cap. If exceeding it is unacceptable, enforce it in code — truncate, validate the schema, cap the tool-call count in your agent loop. Treat prompt constraints as the first line of defense, not the only one.
The honest summary: constraints dramatically tighten the distribution of outputs, and that is usually enough for a good product. For anything where a violation is genuinely costly, pair the prompt constraint with a code-level enforcement and an eval that tries to break it.
Length and scope for a UI-embedded summarizer
✕ Weaker
Summarize this support ticket for the agent.
✓ Stronger
Summarize this support ticket in at most 3 sentences for a support agent skimming a queue. Cover only: the customer's core problem, what they've already tried, and the single next action needed. Do not include greetings, apologies, or speculation about cause. If the ticket lacks enough detail to summarize, return exactly: 'Insufficient detail to summarize.'
Why it's better: The weak version produces variable-length output that may overflow a fixed UI card and may editorialize. The strong version bounds length, scope (three named facts), forbidden content (greetings, speculation), and specifies the edge-case behavior — every dimension a downstream renderer cares about is pinned down and checkable.
Tool-call budget in an agent
✕ Weaker
You are a research agent. Use the web search tool to answer the user's question thoroughly.
✓ Stronger
You are a research agent. Use the web_search tool at most 3 times total. After each search, decide whether you have enough to answer; if so, stop searching and respond. If 3 searches are insufficient, answer with what you have and state explicitly which facts you could not verify. Never call the same query twice.
Why it's better: 'Thoroughly' is an open invitation to loop, driving up latency and cost unpredictably. The strong version caps the budget, gives a stopping rule, prescribes the behavior when the budget is exhausted, and forbids redundant calls — turning an unbounded loop into a bounded, costable operation.
Forbidden action with a fallback, in a system prompt
✕ Weaker
You are a health assistant. Don't give dangerous medical advice.
✓ Stronger
You are a wellness information assistant. You may share general, publicly documented health information. You must not: diagnose conditions, recommend specific medications or dosages, or interpret a user's symptoms as a particular illness. When a user asks for any of these, respond: 'I can share general information, but for anything specific to your situation please consult a licensed clinician,' then offer the general information only. Keep answers under 5 sentences.
Why it's better: 'Don't give dangerous advice' is unverifiable and leaves the model to guess where the line is. The strong version enumerates the exact forbidden actions, supplies a precise fallback sentence so refusals are consistent rather than improvised, and adds a length bound — the structure a compliance team can actually review and a test can actually check.
Key takeaways
- Constraints convert a capable-but-unbounded model into a component you can integrate — they buy the predictability that downstream code and UIs assume.
- Think in four buckets: length/format, allowed-vs-forbidden actions, scope boundaries, and tool-call budgets. Name them explicitly in the prompt.
- Always pair a prohibition with its fallback: forbid X, then state exactly what to do instead, so the model never has to improvise a refusal.
- Positive framing tends to be more reliable than a pile of 'don'ts,' but the evidence is mixed — keep explicit prohibitions for real safety boundaries and test them.
- A prompt constraint is a strong suggestion, not a hard guarantee. For anything costly to violate, enforce it in code and write an eval that tries to break it.
Further reading
- Sander Schulhoff et al., 'The Prompt Report: A Systematic Survey of Prompting Techniques' (2024)
- Learn Prompting — learnprompting.org
- Sander Schulhoff interview, Lenny's Podcast (prompt engineering techniques and the empirical/trial-and-error philosophy)