Ship AI agents like tables: dbt materializations for Snowflake CoWork

Last edited on Oct 27, 2026
At dbt Summit 2026, Stanley Bathina and Ryan Ballman, senior data platform engineers at Under Armour, walked through how their team closed a gap between two deployment processes: the mature, five-year-old dbt and Snowflake pipeline that shipped roughly 3,000 governed data products to about 950 daily users, and a newer, ungoverned process for the Snowflake AI agents and Cortex objects the team started building on top of that data. Their argument was simple: an AI agent should ship the same way a table does, through the same pull requests, the same environments, and the same commands.
Under Armour's first agents covered three business domains: a commercial sales assistant built on Cortex Analyst text-to-SQL, a consumer insights assistant also built on Cortex Analyst, and a product knowledge assistant built on Cortex Search for unstructured retrieval over hundreds of PowerPoint files. Each agent, along with the semantic views and search services underneath it, was defined by hand inside the Snowflake UI.
That UI is a capable editor, but Bathina and Ballman were candid that it offered no version control, no pull request, no CI checks, and no promotion path between environments. Anyone with sufficient access could edit a production agent directly, and the team found out about one broken agent, caused by an upstream column that had been deleted, only after business users started getting wrong answers from it.
The fix centered on three tactics. First, the team wrote custom dbt materializations, one called agent and one called cortex_search_service, alongside a Snowflake Labs materialization for semantic views. Each materialization creates the object if it doesn't exist or alters the live version if it does (agents are stateful, so replacing them outright would wipe conversation history and usage analytics), then returns the relation so dbt can track it in its dependency graph.
That let every agent, search service, and semantic view live as an ordinary dbt model, with a materialized config and a ref() call pointing at the tables underneath it. Second, because those objects now sit inside the dbt DAG, the team could run dbt ls --select daily_sales_semv+ to see every agent a change would touch before merging, and dbt build --select state:modified+ to rebuild only what changed in CI. Third, they automated grants and Snowflake CoWork registration through a post-hook that resolves the environment-specific role, fails the build loudly if a role is missing, grants the permission chain from database down to object, and, in production, registers the agent in Snowflake CoWork so business users can actually see it.
Five months after go-live, the team had more than 30 Cortex objects deployed through dbt across three domains and three environments, with full upstream and downstream lineage and a named reviewer on every change. A bad change is now a git revert instead of a manual scramble. On the business side, the commercial team gets same-day answers instead of overnight reports, consumer insights that used to take days now take seconds, and the product team can search training material in natural language instead of digging through files by hand.
The automation stops at the object layer, for now. Moving analyst-built objects out of the Snowflake UI and into dbt is still a manual cleanup step, and the handoff for user access requests isn't automated yet, even though the grants themselves are. Some manual steps, like CAB-approved change requests and a fixed release schedule, are deliberate and staying in place.
Watch every keynote and breakout from dbt Summit 2026 on demand. Watch dbt Summit 2026 on demand →
Get started in dbt
Join the analytics engineers building data infrastructure that actually scales.
Install dbt Wizard CLI
Get started with an agent purpose-built for analytics engineering. It knows which tool to call, which context to pull, and checks its own work before surfacing anything to you.


