Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@
"guides/ai-agents/ai-writeback",
"guides/ai-agents/content-tools",
"guides/ai-agents/mcp-servers",
"guides/ai-agents/autopilot"
"guides/ai-agents/autopilot",
"guides/ai-agents/agents-as-code"
]
},
"references/integrations/lightdash-mcp",
Expand Down
3 changes: 3 additions & 0 deletions guides/ai-agents.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ This guide covers everything you need to know about AI agents in Lightdash:
</Card>
<Card title="Creating & editing content (Beta)" icon="pen-to-square" horizontal href="/guides/ai-agents/content-tools">

</Card>
<Card title="Agents as code" icon="file-code" horizontal href="/guides/ai-agents/agents-as-code">

</Card>
</CardGroup>

Expand Down
172 changes: 172 additions & 0 deletions guides/ai-agents/agents-as-code.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
---
title: "AI agents as code"
sidebarTitle: "Agents as code"
description: "Download AI agents to YAML, review them in Git, and promote them between projects using the same content-as-code workflow as charts and dashboards."
---

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`.

<Note>
This is part of the same content-as-code system as [dashboards as code](/guides/developer/dashboards-as-code). The same disposable-vs-Git-managed tradeoff and CI patterns apply.
</Note>

## 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:

```text
lightdash/
├── ai-agents/
│ ├── orders-support-agent.yml
│ └── revenue-analyst.yml
├── charts/
└── dashboards/
```

`lightdash upload` automatically picks up every `.yml` (or `.yaml`) file in `lightdash/ai-agents/` and syncs it to the [selected project](/references/lightdash-cli#lightdash-config-set-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):

```bash
lightdash download --include-agents
```

Download only specific agents by slug or UUID:

```bash
lightdash download --agents orders-support-agent revenue-analyst
```

You can combine agent flags with the usual `--charts`, `--dashboards`, `--project`, and `-p / --path` flags on [`lightdash download`](/references/lightdash-cli#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:

```bash
lightdash upload
```

Upload only specific agents by slug:

```bash
lightdash upload --agents orders-support-agent
```

Skip agent uploads entirely, even when files exist under `lightdash/ai-agents/`:

```bash
lightdash upload --skip-agents
```

<Note>
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).
</Note>

### 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.

```yaml lightdash/ai-agents/orders-support-agent.yml
contentType: ai_agent
version: 1
agentVersion: 2
slug: orders-support-agent
name: Orders Support Agent
description: Answers questions about orders, fulfillment, and refunds.
imageUrl: null
instruction: |
You are a support analyst for the ecommerce team. Use the orders and
shipments explores to answer questions about order status, refunds, and
fulfillment SLAs. Always report totals in GBP.
tags:
- ai
- orders
enableDataAccess: true
enableSelfImprovement: true
enableContentTools: false
enableUserContext: true
modelConfig:
modelName: gpt-4o
modelProvider: openai
reasoning: false
```

### Field reference

| Field | Type | Description |
| --- | --- | --- |
| `contentType` | string | Always `ai_agent`. The CLI refuses to upload files with any other value. |
| `version` | number | Schema version of the file itself. Currently `1`. |
| `agentVersion` | `1` \| `2` | Runtime version of the agent. Both v1 and v2 round-trip through download and upload. |
| `slug` | string | Stable identifier used to match against agents in the target project. Changing the slug creates a new agent on upload. |
| `name` | string | Human-readable name shown in the UI. |
| `description` | string \| null | Short description. |
| `imageUrl` | string \| null | URL for the agent's avatar. Uploaded-avatar provenance is preserved across environments. |
| `instruction` | string \| null | The agent's system prompt / instructions. See [getting started](/guides/ai-agents/getting-started#instructions) for guidance on what to include. |
| `tags` | string[] \| null | Semantic tags used for [data access control](/guides/ai-agents/data-access#limiting-access-to-specific-explores-and-fields). |
| `enableDataAccess` | boolean | Whether the agent can execute queries and read actual data. See [data access](/guides/ai-agents/data-access). |
| `enableSelfImprovement` | boolean | Whether the agent captures corrections into [agent memory](/guides/ai-agents/agent-memory). |
| `enableContentTools` | boolean | Whether the agent can create and edit charts and dashboards. See [creating & editing content](/guides/ai-agents/content-tools). |
| `enableUserContext` | boolean | Whether the agent receives the asking user's identity for [personalized answers](/guides/ai-agents/data-access#personalizing-answers-to-who-is-asking). |
| `modelConfig` | object \| null | Default model settings: `modelName`, `modelProvider`, and optional `reasoning` flag. When `null`, the agent inherits the [organization default](/guides/ai-agents/getting-started#set-an-organization-default-ai-model). |

## 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](/guides/ai-agents/getting-started#user-and-group-access-optional).
- **Slack integrations.** Slack channel bindings are per-environment and are not serialized.
- **MCP server references.** [MCP server](/guides/ai-agents/mcp-servers) references stay in the target project.
- **Uploaded knowledge documents.** Uploaded [documents](/guides/ai-agents/getting-started#knowledge-documents-optional) 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](/api-reference/v1/introduction) 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](/guides/developer/dashboards-as-code#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](/guides/developer/preview-projects) 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.
5 changes: 5 additions & 0 deletions guides/developer/dashboards-as-code.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,11 @@ And the matching tile entry on a dashboard:
tileSlug: orders-by-status
```

## AI agents as code

AI agent configuration can also be managed as code and promoted between projects with the same `lightdash download` / `lightdash upload` workflow used for charts and dashboards. This is useful for keeping agent instructions and tags under review in Git, and for copying a working agent from a preview or staging project into production.

Agent config as code is **opt-in**: a bare `lightdash download` does not include agents. See [AI agents as code](/guides/ai-agents/agents-as-code) for the full guide, including the YAML schema, CLI flags, and what runtime state stays in the target environment.
## Custom roles as code

[Custom roles](/references/workspace/custom-roles) are also managed as code. Unlike charts and dashboards, custom roles are **organization-scoped** rather than project-scoped, so downloading and uploading them uses the `--organization` mode of `lightdash download` and `lightdash upload` and requires an organization admin.
Expand Down
30 changes: 30 additions & 0 deletions references/lightdash-cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,11 @@ You can make changes to the code and upload these changes back to your Lightdash
- `--skip-dashboards`
- (default: false)
- skip downloading dashboards
- `--agents <slugs...>`
- opt-in flag to also download specific AI agents as code. Pass one or more agent slugs or UUIDs. Files are written to `lightdash/ai-agents/<slug>.yml`. See [AI agents as code](/guides/ai-agents/agents-as-code) for the YAML schema and lifecycle rules.
- `--include-agents`
- (default: false)
- opt-in flag to download every AI agent in the project as code. The endpoint is paginated, so the CLI walks all pages automatically. Agent files are written to `lightdash/ai-agents/`. Bare `lightdash download` does not include agents.
- `--organization`
- (default: false)
- switch to organization mode and download organization-scoped content (currently [custom roles](/guides/developer/dashboards-as-code#custom-roles-as-code)) instead of project content. Files are written to `lightdash/custom-roles/<role-slug>.yml`. Requires organization admin permissions. Cannot be combined with project-content flags such as `--charts`, `--dashboards`, `--project`, or `--nested`.
Expand Down Expand Up @@ -777,6 +782,16 @@ Download just one data app and nothing else.
lightdash download --apps-only --apps 8f2b1c4d-1111-2222-3333-444455556666
```

Download every AI agent in the project alongside charts and dashboards.

```bash
lightdash download --include-agents
```

Download only a specific AI agent by slug (or UUID).

```bash
lightdash download --agents orders-support-agent
Download all charts and dashboards, plus every virtual view in the project.

```bash
Expand Down Expand Up @@ -841,6 +856,11 @@ If there have been changes made to a chart or dashboard in the application that
- `--create-new`
- (default: false)
- always create a new data app from the uploaded source instead of appending a new version to the app referenced by `lightdash-app.yml`. Combine with `--apps` and `--project` when copying an app to a different project or instance in a non-interactive shell.
- `--agents <slugs...>`
- upload only the AI agent files matching these slugs from `lightdash/ai-agents/`. Omit to upload every agent file in that folder. Upload is idempotent — the server creates missing agents, updates existing agents by slug, and leaves unchanged agents alone. See [AI agents as code](/guides/ai-agents/agents-as-code).
- `--skip-agents`
- (default: false)
- skip uploading AI agents even when `lightdash/ai-agents/` contains files. Use this to keep an agents folder in your repo without pushing changes on every `lightdash upload`.
- `--organization`
- (default: false)
- switch to organization mode and upload organization-scoped content (currently [custom roles](/guides/developer/dashboards-as-code#custom-roles-as-code)) instead of project content. Reads YAML files from `lightdash/custom-roles/` and upserts each role by name — creating, updating, or reporting no change per file. Requires organization admin permissions. Cannot be combined with project-content flags such as `--charts`, `--dashboards`, `--project`, or `--force`. Uploads never delete roles.
Expand Down Expand Up @@ -921,6 +941,16 @@ Copy a data app to a different project as a brand-new app (non-interactive).
lightdash upload --apps --project 21eef0b9-5bae-40f3-851e-9554588e71a6 --create-new
```

Upload every AI agent file under `lightdash/ai-agents/` (creates missing agents, updates existing ones by slug).

```bash
lightdash upload
```

Upload only a specific AI agent by slug.

```bash
lightdash upload --agents orders-support-agent
Upload every custom role in `lightdash/custom-roles/` back to the organization (requires org admin).

```bash
Expand Down
Loading