Otto prompts
Otto prompts are comprehensive, context-rich instructions that transform simple user requests into detailed, actionable commands for the AI agent. This document explains how Ascend automatically builds these prompts by combining system instructions, relevant rules, Project context, and user input.
How Otto prompts work
Every prompt sent to Otto follows a structured assembly process that enriches your simple request with extensive context:
- System instructions - Core Ascend instructions that define Otto's behavior and capabilities
- Relevant rules - Context-specific guidelines fetched based on your request and Project state
- User input - Your original prompt or request accompanied by user settings and relevant Project files
This intelligent prompt engineering leverages Ascend's unified metadata collection capabilities, automatically gathering all necessary context so you don't have to manually specify every detail.
System instructions and custom agents
Every Otto prompt starts with Ascend's core system instructions, which define the Otto chat agent's behavior and capabilities. When you create a custom agent, its prompt completely replaces these default system instructions, allowing you to customize Otto's personality, expertise, and response patterns for specific use cases.
Sample prompt trace
To illustrate how Otto prompts are assembled, let's trace through a real example. When a user sends this request to the standard Otto chat agent:
Perform the instructions in this Automation...
Use the details in the trigger to find the appropriate information to use as additional input.
Do exactly what the instructions tell you to do.
Here's how Ascend transforms this simple request into a comprehensive prompt:
System instructions
The prompt begins with Ascend's core system instructions that define Otto's behavior, capabilities, and personality:
This section would be completely replaced if you're using a custom agent instead of the default Otto chat agent.
Relevant rules
Since the user mentioned "Automation," Otto automatically fetches the relevant Automation rules to provide context-specific guidance:
Ascend-created rules always take precedence over your custom rules.
At least one trigger (sensor or event) must be specified.
Sensors
Sensors are time-based or condition-based triggers that initiate automations.
Timer Sensor
Triggers the automation on a schedule using cron expressions:
sensors:
- type: timer
name: cron-timer
config:
schedule:
cron: '0 * * * *' # Every hour
Common cron patterns:
'0 * * * *'- Every hour'0 0 * * *'- Daily at midnight'0 0 * * 1'- Weekly on Monday'0 0 1 * *'- Monthly on the 1st
Event Triggers
Event triggers activate automations based on system events, typically flow run statuses.
Event Types
Common event types include:
FlowRunSuccess- When a flow completes successfullyFlowRunError- When a flow failsFlowRunStart- When a flow startsComponentRunSuccess- When a component completesComponentRunFailure- When a component fails
Event Filters
Events can be filtered using SQL expressions or Python code:
SQL Filter
events:
- types:
- FlowRunSuccess
sql_filter: json_extract_string(event, '$.data.flow') = 'my-flow-name'
Python Filter
events:
- types:
- FlowRunSuccess
python_filter: |
import json
event_data = json.loads(event)
return event_data.get('data', {}).get('flow') == 'my-flow-name'
Type-Only Filter
events:
- types:
- FlowRunSuccess
- FlowRunError
Actions
Actions define what happens when an automation is triggered.
Run Flow Action
Executes a flow when triggered:
actions:
- type: run_flow
name: run-my-flow
config:
flow: my-flow-name
Run Otto Action
Executes Otto (AI agent) with a specific prompt:
actions:
- type: run_otto
name: analyze-failure
config:
agent_name: failure-analyzer
prompt: |
Analyze the recent flow failure and identify the root cause.
Check recent git commits and suggest fixes.
Email Alert Action
Sends an email alert when triggered by an event.
actions:
- type: email_alert
name: notify-on-failure
config:
emails:
- team@company.com
- alerts@company.com
include_otto_summary: true
Configuration options:
emails(required): List of email addresses to send alerts toinclude_otto_summary(optional): Whether to include Otto's explanation of the event (default: false)agent_name(optional): Specific Otto agent to use for explanation generation (default: Otto Chat)prompt(optional): Additional prompt to provide to Otto when generation explanation
Function Action
Executes a Python function (requires Python automation file):
actions:
- type: function
name: custom-handler
config:
python:
entrypoint: automations.custom_automation.handle_event
Multiple Actions
An automation can trigger multiple actions sequentially:
actions:
- type: run_flow
name: run-primary-flow
config:
flow: primary-flow
- type: run_flow
name: run-secondary-flow
config:
flow: secondary-flow
Common Patterns
Schedule-Based Flow Execution
Run a flow on a regular schedule:
Event-Driven Pipeline
Trigger downstream flows when upstream completes:
automation:
name: cascade-pipeline
enabled: true
triggers:
events:
- types:
- FlowRunSuccess
sql_filter: json_extract_string(event, '$.data.flow') = 'extract-data'
actions:
- type: run_flow
name: run-transform
config:
flow: transform-data
Failure Notification with Email Alert
Send email notifications when a flow fails:
Multi-Flow Orchestration
Trigger multiple downstream flows from a single upstream event:
Python Automations
Automations can be defined programmatically using Python decorators:
Mixing Declarative and Programmatic
Combine YAML configuration with Python actions:
Best Practices
- Naming: Use descriptive names that indicate the automation's purpose
- Enable/Disable: Use
enabledfield to temporarily disable automations - Event Filtering: Be specific with SQL filters to avoid unintended triggers
- State Management: Use
context.statein Python actions to track execution state - Error Handling: Create separate automations for failure scenarios
SQL Filter Functions
json_extract_string(event, '$.path.to.field')- Extract string valuesjson_extract(event, '$.path.to.field')- Extract any JSON value- Standard SQL operators:
=,!=,>,<,AND,OR,IN,LIKE
Debugging Tips
- Check automation run history for trigger timing
- Verify trigger conditions match expectations
- Use
enabled: falseto temporarily disable - For Python automations, use
context.stateto track execution state
User Settings
context:
current_build:
created_at: '2025-10-17T00:46:32.667589Z'
details:
end_time: '2025-10-17T00:46:40.804321Z'
start_time: '2025-10-17T00:46:36.344493Z'
git_sha: a2391972ce0ddade6b036b4ed691df8c5ed1a3d5
profile_name: workspace_sean
project_path: ''
project_uuid: 01917833-1142-78b0-9373-113fcb44209b
runtime_uuid: 01980644-0118-72a2-868e-0de671a5b026
state: ready
uuid: 0199efa1-f4db-74b0-9f06-191568b0e6bf
...
User
Perform the instructions in this automation... use the details in the trigger to find the appropriate information to use as additional input. Do exactly what the instructions tell you to do.
The result is a comprehensive prompt that transforms a simple 3-line request into hundreds of lines of context-rich instructions, giving Otto everything it needs to understand and execute the Automation effectively.
## Next steps
Now that you understand how Otto prompts work, you can:
- 🤖 [Build your own custom agents](/how-to/otto/agents.mdx)
- 📝 [Build your own custom rules](/how-to/otto/agents.mdx)