A no-code customer support agent lets you route and answer tickets without standing up a Python service. This tutorial builds one on a generic visual workflow builder that calls an OpenAI-compatible inference endpoint, so you can swap models or add fallback without writing backend code.
Prerequisites
- A no-code builder that can send HTTP requests and parse JSON (n8n, Make, Zapier, or a self-hosted alternative).
- An API key for an OpenAI-compatible LLM gateway. n4n.ai provides a single endpoint covering 240+ models with automatic fallback when a provider is degraded, which removes a class of operational headaches.
- A minimal FAQ dataset in JSON.
- A webhook-capable support front end (chat widget, email pipe, or Slack command).
If you can satisfy those, you can ship a working agent in an afternoon.
Step 1: Define the agent configuration
Keep the prompt and model selection in a config object. This isolates prompt engineering from workflow logic. Save this as agent_config.json:
{
"system_prompt": "You are a tier-1 support agent for Acme Corp. Answer only from the FAQ. If the answer is not present, reply with the single word ESCALATE.",
"models": ["openai/gpt-4o-mini", "anthropic/claude-3-haiku"],
"temperature": 0.1,
"max_tokens": 250,
"faq": [
{"q": "reset password", "a": "Go to Settings > Security > Reset Password. A link arrives within 2 minutes."},
{"q": "refund policy", "a": "Refunds within 30 days of purchase, no questions asked."}
]
}
Low temperature prevents creative drift. The ESCALATE token gives the no-code builder a deterministic branch point.
Step 2: Set up the trigger
In your builder, add a webhook trigger that accepts POST with this shape:
{
"ticket_id": "t-001",
"channel": "chat",
"message": "How do I reset my password?"
}
Validate the payload. In n8n, use an “IF” node to reject missing message. In Make, use a router with a filter. Do not skip this; malformed tickets will burn tokens.
Step 3: Call the LLM gateway
Add an HTTP node. Point it at the chat completions endpoint. The request must match the OpenAI schema exactly.
curl -s https://api.n4n.ai/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-H "Cache-Control: max-age=3600" \
-d '{
"model": "openai/gpt-4o-mini",
"messages": [
{"role": "system", "content": "You are a tier-1 support agent for Acme Corp. Answer only from the FAQ. If the answer is not present, reply with the single word ESCALATE."},
{"role": "user", "content": "How do I reset my password?"}
],
"temperature": 0.1
}'
Expected response:
{
"id": "chatcmpl-abc",
"choices": [
{
"message": {"role": "assistant", "content": "Go to Settings > Security > Reset Password. A link arrives within 2 minutes."}
}
],
"usage": {"prompt_tokens": 42, "completion_tokens": 18, "total_tokens": 60}
}
In the builder, map the webhook message into the user content. Set the Cache-Control header—gateways that forward provider cache hints will reuse prompt prefixes and cut cost on repeat FAQ hits.
Step 4: Implement fallback without code
The primary model can be rate-limited. The gateway returns 429 or 503 on degradation. Build a second HTTP node wired to the error output of the first. Use the secondary model from your config.
If your builder lacks native error branching, replicate this Python logic in a function node:
import requests
def complete(msg: str, api_key: str, models: list[str]) -> str:
for m in models:
r = requests.post(
"https://api.n4n.ai/v1/chat/completions",
headers={"Authorization": f"Bearer {api_key}"},
json={"model": m, "messages":[{"role":"user","content":msg}], "temperature":0.1},
timeout=10,
)
if r.status_code == 200:
return r.json()["choices"][0]["message"]["content"]
return "ESCALATE"
print(complete("How do I reset my password?", "sk-...", ["openai/gpt-4o-mini","anthropic/claude-3-haiku"]))
Automatic fallback at the gateway layer means you often don’t need this loop, but keeping it in the workflow makes behavior explicit.
Step 5: Parse and branch
Extract the assistant message. If it equals ESCALATE, route to a human queue. Otherwise format the response.
interface GatewayResp {
choices: { message: { content: string } }[];
}
function route(resp: GatewayResp): { status: "answered" | "escalated"; text: string } {
const text = resp.choices[0].message.content.trim();
if (text === "ESCALATE") return { status: "escalated", text: "" };
return { status: "answered", text };
}
In a no-code builder, use a string compare node. Output payload for the answered path:
{
"ticket_id": "t-001",
"response": "Go to Settings > Security > Reset Password. A link arrives within 2 minutes.",
"status": "answered"
}
Step 6: Send the reply
Add a final HTTP node that POSTs to your support channel. For a chat widget, that might be:
curl -s -X POST https://chat.acme.com/api/v1/reply \
-H "Authorization: Bearer $CHAT_TOKEN" \
-d '{"ticket_id":"t-001","message":"Go to Settings > Security > Reset Password. A link arrives within 2 minutes."}'
Test with the sample ticket. Execution log should show:
Webhook received: t-001
LLM responded: Go to Settings > Security > Reset Password.
Status: answered
Reply posted to chat
Step 7: Add a pre-classifier
Not every message needs an LLM. Add a lightweight filter before the expensive call. In a function node:
import re
def needs_human(text: str) -> bool:
return bool(re.search(r"refund", text, re.I)) and bool(re.search(r"angry|scam|lawyer", text, re.I))
print(needs_human("Your refund process is a scam")) # True
If needs_human returns True, skip to escalation. This cuts token spend on high-risk tickets where you want a person anyway.
Step 8: Observe usage
The gateway returns a usage object. Log it per ticket. In n8n, write it to a sheet or metrics endpoint:
{
"ticket_id": "t-001",
"prompt_tokens": 42,
"completion_tokens": 18,
"model": "openai/gpt-4o-mini"
}
Per-token metering lets you compute cost per resolution. Set an alert if a single ticket exceeds 2,000 total tokens—that signals a loop or a broken fallback.
Testing matrix
Run these three cases before promoting the agent:
- Known FAQ – “reset password” → answered with FAQ text.
- Unknown query – “do you sponsor visas” → ESCALATE.
- High anger – “refund now or I lawyer up” → human queue, no LLM call.
If all three behave, the no-code customer support agent is safe for shadow mode.
Why this holds up in production
A no-code customer support agent is not a demo if you respect three constraints: deterministic escalation, explicit fallback, and token accounting. The visual builder handles orchestration; the gateway handles model heterogeneity. You avoid writing a model client, a retry loop, or a cache layer.
When the FAQ changes, edit agent_config.json and redeploy the builder. When a provider goes down, the gateway reroutes. Your support team sees a steady stream of deflected tier-1 tickets and clean escalations.