mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-09-27 20:15:00 +02:00
[docs] LangGraph / LangGraph Platform docs updates (#4479)
Main changes made: - Add top level horizontal tabs - Reorganize the sidenav - Build out README/index page - Consolidate how-tos under each section - Remove duplicate content --------- Signed-off-by: William Fu-Hinthorn <13333726+hinthornw@users.noreply.github.com> Co-authored-by: Tat Dat Duong <david@duong.cz> Co-authored-by: Sydney Runkle <sydneymarierunkle@gmail.com> Co-authored-by: William Fu-Hinthorn <13333726+hinthornw@users.noreply.github.com> Co-authored-by: Vadym Barda <vadym@langchain.dev> Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com> Co-authored-by: ccurme <chester.curme@gmail.com> Co-authored-by: Andrew Nguonly <andrewnguonly@users.noreply.github.com> Co-authored-by: David Asamu <david.asamu@langchain.dev> Co-authored-by: infra <mukil@langchain.dev> Co-authored-by: Arjun Natarajan <arjun@langchain.dev>
This commit is contained in:
co-authored by
Tat Dat Duong
Sydney Runkle
William Fu-Hinthorn
Vadym Barda
Eugene Yurtsev
ccurme
Andrew Nguonly
David Asamu
infra
Arjun Natarajan
parent
909a4591a8
commit
3055c4b9cc
@@ -3,7 +3,7 @@ search:
|
||||
boost: 2
|
||||
---
|
||||
|
||||
# Multi-agent Systems
|
||||
# Multi-agent systems
|
||||
|
||||
An [agent](./agentic_concepts.md#agent-architectures) is _a system that uses an LLM to decide the control flow of an application_. As you develop these systems, they might grow more complex over time, making them harder to manage and scale. For example, you might run into the following problems:
|
||||
|
||||
@@ -33,7 +33,7 @@ There are several ways to connect agents in a multi-agent system:
|
||||
|
||||
### Handoffs
|
||||
|
||||
In multi-agent architectures, agents can be represented as graph nodes. Each agent node executes its step(s) and decides whether to finish execution or route to another agent, including potentially routing to itself (e.g., running in a loop). A common pattern in multi-agent interactions is handoffs, where one agent hands off control to another. Handoffs allow you to specify:
|
||||
In multi-agent architectures, agents can be represented as graph nodes. Each agent node executes its step(s) and decides whether to finish execution or route to another agent, including potentially routing to itself (e.g., running in a loop). A common pattern in multi-agent interactions is **handoffs**, where one agent *hands off* control to another. Handoffs allow you to specify:
|
||||
|
||||
- __destination__: target agent to navigate to (e.g., name of the node to go to)
|
||||
- __payload__: [information to pass to that agent](#communication-between-agents) (e.g., state update)
|
||||
@@ -82,14 +82,20 @@ def some_node_inside_alice(state):
|
||||
|
||||
#### Handoffs as tools
|
||||
|
||||
One of the most common agent types is a ReAct-style tool-calling agents. For those types of agents, a common pattern is wrapping a handoff in a tool call, e.g.:
|
||||
One of the most common agent types is a [tool-calling agent](../agents/overview.md). For those types of agents, a common pattern is wrapping a handoff in a tool call, e.g.:
|
||||
|
||||
```python
|
||||
def transfer_to_bob(state):
|
||||
from langchain_core.tools import tool
|
||||
|
||||
def transfer_to_bob():
|
||||
"""Transfer to bob."""
|
||||
return Command(
|
||||
# name of the agent (node) to go to
|
||||
goto="bob",
|
||||
# data to send to the agent
|
||||
update={"my_state_key": "my_state_value"},
|
||||
# indicate to LangGraph that we need to navigate to
|
||||
# agent node in a parent graph
|
||||
graph=Command.PARENT,
|
||||
)
|
||||
```
|
||||
@@ -342,45 +348,70 @@ builder.add_edge(START, "agent_1")
|
||||
builder.add_edge("agent_1", "agent_2")
|
||||
```
|
||||
|
||||
## Communication between agents
|
||||
## Communication and state management
|
||||
|
||||
The most important thing when building multi-agent systems is figuring out how the agents communicate. There are a few different considerations:
|
||||
The most important thing when building multi-agent systems is figuring out how the agents communicate.
|
||||
|
||||
- Do agents communicate [**via graph state or via tool calls**](#graph-state-vs-tool-calls)?
|
||||
- What if two agents have [**different state schemas**](#different-state-schemas)?
|
||||
- How to communicate over a [**shared message list**](#shared-message-list)?
|
||||
A common, generic way for agents to communicate is via a list of messages. This opens up the following questions:
|
||||
|
||||
### Graph state vs tool calls
|
||||
- Do agents communicate [**via handoffs or via tool calls**](#handoffs-vs-tool-calls)?
|
||||
- What messages are [**passed from one agent to the next**](#message-passing-between-agents)?
|
||||
- How are [**handoffs represented in the list of messages**](#representing-handoffs-in-message-history)?
|
||||
- How do you [**manage state for subagents**](#state-management-for-subagents)?
|
||||
|
||||
What is the "payload" that is being passed around between agents? In most of the architectures discussed above the agents communicate via the [graph state](./low_level.md#state). In the case of the [supervisor with tool-calling](#supervisor-tool-calling), the payloads are tool call arguments.
|
||||
Additionally, if you are dealing with more complex agents or wish to keep individual agent state separate from the multi-agent system state, you may need to use [**different state schemas**](#using-different-state-schemas).
|
||||
|
||||
### Handoffs vs tool calls
|
||||
|
||||
What is the "payload" that is being passed around between agents? In most of the architectures discussed above, the agents communicate via [handoffs](#handoffs) and pass the [graph state](./low_level.md#state) as part of the handoff payload. Specifically, agents pass around lists of messages as part of the graph state. In the case of the [supervisor with tool-calling](#supervisor-tool-calling), the payloads are tool call arguments.
|
||||
|
||||

|
||||
|
||||
#### Graph state
|
||||
### Message passing between agents
|
||||
|
||||
To communicate via graph state, individual agents need to be defined as [graph nodes](./low_level.md#nodes). These can be added as functions or as entire [subgraphs](./low_level.md#subgraphs). At each step of the graph execution, agent node receives the current state of the graph, executes the agent code and then passes the updated state to the next nodes.
|
||||
|
||||
Typically agent nodes share a single [state schema](./low_level.md#schema). However, you might want to design agent nodes with [different state schemas](#different-state-schemas).
|
||||
|
||||
### Different state schemas
|
||||
|
||||
An agent might need to have a different state schema from the rest of the agents. For example, a search agent might only need to keep track of queries and retrieved documents. There are two ways to achieve this in LangGraph:
|
||||
|
||||
- Define [subgraph](./low_level.md#subgraphs) agents with a separate state schema. If there are no shared state keys (channels) between the subgraph and the parent graph, it’s important to [add input / output transformations](https://langchain-ai.github.io/langgraph/how-tos/subgraph-transform-state/) so that the parent graph knows how to communicate with the subgraphs.
|
||||
- Define agent node functions with a [private input state schema](https://langchain-ai.github.io/langgraph/how-tos/pass_private_state/) that is distinct from the overall graph state schema. This allows passing information that is only needed for executing that particular agent.
|
||||
|
||||
### Shared message list
|
||||
|
||||
The most common way for the agents to communicate is via a shared state channel, typically a list of messages. This assumes that there is always at least a single channel (key) in the state that is shared by the agents. When communicating via a shared message list there is an additional consideration: should the agents [share the full history](#share-full-history) of their thought process or only [the final result](#share-final-result)?
|
||||
The most common way for agents to communicate is via a shared state channel, typically a list of messages. This assumes that there is always at least a single channel (key) in the state that is shared by the agents (e.g., `messages`). When communicating via a shared message list, there is an additional consideration: should the agents [share the full history](#sharing-full-thought-process) of their thought process or only [the final result](#sharing-only-final-results)?
|
||||
|
||||

|
||||
|
||||
#### Share full history
|
||||
#### Sharing full thought process
|
||||
|
||||
Agents can **share the full history** of their thought process (i.e. "scratchpad") with all other agents. This "scratchpad" would typically look like a [list of messages](./low_level.md#why-use-messages). The benefit of sharing full thought process is that it might help other agents make better decisions and improve reasoning ability for the system as a whole. The downside is that as the number of agents and their complexity grows, the "scratchpad" will grow quickly and might require additional strategies for [memory management](./memory.md/#managing-long-conversation-history).
|
||||
Agents can **share the full history** of their thought process (i.e., "scratchpad") with all other agents. This "scratchpad" would typically look like a [list of messages](./low_level.md#why-use-messages). The benefit of sharing the full thought process is that it might help other agents make better decisions and improve reasoning ability for the system as a whole. The downside is that as the number of agents and their complexity grows, the "scratchpad" will grow quickly and might require additional strategies for [memory management](./memory.md/#managing-long-conversation-history).
|
||||
|
||||
#### Share final result
|
||||
#### Sharing only final results
|
||||
|
||||
Agents can have their own private "scratchpad" and only **share the final result** with the rest of the agents. This approach might work better for systems with many agents or agents that are more complex. In this case, you would need to define agents with [different state schemas](#different-state-schemas)
|
||||
Agents can have their own private "scratchpad" and only **share the final result** with the rest of the agents. This approach might work better for systems with many agents or agents that are more complex. In this case, you would need to define agents with [different state schemas](#using-different-state-schemas).
|
||||
|
||||
For agents called as tools, the supervisor determines the inputs based on the tool schema. Additionally, LangGraph allows [passing state](https://langchain-ai.github.io/langgraph/how-tos/pass-run-time-values-to-tools/#pass-graph-state-to-tools) to individual tools at runtime, so subordinate agents can access parent state, if needed.
|
||||
For agents called as tools, the supervisor determines the inputs based on the tool schema. Additionally, LangGraph allows [passing state](../how-tos/tool-calling.ipynb#read-state) to individual tools at runtime, so subordinate agents can access parent state, if needed.
|
||||
|
||||
#### Indicating agent name in messages
|
||||
|
||||
It can be helpful to indicate which agent a particular AI message is from, especially for long message histories. Some LLM providers (like OpenAI) support adding a `name` parameter to messages — you can use that to attach the agent name to the message. If that is not supported, you can consider manually injecting the agent name into the message content, e.g., `<agent>alice</agent><message>message from alice</message>`.
|
||||
|
||||
### Representing handoffs in message history
|
||||
|
||||
Handoffs are typically done via the LLM calling a dedicated [handoff tool](#handoffs-as-tools). This is represented as an [AI message](https://python.langchain.com/docs/concepts/messages/#aimessage) with tool calls that is passed to the next agent (LLM). Most LLM providers don't support receiving AI messages with tool calls **without** corresponding tool messages.
|
||||
|
||||
You therefore have two options:
|
||||
|
||||
1. Add an extra [tool message](https://python.langchain.com/docs/concepts/messages/#toolmessage) to the message list, e.g., "Successfully transferred to agent X"
|
||||
2. Remove the AI message with the tool calls
|
||||
|
||||
In practice, we see that most developers opt for option (1).
|
||||
|
||||
### State management for subagents
|
||||
|
||||
A common practice is to have multiple agents communicating on a shared message list, but only [adding their final messages to the list](#sharing-only-final-results). This means that any intermediate messages (e.g., tool calls) are not saved in this list.
|
||||
|
||||
What if you __do__ want to save these messages so that if this particular subagent is invoked in the future you can pass those back in?
|
||||
|
||||
There are two high-level approaches to achieve that:
|
||||
|
||||
1. Store these messages in the shared message list, but filter the list before passing it to the subagent LLM. For example, you can choose to filter out all tool calls from **other** agents.
|
||||
2. Store a separate message list for each agent (e.g., `alice_messages`) in the subagent's graph state. This would be their "view" of what the message history looks like.
|
||||
|
||||
### Using different state schemas
|
||||
|
||||
An agent might need to have a different state schema from the rest of the agents. For example, a search agent might only need to keep track of queries and retrieved documents. There are two ways to achieve this in LangGraph:
|
||||
|
||||
- Define [subgraph](./low_level.md#subgraphs) agents with a separate state schema. If there are no shared state keys (channels) between the subgraph and the parent graph, it’s important to [add input / output transformations](../how-tos/subgraph.ipynb#different-state-schemas) so that the parent graph knows how to communicate with the subgraphs.
|
||||
- Define agent node functions with a [private input state schema](../how-tos/graph-api.ipynb/#pass-private-state-between-nodes) that is distinct from the overall graph state schema. This allows passing information that is only needed for executing that particular agent.
|
||||
Reference in New Issue
Block a user