Mastering LangGraph – Multi-Agent 03

Mastering LangGraph - Multi-Agent 03
How to Pass Private Data Between Nodes
In some cases, you may want nodes to exchange information that is crucial to the intermediate logic but does not need to be part of the main architecture of the graph. This private data is unrelated to the overall input/output of the graph and should only be shared between certain nodes.
In this tutorial, we will create an example sequence diagram consisting of three nodes (node_1, node_2, and node_3), where private data is passed between the first two steps (node_1 and node_2), while the third step (node_3) can only access the public overall state.
The example is quite simple:
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict

# Overall state of the graph (this is the public state shared between nodes)
class OverallState(TypedDict):
    a: str

# The output of node_1 contains private data that is not part of the overall state
class Node1Output(TypedDict):
    private_data: str

# Private data is only shared between node_1 and node_2
def node_1(state: OverallState) -> Node1Output:
    output = {"private_data": "Set by node_1"}
    print(f"Entering node `node_1`:\n\tInput: {state}.\n\tReturn: {output}")
    return output

# The input of node_2 only requests private data available after node_1
class Node2Input(TypedDict):
    private_data: str

def node_2(state: Node2Input) -> OverallState:
    output = {"a": "Set by node_2"}
    print(f"Entering node `node_2`:\n\tInput: {state}.\n\tReturn: {output}")
    return output

# Node_3 can only access the overall state (cannot access private data from node_1)
def node_3(state: OverallState) -> OverallState:
    output = {"a": "Set by node_3"}
    print(f"Entering node `node_3`:\n\tInput: {state}.\n\tReturn: {output}")
    return output

# Build the state graph
builder = StateGraph(OverallState)
builder.add_node(node_1)  # node_1 is the first node
builder.add_node(node_2)  # node_2 is the second node and receives private data from node_1
builder.add_node(node_3)  # node_3 is the third node, cannot see private data

builder.add_edge(START, "node_1")  # Start the graph from node_1
builder.add_edge("node_1", "node_2")  # Pass from node_1 to node_2
builder.add_edge("node_2", "node_3")  # Pass from node_2 to node_3 (only shares overall state)
builder.add_edge("node_3", END)  # End the graph after node_3
graph = builder.compile()

# Invoke the graph with the initial state
response = graph.invoke({
    "a": "Set at the start",
})
print()
print(f"Output of the graph invocation: {response}")
The core idea is that when your current node sets data, if you want the next node to use it, you return that data, and it will be carried to the next node. When you do not want it to be passed to the next node, you only return the public part.

Leave a Comment