DEV Community

Manuel Bruña
Manuel Bruña

Posted on

Why I Stopped Letting One Turn Give an Agent Two Orders

Why I Stopped Letting One Turn Give an Agent Two Orders

I used to think duplicate delegation was a small prompting problem. If an agent received two instructions in one turn, surely it could infer which one mattered most. That is a comforting assumption. It is also a poor runtime rule.

While building APX, I found a more honest default: one turn gets one instruction per target agent. A second instruction to that same agent is refused unless the caller marks it as an explicit follow-up and explains whether it extends or replaces the first one.

This is not about making agents less capable. It is about making a handoff readable before it becomes expensive.

The failure looks harmless at first

Imagine a coordinator receives a request to prepare a post for next week. It delegates: "Draft it and schedule it; do not publish it." A few tool calls later, the coordinator emits another instruction to the same specialist: "Publish it now."

Both messages may look plausible in isolation. Together, they create a conflict. Which instruction wins? Did the second message deliberately correct the first? Was it generated because the model forgot that it had already delegated? Is the second action safe to perform at all?

Leaving those questions to the receiving agent makes the system harder to audit. The specialist has to guess intent from two competing messages. The owner sees a surprising result and has to reconstruct what happened from chat history. And if the task has external effects, "probably the latest message" is a terrible policy.

The deeper problem is that a turn is not a reliable plan document. A model can repeat itself, revise itself halfway through reasoning, or lose track of a tool result. I do not want those normal failure modes to silently turn into two pieces of work.

The guard is deliberately small

APX keeps a delegation guard for the duration of a turn. When an instruction is actually sent, it records the target agent and a short copy of the instruction. Before another send_to_agent or call_agent operation goes out, APX checks whether that target already received an instruction.

If it did, the second operation does not go out. The caller gets a concrete error: that agent was already delegated to earlier in this turn, plus the earlier instruction. The runtime asks for an explicit correction instead of pretending the ambiguity does not exist.

There is one escape hatch: followup: true. It is not meant as a magic override. The tool contract says the caller should use it only when the new message deliberately corrects or extends the earlier one, and should say that in the text.

That distinction matters. A true follow-up is useful: "Keep the draft private; replace the target date with Friday." A second unmarked command is often just drift. Those two cases should not receive identical treatment.

Why refusal beats clever reconciliation

I considered letting APX merge the instructions. It could prefer the latest command, compare verbs, or ask the receiving agent to summarize a final plan before acting. Each option sounds helpful until it crosses a real boundary.

A latest-message rule rewards accidental reversals. Automated merging needs semantics the runtime cannot reliably know. Sending both messages to the specialist merely relocates ambiguity to another model. Asking for a plan adds another turn but still leaves the original order unclear.

The guard chooses a narrower claim: APX knows that two unmarked instructions went to the same agent in the same turn. That is enough evidence to stop and ask for intent. It does not need to infer which instruction a human would have wanted.

This is a design pattern I keep returning to in APC and APX: preserve the boundary of what the system actually knows. A runtime should not manufacture certainty just because a workflow would look smoother with it.

Handoffs need a visible correction path

The follow-up flag gives a caller a way to change course without turning a safeguard into a dead end. But requiring it changes the shape of the message. A correction must be named as a correction. An extension must be named as an extension.

That small bit of friction has practical value. It makes the intent visible in the delegation thread. The receiving agent can see that a new instruction is not an unrelated second job. The owner can see that the coordinator revised a decision rather than accidentally firing two requests.

APX already treats agent-to-agent work as a readable conversation, not an invisible internal function call. A handoff records who sent work, who received it, and the thread where the answer belongs. The one-order rule fits that model: if a delegation is a conversation, contradictory messages deserve an explicit repair, not silent precedence.

This does not solve planning

The guard does not make a vague task precise. It does not prevent two different agents from receiving overlapping work. It does not decide whether a follow-up is wise. And it does not replace confirmations or permission boundaries for consequential actions.

Those are separate problems.

What it does is keep one common error from becoming invisible: the same turn accidentally telling the same agent to do two things. APX can detect that locally, cheaply, and before the second message changes the world.

I have learned to value those boring constraints. They do not make a demo more magical. They make a real workflow easier to trust when the model changes its mind halfway through a turn.

For me, that is the right default: first instruction stands. If the plan changed, say so.

Top comments (0)