You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(state): update state key references in instructions (#493)
* fix: update state key references
* update docs to include info on state injection in instructions
* update java snippet
* add docs on InstructionProvider
* add tooltip on direct state modification
---------
Co-authored-by: Lavi Nigam <[email protected]>
Copy file name to clipboardExpand all lines: docs/agents/custom-agents.md
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -197,6 +197,9 @@ Let's illustrate the power of custom agents with an example pattern: a multi-sta
197
197
198
198
These are standard `LlmAgent` definitions, responsible for specific tasks. Their `output key` parameter is crucial for placing results into the `session.state` where other agents or the custom orchestrator can access them.
199
199
200
+
!!! tip "Direct State Injection in Instructions"
201
+
Notice the `story_generator`'s instruction. The `{var}` syntax is a placeholder. Before the instruction is sent to the LLM, the ADK framework automatically replaces (Example:`{topic}`) with the value of `session.state['topic']`. This is the recommended way to provide context to an agent, using templating in the instructions. For more details, see the [State documentation](../sessions/state.md#accessing-session-state-in-agent-instructions).
Copy file name to clipboardExpand all lines: docs/sessions/state.md
+93Lines changed: 93 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -67,8 +67,101 @@ Prefixes on state keys define their scope and persistence behavior, especially w
67
67
68
68
**How the Agent Sees It:** Your agent code interacts with the *combined* state through the single `session.state` collection (dict/ Map). The `SessionService` handles fetching/merging state from the correct underlying storage based on prefixes.
69
69
70
+
### Accessing Session State in Agent Instructions
71
+
72
+
When working with `LlmAgent` instances, you can directly inject session state values into the agent's instruction string using a simple templating syntax. This allows you to create dynamic and context-aware instructions without relying solely on natural language directives.
73
+
74
+
#### Using `{key}` Templating
75
+
76
+
To inject a value from the session state, enclose the key of the desired state variable within curly braces: `{key}`. The framework will automatically replace this placeholder with the corresponding value from `session.state` before passing the instruction to the LLM.
77
+
78
+
**Example:**
79
+
80
+
```python
81
+
from google.adk.agents import LlmAgent
82
+
83
+
story_generator = LlmAgent(
84
+
name="StoryGenerator",
85
+
model="gemini-2.0-flash",
86
+
instruction="""Write a short story about a cat, focusing on the theme: {topic}."""
87
+
)
88
+
89
+
# Assuming session.state['topic'] is set to "friendship", the LLM
90
+
# will receive the following instruction:
91
+
# "Write a short story about a cat, focusing on the theme: friendship."
92
+
```
93
+
94
+
#### Important Considerations
95
+
96
+
* Key Existence: Ensure that the key you reference in the instruction string exists in the session.state. If the key is missing, the agent might misbehave or throw an error.
97
+
* Data Types: The value associated with the key should be a string or a type that can be easily converted to a string.
98
+
* Escaping: If you need to use literal curly braces in your instruction (e.g., for JSON formatting), you'll need to escape them.
99
+
100
+
#### Bypassing State Injection with `InstructionProvider`
101
+
102
+
In some cases, you might want to use `{{` and `}}` literally in your instructions without triggering the state injection mechanism. For example, you might be writing instructions for an agent that helps with a templating language that uses the same syntax.
103
+
104
+
To achieve this, you can provide a function to the `instruction` parameter instead of a string. This function is called an `InstructionProvider`. When you use an `InstructionProvider`, the ADK will not attempt to inject state, and your instruction string will be passed to the model as-is.
105
+
106
+
The `InstructionProvider` function receives a `ReadonlyContext` object, which you can use to access session state or other contextual information if you need to build the instruction dynamically.
107
+
108
+
=== "Python"
109
+
110
+
```python
111
+
from google.adk.agents import LlmAgent
112
+
from google.adk.agents.readonly_context import ReadonlyContext
* Clarity: Makes it explicit which parts of the instruction are dynamic and based on session state.
151
+
* Reliability: Avoids relying on the LLM to correctly interpret natural language instructions to access state.
152
+
* Maintainability: Simplifies instruction strings and reduces the risk of errors when updating state variable names.
153
+
154
+
**Relation to Other State Access Methods**
155
+
156
+
This direct injection method is specific to LlmAgent instructions. Refer to the following section for more information on other state access methods.
157
+
70
158
### How State is Updated: Recommended Methods
71
159
160
+
!!! note "The Right Way to Modify State"
161
+
When you need to change the session state, the correct and safest method is to **directly modify the `state` object on the `Context`** provided to your function (e.g., `callback_context.state['my_key'] = 'new_value'`). This is considered "direct state manipulation" in the right way, as the framework automatically tracks these changes.
162
+
163
+
This is critically different from directly modifying the `state` on a `Session` object you retrieve from the `SessionService` (e.g., `my_session.state['my_key'] = 'new_value'`). **You should avoid this**, as it bypasses the ADK's event tracking and can lead to lost data. The "Warning" section at the end of this page has more details on this important distinction.
164
+
72
165
State should **always** be updated as part of adding an `Event` to the session history using `session_service.append_event()`. This ensures changes are tracked, persistence works correctly, and updates are thread-safe.
73
166
74
167
**1\. The Easy Way: `output_key` (for Agent Text Responses)**
0 commit comments