Skip to content

Commit e9ec4be

Browse files
authored
Add multi-agent shared state docs (#265)
1 parent 54bdfae commit e9ec4be

File tree

5 files changed

+161
-0
lines changed

5 files changed

+161
-0
lines changed

docs/user-guide/concepts/agents/hooks.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,56 @@ Some events come in pairs, such as Before/After events. The After event callback
121121

122122
## Advanced Usage
123123

124+
### Accessing Invocation State in Hooks
125+
126+
Hook events that involve tool execution include access to `invocation_state`, which provides configuration and context data passed through the agent invocation. This is particularly useful for:
127+
128+
1. **Custom Objects**: Access database client objects, connection pools, or other Python objects
129+
2. **Request Context**: Access session IDs, user information, settings, or request-specific data
130+
3. **Multi-Agent Shared State**: In multi-agent patterns, access state shared across all agents - see [Shared State Across Multi-Agent Patterns](../multi-agent/multi-agent-patterns.md#shared-state-across-multi-agent-patterns)
131+
4. **Custom Parameters**: Pass any additional data that hooks might need
132+
133+
```python
134+
from strands.hooks import BeforeToolCallEvent
135+
import logging
136+
137+
def log_with_context(event: BeforeToolCallEvent) -> None:
138+
"""Log tool invocations with context from invocation state."""
139+
# Access invocation state from the event
140+
user_id = event.invocation_state.get("user_id", "unknown")
141+
session_id = event.invocation_state.get("session_id")
142+
143+
# Access non-JSON serializable objects like database connections
144+
db_connection = event.invocation_state.get("database_connection")
145+
logger_instance = event.invocation_state.get("custom_logger")
146+
147+
# Use custom logger if provided, otherwise use default
148+
logger = logger_instance if logger_instance else logging.getLogger(__name__)
149+
150+
logger.info(
151+
f"User {user_id} in session {session_id} "
152+
f"invoking tool: {event.tool_use['name']} "
153+
f"with DB connection: {db_connection is not None}"
154+
)
155+
156+
# Register the hook
157+
agent = Agent(tools=[my_tool])
158+
agent.hooks.add_callback(BeforeToolCallEvent, log_with_context)
159+
160+
# Execute with context including non-serializable objects
161+
import sqlite3
162+
custom_logger = logging.getLogger("custom")
163+
db_conn = sqlite3.connect(":memory:")
164+
165+
result = agent(
166+
"Process the data",
167+
user_id="user123",
168+
session_id="sess456",
169+
database_connection=db_conn, # Non-JSON serializable object
170+
custom_logger=custom_logger # Non-JSON serializable object
171+
)
172+
```
173+
124174
### Fixed Tool Arguments
125175

126176
Enforce specific arguments for tools, ensuring they always use particular values regardless of what the agent specifies:

docs/user-guide/concepts/multi-agent/graph.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,12 @@ From [another_node_id]:
319319
- [Agent name]: [Result text]
320320
```
321321

322+
## Shared State
323+
324+
Graphs support passing shared state to all agents through the `invocation_state` parameter. This enables sharing context and configuration across agents without exposing it to the LLM.
325+
326+
For detailed information about shared state, including examples and best practices, see [Shared State Across Multi-Agent Patterns](./multi-agent-patterns.md#shared-state-across-multi-agent-patterns).
327+
322328
## Graphs as a Tool
323329

324330
Agents can dynamically create and orchestrate graphs by using the `graph` tool available in the [Strands tools package](../tools/community-tools-package.md).

docs/user-guide/concepts/multi-agent/multi-agent-patterns.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,61 @@ Some Examples:
7272
- Automated Data Pipelines: A fixed set of tasks to extract, analyze, and report on data, where independent analysis steps can run in parallel.
7373
- Standard Business Processes: Onboarding a new employee by creating accounts, assigning training, and sending a welcome email, all triggered by a single agent action.
7474

75+
## Shared State Across Multi-Agent Patterns
76+
77+
Both Graph and Swarm patterns support passing shared state to all agents through the `invocation_state` parameter. This enables sharing context and configuration across agents without exposing it to the LLM.
78+
79+
### How Shared State Works
80+
81+
The `invocation_state` is automatically propagated to:
82+
83+
- All agents in the pattern via their `**kwargs`
84+
- Tools via `ToolContext` when using `@tool(context=True)` - see [Python Tools](../tools/python-tools.md#accessing-invocation-state-in-tools)
85+
- Tool-related hooks (BeforeToolCallEvent, AfterToolCallEvent) - see [Hooks](../agents/hooks.md#accessing-invocation-state-in-hooks)
86+
87+
### Example Usage
88+
89+
```python
90+
# Same invocation_state works for both patterns
91+
shared_state = {
92+
"user_id": "user123",
93+
"session_id": "sess456",
94+
"debug_mode": True,
95+
"database_connection": db_connection_object
96+
}
97+
98+
# Execute with Graph
99+
result = graph(
100+
"Analyze customer data",
101+
invocation_state=shared_state
102+
)
103+
104+
# Execute with Swarm (same shared_state)
105+
result = swarm(
106+
"Analyze customer data",
107+
invocation_state=shared_state
108+
)
109+
```
110+
111+
### Accessing Shared State in Tools
112+
113+
```python
114+
from strands import tool, ToolContext
115+
116+
@tool(context=True)
117+
def query_data(query: str, tool_context: ToolContext) -> str:
118+
user_id = tool_context.invocation_state.get("user_id")
119+
debug_mode = tool_context.invocation_state.get("debug_mode", False)
120+
# Use context for personalized queries...
121+
```
122+
123+
### Important Distinctions
124+
125+
- **Shared State**: Configuration and objects passed via `invocation_state`, not visible in prompts
126+
- **Pattern-Specific Data Flow**: Each pattern has its own mechanisms for passing data that the LLM should reason about including shared context for swarms and agent inputs for graphs
127+
128+
Use `invocation_state` for context and configuration that shouldn't appear in prompts, while using each pattern's specific data flow mechanisms for data the LLM should reason about.
129+
75130
## Conclusion
76131

77132
This guide has explored the three primary multi-agent patterns in Strands: Graph, Swarm, and Workflow. Each pattern serves distinct use cases based on how execution paths are determined and controlled. When choosing between patterns, consider your problem's complexity, the need for deterministic vs. emergent behavior, and whether you require cycles, parallel execution, or specific error handling approaches.

docs/user-guide/concepts/multi-agent/swarm.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ Agent name: security_specialist. Agent description: Focuses on secure coding pra
166166
You have access to swarm coordination tools if you need help from other agents.
167167
```
168168

169+
## Shared State
170+
171+
Swarms support passing shared state to all agents through the `invocation_state` parameter. This enables sharing context and configuration across agents without exposing them to the LLM, keeping them separate from the shared context used for collaboration.
172+
173+
For detailed information about shared state, including examples and best practices, see [Shared State Across Multi-Agent Patterns](./multi-agent-patterns.md#shared-state-across-multi-agent-patterns).
174+
169175
## Asynchronous Execution
170176

171177
You can also execute a Swarm asynchronously by calling the [`invoke_async`](../../../api-reference/multiagent.md#strands.multiagent.swarm.Swarm.invoke_async) function:

docs/user-guide/concepts/tools/python-tools.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,50 @@ agent("What is the tool use id?")
172172
agent("What is the invocation state?", custom_data="You're the best agent ;)")
173173
```
174174

175+
#### Accessing Invocation State in Tools
176+
177+
The `invocation_state` attribute in `ToolContext` provides access to data passed through the agent invocation. This is particularly useful for:
178+
179+
1. **Request Context**: Access session IDs, user information, or request-specific data
180+
2. **Multi-Agent Shared State**: In [Graph](../multi-agent/graph.md) and [Swarm](../multi-agent/swarm.md) patterns, access state shared across all agents
181+
3. **Per-Invocation Overrides**: Override behavior or settings for specific requests
182+
183+
```python
184+
from strands import tool, Agent, ToolContext
185+
import requests
186+
187+
@tool(context=True)
188+
def api_call(query: str, tool_context: ToolContext) -> dict:
189+
"""Make an API call with user context.
190+
191+
Args:
192+
query: The search query to send to the API
193+
tool_context: Context containing user information
194+
"""
195+
user_id = tool_context.invocation_state.get("user_id")
196+
197+
response = requests.get(
198+
"https://api.example.com/search",
199+
headers={"X-User-ID": user_id},
200+
params={"q": query}
201+
)
202+
203+
return response.json()
204+
205+
agent = Agent(tools=[api_call])
206+
result = agent("Get my profile data", user_id="user123")
207+
```
208+
209+
##### Invocation State Compared To Other Approaches
210+
211+
It's important to understand how invocation state compares to other approaches that impact tool execution:
212+
213+
- **Tool Parameters**: Use for data that the LLM should reason about and provide based on the user's request. Examples include search queries, file paths, calculation inputs, or any data the agent needs to determine from context.
214+
215+
- **Invocation State**: Use for context and configuration that should not appear in prompts but affects tool behavior. Best suited for parameters that can change between agent invocations. Examples include user IDs for personalization, session IDs, or user flags.
216+
217+
- **[Class-based tools](#class-based-tools)**: Use for configuration that doesn't change between requests and requires initialization. Examples include API keys, database connection strings, service endpoints, or shared resources that need setup.
218+
175219
### Tool Streaming
176220

177221
Async tools can yield intermediate results to provide real-time progress updates. Each yielded value becomes a [streaming event](../streaming/overview.md), with the final value serving as the tool's return result:

0 commit comments

Comments
 (0)