Coretours Support Agent
Every new support ticket at Coretours gets a ready reply draft, written as an internal note in Zendesk. A person reads it, edits it and sends it. Nothing reaches a customer without a human.
Coretours is a Swedish company that sells bus trips to festivals such as Defqon.1. This agent has no chat window: a schedule wakes it, and it works in the background on Coretours' own Cloudflare account. This page shows how it works and contains no customer data.
The problem
Customers ask the same things every day: pick-up points, passports, tents, changes, refunds. The right answer depends on the trip, the year and the customer's own booking, and a confident wrong answer is worse than no answer.
How one ticket runs
Every 5 minutes a Cron Trigger searches Zendesk and starts one Workflow per ticket and change. Each step is retried on its own.
- Fetch the whole thread from Zendesk.
- Learn from the human: decisions written as notes, and differences between earlier drafts and the replies actually sent.
- Stop unless the customer wrote last.
- Assess with Clef (Workers AI): sender, topic, trip, and is this trying to fool the AI?
- Gather facts: AI Search over coretours.se (trips, FAQ, terms), the customer's own booking, and the customer's earlier tickets.
- Write the draft (DeepSeek V4.1 Flash on Workers AI, through AI Gateway), with a confidence level and questions for the human.
- Check it: a second pass lists every fact without a source; if it finds one, the draft is rewritten and the fact becomes a question.
- Save the draft as an internal note with tags, so a Zendesk view shows what needs attention.
- Remember the ticket in the customer's own memory.
Where a person stays in charge
Every reply is a draft
The agent never sends. It writes an internal note; a person sends from Zendesk.
Honest confidence
Each draft says can answer, partly or cannot answer. When no source covers the main question there is no customer reply at all, only questions for the human.
Learning needs approval
Decisions the agent proposes from the human's sent replies wait in the run viewer until they are approved, edited or rejected.
Booking data stays scoped
The code, not the model, calls the booking tools in a fixed order, only for the ticket's own requester.
Securing what it ships
- Prompt injection: when Clef rates a ticket as an attempt to fool the AI (50 % or more), the agent writes "read this yourself" and makes no draft.
- Advertising and unsure senders get their own routes, also without a draft.
- A customer's private comment is always treated as customer text, never as a staff note.
- The run viewer is behind Cloudflare Access.
- Customer memory lives in the EU and is deleted 18 months after the customer's last ticket.
The Cloudflare pieces
| Hackathon step | In this agent |
|---|---|
| Agent and model | Workers AI: Clef for the assessment, DeepSeek V4.1 Flash for the draft, every call through AI Gateway |
| Tools | Zendesk, AI Search over the public site, and a signed booking lookup |
| State and memory | A Durable Object per customer with its own SQLite and an alarm for deletion; D1 for runs and decisions |
| Primitive | Cron Trigger plus Workflows: one durable job per ticket, step by step |
| Human approval | Drafts as internal notes; learned decisions wait for approval |
| Secure it | Clef prompt-injection route, fact check, Cloudflare Access |
| Observe it | A run viewer per ticket and Workers traces with custom spans |
Does it help?
An evaluation on 43 earlier tickets (37 judged by Claude Opus 5.5 against the replies actually sent) went from 38 % to 57 % usable drafts after one round of fixes. The largest remaining gap is knowledge only the team has, which is why the agent now learns decisions from the team, with approval.
Next
- Move the approval into the Workflow (
waitForEvent), so a reply can be approved from a phone and sent by the agent. - A promise watch: the customer's alarm flags a promise in a sent reply that was never kept.
- One run at a time per customer, and booking lookups for more festivals.