← Tidelines/Guides

How to make your agent ask one question at a time

Your prompt says to collect three things before troubleshooting. It does not say over how many turns, so the agent asks for all three in one message, the customer answers one, and the agent asks the other two again. The missing rule is a number.

by TypeGlish team7 min read#guides
One ask per turn.

TL;DR Replace the collection checklist with a counted bound on the turn (MUST ask at most 1 question in each reply) plus one guarded rule per ask: the bound is a number the prover holds, so a later edit that widens it to at least 2 questions is 4 blocking errors and even loosening it to at most 3 is 2 blocking logic/action-count errors, and a $TEST assert of matches /^[^?]*\?[^?]*$/ pins the behaviour deterministically. The rewritten spec goes from C (78/100) to A (94/100).

This is the most reliably annoying thing an agent does, and the one customers describe most vividly. Four questions arrive in a single paragraph. The customer scans it, answers the easy one, and now the agent is holding a partial form. On chat that costs turns. On voice it is worse, because a caller can hold two questions in their head at once and no more, and the third one just erases the first.

§1The rule that causes it looks correct

Here is the first draft everybody writes, and it is a reasonable first draft. It names what is needed, it names when it is needed by, and it has a politeness rule attached because somebody already noticed the agent was being brusque.

ask-before.tg - the collection checklist✓ compiles
# Role
You are a support agent for Northwind Broadband.

# Instructions
- MUST collect the account number, the postcode, and the fault description before you troubleshoot.
- SHOULD avoid interrogating the customer.
- MUST keep every chat reply to at most 4 sentences.
Three rules, one of which is a list of three things. The second rule is the one that was supposed to fix the pacing, and it is a mood, not a bound.

Every gate you own signs this off. Zero errors, zero warnings, nothing new under --strict, and a passing grade:

tg check and tg score ask-before.tg - output
ask-before.tg:5:1  info   prompt/unintroduced-definite  "the postcode" retrieves something this
  document never introduces - a model must guess which postcode is meant.
ask-before.tg:5:1  info   prompt/unintroduced-definite  "the fault description" retrieves something
  this document never introduces - a model must guess which description is meant.

 1 file - 0 error, 0 warning, 2 info

ask-before.tg - C (78/100)  proven errors: none  tiers: base+z3
  planes  runtime 87 (what the model reads) · hygiene 50 (source only)
  facets  enforceability 85 x.21 · hardness 83 x.12 · directness 83 x.08
          consistency 100 x.17 · structure 100 x.12 (hygiene) · annotation 0 x.12 (hygiene)
          style 63 x.08 · security 100 x.08
Enforceability 85 on a file that will interrogate your customers. It is not lying: each rule really is written as a modal plus a concrete action. The problem is not in any rule, it is the rule that is not there.

Look at what the first rule actually constrains. It constrains the set of facts the agent holds when it starts troubleshooting. It says nothing whatsoever about the shape of a turn, and the cheapest way to satisfy a set constraint is to ask for the whole set at once. The agent is not being clumsy. It is finding the shortest path through the spec you wrote.

Avoid interrogating the customer was the attempt to fix that, and it is a quality, not a quantity. Nothing in the file says how many questions is an interrogation, so the model picks a threshold per conversation, which is the same failure as any other unquantified rule.

A list of what to collect is a checklist. Pacing is a separate rule, and it is a number.

§2Write the number

The bound is one line, and it belongs above everything else in the section because it governs every ask below it:

- MUST ask at most 1 question in each reply.

What that buys is not politeness. It is that 1 is a number in the same slot as every other count in your file, so the compiler will defend it. Take the finished spec from §3 and let the calendar do what the calendar does: six weeks later the CX team wants the satisfaction question paired with the resolution check, and somebody appends a rule.

tg check ask-ratchet.tg - one rule appended✗ blocked
ask-ratchet.tg:6:1  error  logic/action-count  One action, two counts - "ask at most 1 question"
  but "ask at least 2 questions". A directive carries ONE count for "ask questions in each
  reply" - state how many once. (conflicts with line 20)
ask-ratchet.tg:6:1  error  logic/numeric  Numeric conflict - "at most 1 question" and "at least 2
  questions" can't both hold. (conflicts with line 20)
ask-ratchet.tg:29:1  error  logic/action-count  One action, two counts - "ask at most 1 question"
  but "ask at least 2 questions". A directive carries ONE count for "ask questions in each
  reply" - state how many once. (conflicts with line 4)
ask-ratchet.tg:29:1  error  logic/numeric  Numeric conflict - "at most 1 question" and "at least 2
  questions" can't both hold. (conflicts with line 4)

 1 file - 4 error, 0 warning, 0 info
Two independent proofs, reported once per participating rule. logic/numeric is Z3 saying the intervals cannot intersect; logic/action-count is the stronger claim that one directive carries one count for one action, which is why it fires even when the intervals do intersect.

That second code is the one worth understanding, because it catches the edit that looks harmless. Suppose the voice team does not ask for more questions, only for permission to fit three into an IVR prompt. At most 3 is strictly weaker than at most 1, so there is no numeric impossibility at all, and it still blocks:

tg check ask-loose.tg - a strictly weaker bound✗ blocked
ask-loose.tg:6:1  error  logic/action-count  One action, two counts - "ask at most 1 question"
  but "ask at most 3 questions". A directive carries ONE count for "ask questions in each
  reply" - state how many once. (conflicts with line 20)
ask-loose.tg:29:1  error  logic/action-count  One action, two counts - "ask at most 1 question"
  but "ask at most 3 questions". A directive carries ONE count for "ask questions in each
  reply" - state how many once. (conflicts with line 4)

 1 file - 2 error, 0 warning, 0 info
No logic/numeric this time, because both bounds can hold at once. logic/action-count blocks it anyway: two numbers for one action means a reader cannot tell which one is the policy, and neither can the model.

So the number is not decoration. It is the thing that turns a pacing decision into something a colleague has to argue with you about rather than quietly outvote.

§3One rule per ask, guarded by what you are missing

With the bound in place, the checklist has to come apart, because a single rule naming three facts cannot be satisfied one turn at a time. Each ask becomes its own rule, and each gets a guard describing the state in which it fires. The guards are what encode the order, and they are also what stops the agent asking for something the customer already gave it.

ask-after.tg - the shipping version✓ A (94/100)
# Role
You are a support agent for Northwind Broadband.

# Instructions
@@ one_ask: a reply with three questions comes back with one answer, and the other two get asked again
- MUST ask at most 1 question in each reply.
@@ account_first: everything else needs the account, so a wrong order costs an extra turn
- MUST ask for the account number when you do not have an account number.
@@ postcode_second: the postcode confirms the line, and only makes sense once an account is open
- MUST ask for the postcode when you have an account number and you do not have a postcode.
@@ symptom_last: identity first keeps the fault description out of the wrong record
- MUST ask what the fault is when you have a postcode and you do not have a fault description.
@@ no_question_on_close: a closing turn that ends in a question restarts the contact
- NEVER ask a question when you have a fault description.
@@ brevity: chat replies over 4 sentences stop being read
- MUST keep every chat reply to at most 4 sentences.

$TEST first_turn_asks_once
  - input:: My broadband has been down since this morning and it is really annoying.
  - expect::
    - matches /^[^?]*\?[^?]*$/
    - at most 4 sentences
$TEST close_turn_asks_nothing
  - input:: Account 40118, postcode BS1 4TR, and the router light is red.
  - expect::
    - matches /^[^?]*$/
    - at most 4 sentences
Each guard names the state, not the step number, so nothing renumbers when the postcode ask is dropped for callers who verified in the IVR. The NEVER rule is the one people leave out, and it is the one that stops a wrap-up message ending in is there anything else? when the contact is finished.

Two things about that file are worth flagging honestly. The first is that guards cost you enforceability: this version scores enforceability 80 against the checklist version's 85, because a conditional rule is by definition less enforceable than an unconditional one. That is a real trade and the score is right to name it. The grade still moves a long way, because directness and consistency and annotation all move the other way.

tg score and tg test --dry ask-after.tg - output
ask-after.tg - A (94/100)  proven errors: none  tiers: base+z3
  planes  runtime 94 (what the model reads) · hygiene 93 (source only)
  facets  enforceability 80 x.21 · hardness 100 x.12 · directness 100 x.08
          consistency 100 x.17 · structure 100 x.12 (hygiene) · annotation 86 x.12 (hygiene)
          style 100 x.08 · security 100 x.08
  lever   enforceability 80/100 (up to +4 overall) - Write rules as MUST / NEVER <verb> ... with
          concrete bounds ("at most 3 sentences"), not vague qualities.

 ask-after.tg  coverage: 1/8 rules exercised
  · first_turn_asks_once - "My broadband has been down since this morning and it is real" (not run)
       matches /^[^?]*\?[^?]*$/
       at most 4 sentences
  · close_turn_asks_nothing - "Account 40118, postcode BS1 4TR, and the router light is red." (not run)
       matches /^[^?]*$/
       at most 4 sentences
The second honest number is coverage: 1/8. Two cases, eight rules, and only one rule counted as exercised, because a guarded rule is only covered by a case that puts the agent in that state. Splitting the checklist multiplied the rules faster than it multiplied the tests.

§4Count the question marks

The assert doing the work above is matches /^[^?]*\?[^?]*$/: any amount of text with no question mark, then exactly one question mark, then any amount of text with no question mark. It passes only on a reply containing precisely one ?. Its sibling, matches /^[^?]*$/, passes only on a reply containing none, and that is the assert for a closing turn.

Use those instead of writing asks only one question as a prose expectation. A prose expectation is judge-scored, which means a model call, an API key, and a verdict that can differ between runs. A regex over the output is deterministic, so typeglish test --dry settles the whole suite offline: no key, no spend, and a result CI can gate on. Counting characters is one of the few things in an agent eval that never needs an opinion.

The pairing matters too. Keep at most 4 sentences next to the question assert, because the failure this guide is about has two halves. One question in a reply that also delivers three paragraphs of preamble is still a wall of text, and the customer still scrolls past the question.

§5What the bound does not cover

Two gaps, both worth knowing before you rely on this.

The first is that the count is enforced against counts, not against compounds. Append this to the shipping file and everything stays green:

tg check ask-compound.tg - the compound ask, re-added✓ compiles
  @@ voice_pair: the voice team wants the account number and the postcode in one breath
  - MUST ask for the account number and the postcode in the same reply.

 1 file - 0 error, 0 warning, 0 info
Two asks, one sentence, no number anywhere in it, so no count to conflict with. This is exactly the rule §1 started with, walking back in through the door the bound does not cover.

The defence is the shape of the section rather than the prover: one ask per rule, so a compound is visible as a diff that adds a conjunction instead of a line. That is a review habit, and it is the same habit that keeps a procedure your agent follows in order honest.

The second gap is the modal. Write the same widening edit as SHOULD rather than MUST and all four errors vanish:

tg check ask-soft.tg - the same edit, softened✓ compiles
  @@ survey_pair: the CX team wants the CSAT question paired with the resolution check
  - SHOULD ask at least 2 questions in each reply.

 1 file - 0 error, 0 warning, 0 info
A softened rule is not claimed to always hold, so it never lands in the same slot as the bound and there is nothing to prove. The prompt now contains two contradictory pacing policies and compiles.

This is the standing rule of the whole language and it is worth internalising once: the prover reaches a conflict only when two rules occupy one slot, and every softening, guard and qualifier makes a smaller slot. We measured the effect end to end in soften a rule and it stops being graded, where downgrading any single rule in a clean prompt left the grade within a point of baseline. So when you review a diff that turns a MUST into a SHOULD, read it as a policy change, because the gate will not.

§6Common questions

How do I stop my AI agent asking several questions at once?
Write a counted bound on the turn rather than a checklist of what to collect. MUST ask at most 1 question in each reply is a number the compiler holds, so a later edit that widens it is a blocking error rather than a silent override. The collection list then has to be split into one rule per ask, each guarded by what you do not have yet, which is also what stops the agent asking again for something the customer already gave you.
Why does my agent ask for three things in one message?
Because the rule you wrote is a checklist, not a turn budget. MUST collect the account number, the postcode, and the fault description before you troubleshoot lists three things and says nothing about how many turns they take, so the shortest way to satisfy it is one message with three questions. Nothing in the file is wrong: that prompt checks at 0 error, 0 warning, and stays clean under --strict, scoring C (78/100). The defect is a missing rule, not a broken one.
Can TypeGlish actually enforce one question per turn?
It can enforce the bound against the rest of your file, which is the part that decays. With MUST ask at most 1 question in each reply in place, adding MUST ask at least 2 questions in each reply is 4 blocking errors, 2 logic/action-count and 2 logic/numeric, and even loosening it to at most 3 questions is 2 blocking logic/action-count errors, because a directive carries one count per action. What no compiler can enforce is the model's behaviour on a live turn, which is what the $TEST suite and a regex assert are for.
How do I test that an agent asked only one question?
Assert on the question marks with a deterministic regex rather than asking a judge. In a $TEST block, - matches /^[^?]*\?[^?]*$/ passes only when the reply contains exactly one question mark, and - matches /^[^?]*$/ passes only when it contains none, which is the assert for a closing turn. Both are deterministic, so typeglish test --dry validates them offline with no API key and no model call.
Field note

The reason this one is worth the effort is that turn count is the only agent metric your contact-centre reporting already has. Average handle time, containment, abandon rate: all of them move when the agent stops re-asking for facts it already collected, and none of them will tell you the cause. A bound on questions per reply is one line, it costs nothing at runtime, and it is the rare prompt change whose effect shows up in a dashboard somebody else already reads. Start with typeglish --explain logic/action-count to see what else in your file carries a count you did not know you had committed to.

∿ washed up Aug 13, 2026 ∿