Quick answer
Agentic data operations means the routine work of a data team is run by agents on a schedule or in response to events, with people reviewing the results. On Nori, a cron schedule or a webhook starts an agent in an isolated sandbox with scoped access to your warehouse and repositories. It checks freshness, tests and policy, investigates failures, and reports in Slack. Fixes arrive as pull requests. Nothing is applied until a person approves it.
The work that fits
Data teams carry a long list of jobs that are important, repetitive and usually late. Each one has a clear check and a clear output, which is what an unattended agent needs.
| Job | Trigger | What the agent returns |
|---|---|---|
| Pipeline health | Nightly schedule, or a webhook when a dbt or orchestrator job fails | Root cause, affected downstream tables, a fix pull request |
| Data quality | Schedule after each load | Failed tests with first bad load, row counts, proposed test or model change |
| Governance | Schedule, and a webhook on every pull request that touches a model | Unclassified columns, missing masked views, certification changes |
| Cleanup | Monthly schedule | Unused tables, stale exports and copies with owner and a recommendation |
| Cost | Weekly schedule | Most expensive queries and models, with a rewrite proposed as a pull request |
| Reference data upkeep | Business-day schedule, late-file webhook | Matched records, an exceptions queue for people |
Three of these have full worked examples: bronze, silver and gold tables with dbt, a governance pipeline from raw to certified, and finding shadow data.
How it works
Every run, whether a person or a schedule started it, is the same kind of Nori session. That is the point: one history, one set of permissions, one place to look.
Triggers: schedules, webhooks and Slack
An automation is a prompt plus a trigger. The trigger is a cron line, a one-time reminder, or a webhook URL that your orchestrator, dbt Cloud, git host or file transfer job calls. The webhook payload is passed to the agent, so it starts with the failing job id or the pull request number. Anyone on the team can also start the same work by mentioning Nori in a Slack thread.
An isolated sandbox with scoped access
Each session gets its own cloud sandbox with your analytics repository cloned, dbt and your warehouse client installed by your setup script, and the credentials scoped to that agent. Give the data agent a warehouse role that reads production and writes only to a development schema. Connect catalogs, orchestrators and ticket systems as integrations or through any MCP server.
Shared skillsets and memories
Your conventions live in the team's skillset: layer rules, naming, test requirements, who owns which schema, what counts as an incident. Every session starts with them. Shared memories hold what was learned: that a vendor file arrives late on the first business day of the month, that a test on orders flaps when a backfill is running. The next run reads those notes before it raises an alarm.
Reports in Slack, changes in pull requests
The agent posts to the channel you name, and stays silent when a check passes if you ask it to. Anything that changes a model, a test, a policy file or a job definition arrives as a pull request with the build result attached. People reply in the thread to steer it, and the agent updates the branch.
Your models, your harness
Sessions run Jiro, Nori's own agent, or the harness your team already uses: Claude Code, Codex, Gemini CLI or any ACP agent. They run on your own Claude or ChatGPT subscription, API keys or LLM gateway. Nori never charges for tokens, so a hundred nightly runs cost a flat plan price plus whatever your own model plan charges.
Reversible, reviewed changes
An agent that can run at 3 a.m. needs firmer limits than a person at a desk. Four rules keep unattended runs safe, and they are enforced by permissions, not by asking the agent nicely.
- Read production, write development. The agent's warehouse role cannot write to production schemas. Production changes when your deploy job runs after a merge.
- Every change is a pull request. Branch protection and
CODEOWNERSin your git host decide who must approve. The agent cannot approve its own work. - Destructive actions have two steps. For drops and deletes the agent prepares the statement and a dry-run count. A person approves in the thread and a person with the rights applies it. Where possible the first step is a rename or quarantine, so there is something to restore.
- Every run is recorded. Run history keeps the prompt, the trigger payload, the commands and the result of each session, so you can answer what ran last night and why.
On Enterprise, the full stack, control plane included, deploys into your own AWS VPC or Azure VNet with your identity provider and LLM gateway, so warehouse credentials, query results and prompts stay inside your network.
Worked example: a failed dbt job at 02:14
A team runs its production dbt build from an orchestrator at 02:00 UTC. The orchestrator's failure callback calls a Nori webhook. The automation is defined once:
name: dbt-failure-triage
trigger: webhook (called by the orchestrator's on-failure callback)
channel: #data-alerts
prompt: A production dbt job failed. The payload has the run id and
failed nodes. Read the logs, find the root cause, and list the
gold tables and dashboards downstream. Check shared memories
for the same failure. Post a report. If the fix is a code
change, open a PR against main and run `dbt build --select
state:modified+ --target ci`. Do not rerun the production job
and do not change production data.
What happens on the night:
- 02:14 The build fails on
stg_payments__transactions. The orchestrator posts the run id and failed node to the webhook. - 02:14 Nori starts a sandbox with the analytics repository, the team skillset and the data agent's read-only production role.
- 02:16 The agent reads the run logs. The error is a cast failure:
Numeric value 'N/A' is not recognizedon columnfee_amount. - 02:19 It queries bronze. 1,208 rows loaded at 01:47 have
fee_amount = 'N/A'. All come from one new payment provider code,PAYX. No earlier load has the value. - 02:21 It finds a shared memory from August: the same provider sent empty strings for a week, and the team chose to treat them as null and add a warning test.
- 02:27 It opens a pull request that uses
try_to_number, adds awarn-severity test that counts non-numeric fees per provider, and attaches a passing CI build. - 02:28 It posts the report below and stops.
Nori 02:28
Production dbt run 48213 failed at stg_payments__transactions.
Cause: 1,208 rows from provider PAYX (loaded 01:47 UTC) have
fee_amount = 'N/A'. The cast to numeric fails.
Downstream not refreshed: fct_payments, fct_monthly_revenue,
Finance daily dashboard. They still show data through 2026-11-09.
Seen before: PAYX sent empty strings in August. We decided then to load
them as null and warn (memory: payx-fee-format).
Fix: PR #531 casts with try_to_number and adds a warn test for
non-numeric fees. CI build passed. I have not rerun production.
@oncall-data: merge and rerun, or reply here if you want it handled
another way.
The on-call engineer reads one message in the morning, reviews a small diff, merges and reruns. The agent then saves a line to shared memory: PAYX can send N/A as well as empty strings.
How to start
- Pick one job from the table that already has a clear pass or fail, usually the nightly build.
- Create the scoped warehouse role and add it as an integration for your data agent.
- Write your conventions into the team skillset. A page is enough to begin.
- Run the job by hand from Slack a few times and correct the agent in the thread. Those corrections become memories.
- Turn the prompt into an automation with a schedule or webhook, and add the next job when the first is boring.
For how schedules work in general, see scheduled coding agents. For the role view, see Nori for data teams. Teams in fund operations use the same pattern for reference data; see AI agents for asset managers.
Frequently asked questions
Can a scheduled agent change production data?
Not in the recommended setup. The agent's warehouse role reads production and writes only to a development schema. Model and policy changes ship through reviewed pull requests and your own deploy job. Deletes and drops need a person's approval and a person to apply them.
Which warehouses and tools does it work with?
Anything the sandbox can reach with a client, API or MCP server: Snowflake, BigQuery, Databricks, Redshift, Postgres, dbt Core and dbt Cloud, Airflow, Dagster, and your catalog. Your setup script installs the tools, so every session starts ready.
Does this replace our orchestrator or dbt?
No. Your orchestrator still runs pipelines and dbt still builds models. Nori runs the agents that watch them, investigate failures, apply governance rules and propose fixes. The orchestrator calls a webhook when something needs attention.
How does the agent remember past incidents?
Through shared memories. When a thread ends with a decision or a root cause, the agent saves a short note. Later sessions search those notes before reporting, so a repeat failure arrives with the earlier cause and the fix the team chose.
What does it cost to run nightly agents?
Nori charges a flat plan price for machines: Developer is $99 per month and Team starts at $250 per month, with a 30-day free trial. Model usage runs on your own subscription, API keys or gateway. Nori never charges for tokens.
Can analysts who do not write code use it?
Yes. Anyone you allow can ask in Slack why a number changed or whether a table is fresh, and the agent answers with the query it ran. Changes still go through pull requests that a data engineer reviews.