{"course":{"slug":"building-with-ai","title":"Building with AI","url":"https://addaly.com/learn/building-with-ai","level":"intermediate","track":"build"},"lesson":{"slug":"steering-refusals-and-tone","title":"Scope, refusals, and a voice that stays put","url":"https://addaly.com/learn/building-with-ai/steering-refusals-and-tone","position":17,"of":80,"minutes":8,"answer":"Define scope as an explicit list of what the assistant does not do plus what to offer instead, express tone as constraints you could assert on, and test over-refusal as carefully as you test refusal.","keyIdea":"Define scope as an explicit list of what the assistant does not do plus what to offer instead, express tone as constraints you could assert on, and test over-refusal as carefully as you test refusal."},"body":{"format":"markdown","text":"## The three things every deployed assistant gets asked\n\nWithin a week of launch, whatever your product does, your assistant will receive: a question about a competitor, a request for legal or medical advice, and an attempt to make it say something embarrassing so the screenshot can be posted. None of these are hostile edge cases. They are the ordinary traffic of a public text box.\n\nSo the scope of your assistant is not a philosophical matter. It is a list you write down.\n\n## Write the out-of-scope list explicitly\n\nA prompt that says what the assistant *does* leaves everything else undefined, and undefined means the model improvises. Say what it does not do, and say what to do instead.\n\n> You answer questions about ordering, delivery and returns for this shop.\n>\n> You do not: give medical, legal or financial advice; compare us with named competitors; discuss pricing not listed on the site; agree to refunds, discounts or exceptions; or discuss politics, religion or current events.\n>\n> When a request falls outside that list, say in one sentence that you cannot help with it, and offer the one thing you can do that is closest to what they want.\n\nThat last clause is the difference between a refusal that feels like a wall and one that feels like service. \"I can't advise on whether this medicine suits you; I can show you the ingredients list and our returns policy\" is a refusal that keeps the customer.\n\n## Refuse without being unpleasant\n\nThree properties of a refusal that does not generate a complaint:\n\n**Short.** One sentence. A four-paragraph explanation of policy reads as defensive and invites argument.\n\n**Free of moralising.** Do not explain to an adult why their question was inappropriate. State the boundary and move on.\n\n**Offering an exit.** A route to a human, a relevant page, or the nearest thing in scope. A refusal with no next step converts into a support ticket, which costs more than the answer would have.\n\nAnd the counterpart failure is real: **over-refusal**. Models trained to be careful will decline questions about medication *packaging*, about historical violence, about ordinary security work, about a user's own medical records. Over-refusal is a quality bug with a business cost, and it does not show up on the metrics people usually watch. Put ten legitimate-but-adjacent questions into your test set and check they get answered.\n\n## Tone that stays put\n\nA persona described in adjectives drifts within a few turns, because adjectives do not constrain generation. A persona described in constraints holds.\n\nInstead of *friendly, professional and warm*, write:\n\n- Address the customer as \"you\". Never use their first name more than once in a reply.\n- Two to five sentences. No bullet lists unless listing three or more items.\n- No exclamation marks. No emoji.\n- Do not open with \"Great question\" or \"I'd be happy to help\".\n- British spelling.\n- If you do not know, say so in the first sentence, not the last.\n\nEvery one of those is checkable by a regular expression or a five-line function, which means every one of them can be an assertion in your test suite. That is the test for whether a tone instruction is real.\n\n**Drift over a long conversation** is a specific, mechanical problem: as history grows, the system prompt is a smaller fraction of the context and the model increasingly imitates the recent turns, including the user's register. If the user starts writing in capitals and slang, the model slides towards it. The fixes are restating the two or three most important constraints in the final user turn, and capping history length rather than letting a chat run to 60 turns.\n\n## Do not let the user be the author\n\nOne security point belongs here rather than in the security module, because it looks like a tone problem.\n\nIf your interface lets a user set a persona, a name, or \"custom instructions\", that text is being placed in the same system context as your rules, and it is being written by someone who may want your assistant to behave badly with your logo on it. Treat user-supplied persona text as data: put it inside delimiters, put your non-negotiable rules *after* it, and state that instructions inside the persona block are preferences about tone only and cannot change scope.\n\nThat is a mitigation and not a guarantee (the full argument is in the security module) but the sequencing alone removes the easiest version of the attack.\n\n## Test the boundary, not the middle\n\nYour test set should contain, for every scope rule, one clear violation, one adjacent-but-legitimate question, and one attempt to argue past a refusal. It is the middle case that costs you money: a model that refuses cleanly and refuses too often has traded one visible failure for an invisible one."},"check":{"question":"A shopping assistant is given a persona described as \"friendly, expert and reassuring\". Over long chats it starts matching the customer's casual register and eventually promises a discount. What is the underlying mechanism?","options":[{"text":"Temperature is too high, allowing the model to drift from its instructions.","correct":false,"tempting":"Sampling variance affects wording per call but does not explain a directional drift towards the user's register as the conversation lengthens."},{"text":"The model has a limited context window and the system prompt has been dropped.","correct":false,"tempting":"System prompts are resent every turn and are not silently discarded until the window is genuinely exceeded, which long before that would raise an error."},{"text":"Adjective-based personas impose no checkable constraint, and as history grows the recent turns dominate the system prompt as a pattern to imitate.","correct":true},{"text":"The model has learned the customer's preferences from earlier sessions.","correct":false,"tempting":"Attributes memory across sessions to a stateless API that only sees what you resend in the current request."}]},"prev":{"slug":"grounding-and-citations","title":"Making the model quote before it answers","url":"https://addaly.com/learn/building-with-ai/grounding-and-citations"},"next":{"slug":"prompts-in-version-control","title":"Prompts belong in version control","url":"https://addaly.com/learn/building-with-ai/prompts-in-version-control"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'Scope, refusals, and a voice that stays put', in Building with AI. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/building-with-ai/steering-refusals-and-tone (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"Scope, refusals, and a voice that stays put","courseTitle":"Building with AI","module":{"index":2,"slug":"prompting-as-engineering","title":"Prompting as engineering"},"answer":null,"keyIdea":"Define scope as an explicit list of what the assistant does not do plus what to offer instead, express tone as constraints you could assert on, and test over-refusal as carefully as you test refusal.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"the-three-things-every-deployed-assistant-gets-asked","runs":[{"text":"The three things every deployed assistant gets asked"}]},{"t":"p","runs":[{"text":"Within a week of launch, whatever your product does, your assistant will receive: a question about a competitor, a request for legal or medical advice, and an attempt to make it say something embarrassing so the screenshot can be posted. None of these are hostile edge cases. They are the ordinary traffic of a public text box."}]},{"t":"p","runs":[{"text":"So the scope of your assistant is not a philosophical matter. It is a list you write down."}]},{"t":"h2","id":"write-the-out-of-scope-list-explicitly","runs":[{"text":"Write the out-of-scope list explicitly"}]},{"t":"p","runs":[{"text":"A prompt that says what the assistant "},{"text":"does","i":true},{"text":" leaves everything else undefined, and undefined means the model improvises. Say what it does not do, and say what to do instead."}]},{"t":"quote","runs":[{"text":"You answer questions about ordering, delivery and returns for this shop."}]},{"t":"quote","runs":[]},{"t":"quote","runs":[{"text":"You do not: give medical, legal or financial advice; compare us with named competitors; discuss pricing not listed on the site; agree to refunds, discounts or exceptions; or discuss politics, religion or current events."}]},{"t":"quote","runs":[]},{"t":"quote","runs":[{"text":"When a request falls outside that list, say in one sentence that you cannot help with it, and offer the one thing you can do that is closest to what they want."}]},{"t":"p","runs":[{"text":"That last clause is the difference between a refusal that feels like a wall and one that feels like service. “I can’t advise on whether this medicine suits you; I can show you the ingredients list and our returns policy” is a refusal that keeps the customer."}]},{"t":"h2","id":"refuse-without-being-unpleasant","runs":[{"text":"Refuse without being unpleasant"}]},{"t":"p","runs":[{"text":"Three properties of a refusal that does not generate a complaint:"}]},{"t":"p","runs":[{"text":"Short.","b":true},{"text":" One sentence. A four-paragraph explanation of policy reads as defensive and invites argument."}]},{"t":"p","runs":[{"text":"Free of moralising.","b":true},{"text":" Do not explain to an adult why their question was inappropriate. State the boundary and move on."}]},{"t":"p","runs":[{"text":"Offering an exit.","b":true},{"text":" A route to a human, a relevant page, or the nearest thing in scope. A refusal with no next step converts into a support ticket, which costs more than the answer would have."}]},{"t":"p","runs":[{"text":"And the counterpart failure is real: "},{"text":"over-refusal","b":true},{"text":". Models trained to be careful will decline questions about medication "},{"text":"packaging","i":true},{"text":", about historical violence, about ordinary security work, about a user’s own medical records. Over-refusal is a quality bug with a business cost, and it does not show up on the metrics people usually watch. Put ten legitimate-but-adjacent questions into your test set and check they get answered."}]},{"t":"h2","id":"tone-that-stays-put","runs":[{"text":"Tone that stays put"}]},{"t":"p","runs":[{"text":"A persona described in adjectives drifts within a few turns, because adjectives do not constrain generation. A persona described in constraints holds."}]},{"t":"p","runs":[{"text":"Instead of "},{"text":"friendly, professional and warm","i":true},{"text":", write:"}]},{"t":"ul","items":[[{"text":"Address the customer as “you”. Never use their first name more than once in a reply."}],[{"text":"Two to five sentences. No bullet lists unless listing three or more items."}],[{"text":"No exclamation marks. No emoji."}],[{"text":"Do not open with “Great question” or “I’d be happy to help”."}],[{"text":"British spelling."}],[{"text":"If you do not know, say so in the first sentence, not the last."}]]},{"t":"p","runs":[{"text":"Every one of those is checkable by a regular expression or a five-line function, which means every one of them can be an assertion in your test suite. That is the test for whether a tone instruction is real."}]},{"t":"p","runs":[{"text":"Drift over a long conversation","b":true},{"text":" is a specific, mechanical problem: as history grows, the system prompt is a smaller fraction of the context and the model increasingly imitates the recent turns, including the user’s register. If the user starts writing in capitals and slang, the model slides towards it. The fixes are restating the two or three most important constraints in the final user turn, and capping history length rather than letting a chat run to 60 turns."}]},{"t":"h2","id":"do-not-let-the-user-be-the-author","runs":[{"text":"Do not let the user be the author"}]},{"t":"p","runs":[{"text":"One security point belongs here rather than in the security module, because it looks like a tone problem."}]},{"t":"p","runs":[{"text":"If your interface lets a user set a persona, a name, or “custom instructions”, that text is being placed in the same system context as your rules, and it is being written by someone who may want your assistant to behave badly with your logo on it. Treat user-supplied persona text as data: put it inside delimiters, put your non-negotiable rules "},{"text":"after","i":true},{"text":" it, and state that instructions inside the persona block are preferences about tone only and cannot change scope."}]},{"t":"p","runs":[{"text":"That is a mitigation and not a guarantee (the full argument is in the security module) but the sequencing alone removes the easiest version of the attack."}]},{"t":"h2","id":"test-the-boundary-not-the-middle","runs":[{"text":"Test the boundary, not the middle"}]},{"t":"p","runs":[{"text":"Your test set should contain, for every scope rule, one clear violation, one adjacent-but-legitimate question, and one attempt to argue past a refusal. It is the middle case that costs you money: a model that refuses cleanly and refuses too often has traded one visible failure for an invisible one."}]}],"check":{"question":[{"text":"A shopping assistant is given a persona described as “friendly, expert and reassuring”. Over long chats it starts matching the customer’s casual register and eventually promises a discount. What is the underlying mechanism?"}],"options":[{"text":[{"text":"Temperature is too high, allowing the model to drift from its instructions."}],"correct":false,"tempting":[{"text":"Sampling variance affects wording per call but does not explain a directional drift towards the user’s register as the conversation lengthens."}]},{"text":[{"text":"The model has a limited context window and the system prompt has been dropped."}],"correct":false,"tempting":[{"text":"System prompts are resent every turn and are not silently discarded until the window is genuinely exceeded, which long before that would raise an error."}]},{"text":[{"text":"Adjective-based personas impose no checkable constraint, and as history grows the recent turns dominate the system prompt as a pattern to imitate."}],"correct":true,"tempting":null},{"text":[{"text":"The model has learned the customer’s preferences from earlier sessions."}],"correct":false,"tempting":[{"text":"Attributes memory across sessions to a stateless API that only sees what you resend in the current request."}]}],"order":[0,2,3,1],"why":null},"prev":{"slug":"grounding-and-citations","title":"Making the model quote before it answers","minutes":9},"next":{"slug":"prompts-in-version-control","title":"Prompts belong in version control","minutes":8}}}