Prerequisites
- Slack connected (the agent posts the PR link and cost summary to
#finops). - An active BigQuery connection with permission to read job metadata (the agent calls
get_bigquery_query_performance_stats). - Familiarity with programmable agents and running an agent with Bolt.
- API credentials with DinoAI Agent capabilities (Workspace Settings → API, Admin access required).
Steps
1
Create the agent
Build the agent in the Agent UI, or commit this file at
.dinoai/agents/query-optimizer.yml. It defines the agent’s role, five-phase goal, anti-pattern knowledge, guardrails, and Slack output channel..dinoai/agents/query-optimizer.yml
tools.mode: allowlist restricts the agent to only the tools listed, which keeps a write-capable agent from reaching outside the intended optimisation workflow. Update slack.channel before committing if your team routes cost alerts to a different channel.2
Add the trigger script
The optimizer runs from a small trigger script that reads dbt™ model results from Bolt artifacts (or accepts BigQuery job IDs directly), filters to the top costly models by bytes processed, and hands the full context to the agent. Commit
pyproject.toml at the same directory level as your dbt_project.yml so the agent can locate and rewrite model files, and scripts/run_query_optimizer.py alongside it.pyproject.toml
scripts/run_query_optimizer.py
When
--schedule-name is used, the script reads run_results.json from the latest Bolt run and maps each dbt™ model to the BigQuery job ID it produced. When --job-ids is used, the agent receives the job IDs directly and resolves the model files itself. When no model is above the bytes threshold the script exits cleanly with code 0, so it is safe to run on a schedule.3
Set your environment variables
Store your secrets in Paradime before scheduling. Go to Workspace Settings → Environment Variables and add the following. Bolt schedules read from the same store, so no separate setup is needed.
Your Paradime API endpoint, key, and secret are available under Workspace Settings → API. Make sure the key has
DinoAI agent API capabilities enabled.4
Run it from Bolt
Add a Bolt schedule that runs the trigger script, so costly models are caught and fixed on a cadence. Go to Bolt → Schedules, create a schedule named something like Replace To run the optimizer manually while testing, you can invoke the script from your local machine instead of a schedule. Detect costly models from a Bolt schedule, supply job IDs directly, or add a follow-up drill-down on one model:
Query Cost Optimizer, and add these two commands in order:your_dbt_production_schedule with the exact name of the schedule that runs your dbt™ models in production. See Run an agent with Bolt for the full walkthrough, including cron, run-on-merge, and Turbo CI triggers. A sensible default cadence is weekdays at 8 AM (0 8 * * 1-5), which runs after overnight production models complete so the latest artifacts are available.poetry install runs first on every execution so dependency updates committed to pyproject.toml are picked up automatically. pyproject.toml must sit at the same directory level as dbt_project.yml, since the agent uses run_terminal_command, read_file, and write_file from the repo root.On a run with costly models, the agent opens a PR titled If no PR appears, check that a model actually processed at least 10 GB (the default threshold). Review the PR and merge it.
perf: optimise BigQuery cost — <models> and posts a cost summary to #finops. The console shows the pre-fetched model table followed by the session ID and poll lines:How it works
The trigger script reads the latest Bolt run’srun_results.json, extracts the BigQuery job ID produced by each dbt™ model, filters to the top-N costliest models above the bytes threshold, and triggers a single agent session with the model context pre-embedded. BigQuery is filtered by bytes processed because that is the direct driver of on-demand query cost.
Once triggered, the agent works through five phases without stopping: gather BigQuery stats per job ID, locate the model .sql and YAML files, diagnose anti-patterns and build a plan, apply the changes on a new branch, then open the PR and post the summary. It never drops columns referenced downstream, never pushes to main, and leaves a TODO in the SQL when a business decision is required. The anti-patterns it detects and fixes:
Next steps
Query cost optimizer (Snowflake)
The same recipe for Snowflake, filtered by execution time and credits.
Run an agent with Bolt
Cron, run-on-merge, and Turbo CI triggers for this agent.
Build an agent in the UI
Create this agent visually instead of by hand.
Programmable Agents reference
The agent YAML schema and tools.