A reviewer agent prompt did more for my support automation than another week of prompt tweaking.
I kept trying to make one model call classify the ticket, draft the reply, enforce policy, and check tone.
Bad idea.
What finally worked was splitting the workflow into 3 steps:
- Classify
- Draft
- Review
That extra review step caught policy misses, weird tone, and missing fields before anything went out.
If you’re building support automations in n8n, Make, Zapier, OpenClaw, or a custom agent stack, this pattern is worth stealing.
The failure mode was subtle, which made it expensive
My support bot was not failing in dramatic ways.
It was failing in the annoying ways:
- technically correct, but rude
- confident when it should have asked for more info
- compliant on one rule, sloppy on another
- missing account IDs or order numbers, then replying anyway
One draft in particular made the problem obvious.
It answered the customer correctly.
It referenced the right order.
It also sounded like a parking ticket.
So I did the obvious thing first: I made the prompt longer.
Then longer again.
I added bullets for tone, refunds, escalation, missing fields, sensitive data, identity checks. Eventually the prompt looked like six internal docs glued together.
The bot still found new ways to be weird.
That was the clue.
I did not have a model problem.
I had a workflow problem.
One prompt was doing four jobs badly
I was asking one GPT call to do all of this at once:
- classify the ticket
- draft the reply
- check policy compliance
- verify completeness and tone
That sounds efficient.
It is not.
When the output is bad, debugging is miserable.
Did classification drift?
Did the draft overreach?
Did it skip a required field?
Did it follow policy but sound hostile?
Everything is hidden inside one blob.
That is why the reviewer step helped so much. It separated responsibilities.
The workflow that actually worked
I switched to a simple pipeline:
- Classifier agent decides what kind of ticket this is
- Draft agent writes the reply
- Reviewer agent checks policy, tone, and missing info
- Fallback routes uncertain cases to a human
This is the same general pattern you see in LangChain supervisor-style workflows and in practical automation tools like n8n.
If one agent writes and approves its own outbound message, it is grading its own homework.
That is not quality control.
That is optimism.
The reviewer prompt was intentionally narrow
The reviewer was not a second writer.
It was a fussy editor.
Its job was:
- approve
- reject with reasons
- rewrite minimally
- escalate if confidence is low
That’s it.
The reviewer checked three things:
- Policy: did the draft promise something support cannot promise?
- Tone: is it calm, helpful, and non-defensive?
- Completeness: did it ask for the missing order number, account email, or screenshot before pretending the issue was solved?
That one extra step improved reliability more than all my giant-prompt experiments.
Why a bigger prompt didn’t fix it
Because chain prompting beats prompt hoarding.
Once a prompt tries to classify, draft, enforce policy, check completeness, and sound empathetic, instructions start competing with each other.
Every edge case makes the prompt harder to reason about.
Every failure gets harder to trace.
Breaking the work into stages made the system legible.
When something failed, I knew where to look.
That sounds boring until you’ve spent half a day figuring out why a bot apologized for a billing issue before verifying identity.
Use deterministic checks for hard rules
My strong opinion: if a rule is explicit, don’t spend a model call on it.
Use deterministic validation for yes/no checks:
- required fields exist
- email format is valid
- order ID matches expected pattern
- sensitive strings are blocked or redacted
- refund promises are disallowed for specific ticket classes
For example:
import re
def validate_ticket_context(ticket):
errors = []
if ticket["type"] == "order_status" and not ticket.get("order_id"):
errors.append("Missing order_id")
if ticket.get("email") and not re.match(r"^[^@]+@[^@]+\.[^@]+$", ticket["email"]):
errors.append("Invalid email format")
return errors
And if you’re using LangChain middleware for PII handling, keep that logic out of the model prompt entirely.
from langchain.agents import create_agent
from langchain.agents.middleware import PIIMiddleware
agent = create_agent(
model="gpt-5.5",
tools=[customer_service_tool, email_tool],
middleware=[
PIIMiddleware("email", strategy="redact", apply_to_input=True),
PIIMiddleware("credit_card", strategy="mask", apply_to_input=True),
PIIMiddleware("api_key", detector=r"sk-[a-zA-Z0-9]{32}", strategy="block", apply_to_input=True),
],
)
That kind of guardrail is not glamorous.
It is also how you avoid the dumbest possible production mistakes.
Use a model reviewer for judgment calls
Some checks are fuzzy.
Examples:
- “This is technically compliant but sounds passive-aggressive”
- “This should be escalated even though the customer did not explicitly ask”
- “This answer is too confident given the missing context”
That is where the reviewer agent earns its keep.
Here’s a simple reviewer prompt shape:
You are reviewing a support reply before it is sent.
Return one of:
- APPROVE
- REJECT
- REWRITE
- ESCALATE
Check for:
1. Policy violations
2. Missing required information
3. Tone problems
4. Overpromising or unsupported claims
If REWRITE, make the smallest possible fix.
If ESCALATE, explain why briefly.
Keep it narrow.
Don’t ask the reviewer to be clever.
Ask it to be strict.
Minimal pipeline example
This is roughly the shape I’d use in a custom Python service:
def handle_ticket(ticket):
validation_errors = validate_ticket_context(ticket)
if validation_errors:
return {
"action": "escalate",
"reason": validation_errors,
}
classification = classify_ticket(ticket)
draft = draft_reply(ticket, classification)
review = review_reply(ticket, classification, draft)
if review["action"] == "approve":
return {"action": "send", "reply": draft}
if review["action"] == "rewrite":
return {"action": "send", "reply": review["reply"]}
return {
"action": "escalate",
"reason": review.get("reason", "review_failed"),
}
Nothing fancy.
Just separation of concerns.
This fits n8n better than people think
A lot of people hear “reviewer agent” and assume they need a full orchestration stack and a month of yak shaving.
You usually don’t.
This pattern maps nicely to n8n:
- Zendesk, Intercom, or Gmail trigger
- classifier node
- draft node
- reviewer node
- if/else branch for approve vs escalate
- human fallback node
Same idea in Make or Zapier.
Same idea in OpenClaw.
Same idea in a custom worker.
The architecture matters more than the tool.
The real cost of doing this right
Here’s the uncomfortable part:
guardrails cost money.
Every reviewer step is another model call.
Every retry is another model call.
Every escalation check is another model call.
As soon as your agent gets more responsible, your workflow starts looking less like “one chatbot” and more like a small assembly line.
That is exactly where per-token pricing starts getting painful.
A support bot that only drafts replies is one thing.
A support workflow that classifies, drafts, reviews, redacts, and occasionally escalates is another.
And this creates a dumb incentive: teams start removing reviewer steps because they are expensive, not because they are unnecessary.
I think that is backward.
If a bad reply can trigger refunds, compliance issues, angry screenshots in Slack, or manager escalations, the review step is worth keeping.
This is one reason flat-rate API access is so useful for agent workflows.
When you’re paying per token, every extra safety layer feels like a tax.
When you’re using something like Standard Compute as a drop-in OpenAI-compatible API, you can afford to be more aggressive about multi-step workflows because cost is predictable instead of turning into a surprise bill.
That matters a lot for 24/7 automations.
Especially in n8n, Make, Zapier, or custom agent systems where one “task” can quietly become 4 or 5 model calls.
The stack I’d use if I rebuilt this tomorrow
I would start with clean stages and tracing, not the fanciest model.
Install LangChain:
pip install langchain
Turn on tracing early:
export LANGSMITH_TRACING="true"
export LANGSMITH_API_KEY="..."
Then structure the pipeline like this:
Stage 1: classify
Use GPT-5, Claude, or another reliable model to identify:
- ticket type
- urgency
- required fields
- whether identity verification is needed
Stage 2: draft
Generate the reply using:
- ticket class
- customer context
- relevant policy snippets
Stage 3: review
Run a reviewer prompt that checks:
- policy violations
- tone problems
- missing information
- escalation need
Stage 4: deterministic guardrails
Run regex and structured validation for:
- PII
- IDs
- required fields
- blocked promises or phrases
Stage 5: human fallback
If confidence is low or a hard rule fails, route to a human.
That setup is simple, debuggable, and much safer than one giant prompt.
When is the reviewer step worth it?
My rule is simple:
if a bad reply can cause real damage, review it.
Here’s the tradeoff:
| Approach | What actually happens |
|---|---|
| Single smart prompt | Lower latency, but policy, tone, and completeness failures are tangled together and harder to debug |
| Draft agent + lightweight reviewer agent | Better separation of concerns, easier to enforce quality, slightly more latency |
| Draft agent + deterministic guardrails + human fallback | Strong explicit validation, lower model usage than full semantic review, best when rules are clear |
For harmless FAQ answers with strong structured input, I’m fine keeping it lean.
For anything involving refunds, account access, billing, compliance, or identity checks, it gets reviewed.
The part that surprised me most
I expected the reviewer to catch policy issues.
What surprised me was how often it caught missing context.
Not because the draft agent was dumb.
Because once a model starts answering, it wants to keep answering.
The reviewer was much better at saying:
- we never got the order number
- identity was not verified
- this should be escalated before replying
That was the real win.
Not smarter prose.
Better brakes.
Takeaway
If your support agent is getting weird, the fix may not be a smarter prompt.
It may be a cleaner division of labor.
- classifier decides what it is
- drafter writes the reply
- reviewer decides whether that reply deserves to exist
That is not overengineering.
For outbound support automation, that is just grown-up design.
And if you’re building multi-step agent workflows, be honest about the economics too. More reliable automations usually mean more model calls. If you’re running them on per-token billing, quality control gets expensive fast. If you’re using a flat-rate OpenAI-compatible API like Standard Compute, adding review layers is a much easier decision.
Top comments (0)