EQTY LabDocs

Deep Agents Quickstart

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.

View as Markdown

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 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).
  • Viper 0.3.0 or later, installed and pointed at your Agent Gateway. See Install Viper.
  • 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.
  • 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.

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:

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)

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

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.

Troubleshooting

SymptomWhat to do
viper proxy stops with no DID configured for proxyCreate the proxy’s key: viper did add --assign proxy.
Connection error. from the OpenAI clientNothing 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 proxySet 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 APISomething 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_incompatibleThe proxy’s Viper is older than the SDK needs. Upgrade to Viper 0.3.0 or later (Install Viper).
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 credentialsSet OPENAI_API_KEY.
Model requests fail with 401 from OpenAIOPENAI_API_KEY is wrong. The gateway does not add a key.
Model requests fail with 502 and another codeViper could not sign the request or reach the gateway; the error’s code and hint say which. See Run Agents.

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 reference lists every error, with what to do.

Go further

The Guardian Agent SDK docs cover everything this page leaves out:

  • Deep Agents: skills, memory, backends, and what’s refused.
  • MCP tools: tools from MCP servers, with each server recorded.
  • Multiple agents: several agents in one process, each signing as itself.
  • Test your agents: run them in tests without Viper, keys or a network.