Events & Schemas
Learn how AgentML treats LLM outputs as structured events validated against JSON schemas.
Events and Schema Validation
AgentML treats LLM outputs as events. When the agent is in a state that expects certain events, it will prompt the LLM accordingly. The LLM's response must be a JSON object that the runtime interprets as an event. To enforce correctness, AgentML uses JSON Schema validation on these events.
How Schema Validation Works
1. Declare Schema on Transitions
You declare an event:schema
on transitions to define the expected structure and content of the event. This schema can enforce types, required fields, specific values, etc.
2. LLM Output Validation
When the LLM produces output, the AgentML interpreter will parse it and validate it against the schema. If it fails validation (or doesn't correspond to any expected event), the event can be rejected or handled as an error.
3. Guide with Descriptions
By providing detailed description fields in the schema (both at the top level and for each property), you guide the LLM to produce the correct data. These descriptions act like the spec that the LLM tries to fulfill.
Why Use Schemas?
This approach shifts the prompt paradigm from "LLM as free-text oracle" to "LLM as function that must return a specific JSON shape." It dramatically improves reliability.
- You can be confident that when a transition fires, the data is present and well-formed
- Schemas serve as up-to-date documentation of what the agent expects at each step
- Schema definitions can be reviewed and version-controlled like code
- Reduces debugging time by catching malformed outputs early
Example: Flight Search Intent
<transition event="intent.flight.search"
event:schema='{
"type": "object",
"description": "User intent to search for a flight",
"properties": {
"category": {
"const": "flight",
"description": "Category identifier for flight requests"
},
"action": {
"const": "search",
"description": "Specific action is flight search"
},
"details": {
"type": "object",
"properties": {
"from": {
"type": "string",
"description": "Departure location"
},
"to": {
"type": "string",
"description": "Destination location"
}
}
}
},
"required": ["category", "action"]
}'
target="handle_flight_search"/>
In this snippet, any LLM output event must have category: "flight"
and action: "search"
, plus optional details like from/to. The LLM will see in the prompt that an event with name intent.flight.search
is expected and what fields it should include.
Best Practices
Use Specific Event Names
Prefer granular events like intent.flight.search
or user.profile.update
over generic names. Specific names make the flow clear and avoid unintended catches.
Leverage JSON Pointer References
Instead of embedding large schemas inline, load them via use:events="events.json"
and reference with events:#/components/schemas/YourEvent
. This keeps your agent file clean and promotes reuse.
Use const and enum for Fixed Values
When an event field should only ever be a specific value (like a category flag), use a JSON Schema const
to enforce it. For a set of allowed values, use an enum
with clear descriptions.
Next Steps
Learn how AgentML optimizes token usage through runtime snapshots and caching.
Token Efficiency →