> How Agent Script instructions are processed at runtime: from static text to dynamic LLM prompts.
---
## 1. Three Phases of Instruction Resolution
Agent Script instructions go through three distinct phases at runtime. Understanding these phases is critical for writing effective instructions and debugging unexpected behavior.
```
Phase 1: Pre-LLM Setup
(deterministic -- runs before the LLM sees anything)
|
v
Phase 2: LLM Reasoning
(non-deterministic -- LLM processes the assembled prompt)
|
v
Phase 3: Post-Action Loop
(deterministic -- runs after an action completes, then loops back to Phase 1)
```
---
## 2. Phase 1: Pre-LLM Resolution
During Phase 1, the Agent Script runtime evaluates deterministic constructs in `instructions: ->` blocks. This happens BEFORE the LLM sees any text.
### What Happens in Phase 1
1.**`if`/`else` evaluation**: Conditions are evaluated against current variable values. Only the matching branch is included in the prompt.
2.**Variable injection**: `{!@variables.X}` tokens are replaced with current values.
3.**`run` execution**: Deterministic `run @actions.X` calls execute and their outputs are captured.
-`after_reasoning` blocks (run after the LLM, not shown to it)
---
## 4. Phase 3: Post-Action Loop
After the LLM selects and executes an action, the system loops back to Phase 1 for **re-resolution**. This is the post-action loop pattern described in the SKILL.md architecture section.
### Loop Sequence
```
1. Phase 1 resolves instructions (first time)
2. Phase 2: LLM reasons and selects an action
3. Action executes -> outputs captured in variables
# These instructions are for the FIRST entry (before action runs)
| I can help you cancel your order.
| What is your order number?
```
If the check were at the BOTTOM, the LLM would see the "ask for order number" instructions again even after the cancellation succeeded, causing confusion.
---
## 5. Recommended Instruction Order
Within a `instructions: ->` block, follow this order for maximum clarity:
While `run` compiles inside `after_reasoning:`, its runtime behavior is inconsistent across bundle types. Prefer using `run` in `reasoning: instructions: ->` or `reasoning: actions:` instead.
```
# RISKY -- run in after_reasoning has inconsistent behavior
after_reasoning:
run @actions.log_event
with event = "turn_completed"
# SAFER -- Use instructions: -> for deterministic runs
reasoning:
instructions: ->
# Post-action logging
if @variables.last_action != "":
run @actions.log_event
with event = @variables.last_action
```
---
## 8. Syntax Patterns Reference
### Literal Mode (`|`)
Static text passed directly to the LLM. No evaluation occurs:
```
instructions: |
Help the customer with their order.
Be professional and concise.
```
Or with the `|` prefix on each line (inside procedural mode):
```
instructions: ->
| Help the customer with their order.
| Be professional and concise.
```
### Procedural Mode (`->`)
Enables conditionals, variable injection, and deterministic actions:
```
instructions: ->
if @variables.condition == True:
| Text shown when condition is true.
else:
| Text shown when condition is false.
```
### Variable Injection
```
| Your order {!@variables.order_id} is {!@variables.status}.
To confirm that `if`/`else` blocks resolved correctly, compare the trace's `LLM_STEP` input against your `instructions: ->` block. The LLM input should contain only the branches that matched, with all `{!@variables.X}` tokens replaced with actual values.
If the trace shows unexpected instruction text:
1. Check that you used `->` mode (not `|` mode) when conditionals are present
2. Verify variable values at the time of resolution (check `preVars` on preceding `ACTION_STEP`)
3. Confirm that `if` conditions use the correct comparison operators
### Using STDM for Production Trace Analysis
For production agents, use the Session Trace Data Model (STDM) in Data Cloud to access trace data programmatically. The STDM captures `LLM_STEP` records with `input` and `output` fields that contain the resolved prompt and LLM response. This is useful for auditing instruction resolution at scale across hundreds of live sessions.
When a topic transition occurs (via `@utils.transition to @subagent.X` or `transition to @subagent.X`), instruction resolution starts fresh in the new topic: