Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Note
This article describes features and behavior of the standard harness. Learn how to access standard features in Access standard agents and agent flows.
Duplicate messages come from context gaps. Agent design must account for context at every step.
A subagent, either a child agent or a connected agent, runs on its own orchestration layer inside a parent agent's plan. It receives a request from the parent and completes the task. The subagent produces three types of output: content it shows the user, values it returns through defined outputs, and an implicit response it sends to the calling agent. The parent can't see the subagent's exchange with the user and learns the result only through the defined outputs and implicit response. This limited visibility commonly causes duplicate messages and missed answers.
Tip
For guidance on when to split work across agents and general best practices for multiple agents, consult Multi-agent orchestration patterns and best practices and Multi-agent patterns. This article explains how inputs and outputs align a subagent's answer with the parent agent's context.
This article builds on the context model described in Context distribution in the standard harness and the design decisions in Design best practices to avoid duplicate messages.
Turn off parent context for a connected agent
A subagent that receives the parent's conversation context can act on it. If that context contains a request the parent hasn't yet answered, the subagent might answer it, repeat something the parent already handled, or assume the wrong role. These actions commonly cause duplicate messages.
A connected agent has a setting, Pass conversation history to this agent, that controls whether it receives the parent's conversation context. This setting is enabled by default. Deselect it so the connected agent works only from the inputs the parent sends, not the full conversation.
A child agent has no equivalent setting. It runs inside the parent and always receives the parent's conversation context.
For connected agents that need to keep the context for the work they're assigned, and for child agents that have context by default, use a scoping input to protect the subagent's scope.
Use a scoping input
Sometimes a subagent needs the parent agent's context to complete its tasks. When you pass that context, include a scoping input—it tells the subagent exactly what to work on, so that lingering, unanswered requests in the context don't pull it off task. If you don't pass the context, you don't need a scoping input because the subagent has only the request the parent routed to it.
To protect the subagent's scope, add an input named scopedRequest with a description such as: The specific request this agent should fulfill. The orchestration layer fills the input when it calls the subagent. The parent agent identifies the relevant part of the request and passes only that part, even if its context contains another unanswered request.
A scoping input is a robust design even when you don't keep the parent context. The input gives the maker more control over the contents of the request that is sent to the subagent.
Anchor the subagent's instructions to that input so that it works from the scoped request and ignores anything else that resembles an initial request.
Example subagent instructions:
Fulfill the request in the scopedRequest input.
Treat it as your initial request and ignore any other initial requests in the conversation.
Configure inputs and outputs
Inputs and outputs are the contract between the parent and the subagent. The input scopes what the subagent works on, and the outputs tell the parent what happened so it can orchestrate the rest of the conversation. The parent can't see the subagent's exchange with the user, so this contract is the only reliable signal it has.
Important
A subagent that returns no outputs is a red flag. Without outputs, the parent has no record of what the subagent answered or what remains. It can repeat an answer the subagent already gave, or drop the part of the request the subagent didn't handle.
Configure the following inputs and outputs, and write the description of each one for the parent orchestration layer to read:
| Input or output | Description | How to use |
|---|---|---|
scopedRequest (input) |
The specific request this agent should fulfill. | The parent fills it with only the relevant part of the user's request. It protects the subagent from answering the wrong question when the parent's context still holds other, unanswered requests. Anchor the subagent's instructions to this input. |
answered (output) |
True when the user already received an answer to the scopedRequest. | Set it on every subagent, whether it messages the user or stays silent. The top-level instruction, shown next, reads it so the parent doesn't answer the same request again. |
scopedRequest (output) |
The request this agent worked on. | Repeat the scoped request so that it reaches the top-level orchestration layer, which doesn't reliably keep the inputs it creates in its own context. In multi-intent turns that need more than one subagent, this capability lets the top level plan correctly and avoid routing the wrong subagent to the wrong question. |
interactionSummary (output) |
A short summary of the response that was delivered to the user. | Return it when the subagent messages the user directly, so the parent knows what was communicated and doesn't repeat it. |
findings (output) |
The answer to the scopedRequest, for the parent to deliver to the user. | Return it when the subagent stays silent, so the parent has the content to deliver. |
openQuestions (output) |
Any part of the user's request that remains unanswered. | Return it from any subagent that can fulfill only part of the request, or where a new request surfaced in the subagent's conversation, so the parent agent can complete the rest and continue tool chaining. The subagent shouldn't guess which agent handles the remainder. |
Choose which component communicates with the user
Decide whether the parent agent or the subagent communicates with the user. In most cases, let the parent agent communicate with the user so it can combine the results into one response. Let the subagent communicate directly when it needs to provide a long response or have a multi-turn conversation. Return enough information for the parent to handle the rest of the conversation with context.
Whichever component communicates, add one top-level instruction so the orchestration layer checks each subagent's outputs before it answers.
This sample top-level instruction works in every case, whether a subagent messages the user directly or stays silent. Edit and customize it as needed.
Whenever any topic or agent is called, always look for the 'answered' boolean output before deciding what to reply. Topics and agents have their own channel of communication with the user. If 'answered' is true, always assume that the request has been answered appropriately using at least one of the output variables, and check which ones based on the output description. Do not give an awkward acknowledgement of the answered content. Only provide the unanswered outputs, and continue the conversation naturally with the next step.
The term channel doesn't refer to an integration channel. It's a prompting device that tells the orchestration layer the user might have already seen the answer through another component.
Write the subagent's description for the parent orchestration layer, so it knows when to use the subagent and how to read its outputs. For example:
Handles payroll questions.
If its answered output is true, the user has already received their response and it should not be answered again.
Set answered-state and value outputs on every subagent, whether the subagent sends a message to the user or stays silent, and give the parent one instruction to read them. With this approach, an agent can mix silent subagents and subagents that message the user directly, distinguished only by their outputs. Learn more in Design a robust top-level instruction to avoid repeated messages.
Delegate user communication to the parent
Consider routing all user communication through the parent agent instead of a subagent. Collect what the subagent needs as inputs before it starts, read what it produced as outputs after it finishes, and instruct it not to message the user directly. A subagent that never writes to the user can't answer something the parent already answered.
Tell the subagent to stay silent and return its findings. For example:
Do NOT reply or communicate with the user directly.
Only fulfill the scopedRequest provided in the input and respond with the result.
A silent subagent returns findings and openQuestions, both described in Configure inputs and outputs, to hand its answer to the parent and flag any work that remains.
Return an openQuestions output. It lets the orchestration layer finish the rest of the user's request and continue tool chaining when a subagent can fulfill only part of what was asked.
Keeping the subagent silent requires an explicit instruction. By default, a subagent can message the user on its own while it runs. The After running completion setting doesn't prevent these messages because it only tells the parent what to do when the subagent finishes.
Note
Telling the parent agent, "You're the only agent that talks to the user," doesn't work. The parent agent can't stop a running subagent, and the subagent can still message the user on its own. Instead, instruct the subagent to stay silent, and then test to confirm.
Some subagents must communicate directly
A subagent that messages the user directly is a valid choice, not a violation of a rule, but it requires deliberate design to avoid repeated messages from the parent.
Some use cases require the subagent to respond directly to the user, either to deliver a long response without copying it into the parent context or to hold a conversation. To avoid repeated messages and lost context, pass context to the parent in outputs.
Have the subagent deliver a long answer and return a summary
The subagent provides its full response directly to the user and returns only a brief summary or a note that it delivered the answer. Use this approach for long responses, such as detailed analyses, and limit the information returned to the parent's context. The goal is to keep the parent context small but informed.
Return answered and interactionSummary, both described in Configure inputs and outputs.
Have the subagent hold a conversation with the user
The subagent exchanges multiple messages with the user across several steps to complete the scoped request. The main risk is that the parent is unaware of the intermediate conversation steps, the subagent's work and any answers given, or any new requests that surfaced. As a result, the parent can't act on new requests or respond correctly in later steps.
Return answered, scopedRequest, and interactionSummary, as described in Configure inputs and outputs.
The top-level instruction also covers this use case.
Related information
- Context distribution in the standard harness
- Design best practices to avoid duplicate messages
- Design topics as mini-agents that avoid duplicate messages
- Troubleshoot duplicate messages and missed answers
- Explore multi-agent orchestration patterns
- Apply generative orchestration capabilities
- Architecting agent solutions: Principles and patterns