Urgent.News

What's breaking now, across thousands of outlets.

AI

Why Your AI Agent Produces Duplicates (It’s a Modeling Error, Not a Logic Error)

Most duplicate-dispatch bugs in AI agents aren’t caused by missing retry guards or broken idempotency keys. They’re caused by collapsing two independent questions into one state field. The question “did we get evidence of dispatch?” and the question “does that evidence satisfy the intended outcome?” are not the same question. When you force both into a single SUCCESS / FAILED enum, you lose the…

Duplicate-dispatch bugs in AI agents stem from a modeling error, not a logic error. The problem arises when two independent questions are collapsed into a single state field. The question "did we get evidence of dispatch?" and the question "does that evidence satisfy the intended outcome?" are not the same. When forced into a single SUCCESS/FAILED enum, the information needed to determine the next steps is lost, leading to duplicate dispatches.

To prevent duplicates, StareBrain uses a Two-Axis Model. Every action that produces an observable artifact tracks two independent states: DeliveryState and AcceptanceState. DeliveryState represents whether the artifact has been confirmed by the provider (PENDING, CONFIRMED, or FAILED), while AcceptanceState represents whether the artifact matches the intended outcome (PENDING, ACCEPTED, or REJECTED). The combined status is derived, never stored directly.

A Structural Invariant ensures this approach is safe. The tryAccept() function only evaluates acceptance if delivery is confirmed. This prevents the acceptance state from moving out of PENDING until a provider lookup has confirmed the artifact exists. Without this separation, the system could mark a failed dispatch as succeeded and cause duplicates. For example, an agent dispatching an SMS action would result in a duplicate if the dispatch times out before confirmation arrives and the system retries the failed dispatch.

With the Two-Axis Model, a different set of rules applies. The shouldRedispatch() function determines whether to retry a dispatch based on the current states of DeliveryState and AcceptanceState. If the delivery state is PENDING, the dispatch should not be redispatched. If the delivery state is FAILED, the dispatch should be redispatched. If the acceptance state is REJECTED, the dispatch should also be redispatched. In all other cases, the dispatch should not be redispatched.

When reconciling a dispatch, the reconcile() function checks the delivery state. If it's not PENDING, the function returns the current record. If the artifact is found via provider lookup, the delivery state is set to CONFIRMED, and the acceptance state is evaluated. If the artifact is not found, the delivery state is set to FAILED. This recovery path ensures that only confirmed artifacts are considered for evaluation, preventing duplicates caused by unconfirmed dispatches.

Persisting the dispatch information in an ActionRecord class allows for querying the status of the dispatch at any point, including across retries and process restarts. The class includes fields for actionId, dispatchId, providerObjectId (null until confirmed), delivery state, acceptance state, the time of dispatch, and the times of confirmation and acceptance (which are null if not yet confirmed or accepted).

In practice, for StareBrain's SMS dispatch on Android, a new ActionRecord is created with a unique actionId, a dispatchId based on the pendingIntent creatorUid, and initial values for delivery and acceptance states set to PENDING. After the accessibility service confirms the send button tap, the providerObjectId is set to the sent message ID, delivery is set to CONFIRMED, and confirmedAt is set to the current instant.

Finally, after verifying the recipient and content match, the acceptance state is set based on the result of messageMatchesIntent(). This workflow ensures that duplicates are prevented by maintaining separate records for each dispatch attempt and accurately tracking the delivery and acceptance states.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in AI

VAI Assistant: a non-injection AI customer service tool for WeChat on Windows

VAI助手 (formerly "微信管家", https://vx.cuxn.cn/ ) is a Windows desktop app that auto-answers routine customer questions in WeChat for online sellers, WeChat merchants and private-domain customer service…

  • VAI Assistant is a Windows desktop tool for WeChat customer service.
  • Uses local RAG knowledge base from PDF/DOCX files.
  • Reads messages, types replies at system UI level, not injecting into WeChat.

More from Tuesday 13 October →