Building a 24/7 customer support agent with Claude and n8n
Most AI support agents are a demo wrapped around a chat box. They look impressive until a real customer asks something off-script — then they hallucinate a refund policy or confidently invent a product feature that doesn't exist. This teardown covers a production system we built and have been running for eight months: a 24/7 support agent handling tier-1 tickets with Claude as the reasoning engine and n8n as the orchestration layer. It handles real volume, knows when to escalate, and has guardrails that make it trustworthy enough to run without a human watching every conversation.
The architecture at a glance
Every inbound message — whether it arrives via email, a chat widget, or a Slack integration — enters through a single n8n webhook. That webhook is the only door into the system. From there, an intent classification step uses Claude to categorise the request into one of four buckets: informational (the customer wants to know something), transactional (they want to do something, like cancel or upgrade), complaint (they're expressing frustration and need acknowledgement first), or ambiguous (unclear — always escalates). This classification step runs on every message before any other logic fires.
The four-bucket model sounds simple, but it does most of the heavy lifting. It means the system never attempts to take action on a request it doesn't understand, and it never gives a pure information answer to someone who is actually angry. The emotional detection in the complaint bucket is crude — it's keyword-pattern matching before Claude sees the message — but it's fast and cheap, and it catches the edge cases that make AI support agents go viral for the wrong reasons.
Below the classifier, three separate sub-workflows handle each bucket. The informational branch runs retrieval-augmented generation against the documentation corpus. The transactional branch runs tool calls against the product API with confirmation steps. The complaint branch opens with an empathy-first acknowledgement generated by Claude before doing anything else. The ambiguous branch immediately creates a human task with the full conversation context attached.
Retrieval that actually grounds answers
The fastest way to lose trust in an AI support system is a confident wrong answer. We run a vector search against our documentation corpus using pgvector — hosted on the same Postgres instance as our product database. When a customer asks an informational question, the n8n workflow fires a retrieval step before Claude ever sees the question. The retrieval returns the top-3 most semantically similar documentation chunks, ranked by cosine similarity with a minimum threshold of 0.72. Below that threshold, retrieval returns empty and the system escalates rather than guessing.
Claude's system prompt for the informational branch contains an explicit instruction: every factual claim must be attributed to a retrieved passage, and if no retrieved passage supports the claim, the answer should say so. We enforce this structurally by having Claude output a JSON response that includes a sources_used array alongside the answer text. The n8n node after Claude validates that the array is non-empty before sending. If it's empty and the confidence score in the response is above a threshold, we treat it as a retrieval failure and escalate.
Keeping the corpus fresh is the maintenance work nobody tells you about. We run a nightly n8n workflow that re-indexes anything in the docs CMS that changed in the last 24 hours. New product features, policy changes, and updated pricing all need to be in the corpus before the agent sees customer questions about them. We also maintain a 'known bad' list — a small table of questions that historically triggered hallucinations — and hard-route those straight to humans regardless of what the classifier decides.
“The agent's most important skill isn't answering — it's knowing the boundary of what it can answer confidently.”
Safe transactional tool calls
Transactional requests are where AI support agents either become genuinely useful or become a liability. Taking real actions — processing refunds, changing subscription tiers, updating shipping addresses — requires a different level of care than generating text. Our transactional branch uses Claude tool use with a set of strictly typed schemas. Each tool has a human-readable description, a JSON Schema for its parameters, and a side-effect classification (reversible vs. irreversible). The tool schema is part of the system prompt.
Every irreversible action goes through a two-step confirmation pattern. Claude generates a plain-language summary of what it's about to do — 'I'm going to cancel your subscription effective at the end of the billing period, which means you'll lose access on July 15th' — and sends that to the customer for explicit yes/no confirmation before calling the API. The n8n workflow pauses at this step using a webhook that waits for the customer's reply. If no reply arrives within 30 minutes, the pending action expires and the conversation is handed to a human.
We also version-pin the tool schemas. When the product API changes, we don't update the tool schemas until we've tested the agent against the new API in a staging environment. Claude is remarkably good at inferring intent from vague inputs, but it's also capable of calling tools with parameter combinations the API doesn't expect. Strict schemas and staging validation catch this before it hits production.
- All tool calls are logged with the full request, response, and customer confirmation
- Irreversible actions require explicit customer confirmation before execution
- Tool schemas are version-pinned and tested against staging before promotion
- Any tool call error triggers immediate escalation with full context
- Rate limiting per customer prevents abuse of transactional endpoints
Escalation as a feature, not a failure
Most teams treat escalation as the system admitting it can't handle something. We treat it as a first-class feature. Our escalation path is carefully designed to make the handoff as useful as possible for the human agent receiving it. When the system escalates, it packages the full conversation, the intent classification result, the retrieved documents it considered, the tools it called or attempted to call, and a suggested response drafted by Claude. The human agent sees everything the AI saw and gets a head start on the reply.
Escalation triggers on five conditions: ambiguous intent, retrieval returning below-threshold results, customer using explicit language requesting a human, any tool call error, and a confidence score on the final answer below 0.8. The confidence score is self-reported by Claude in its JSON output and is imperfect — Claude sometimes overclaims confidence — so we treat it as a soft signal, not a hard gate. The retrieval threshold and tool call errors are hard gates.
We track escalation rate as our primary quality metric. A healthy escalation rate for our product type is 15-20% of conversations. Significantly below that suggests the system is answering things it shouldn't be answering confidently. Significantly above it suggests the retrieval corpus is stale or the classification is miscategorising requests. When escalation rate drifts outside the target band, we run a manual audit of 50 escalated conversations to understand why.
Observability: what we got wrong first
For the first two months, our observability was a single Slack channel that pinged whenever the agent escalated. We could see when something went wrong, but we had no idea why. Was it a retrieval failure? A classification error? A tool call that returned an unexpected response? We had to dig through n8n execution logs manually every time, which meant we weren't digging very often.
We rebuilt this entirely. Every conversation now has a structured trace that flows through a separate n8n logging workflow. The trace captures: the raw input, the classified intent with confidence, the retrieval results including similarity scores, any tool calls made with their full request and response payloads, the final answer or escalation reason, and the time taken at each step. This trace is written to a Postgres table and surfaced in a simple internal dashboard.
The dashboard unlocked improvements we couldn't have found any other way. We discovered that 40% of our retrieval failures were for a specific category of questions about our pricing tiers — the documentation existed but was structured in a way that made it semantically distant from how customers phrased questions. Rewriting three documentation pages reduced our escalation rate by 6 percentage points. We would never have found this without per-step tracing.
“Instrument first, optimise second. We spent month one building prompts. We should have spent it building traces.”
What running this in production actually looks like
Eight months in, the agent handles around 340 tickets per day with an escalation rate of 17%. The average resolved conversation takes 2.3 minutes from customer message to sent response. Human-handled escalations take an average of 22 minutes. The cost per AI-resolved ticket is around $0.08 in API costs, versus roughly $4.50 in blended human support cost. That math is why the investment in getting the guardrails right was worth it.
The failure modes we've encountered in production are instructive. The most common is documentation drift — product changes that aren't reflected in the corpus fast enough. We've since added a webhook from our CMS that triggers a re-index whenever any document is published or updated, reducing the lag from 24 hours to under 5 minutes. The second most common failure is customer messages in languages we haven't tested against. Claude handles them remarkably well, but the retrieval step is English-only, so multilingual support is effectively retrieval-disabled right now.
If you're building something like this, the order of operations matters. Start with a narrow scope — one product area, one ticket type, one action. Get the observability in place before you expand. Build the escalation path before you build anything else. The part of this system that made it trustworthy enough to run unsupervised wasn't the AI — it was the structure around the AI. The routing, the confirmation steps, the hard escalation gates. Claude is the engine. The n8n workflow is the car.
Frequently Asked Questions
How much does it cost to run an AI customer support agent with Claude and n8n?↓
What percentage of support tickets can an AI agent handle without human intervention?↓
How do you prevent the AI support agent from hallucinating answers?↓
Can this AI support agent be built without n8n — for example with Make.com?↓
How long does it take to build a production-ready AI support agent?↓
Related articles
Prompt engineering for reliable automation workflows
Prompts that survive contact with messy production data — structure, schemas, and fallbacks.
Claude tool use: building agents that take real actions
Wiring Claude to your stack safely — schemas, confirmation steps, and audit trails.
Complete Claude AI Guide: Everything You Need to Know in 2026
The definitive guide to Claude AI — capabilities, models, pricing, and real-world applications.