---
title: "Deep Agents Quickstart"
description: "Run a Deep Agent and its sub-agents as a named agent, so every model request is signed with the agent's key and records which sub-agent made it."
source: "Guardian Platform"
---
A Deep Agents agent runs through Viper as a **named agent**. It has its own key, it describes itself and its sub-agents when it starts, and it names itself, and the sub-agent asking, on every model request. The Guardian Platform then records each request under that agent. The [Guardian Agent SDK](https://guardian-agent-sdk.docs.eqtylab.io/) does the describing and the naming.

This page takes you from an empty machine to a signed request you can see in Guardian.

## Before you start

- **Python 3.11 to 3.14**, since Deep Agents needs 3.11, with the Guardian Agent SDK's `deepagents` extra and `langchain-openai`. The SDK comes from EQTY Lab's Cloudsmith repository, with the entitlement token you install Viper with ([Package managers](https://guardian-agent-sdk.docs.eqtylab.io/install/package-managers/)).
- **Viper 0.3.0 or later**, installed and pointed at your Agent Gateway. See [Install Viper](./install-viper.mdx).
- **An API key with the Register Agents scope**, or the **Register Agents** permission to get a registration token from Guardian, to enroll the agent. See [Register Agents](./register-agents.mdx#1-generate-an-enrollment-key).
- **Your own OpenAI API key.** The gateway does not hold provider keys; your key passes through it to OpenAI unchanged.

```bash
python3 -m venv .venv && . .venv/bin/activate
export VIPER_CLOUDSMITH_TOKEN=<your entitlement token>
PIP_INDEX_URL="https://dl.cloudsmith.io/$VIPER_CLOUDSMITH_TOKEN/eqtylab/prod/python/simple/" \
  pip install "eqty-guardian-agent[deepagents]"
pip install "langchain-openai>=1.7,<1.8"
```

**Coming from the Register Agent dialog in Guardian?** The dialog shows the commands for this page's steps 1 and 2, with your agent's name, token and gateway address filled in. You still need **Before you start** (the install) and the `agent.py` in step 3, and you use your own agent's name wherever this page says `research-bot`.

## 1. Enroll the agent

Give the agent a name and its own key, then register it with the Guardian Platform. The name is 1 to 64 characters of lowercase letters, digits, `.`, `_` or `-`, starting with a letter or digit. Sub-agents share the agent's key, so they are not enrolled separately.

```bash
viper agent add research-bot
GUARDIAN_API_KEY=ak_… viper agent register research-bot
```

Viper prints the agent's key, then the agent ID the Guardian Platform minted:

```console
added agent `research-bot`
did:key:z6Mk…
registered agent `research-bot` (did:key:z6Mk…) as urn:uuid:3f2a…
```

If you have no API key, register with a token from Guardian instead: `VIPER_PROVISIONING_TOKEN='ggr1.…' viper agent register research-bot`. Choosing **Deep Agents** in the **Register Agent** dialog shows this page's commands with the token and your gateway address filled in. See [Named agents](./register-agents.mdx#named-agents).

Check the enrollment with `viper doctor`. It confirms the gateway answers and accepts `research-bot`'s key, and prints a fix for anything that fails. Its warning that the proxy has no key is expected until you start the proxy.

## 2. Start the proxy

Start a proxy for OpenAI traffic. It loads every enrolled agent when it starts, so start it after enrolling the agent, and restart it after enrolling another. To restart it, stop it with `kill %1` (or `fg`, then Ctrl-C), then run `viper proxy` again. The proxy also needs a key of its own, which signs any request that names no agent; create it once if you have not already.

```bash
viper did add --assign proxy
viper proxy --app proxy --port 8080 \
  --gateway-endpoint https://gateway.example.com/v1/openai_api &
```

Replace `https://gateway.example.com` with your gateway address. The proxy prints its address, `http://localhost:8080`. If something else already listens on port 8080, the proxy can't start, and with `&` its error is easy to miss: pick another `--port` and set `VIPER_PROXY_URL` to the address the proxy prints. To confirm it loaded the agent, ask its local agent API:

```bash
curl -s http://127.0.0.1:8080/__viper__/v1/agents/research-bot   # your agent's name
```

```json
{ "name": "research-bot", "did": "did:key:z6Mk…", "definitions": [], "latestDefinitionCid": null }
```

A `404` with `agent_not_enrolled` means the name doesn't match the one you enrolled, or the proxy started before the agent was enrolled; restart it.

## 3. Run the agent

The SDK's `create_deep_agent` takes the same arguments as Deep Agents' own, plus the agent's `name`. It routes the agent's model, and each sub-agent's, through the proxy, so every request names the agent and the sub-agent asking. It registers the agent's definition: what Deep Agents builds, its tools, middleware and models, and each sub-agent as a definition of its own, the `general-purpose` sub-agent Deep Agents adds included. Changing a sub-agent, a prompt or a package version gives a new definition.

Save this as `agent.py`:

{/* generated file sdks/python/snippets/platform_deepagents_agent.py python */}

```python
import os

from langchain_openai import ChatOpenAI

import guardian_agent as ga
from guardian_agent.deepagents import create_deep_agent

AGENT = os.environ.get("VIPER_AGENT", "research-bot")

# Deep Agents' create_deep_agent, with one import changed and the agent's name added
agent = create_deep_agent(
    model=ChatOpenAI(model="gpt-4o-mini"),
    system_prompt="You write short answers and have them reviewed before replying.",
    subagents=[
        {
            "name": "critic",
            "description": "Reviews a draft and suggests fixes.",
            "system_prompt": "You review drafts and reply with fixes.",
        },
    ],
    name=AGENT,
    guardian=ga.Guardian(os.environ.get("VIPER_PROXY_URL", "http://127.0.0.1:8080")),
)

result = agent.invoke(
    {"messages": [{"role": "user", "content": "Draft a one-line welcome message."}]}
)
print(result["messages"][-1].content)
```

{/* end generated */}

Run it as the agent you enrolled:

```bash
VIPER_AGENT=research-bot OPENAI_API_KEY=sk-… python agent.py
```

The agent reaches the proxy at `http://127.0.0.1:8080`. Set `VIPER_PROXY_URL` if yours is elsewhere.

## 4. Confirm it in Guardian

1. Open the [Agent Catalog](./agent-inventory.mdx) and paste the agent ID from step 1 (`urn:uuid:…`) into the search box. The agent is listed with the **Deep Agents** type once its first request lands, and as **Custom** before that. If you used the Register Agent dialog, its last step updates when the request lands, and links to the agent.
2. Open the agent. Its Request Logs list the main agent's requests, and the critic's when the agent hands it a draft, all verified and signed with the agent's key. A single run usually makes several requests, because each agent can take more than one turn. Guardian does not yet label which requests a sub-agent made; that is recorded in each request's signed state.
3. To have project policy apply to the agent and see its traffic in a project, [associate it with the project](./associated-agents.mdx).

## What is and is not recorded

Recorded:

- Every model request the main agent and its sub-agents make, signed with the agent's own key, after the SDK checks it against the definition.
- Which sub-agent made each request, in the request's signed state. A request from the main agent names no sub-agent.
- The agent definition each request was sent with: what Deep Agents adds (its tools, middleware and summarization model), each sub-agent, the models and their settings, the prompts, and the package versions.
- The provenance Viper records for any request: host, git and environment details of the process.

Not recorded:

- **Tool calls as separate events.** The model's request to call a tool, `task` included, and the result it gets back travel inside the signed model traffic. Viper does not run tools, so it does not sign or audit what a tool does.
- **Tool traffic.** Calls your tools make to other services, such as databases and web APIs, do not go through the proxy and are neither signed nor audited.
- **What the agent writes as it runs.** Files and memory the agent writes stay with you; the definition records where they live, not what's in them. See [Deep Agents](https://guardian-agent-sdk.docs.eqtylab.io/frameworks/deep-agents/#skills-and-memory).

## Troubleshooting

| Symptom                                                                      | What to do                                                                                                                                                                               |
| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `viper proxy` stops with `no DID configured for proxy`                       | Create the proxy's key: `viper did add --assign proxy`.                                                                                                                                  |
| `Connection error.` from the OpenAI client                                   | Nothing answers at `http://127.0.0.1:8080`. Start the proxy, or set `VIPER_PROXY_URL` to the address it printed.                                                                         |
| `404` with `agent_not_enrolled`: ``agent `…` is not enrolled on this proxy`` | Set `VIPER_AGENT` to the exact name you enrolled: the **Agent Name** in the Register Agent dialog. If you haven't enrolled it yet, do step 1, then restart the proxy.                    |
| `404` with `proxy_incompatible`: `nothing at … serves the Viper agent API`   | Something other than `viper proxy` answers at that address, often another service on port 8080. Start the proxy on another `--port`, and set `VIPER_PROXY_URL` to the address it prints. |
| `502` with `proxy_incompatible`                                              | The proxy's Viper is older than the SDK needs. Upgrade to Viper 0.3.0 or later ([Install Viper](./install-viper.mdx)).                                                                   |
| `ModuleNotFoundError: No module named 'deepagents'`                          | Deep Agents needs Python 3.11 or later; on 3.10 the `deepagents` extra installs nothing. Recreate the environment with Python 3.11 or later.                                             |
| `OpenAIError: Missing credentials`                                           | Set `OPENAI_API_KEY`.                                                                                                                                                                    |
| Model requests fail with `401` from OpenAI                                   | `OPENAI_API_KEY` is wrong. The gateway does not add a key.                                                                                                                               |
| Model requests fail with `502` and another code                              | Viper could not sign the request or reach the gateway; the error's `code` and `hint` say which. See [Run Agents](./run-agents.mdx#troubleshooting).                                      |

Each error reaches you through the OpenAI client, inside LangGraph's traceback, with the proxy's `code`, `message` and `hint` in its body. In your own code, `ga.proxy_error(error)` turns it into the SDK's exception. The SDK's [Errors](https://guardian-agent-sdk.docs.eqtylab.io/reference/errors/) reference lists every error, with what to do.

## Go further

The [Guardian Agent SDK](https://guardian-agent-sdk.docs.eqtylab.io/) docs cover everything this page leaves out:

- [Deep Agents](https://guardian-agent-sdk.docs.eqtylab.io/frameworks/deep-agents/): skills, memory, backends, and what's refused.
- [MCP tools](https://guardian-agent-sdk.docs.eqtylab.io/frameworks/mcp-tools/): tools from MCP servers, with each server recorded.
- [Multiple agents](https://guardian-agent-sdk.docs.eqtylab.io/frameworks/multiple-agents/): several agents in one process, each signing as itself.
- [Test your agents](https://guardian-agent-sdk.docs.eqtylab.io/guides/testing/): run them in tests without Viper, keys or a network.

## Related

- [LangGraph Quickstart](./langgraph-quickstart.mdx) — the same setup for a single LangGraph graph
- [OpenShell Quickstart](./openshell-quickstart.mdx) — run an agent in a sandbox where Viper is its only way out
- [Run Agents](./run-agents.mdx) — sidecar mode in general, and troubleshooting for failed requests
- [Associated Agents](./associated-agents.mdx) — link the agent to a project so project policy applies
- [Agent Configuration](./agent-configuration.mdx) — what Viper captures about the agent at the start of each session
- [Agent Coverage](./agent-coverage.mdx) — how this integration's coverage compares with the others