Multi-Agent Collaboration in Chat: An Engineering Guide
Embedding preferred coding agents into everyday chat is not simply a matter of adding a bot. It requires a reliable layer between messaging platforms and agent runtimes to manage sessions, identities, permissions, context, routing, delivery, and auditing. This guide presents a practical architecture for multi-agent collaboration in direct and group chats, including protocol design, private-network connectivity, agent handoffs, access control, reliability, security, and a staged rollout plan.
Using a preferred programming agent reliably in everyday chat may look like a matter of “adding a bot.” In practice, it means filling the gaps between an instant messaging system and an agent runtime: session management, identity, authorization, and context.
A simple point-to-point relay quickly leads to duplicate replies, mismatched context, scattered credentials, and unauthorized actions in group chats. The following sections describe a practical collaboration design from an engineering perspective.
The Real Problems to Solve
A large amount of development and business collaboration takes place in direct and group chats: error reports, requirement clarification, review feedback, and release approvals. If agents are available only in separate terminals, users must manually move context between systems, and results are difficult to return to the original conversation.
A unified integration should achieve four goals.
First, it should be channel-independent. The same agent capabilities should work across multiple enterprise messaging channels instead of requiring business logic to be rewritten for each platform.
Second, agents should be replaceable. Different tasks can be assigned to different runtimes, such as code modification, design review, or document summarization. Callers should interact with a consistent message and tool interface.
Third, multiple people and agents should be able to collaborate. A group chat may contain several agents that hand work from one role to another instead of competing to overwrite the same reply.
Fourth, the system must be governable. It should be possible to configure and audit who can trigger an agent, which repositories or knowledge sources it can access, and whether tool calls are recorded.
Layered Architecture
A practical design separates the system into five layers. Each layer should exchange normalized messages so that channel-specific details do not leak into agent implementations.
Channel Adapter Layer
The channel adapter receives and sends messages and handles mentions, quotes, files, and cards. It normalizes platform-specific events into a common structure containing:
- Sender identity
- Conversation identifier
- Message identifier
- Visibility scope
- Attachment summary
Agents should not depend directly on the callback format of a particular messaging product.
Session and Routing Layer
This layer maintains the mapping between chat sessions and agent threads. In a direct chat, one user will typically map to one thread. In a group chat, the system must distinguish between a shared thread and branches created for individual topics.
Routing rules may be based on explicit commands, mentions, or task-type policies. However, the rules must be explainable and must prevent two agents from responding to the same request at the same time.
Agent Runtime Layer
The runtime consumes standardized tasks containing:
- User intent
- Authorized context
- Allowed tools
- Output constraints
The runtime may be a local process, a container, or a hosted inference service. Replacing a model or programming assistant should not require changes to channel code.
Tools and Permissions Layer
This layer exposes capabilities such as repository access, search, ticket management, and release operations as scoped tools.
Access should be denied by default. Permissions should be granted with the smallest practical scope for each agent, group, and user.
Observability and Audit Layer
The system should record inbound message summaries, routing decisions, model calls, tool parameters and results, and outbound message identifiers.
Logs should not contain plaintext secrets or complete sensitive source code. They should retain enough correlation identifiers to support tracing without exposing unnecessary data.
The following pseudocode illustrates the inbound control flow. It is intentionally generic and does not correspond to any specific product interface:
on_inbound(event):identity = map_user(event.sender, event.tenant)policy = authorize(identity, event.conversation, event.mentions)if not policy.allow:return reply_denied(event, policy.reason)thread = resolve_thread(event.conversation, event.topic)task = build_task(thread, event, policy.tools)result = runtime.execute(task)deliver(event.conversation, result, reply_to=event.message_id)audit(event.id, thread.id, result.trace_id)
Why Start with a Unified Protocol Instead of Point-to-Point Integrations?
Every new chat channel introduces work for authentication, retries, message deduplication, rich text, and rate limiting. Every new agent introduces work for prompts, tool schemas, and streaming output. If each channel connects directly to each agent, the number of integrations grows rapidly, making failures difficult to diagnose.
A more stable approach is to define an internal event model covering:
- Inbound messages
- Outbound messages
- Tool calls
- Human takeover
- Cancellation
Channel adapters and agent adapters should implement only this shared model. Adding a new channel then requires a new channel adapter, while adding a new agent requires only a runtime adapter.
For example, a group-chat workflow such as “Agent A proposes a code change, then Agent B performs a risk review” becomes a sequence of role-specific tasks appended to the same thread. It does not require two unrelated chatbots with separate contexts.
Connecting to Internal Services Without a Public Endpoint
Many workplace environments do not allow internal services to be exposed publicly or permit arbitrary inbound ports. In such cases, a public callback should not be treated as a prerequisite. Instead, the internal system should establish an outbound connection.
Three common patterns are available.
Long-lived connection or outbound stream: The adapter connects to a message relay, which pushes events to it. After a disconnection, the adapter uses a cursor to retrieve missed events.
Polling: An internal service periodically claims pending messages. This is simple to implement but generally creates more latency and unnecessary requests, making it more suitable for low-frequency scenarios.
Hybrid delivery: Control signals use a long-lived connection, while large attachments are transferred through short-lived, authorized object-storage URLs. This prevents binary content from being pushed through the chat channel.
Regardless of the pattern, the system must support at-least-once delivery.
Inbound messages should be made idempotent using the message identifier. Outbound messages should use a combination of conversation, reply target, and content hash to prevent retries from creating duplicate replies.
Connection credentials should be stored in a secrets manager. Credential rotation should support an overlap period in which both the old and new credentials are valid, preventing a complete outage during the switch.
Multi-Agent Handoffs in Group Chats
The value of handoffs is role separation, not having several models repeat the same answer. A collaboration task should be divided into explicit stages, with defined inputs, outputs, and stop conditions for each stage.
A typical workflow may include:
- Understanding and clarification
- A solution or patch draft
- Independent review
- Execution and confirmation
The structured conclusion from one stage should be written into thread state. The next stage should read only the authorized state instead of receiving the entire conversation history without filtering. This controls context length and reduces the risk of exposing irrelevant discussions to tools.
Routing must avoid ambiguous rules such as “everyone may respond.” Practical policies include:
- An agent responds only when it is explicitly mentioned.
- One message has only one primary responder; other roles add comments through quotes or thread replies.
- Users switch the responsible role with a fixed command, such as “Review the previous proposal.”
- If two runtimes reach conflicting conclusions, the system displays the differences and supporting evidence side by side for human confirmation instead of automatically overwriting one result.
Context should be passed in a compact structured form rather than by pasting the entire conversation:
Stage: ReviewInput summary: Change scope, assumptions, unresolved questionsConstraints: Read-only; direct repository changes are not allowedOutput: Risk list, merge recommendation, required tests
Thread state should include a version number. If a user adds requirements during review, earlier conclusions should be invalidated or marked as outdated. This prevents later agents from executing based on an obsolete proposal.
Identity, Binding, and Permissions
A chat identity is not automatically the same as an identity in a code-hosting or knowledge-base system. The mapping must be explicit and should support tenant isolation.
A group may be bound to a set of agents, but that binding does not grant unlimited access to every participant. The triggering user must still be on an allowed list before an agent can use a particular tool on the user’s behalf.
Least privilege can be limited along three dimensions:
- Data scope: Which repositories, directories, or knowledge bases are visible
- Action scope: Whether the agent can read, propose a patch, create a change, or execute commands
- Conversation scope: Whether the response is visible only to the requester or to the entire group
High-risk actions should require a second confirmation. The system should record the confirmer, confirmation time, and target object in the audit trail.
Personal accounts and managed bot identities have different capabilities. Personal accounts are often less stable and may encounter platform restrictions. Production systems should prefer manageable application identities. Personal channels may be used as supplementary access paths, but they should not be treated as the sole reliability mechanism.
Reliability and Cost
Chat creates a mismatch between synchronous expectations and asynchronous systems. Users expect a response within seconds, while code analysis and tool calls may take much longer.
The system should first acknowledge receipt, then return results through streaming or segmented messages. When a task times out, it should provide a resumable task identifier instead of forcing the user to send the request again and risk concurrent execution.
Rate limits should apply at the user, group, and runtime levels. Common ways to control cost include:
- Trimming context
- Caching unchanged retrieval results
- Avoiding heavyweight tools for purely explanatory questions
- Not enabling every tool by default
At a minimum, observability should track:
- Time from inbound message to first acknowledgment
- Task success rate
- Duplicate delivery rate
- Human takeover rate
A persistently high takeover rate usually indicates unclear routing rules or permission prompts. Simply switching to a larger model will not necessarily solve the underlying problem.
Security Boundaries
Once agents are connected to chat, the attack surface expands to everyone who can send a message. Prompt injection may be hidden in quoted messages, web summaries, or repository files and may attempt to make an agent disclose secrets or execute unrelated tools.
Mitigations include:
- Separating tool parameters from raw user text
- Keeping sensitive tools disabled by default
- Applying policy checks to outbound content
- Preventing chat text from rewriting system instructions
Attachments in logs, monitoring systems, and object storage should be sanitized. When code is transferred across networks, the system must clearly define whether that data is allowed to leave the internal environment. If it is not, both inference and tool execution should remain in an internal runtime, while the relay forwards only the minimum necessary control messages.
Rollout and Acceptance Criteria
A staged rollout is safer than connecting every channel and agent at once.
Stage one: Connect one chat channel to one read-only agent. Validate identity mapping, idempotency, and auditing.
Stage two: Add group-chat roles and handoff state. Limit the workflow to drafting and review, with no automatic production changes.
Stage three: Enable write operations only after adding confirmation, rollback, and on-call alerts.
Acceptance criteria should include:
- The same message never causes two effective executions.
- Unauthorized users cannot trigger tools.
- Conclusions before and after a handoff can be traced to the same thread.
- Reconnection does not lose cursors or create duplicate messages.
- Secrets do not appear in chat history or ordinary logs.
Once these conditions are met, the system can expand to additional channels and runtimes without losing control as usage grows.
The central challenge of bringing multi-agent systems into chat is making clear who works in which context, with what permissions, and in what order. Channels and models can be replaced. The session, routing, and audit foundation should not be tied to a particular assistant or messaging platform.
