--- title: Multi-Agent Systems slug: guides/agents/multi-agent --- Check out a multi-agent tutorial [here](/cookbooks/multi-agent-async)! All agents in Letta are *stateful* - so when you build a multi-agent system in Letta, each agent can run both independently and with others via cross-agent messaging tools! The choice is yours. Letta provides built-in tools for supporting cross-agent communication to build multi-agent systems. To enable multi-agent collaboration, you should create agents that have access to the [built-in cross-agent communication tools](#built-in-multi-agent-tools) - either by attaching the tools in the ADE, or via the API or Python/TypeScript SDK. Letta agents can also share state via [shared memory blocks](/guides/agents/multi-agent-shared-memory). Shared memory blocks allow agents to have shared memory (e.g. memory about an organization they are both a part of or a task they are both working on). ## Built-in Multi-Agent Tools We recommend only attaching one of `send_message_to_agent_and_wait_for_reply` or `send_message_to_agent_async`, but not both. Attaching both tools can cause the agent to become confused and use the tool less reliably. Our built-in tools for multi-agent communication can be used to create both **synchronous** and **asynchronous** communication networks between agents on your Letta server. However, because all agents in Letta are addressible via a REST API, you can also make your own custom tools that use the [API for messaging agents](/api-reference/agents/messages/create) to design your own version of agent-to-agent communication. There are three built-in tools for cross-agent communication: * `send_message_to_agent_async` for asynchronous multi-agent messaging, * `send_message_to_agent_and_wait_for_reply` for synchronous multi-agent messaging, * and `send_message_to_agents_matching_all_tags` for a "supervisor-worker" pattern ### Messaging another agent (async / no wait) ```python # The function signature for the async multi-agent messaging tool def send_message_to_agent_async( message: str, other_agent_id: str, ): -> str ``` ```mermaid sequenceDiagram autonumber Agent 1->>Agent 2: "Hi Agent 2 are you there?" Agent 2-->>Agent 1: "Your message has been delivered." Note over Agent 2: Processes message: "New message from Agent 1: ..." Agent 2->>Agent 1: "Hi Agent 1, yes I'm here!" Agent 1-->>Agent 2: "Your message has been delivered." ``` The `send_message_to_agent_async` tool allows one agent to send a message to another agent. This tool is **asynchronous**: instead of waiting for a response from the target agent, the agent will return immediately after sending the message. The message that is sent to the target agent contains a "message receipt", indicating which agent sent the message, which allows the target agent to reply to the sender (assuming they also have access to the `send_message_to_agent_async` tool). ### Messaging another agent (wait for reply) ```python # The function signature for the synchronous multi-agent messaging tool def send_message_to_agent_and_wait_for_reply( message: str, other_agent_id: str, ): -> str ``` ```mermaid sequenceDiagram autonumber Agent 1->>Agent 2: "Hi Agent 2 are you there?" Note over Agent 2: Processes message: "New message from Agent 1: ..." Agent 2->>Agent 1: "Hi Agent 1, yes I'm here!" ``` The `send_message_to_agent_and_wait_for_reply` tool also allows one agent to send a message to another agent. However, this tool is **synchronous**: the agent will wait for a response from the target agent before returning. The response of the target agent is returned in the tool output - if the target agent does not respond, the tool will return default message indicating no response was received. ### Messaging a group of agents (supervisor-worker pattern) ```python # The function signature for the group broadcast multi-agent messaging tool def send_message_to_agents_matching_all_tags( message: str, tags: List[str], ) -> List[str]: ``` ```mermaid sequenceDiagram autonumber Supervisor->>Worker 1: "Let's start the task" Supervisor->>Worker 2: "Let's start the task" Supervisor->>Worker 3: "Let's start the task" Note over Worker 1,Worker 3: All workers process their tasks Worker 1->>Supervisor: "Here's my result!" Worker 2->>Supervisor: "This is what I have" Worker 3->>Supervisor: "I didn't do anything..." ``` The `send_message_to_agents_matching_all_tags` tool allows one agent to send a message a larger group of agents in a "supervisor-worker" pattern. For example, a supervisor agent can use this tool to send a message asking all workers in a group to begin a task. This tool is also **synchronous**, so the result of the tool call will be a list of the responses from each agent in the group.