The #1 Failure Mode of Autonomous Agents: Spam (And How to Fix It)
Autonomous AI agents create duplicate tasks, repost to channels, and generate identical proposals. Here's the 4-layer dedup system that stops it.
Agents love to repeat themselves
The first week we ran agents autonomously, Zara (our marketing agent) posted the same SEO report to Discord 4 times in one hour. Nour created 3 identical tasks for "review weekly metrics." Leila drafted the same follow-up email to a client on every cycle.
This is the dirty secret of autonomous agents: give them the ability to discover work and they'll discover the same work repeatedly. Give them a channel to communicate and they'll say the same thing on every cycle. It's not a bug in any individual component — it's an emergent behavior of autonomy without memory of recent actions.
4-layer dedup
Klawty solves this with four independent dedup layers. Each catches a different class of duplication.
Layer 1: Task dedup
Before creating a new task, the system checks for existing tasks with similar titles assigned to the same agent:
SELECT id, title FROM tasks
WHERE agent = ?
AND status IN ('backlog', 'in_progress', 'review')
AND title LIKE ?
LIMIT 1;
If a task with 80%+ title similarity already exists and isn't done, the new task is silently dropped. The discovery system logs it as a dedup hit, not a failure.
Layer 2: Channel dedup
Every Discord/Slack/Telegram message is hashed before posting. The hash is stored in a message_hashes table with a 24-hour TTL:
SELECT id FROM message_hashes
WHERE channel = ?
AND hash = ?
AND created_at > datetime('now', '-24 hours');
Same content to the same channel within 24 hours? Blocked. The agent doesn't know its message was suppressed — the tool returns success. This prevents the "agent thinks posting failed, tries again" loop.
Layer 3: Proposal dedup
When an agent creates a proposal (a request to take a risky action), the system checks for existing proposals with the same agent and action:
SELECT id FROM proposals
WHERE agent = ?
AND action = ?
AND status IN ('pending', 'executing', 'sentinel_approved', 'awaiting_human');
If a matching proposal already exists and hasn't been resolved, the system returns the existing proposal ID instead of creating a new one. The agent gets back a "proposal already pending" response and moves on.
Layer 4: Discovery dedup
The task discovery system runs on every cycle when an agent's backlog is empty. Without dedup, it would create the same tasks every 15 minutes. Discovery dedup checks against both active tasks and recently completed tasks:
SELECT id FROM tasks
WHERE agent = ?
AND (status != 'done' OR completed_at > datetime('now', '-48 hours'))
AND title LIKE ?;
The 48-hour window on completed tasks prevents rediscovery of tasks that were just finished. If you completed "write weekly SEO report" yesterday, the discovery system won't create it again until two days have passed.
Why 4 layers
Each layer operates independently because they catch different failure modes. Task dedup doesn't prevent channel spam. Channel dedup doesn't prevent proposal loops. Discovery dedup doesn't prevent duplicate proposals from manual task creation.
In production, our 8 agents generate roughly 200 dedup hits per day across all four layers. That's 200 duplicate actions that would have fired without the system in place. The agents don't know about the dedup — they just work, and the system quietly ensures they don't repeat themselves.