One Customer, Five Tickets: Why Your Scheduled Agent Starts a New Ticket on Every Reply
A customer writes in about a delayed order. Your scheduled agent picks up the message, drafts a reply, and asks for the tracking number. The customer answers with the tracking number. The next run reads that answer and opens a brand new ticket. By the end of the week, one delayed order has become five tickets. Each one holds a fragment of the same conversation, with its own number and its own agent working it. The customer gets replies that contradict each other, and nobody on your team can say
A customer writes in about a delayed order. Your scheduled agent picks up the message, drafts a reply, and asks for the tracking number. The customer answers with the tracking number. The next run reads that answer and opens a brand new ticket.
By the end of the week, one delayed order has become five tickets. Each one holds a fragment of the same conversation, with its own number and its own agent working it. The customer gets replies that contradict each other, and nobody on your team can say which ticket is the real one. The agent is not malfunctioning. It is doing exactly what it was built to do, with no memory of the conversation it is already in.
A reply is not a new problem
Support work is a thread, not a pile of messages. A thread has a beginning, a middle, and a resolution. It has an owner, promises made along the way, and a history of what was already tried. When a customer replies, they are continuing that thread.
A scheduled agent that wakes up fresh every run has no thread. It has an inbox and a set of instructions. It reads a message, classifies it, and acts. If its instructions say "open a ticket for each new customer message," it will do that faithfully, even when the message is the third reply in an open conversation. The agent cannot continue a thread it cannot see.
This is different from reopening a closed ticket. Here, the old ticket is still open. The agent simply cannot find it, so it creates a second one, then a third, while the original sits untouched.
Why the agent cannot find the open ticket
Four gaps combine to produce this failure, and most scheduled setups have all four.
The first is the blank start. Every scheduled run begins as a new session. Nothing from the previous run carries over unless it was written somewhere the next run reads. The agent that asked for the tracking number yesterday is, as far as today is concerned, a stranger.
The second is matching by surface, not by meaning. When the agent does look for an existing ticket, it usually matches on something brittle: an exact subject line, a ticket number in the message, or the sender address. Customers break all three without trying.
The third is channel blindness. The email thread, the chat transcript, and the web form live in different places, and the agent checks only one of them per run. A customer who emails on Monday and chats on Tuesday looks like two customers with two problems. The agent never gets the chance to connect them, because no single record ties the channels together.
The fourth is the missing rule. Nothing in the agent's instructions says "before you create a ticket, check for an open thread for this customer and this issue." Creation is the default action, and an agent with no thread record to check against cannot check even if it wants to.
What fragmentation costs
The cost shows up first in the queue. Five tickets for one problem means five entries competing for attention. Two agents can pick up two fragments and answer the same customer differently, one promising a refund and the other asking for more information.
The cost shows up next in the reporting. Ticket counts inflate, so the team looks busier than it is. Worse, the fragments close independently. An agent closes one fragment after the customer stops replying to it, and the dashboard records a resolution, while the customer's actual problem is still open in the other tickets. Volume metrics built on fragments measure activity, not outcomes.
The deepest cost is trust. Every new ticket number tells the customer that nobody read their last message. People notice that quickly, and they adapt by repeating their whole story in every message, which makes each fragment longer and harder to merge.
The fix: a thread record every run reads first
A resumable support agent follows a simple order of operations, and the order matters more than any single tool.
First, before creating anything, the agent looks up the customer and the issue: the customer plus the order, booking, or account they are writing about, not the exact subject line or channel. If an open thread exists for that pair, the message belongs to it.
Second, the agent appends to that thread instead of creating a ticket. Appending means the new message, the agent's reply, and any promises made all land in the same record the next run will read. The thread becomes the single place where the conversation lives, no matter how many channels the customer uses.
Third, the agent writes its working notes into the same record: what it asked, what the customer answered, what is still outstanding, and who owns the next step. A thread that only holds raw messages helps, but a thread that also holds the state of the work is what stops the next run from asking the same question again.
Fourth, the agent closes the loop properly. When the issue is resolved and the customer confirms it, the thread is marked resolved, and later messages about the same issue start a linked follow-up rather than merging into a dead thread or spawning an unlinked copy.
None of this requires a smarter model. It requires a memory that outlives a single run and a rule that says "check first, create second."
Where a shared memory layer fits
This is the job a shared memory layer is built for. Vilix AI is cloud-hosted, so there is no infrastructure to run and nothing to install. The same memory is available to every agent over MCP, which means the triage agent, the reply agent, and the escalation agent all read the same thread record instead of each keeping a private version. It stores full conversation history, not just extracted facts, so the next run can see what was actually said and promised, in context.
It is free forever, with a 7-day Pro trial that needs no credit card, and you can export or delete your data at any time. The point is that the thread stops living inside one run's short-term context and starts living in a place every run can reach. Once the thread has a durable home, "check first, create second" becomes a rule the agent can actually follow.
A test you can run this week
Reply to one of your own open tickets as a customer would, from a different address or a different channel, and watch what the agent does. If it appends to the open thread, your setup already has the thread record it needs. If it opens a fresh ticket, you have found the gap, and it is a memory gap, not a prompt gap.
Your customers are not opening five tickets. Your agent is opening five tickets for one customer. Give every run the same thread, and the replies will finally land in the conversation they belong to.