diff --git a/README.md b/README.md index 24a8e95978..e0dfd1434a 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,8 @@ Set at least one API key (or use [Docker Model Runner](https://docs.docker.com/a export OPENAI_API_KEY=sk-... # or ANTHROPIC_API_KEY, GOOGLE_API_KEY, etc. ``` +See [Set Up a Model](https://docker.github.io/docker-agent/getting-started/set-up-a-model) for the full walkthrough of both paths (cloud API key or local model). + ## Quick Start ```sh @@ -75,7 +77,7 @@ More examples in the [`examples/`](examples/README.md) directory. 📖 **[Full documentation](https://docker.github.io/docker-agent/)** -- [Installation](https://docker.github.io/docker-agent/getting-started/installation) · [Quick Start](https://docker.github.io/docker-agent/getting-started/quickstart) +- [Installation](https://docker.github.io/docker-agent/getting-started/installation) · [Set Up a Model](https://docker.github.io/docker-agent/getting-started/set-up-a-model) · [Quick Start](https://docker.github.io/docker-agent/getting-started/quickstart) - [Agents](https://docker.github.io/docker-agent/concepts/agents) · [Models](https://docker.github.io/docker-agent/concepts/models) · [Tools](https://docker.github.io/docker-agent/concepts/tools) · [Multi-Agent](https://docker.github.io/docker-agent/concepts/multi-agent) - [Configuration Reference](https://docker.github.io/docker-agent/configuration/overview) - [TUI](https://docker.github.io/docker-agent/features/tui) · [CLI](https://docker.github.io/docker-agent/features/cli) · [MCP Mode](https://docker.github.io/docker-agent/features/mcp-mode) · [RAG](https://docker.github.io/docker-agent/tools/rag) diff --git a/docs/community/troubleshooting/index.md b/docs/community/troubleshooting/index.md index 0cbcb8cb3b..51ae191f41 100644 --- a/docs/community/troubleshooting/index.md +++ b/docs/community/troubleshooting/index.md @@ -68,7 +68,7 @@ Provide them using any of these sources: See https://docs.docker.com/ai/docker-agent/guides/secrets/ for details. ``` -Set the variable through any of the listed [secret sources](../../guides/secrets/index.md). When the missing variable is a model-provider API key, the error also suggests running a local model instead (`docker agent run --model dmr/ai/qwen3 ...`), which needs no API key. +Set the variable through any of the listed [secret sources](../../guides/secrets/index.md). When the missing variable is a model-provider API key, the error also suggests running a local model instead (`docker agent run --model dmr/ai/qwen3 ...`), which needs no API key, and links to the [Set Up a Model](../../getting-started/set-up-a-model/index.md) tutorial. ### No model available (`auto` selection failed) @@ -86,7 +86,7 @@ To fix this, you can: ... ``` -Either configure a cloud provider API key (see [API keys not set](#api-keys-not-set) below) or pull a local model. Run `docker agent doctor` to see which providers have credentials and whether Docker Model Runner is reachable. +Either configure a cloud provider API key (see [API keys not set](#api-keys-not-set) below) or pull a local model. The [Set Up a Model](../../getting-started/set-up-a-model/index.md) tutorial walks through both paths. Run `docker agent doctor` to see which providers have credentials and whether Docker Model Runner is reachable. ### Docker Model Runner model not pulled diff --git a/docs/data/nav.yml b/docs/data/nav.yml index 1d016a7ac2..50fdfb2bcc 100644 --- a/docs/data/nav.yml +++ b/docs/data/nav.yml @@ -4,6 +4,8 @@ url: /getting-started/introduction/ - title: Installation url: /getting-started/installation/ + - title: Set Up a Model + url: /getting-started/set-up-a-model/ - title: Quick Start url: /getting-started/quickstart/ diff --git a/docs/getting-started/quickstart/index.md b/docs/getting-started/quickstart/index.md index cc65bb8441..c42e42db31 100644 --- a/docs/getting-started/quickstart/index.md +++ b/docs/getting-started/quickstart/index.md @@ -21,6 +21,9 @@ $ docker agent run This starts a general-purpose assistant with sensible defaults. Just start chatting. +> [!NOTE] +> This needs a model: a cloud provider API key, or a local model pulled through Docker Model Runner. [Set Up a Model](../set-up-a-model/index.md) walks through both paths. + ## Option B: Run a Pre-Built Agent from the Registry Try a ready-made agent from the [agent catalog](https://hub.docker.com/u/agentcatalog) — no YAML needed: @@ -79,6 +82,8 @@ This gives your agent: - **Shell access** to run commands - **Think tool** for step-by-step reasoning +This config needs `ANTHROPIC_API_KEY` set. See [Set Up a Model](../set-up-a-model/index.md) for where to put it, or use a local `dmr/...` model that needs no key. + ```bash # Launch the interactive terminal UI $ docker agent run agent.yaml diff --git a/docs/getting-started/set-up-a-model/index.md b/docs/getting-started/set-up-a-model/index.md new file mode 100644 index 0000000000..56184bdf81 --- /dev/null +++ b/docs/getting-started/set-up-a-model/index.md @@ -0,0 +1,194 @@ +--- +title: "Set Up a Model" +description: "Make a model available to Docker Agent: bring a cloud provider API key or run a local model with Docker Model Runner." +keywords: docker agent, ai agents, getting started, set up a model, api key, local model, docker model runner +weight: 25 +canonical: https://docs.docker.com/ai/docker-agent/getting-started/set-up-a-model/ +--- + +_Every agent needs a model to think with. Bring an API key for a cloud provider, or run a model locally with Docker Model Runner. This page walks through both paths end to end._ + +## Pick a Path + +| | Cloud provider (Path A) | Local model (Path B) | +| ------------ | ---------------------------------------- | ------------------------------------------- | +| You need | An account and an API key | Docker Desktop with Model Runner enabled | +| Cost | Pay per token | Free once the model is downloaded | +| Your data | Sent to the provider | Never leaves your machine | +| Model quality| Frontier models (Claude, GPT-5, Gemini) | Open models sized to your hardware | + +You can set up both. When you don't name a model, Docker Agent's `auto` selection picks the first cloud provider with a configured key and falls back to a locally pulled Docker Model Runner model. + +> [!TIP] +> **Prefer a wizard?** +> +> `docker agent setup` walks through the same choices interactively: pick a provider and store its key, or check Docker Model Runner and pull a local model. This page is the manual version of both paths. See the [CLI reference](../../features/cli/index.md#docker-agent-setup). + +## Path A: Cloud Provider (API Key) + +### 1. Get an API key + +Create a key in your provider's console: + +| Provider | Environment variable | Get a key at | +| ------------- | -------------------- | ------------------------------------------------------------------- | +| Anthropic | `ANTHROPIC_API_KEY` | [console.anthropic.com](https://console.anthropic.com/settings/keys) | +| OpenAI | `OPENAI_API_KEY` | [platform.openai.com](https://platform.openai.com/api-keys) | +| Google Gemini | `GOOGLE_API_KEY` | [aistudio.google.com](https://aistudio.google.com/apikey) | + +Every other provider works the same way. See [Model Providers](../../providers/overview/index.md) for the full list and each provider's environment variable. + +### 2. Store the key + +The fastest option is an environment variable in your shell: + +```bash +$ export ANTHROPIC_API_KEY=sk-ant-... +``` + +That lasts for the current shell session. To set a key up once, use any other built-in secret source: + +```bash +# Env file, passed at run time +$ echo 'ANTHROPIC_API_KEY=sk-ant-...' > .env +$ docker agent run --env-from-file .env + +# pass password manager (Linux, macOS) +$ pass insert ANTHROPIC_API_KEY + +# macOS Keychain +$ security add-generic-password -a "$USER" -s ANTHROPIC_API_KEY -w +``` + +The entry name must match the environment variable the provider expects. [Managing Secrets](../../guides/secrets/index.md) covers every source (Docker Compose secrets, credential helpers, 1Password references) and the order they are checked in. + +> [!IMPORTANT] +> Keys never go in `agent.yaml`. If you use an env file, add it to `.gitignore`. + +### 3. Verify + +`docker agent doctor` shows whether the key is visible and where it comes from: + +```bash +$ docker agent doctor +``` + +```text +Model provider credentials + PROVIDER STATUS CREDENTIAL SOURCE + anthropic found ANTHROPIC_API_KEY environment + openai not set OPENAI_API_KEY - + ... + +Docker Model Runner + Status: not installed (https://docs.docker.com/ai/model-runner/get-started/) + +Model auto-selection + auto -> anthropic/claude-sonnet-4-6 + +No issues found. +``` + +### 4. Run + +```bash +$ docker agent run +``` + +With no config file, the default agent picks the provider you configured. To name a model explicitly, use `--model` or the `model` field in your config: + +```bash +$ docker agent run --model anthropic/claude-sonnet-4-5 +``` + +```yaml +agents: + root: + model: anthropic/claude-sonnet-4-5 + description: A helpful coding assistant + instruction: You are an expert software developer. +``` + +## Path B: Local Model (Docker Model Runner) + +Docker Model Runner (DMR) runs open models on your own machine: no API key, no per-token cost, and prompts never leave your computer. + +### 1. Install Docker Model Runner + +Model Runner ships with [Docker Desktop](https://www.docker.com/products/docker-desktop/) (enable it under **Settings > AI**) and is also available for Docker Engine. Check that it responds: + +```bash +$ docker model status +``` + +If the command is missing or fails, follow the [Model Runner get-started guide](https://docs.docker.com/ai/model-runner/get-started/). + +### 2. Pull a model + +```bash +$ docker model pull ai/qwen3 +``` + +`ai/qwen3` is the model Docker Agent reaches for by default, but any model from the [Docker Hub `ai` catalog](https://hub.docker.com/u/ai) works. Pick one sized for your machine's memory. List what you have locally: + +```bash +$ docker model ls +``` + +### 3. Verify + +```bash +$ docker agent doctor +``` + +```text +Model provider credentials + PROVIDER STATUS CREDENTIAL SOURCE + anthropic not set ANTHROPIC_API_KEY - + ... + +Docker Model Runner + Status: reachable, 1 model(s) pulled: + - ai/qwen3:latest + +Model auto-selection + auto -> dmr/ai/qwen3:latest + +No issues found. +``` + +### 4. Run + +```bash +$ docker agent run --model dmr/ai/qwen3 +``` + +Or in your config: + +```yaml +agents: + root: + model: dmr/ai/qwen3 + description: A local assistant + instruction: You are a helpful assistant. +``` + +When no cloud key is configured, bare `docker agent run` auto-selects a pulled local model, so after `docker model pull` you can run with no flags at all. The [Docker Model Runner provider page](../../providers/dmr/index.md) covers context size, runtime flags, and other tuning options. + +## Check Your Setup Anytime + +`docker agent doctor` reports which providers have credentials (and from which source), whether Docker Model Runner is reachable and which models are pulled, and which model `auto` would pick. Secret values are never printed. + +```bash +$ docker agent doctor # credential, DMR, and auto-selection state +$ docker agent doctor ./agent.yaml # also check that file's requirements +``` + +It exits non-zero when something would block a run, which makes it usable as a CI preflight. See the [CLI reference](../../features/cli/index.md#docker-agent-doctor). + +## What's Next? + +- [**Quick Start**](../quickstart/index.md) — run your first agent now that a model is available. +- [**Models**](../../concepts/models/index.md) — inline vs. named models, fallbacks, and `auto` selection. +- [**Managing Secrets**](../../guides/secrets/index.md) — every way to store credentials, compared. +- [**Troubleshooting**](../../community/troubleshooting/index.md#missing-credentials-or-model-errors) — decode "no model available" and credential errors. diff --git a/pkg/config/auto.go b/pkg/config/auto.go index 65754caed7..5312efe632 100644 --- a/pkg/config/auto.go +++ b/pkg/config/auto.go @@ -133,6 +133,7 @@ func (e *AutoModelFallbackError) Error() string { b.WriteString(" - Install Docker Model Runner: https://docs.docker.com/ai/model-runner/get-started/\n") b.WriteString(" - Configure an API key for a cloud provider:\n") b.WriteString(strings.Join(hints, "\n")) + fmt.Fprintf(&b, "\n\nStep-by-step model setup (API key or local): %s", environment.ModelSetupDocsURL) return b.String() } diff --git a/pkg/config/auto_test.go b/pkg/config/auto_test.go index e4d71e86d9..dcefab3179 100644 --- a/pkg/config/auto_test.go +++ b/pkg/config/auto_test.go @@ -1010,6 +1010,7 @@ func TestAutoModelFallbackError(t *testing.T) { assert.Contains(t, msg, "docker agent setup") assert.Contains(t, msg, "docker model pull") assert.Contains(t, msg, "ANTHROPIC_API_KEY") + assert.Contains(t, msg, environment.ModelSetupDocsURL) assert.NotContains(t, msg, "Could not initialize") }) diff --git a/pkg/config/first_available.go b/pkg/config/first_available.go index b71a546b33..ad407cd46a 100644 --- a/pkg/config/first_available.go +++ b/pkg/config/first_available.go @@ -184,6 +184,7 @@ func (e *firstAvailableMissingEnvError) Error() string { msg.WriteString("\n") msg.WriteString(environment.SecretSourcesHelp(example)) msg.WriteString("\nOr run `docker agent setup` to configure a provider or local model interactively.\n") + fmt.Fprintf(&msg, "Step-by-step model setup (API key or local): %s\n", environment.ModelSetupDocsURL) return msg.String() } diff --git a/pkg/config/first_available_test.go b/pkg/config/first_available_test.go index 685406b735..b2d7cfdb78 100644 --- a/pkg/config/first_available_test.go +++ b/pkg/config/first_available_test.go @@ -183,6 +183,7 @@ func TestResolveFirstAvailableModels_NoCandidateAvailable(t *testing.T) { assert.Contains(t, err.Error(), "export ANTHROPIC_API_KEY=") assert.Contains(t, err.Error(), "--env-from-file") assert.Contains(t, err.Error(), environment.SecretsDocsURL) + assert.Contains(t, err.Error(), environment.ModelSetupDocsURL) } func TestResolveFirstAvailableModels_InvalidCandidate(t *testing.T) { diff --git a/pkg/environment/errors.go b/pkg/environment/errors.go index d8448af5f1..56ed01b966 100644 --- a/pkg/environment/errors.go +++ b/pkg/environment/errors.go @@ -9,6 +9,10 @@ import ( // source and how to configure it. const SecretsDocsURL = "https://docs.docker.com/ai/docker-agent/guides/secrets/" +// ModelSetupDocsURL is the step-by-step tutorial for making a model available, +// covering both the cloud API-key path and the local Docker Model Runner path. +const ModelSetupDocsURL = "https://docs.docker.com/ai/docker-agent/getting-started/set-up-a-model/" + type RequiredEnvError struct { Missing []string @@ -38,6 +42,7 @@ func (e *RequiredEnvError) Error() string { if e.MissingModelCredentials { msg.WriteString("\nNo API key? Run a local model instead: docker agent run --model dmr/ai/qwen3 ...\n(the model is pulled on first use; `docker model ls` shows models already pulled)\n") msg.WriteString("Or run `docker agent setup` to configure a provider or local model interactively.\n") + fmt.Fprintf(&msg, "Step-by-step model setup (API key or local): %s\n", ModelSetupDocsURL) } return msg.String() diff --git a/pkg/environment/errors_test.go b/pkg/environment/errors_test.go index b60358f98e..f9cb75dfe4 100644 --- a/pkg/environment/errors_test.go +++ b/pkg/environment/errors_test.go @@ -32,6 +32,7 @@ func TestRequiredEnvError_NamesSecretSources(t *testing.T) { // The local-model alternative only applies to model credentials. assert.NotContains(t, msg, "dmr/ai/qwen3") + assert.NotContains(t, msg, ModelSetupDocsURL) } func TestRequiredEnvError_SuggestsLocalModelForModelCredentials(t *testing.T) { @@ -47,4 +48,5 @@ func TestRequiredEnvError_SuggestsLocalModelForModelCredentials(t *testing.T) { assert.Contains(t, msg, "pulled on first use") assert.Contains(t, msg, "docker model ls") assert.Contains(t, msg, "docker agent setup") + assert.Contains(t, msg, ModelSetupDocsURL) }