Skip to main content
You can serialize a project’s AI agents to YAML with the Lightdash CLI, keep them under version control, and promote them between environments — preview, staging, production — using the standard lightdash download / lightdash upload flow. Use agents as code when you want to:
  • Review agent instructions, tags, and model settings in pull requests before they reach production
  • Copy a working agent from one project to another (for example, from a preview into production) without recreating it in the UI
  • Roll agent config back to a known-good version using Git history
  • Bootstrap new projects with the same set of agents you use elsewhere
Agent config as code is opt-in. A bare lightdash download does not include agents — you have to ask for them with --include-agents or --agents.
This is part of the same content-as-code system as dashboards as code. The same disposable-vs-Git-managed tradeoff and CI patterns apply.

On-disk layout

Agent files live under lightdash/ai-agents/ next to your charts/ and dashboards/ folders. Each agent is a single .yml file named after its slug:
lightdash upload automatically picks up every .yml (or .yaml) file in lightdash/ai-agents/ and syncs it to the selected project.

Downloading agents

Use one of the two flags below to include agents in a download. Neither is set by default. Download every AI agent in the project (paginated automatically by the CLI):
Download only specific agents by slug or UUID:
You can combine agent flags with the usual --charts, --dashboards, --project, and -p / --path flags on lightdash download.

Uploading agents

lightdash upload uploads every agent file in lightdash/ai-agents/ by default. Uploads are idempotent: the server creates missing agents, updates existing agents by slug, and leaves unchanged agents alone. Upload every agent along with charts and dashboards:
Upload only specific agents by slug:
Skip agent uploads entirely, even when files exist under lightdash/ai-agents/:
Unlike charts and dashboards, you do not need --force to create a new agent. Uploading a file whose slug does not exist in the target project creates the agent; changing the slug in an existing file creates a new agent under the new slug (the old one is not deleted).

Exit codes and validation

The CLI validates each agent file before uploading. Invalid YAML, missing required fields, wrong contentType, or duplicate slugs across files cause lightdash upload to exit with a non-zero status, which is what you want in CI so bad config fails the build.

YAML schema

Every agent file uses the following top-level shape. The schema is versioned independently from the runtime engine — version describes the as-code file format, and agentVersion records which runtime version the agent uses.
lightdash/ai-agents/orders-support-agent.yml

Field reference

What is not versioned

Some pieces of an agent are runtime state and are deliberately kept out of the YAML file — they stay in the target environment and are preserved across create/update/no-op uploads:
  • Conversations and threads. Chat history is runtime state and never written to YAML. Uploading a change to an agent does not touch existing threads.
  • User and group access lists. Access control is project-specific and stays managed in the target environment. See user and group access.
  • Slack integrations. Slack channel bindings are per-environment and are not serialized.
  • MCP server references. MCP server references stay in the target project.
  • Uploaded knowledge documents. Uploaded documents are preserved across upload but are not written into the YAML file itself.
This split lets you promote agent behavior (instructions, tags, model config, capability flags) through Git while still letting each environment own the things that don’t make sense to copy — production Slack channels, per-project MCP servers, per-environment access lists.

Lifecycle examples

Assuming a file at lightdash/ai-agents/orders-support-agent.yml:
  • Create. The target project has no agent with slug orders-support-agent. lightdash upload creates it.
  • Update. The target project already has orders-support-agent. Editing instruction or tags in the file and running lightdash upload updates the existing agent in place.
  • No-op. Nothing has changed since the last upload. The CLI reports the agent as skipped and makes no API call.
  • Rename by slug. Changing slug: orders-support-agent to slug: orders-support-agent-v2 and uploading creates a new agent under the new slug. The original agent is untouched.
  • Per-project isolation. Uploading with --project <another-uuid> only affects that project — the same slug in different projects refers to different agents.

API

The CLI is a thin wrapper around two permission-gated project endpoints:
  • GET /api/v1/projects/{projectUuid}/aiAgents/code — paginated download of agents as code. Accepts repeated ids query params (slug or UUID) to filter, and an offset for pagination.
  • POST /api/v1/projects/{projectUuid}/aiAgents/code — idempotent create-or-update by slug for one or more agents. Accepts a force query flag. Returns a summary of created, updated, unchanged, and deleted slugs.
Both endpoints require project-level permission to manage AI agents. See the API reference for the full request and response schema.

CI/CD

Because upload is idempotent and returns a non-zero exit code on invalid files, agents as code fits the same CI patterns as Git-managed dashboards:
  1. Store lightdash/ai-agents/ in Git.
  2. On PR, run lightdash upload --skip-charts --skip-dashboards --agents <slug> against a preview project to sanity-check the change.
  3. On merge to main, run lightdash upload against production.
Lock down agent editing in the UI (via role permissions) if you want the YAML files to be the definitive source of truth for agent config.