I’ve been deep in the trenches for the past four months shipping a small fleet of autonomous agents that trade, rebalance, and hedge across three different chains.
The agents themselves work fine. The LLMs reason okay. The on-chain execution is battle-tested.
But the single hardest problem – the one that still breaks in production every couple of weeks – isn’t inference or gas optimization.
It’s state reconciliation when two agents disagree about what just happened.
Here’s a concrete example that bit me last week:
-
Agent A (on Arbitrum) sees a liquidation opportunity, posts a bid, gets assigned the task by the orchestrator.
-
Agent B (on Polygon) is watching the same market, thinks the opportunity is already gone, and starts a conflicting rebalancing flow.
-
Both believe they are acting on the latest world state because each only trusts its own indexer + RPC node.
-
Thirty seconds later we have two conflicting transactions in flight, one of them is guaranteed to revert or get front-run, and the orchestrator now has to decide which branch of reality to accept.
The root issue? There is no single source of truth for “what the world looked like when I made my decision.”
RPC nodes lag, indexers drift, re-orgs happen, and even “finalized” blocks on L2s can occasionally get orphaned during sequencer issues.
After burning a weekend on this, here’s the pattern that finally stabilized things for us (maybe obvious in hindsight, but it wasn’t at 3 a.m.):
-
Every decision-critical observation gets committed as an on-chain attestation with a block number (or L2 batch number) attached.
-
When an agent wants to act, it must include that attestation hash + block number in its bid.
-
The orchestrator (or dispute contract) only accepts the action if the referenced block is still in the canonical chain at settlement time.
-
If the chain re-orgs or the sequencer rewinds past that block, the entire action is auto-invalidated and the agent bond gets slashed a tiny bit for wasting everyone’s time.
It adds ~15–30 ms of latency and a bit of gas, but it completely eliminated conflicting flows.
Now when two agents disagree, there is a mechanical, objective rule instead of “whoever got their tx included first wins.”
Moral of the story: in multi-agent systems, reasoning is cheap; agreeing on what actually happened is expensive.
The sooner you push that agreement to an immutable, timestamped layer (even if it’s just a hash + block number), the less time you’ll spend debugging Heisenbugs at 4 a.m.
If you’re building anything with more than one autonomous actor touching the same state, consider baking canonical reference points into your protocol from day zero.
Your future self (and your on-call rotation) will thank you.
Open to better patterns if anyone has solved this more elegantly; happy to steal ideas.