Separating user-facing requests from the agent loop in the age of self-attending LLMs

by

Recently I have been experimenting heavily with collectives of expert agents and horizontally scaled agentic flows. One thing became apparent early on was the way of interacting with a model, through its chat, I don't think is no longer an good enough. If you missed my earlier post on this, have a look at Horizontal vs vertical agent orchestration.

In traditional agent interaction the user describes the problem, follows the agent's chain of thought, and lands on a final summary and decision point, where the user steps back in.

Cross-agent communication changes that where you are now dealing with multiple chains of thought and multiple agent loops at the same time. The classic sub-agent model solves the problem of having many surfaces pointing at the user with a ringleader: the one agent that spawns the others and manages the communication table between them. Ideally the work does not depend much on user feedback, and even where it does, the ringleader talks to the user as the single point of contact.

That model breaks on parallel, horizontally scaled agents, where each agent has expertise in a different topic and potentially access to different resources. Here you can genuinely be asked by each member about its own topic, while the agents also talk to one another and carry the question towards you inside the conversation history.

After a few days of trying to keep up with a group of agents this way, I concluded the model is not sustainable and we need a new way of interacting with a group. My answer, in my sandboxing environment at Outgate, has been to treat the user as one more member of the ring, but a member who needs more context and an easier way to make decisions.

With that in mind I introduced an approvals MCP tool to the sandboxes. Each agent can create a request for the user (and modify or withdraw it if needed), with a request body that carries the context, a form for the user to fill in, or simply a thumbs-up for a bigger decision. Agents declare a default action and an expiry for time-sensitive decisions. The user then works through the requests in one central place, ordered by the priorities the agents specified, and answers each one.

Here is what one of those requests looks like in practice. An agent researching messaging channels for a product decided it could not pick one on its own and sent this:

Everything the human needs is in the card: the question, the reasoning behind it, the options with the agent's own recommendation, and a plainly stated consequence of silence. The answer goes back as a single line the agent can act on, and the request stays in the thread history as a record of who decided what and when.

A while ago I decided to let agents, if the user agrees, set timed triggers to wake themselves up when needed. With the addition of waking up on a request response, managing a larger number of parallel agents has become genuinely straightforward.

There are of course areas that could improve. Being able to reject certain tool uses outright, and requiring the agent to always ask for approval on them, would also reduce agent ambiguity and help prevent rogue agents, of the kind seen in the Hugging Face incident OpenAI wrote about. The point is this: for self-attending agents we should not be as unreachable as the Pope. We should always give agents the ability to reach out, even in long-horizon tasks, even as a side activity while they push on their collective objectives.

I will keep posting about this development and the path forward.