#Multi-Agent Orchestration & Message Isolation

1 messages · Page 1 of 1 (latest)

primal mountain
#

Hello, I have a couple of questions about orchestrating multiple sub-agents and managing message scope.

  1. Scoped message history

We have an orchestrator with multiple sub-agents (template -> email -> workflow).
Each one runs its own loop and uses frontend actions.

The issue is they all share the same message history:

Sub-agent B can see tool interactions from sub-agent A
Sometimes the model tries to use tools from the wrong sub-agent

We currently archive messages between steps.

Question:
Is there a recommended way to give each sub-agent its own message scope, while still supporting copilotkit exit and frontend actions?

  1. Multi-agent architecture

What is the recommended pattern for this setup?

Sub-agents as sub-graphs or async functions?
Shared vs isolated message history?
Best way to chain agents (A -> B -> C) when each step may trigger frontend actions?

outer phoenixBOT
#

This solution has been AI generated

You can isolate tools and message scope per sub‑agent in CopilotKit v2. Register each frontend action/tool with an agentId and execute sub‑agents through the runtime so only their scoped tools and histories are used. For chaining, model UI interrupts as tool calls and feed toolOutputs back to continue the run.

1) Scoped message history and tool isolation

  • Scope frontend tools to a sub‑agent (v2):
import { useFrontendTool } from "@copilotkit/react-core/v2";
useFrontendTool({
  name: "performSpecializedTaskA",
  description: "Only Sub‑Agent A",
  agentId: "sub-agent-a-id",
  parameters: [{ name: "data", type: "string" }],
  handler: async ({ data }) => {/* ... */},
});
  • Run the sub‑agent via CopilotKit so its scoped tools are bundled automatically:
await copilotkit.runAgent({ agent: subAgentA });
  • Keep message scope per sub‑agent:
    • Maintain separate histories/threads and stream each sub‑agent’s messages directly (supported). You can also subscribe/forward events to an orchestrator if you need a combined view.
    • In v2, you manage thread IDs yourself; pass a distinct threadId per sub‑agent when rendering/connecting so histories don’t leak.

Frontend actions remain supported: when a scoped tool is invoked, the client handles the ActionExecutionMessage and runs the handler; tools without agentId are global, tools with agentId are visible only to that agent.

2) Recommended multi‑agent architecture

  • Sub‑agents: Wrap each in an agent (e.g., ADK/AG‑UI/LangGraph) and let the orchestrator choose which to run. Avoid switching agentId dynamically inside one hook; keep separate useAgent hooks per sub‑agent.
  • History: Both shared and isolated are supported. Given your leakage issue, prefer isolated histories per sub‑agent and optionally mirror important messages into the orchestrator’s store.
#
  • Chaining A → B → C with frontend actions:
    • Model every interrupt/approval/UI step as a tool call. The backend emits a tool_call; the frontend executes it and returns the result to continue the graph.
// When you receive a tool_call from a sub‑agent
await agent.run({ toolOutputs: [{ name: call.name, content: result, /* keep call id */ }] });
  • Execute sequentially while streaming:
await copilotkit.runAgent({ agent: subAgentA });
await copilotkit.runAgent({ agent: subAgentB });
await copilotkit.runAgent({ agent: subAgentC });
  • You can subscribe to each sub‑agent’s events (agent.subscribe) so the orchestrator forwards their streamed messages to the UI in real time.

Was this helpful?

If this solution worked for you, please click on the appropriate option below to help us improve:

outer phoenixBOT
#

Thank you for your feedback! Our team will provide additional assistance. 🔄

primal mountain
#

Thanks, that makes sense.
It sounds like this pattern is for separate CopilotKit agents run independently from the frontend, not for sub-graphs inside one LangGraph agent.
In our case, we have one backend graph with internal sub-agents, so we still need backend-side message/tool isolation.
Is that correct?