|
3 | 3 | # SPDX-License-Identifier: Apache-2.0 |
4 | 4 |
|
5 | 5 | title: "Get started with an example agent" |
6 | | -description: "Run the optimization loop from end to end on τ-Bench" |
| 6 | +description: "Run the optimization loop from end to end" |
7 | 7 | --- |
8 | 8 |
|
9 | | -This provides a guide for how you can quickly load agent traces into your NeMo Platform, run the analyst agent to discover issues with that agent, and launch an experimentalist to fix those issues. This is meant as an example to show how the whole platform works. You can also jump straight to setting up your agent with NeMo Platform. |
| 9 | +This guide runs the NeMo Platform optimization loop on a small example agent |
| 10 | +with a known bug. You will run the agent, and record the execution trace to NeMo |
| 11 | +Platform, use the Analyst to describe the problem, and run the Experimentalist |
| 12 | +to fix the problem. |
10 | 13 |
|
11 | 14 | ## Prerequisites |
12 | 15 |
|
13 | 16 | - Git, GNU Make, uv, and pnpm |
14 | | -- Docker Engine 29.6.2 or later |
| 17 | +- Docker Engine |
15 | 18 | - [Docker Sandboxes](https://docs.docker.com/ai/sandboxes/) (`sbx`) 0.37.1 or later |
16 | | -- An API key for the inference provider used by the Tau3 agent under test. |
| 19 | +- A Docker account signed in through `sbx login` |
| 20 | +- An API key for your model provider |
17 | 21 |
|
18 | | -## 1. Clone and bootstrap NeMo Platform |
| 22 | +## 1. Set up NeMo Platform |
19 | 23 |
|
20 | | -This step will walk you through setting up NeMo Platform on your local computer. It will install the platform and its dependencies. |
| 24 | +Clone the repository and install its dependencies: |
21 | 25 |
|
22 | 26 | ```bash |
23 | 27 | git clone https://github.com/NVIDIA-NeMo/nemo-platform.git |
24 | 28 | cd nemo-platform |
25 | 29 | make bootstrap |
26 | 30 | ``` |
27 | 31 |
|
28 | | -## 2. Start NeMo Platform |
29 | | - |
30 | | -Agent traces are stored in ClickHouse. Make sure Docker Desktop or the Docker daemon is running, then |
31 | | -run setup. Intake automatically provisions and reuses a local ClickHouse container. Setup starts the |
32 | | -platform services in the background and walks you through the configuration required to run the platform: |
| 32 | +Make sure Docker is running, then start the Platform: |
33 | 33 |
|
34 | 34 | ```bash |
35 | 35 | uv run nemo setup |
36 | 36 | ``` |
37 | 37 |
|
38 | | -Register the provider you want the Platform agents to use, then select a |
39 | | -default model for quality-critical work and a fast model for latency-sensitive |
40 | | -work. Press Enter at the fast-model prompt to reuse the default. These |
41 | | -workspace-qualified Model Entities are used by the Analyst, Eval Author, and |
42 | | -Experimentalist; their provider credentials stay in Platform Secrets. |
43 | | - |
44 | | -To use an external ClickHouse instead, set `NMP_INTAKE_CLICKHOUSE_URL` before running setup. |
45 | | - |
46 | | -You should now be able to navigate to `http://localhost:8080` and see the NeMo Platform web UI. |
47 | | - |
48 | | -## 3. Prepare τ-Bench and run the airline agent |
49 | | - |
50 | | -Now that we have a running NeMo Platform, it's time to load up some data! This example uses the τ-Bench from Sierra. It's a great representation of a simplified agent that performs a business-critical task. Our first step will be to set up our environment variables so that we can run models properly. |
51 | | - |
52 | | -```bash |
53 | | -cp plugins/nemo-experimentalist/examples/tau3-nooa-agent/.env.example plugins/nemo-experimentalist/examples/tau3-nooa-agent/.env |
54 | | -``` |
| 38 | +Follow the prompts to connect a model provider and select the default and fast |
| 39 | +models. Press Enter to use the default model for both. |
55 | 40 |
|
56 | | -Then, update the `.env` file with the inference endpoint and key for the Tau3 |
57 | | -agent under test. If you will run the Experimentalist in a Docker Sandbox, |
58 | | -also uncomment `NEMO_DEFAULT_MODEL` and `NEMO_FAST_MODEL` and copy the |
59 | | -workspace-qualified IDs reported by `nemo setup`. Source the file afterward. |
| 41 | +Open [NeMo Studio](http://localhost:8080) when setup finishes. |
60 | 42 |
|
61 | | -```bash |
62 | | -source plugins/nemo-experimentalist/examples/tau3-nooa-agent/.env |
63 | | -``` |
| 43 | +## 2. Record a failing run |
64 | 44 |
|
65 | | -Then, we'll run a script to download the benchmark datasets and put it into the appropriate directories: |
| 45 | +Create a sandbox and build the smoke agent's small test environment: |
66 | 46 |
|
67 | 47 | ```bash |
68 | | -plugins/nemo-experimentalist/examples/tau3-nooa-agent/prepare-airline-datasets.sh |
69 | | -``` |
| 48 | +repo="$(git rev-parse --show-toplevel)" |
| 49 | +smoke="plugins/nemo-experimentalist/examples/smoke-agent" |
| 50 | +workspace="smoke-agent" |
| 51 | +platform_url="http://host.docker.internal:8080" |
70 | 52 |
|
71 | | -Finally, we'll run our agent using the dataset tasks and record the data to NeMo Platform: |
| 53 | +sbx create --clone --name nemo-experimentalist shell "$repo" |
| 54 | +sbx policy check network --sandbox nemo-experimentalist localhost:8080 || |
| 55 | + sbx policy allow network --sandbox nemo-experimentalist localhost:8080 |
| 56 | +sbx exec --user root nemo-experimentalist bash -lc \ |
| 57 | + 'apt-get update && apt-get install -y build-essential python3-dev' |
72 | 58 |
|
73 | | -```bash |
74 | | -uv run --frozen plugins/nemo-experimentalist/examples/tau3-nooa-agent/record_tau_airline_traces.py |
| 59 | +sbx exec --workdir "$repo" \ |
| 60 | + --env UV_PROJECT_ENVIRONMENT=/home/agent/.venvs/nemo-platform \ |
| 61 | + nemo-experimentalist bash -lc " |
| 62 | + uv run --no-project $smoke/scripts/build_image.py && |
| 63 | + uv run --frozen --python 3.13 \ |
| 64 | + --package nemo-experimentalist-plugin \ |
| 65 | + --with ./plugins/nemo-agents \ |
| 66 | + python $smoke/scripts/record_traces.py \ |
| 67 | + --group g1-aggregation \ |
| 68 | + --split insight-evidence \ |
| 69 | + --workspace $workspace \ |
| 70 | + --agent $smoke/agent \ |
| 71 | + --base-url $platform_url" |
75 | 72 | ``` |
76 | 73 |
|
77 | | -To run more tasks concurrently, add an explicit value such as `--concurrency 10`. |
78 | | -Each task starts Docker containers, so choose a value appropriate for your |
79 | | -available CPU and memory. |
| 74 | +If an organization policy rejects the local allow rule, ask your administrator |
| 75 | +to allow `localhost:8080`. |
80 | 76 |
|
81 | | -At this point you can navigate to the [traces tab](http://localhost:8080/studio/workspaces/tau3-airline/intake/traces) and see the traces from the agent. |
| 77 | +The command runs five tasks that expose the same bug in our agent. Open the |
| 78 | +[Traces view](http://localhost:8080/studio/workspaces/smoke-agent/intake/traces) |
| 79 | +to see the results. |
82 | 80 |
|
83 | | -## 4. Run the Analyst |
| 81 | +<Warning> |
| 82 | +The Experimentalist runs model-written code. The sandbox protects your working |
| 83 | +tree, but it can read the cloned repository and any values passed with `--env`. |
| 84 | +</Warning> |
84 | 85 |
|
85 | | -Now that we have data in our system, we can run the analyst agent to understand the ways that our agent is performing well, and where it is falling down. The goal of the analyst agent is to crawl production data, and determine where your agent is falling down or disappointing your customers. |
| 86 | +## 3. Find the problem |
86 | 87 |
|
87 | | -If the analyst discovers issues in your application, it will create what we call an 'insight'. An insight is a human-readable description of a problem in your agentic system. The closest analogy is a bug report. They don't try to describe why an issue happened or the code you should change to fix it, and they should be understandable to a user of your agent. |
| 88 | +The Analyst will examine the agent traces and identify significant problems in |
| 89 | +your AI application, called an 'Insight'. An insight is a description of a |
| 90 | +problem occurring in your AI agent. |
88 | 91 |
|
89 | | -Let's run it: |
| 92 | +Run the Analyst against the failing traces: |
90 | 93 |
|
91 | 94 | ```bash |
92 | 95 | uv run --frozen nemo agents analyst run \ |
93 | | - --agent nemo-experimentalist-tau3-nooa \ |
94 | | - --workspace tau3-airline \ |
95 | | - --base-url "$NMP_BASE_URL" |
| 96 | + --agent smoke-agent \ |
| 97 | + --agent-spec "$smoke/AGENT-SPEC.md" \ |
| 98 | + --workspace "$workspace" |
96 | 99 | ``` |
97 | 100 |
|
98 | | -This will take a few minutes to run. Once it's done, you can navigate to the [insights tab](http://localhost:8080/studio/workspaces/tau3-airline/optimizer) to see the issues the analyst discovered in the τ-Bench Airline Agent. |
| 101 | +The Analyst creates an Insight: a short description of the problem. It will also |
| 102 | +include the traces where it saw the problem. You can always navigate to the |
| 103 | +traces to see the actual execution that the Analyst identified as problematic, |
| 104 | +and see if you agree that it is a problem. |
99 | 105 |
|
100 | | -## 5. Optimize performance with the experimentalist |
101 | | - |
102 | | -The next step is to improve the τ-Bench agent using the experimentalist. The |
103 | | -experimentalist will run your evals, debug failures using trace data, understand |
104 | | -the root cause of the failure and attempt to fix it. After it makes the change, |
105 | | -it will run the evals again to validate whether the change improved the |
106 | | -performance of your agent on the evaluation. |
107 | | - |
108 | | -This is a shortened example that only uses a few tasks, but it can still take up |
109 | | -to an hour to finish. First we will set up a new workspace for the optimization process: |
| 106 | +Copy the Insight ID shown in square brackets at the end of the command: |
110 | 107 |
|
111 | 108 | ```bash |
112 | | -uv run --frozen nemo workspaces create canonical-tau3-airline \ |
113 | | - --description "Tau3 Airline Experimentalist runs" \ |
114 | | - --exist-ok |
| 109 | +insight_id="<Insight ID>" |
115 | 110 | ``` |
116 | 111 |
|
117 | | -The Experimentalist generates a draft pull request (PR) or merge request (MR) |
118 | | -when it receives a GitHub or GitLab agent source. It creates a branch only when |
119 | | -a changed candidate wins validation. |
| 112 | +You can also find it in the |
| 113 | +[Insights view](http://localhost:8080/studio/workspaces/smoke-agent/optimizer). |
120 | 114 |
|
121 | | -Git integration is optional. To run the optimization without creating a |
122 | | -repository or PR/MR, [jump to the local-only alternative](#optional-run-locally-without-creating-a-pr-or-mr). |
| 115 | +## 4. Fix the problem |
123 | 116 |
|
124 | | -To optimize the example agent, create a private GitHub repository with the |
125 | | -[GitHub CLI](https://cli.github.com/) and populate it with the example source. |
126 | | -Replace `your-github-user-or-org` with the GitHub account or organization that |
127 | | -will own the repository. `rsync` excludes `.env`, so your API key is not copied |
128 | | -into the repository. |
| 117 | +Load the models you selected during setup: |
129 | 118 |
|
130 | 119 | ```bash |
131 | | -gh auth login |
132 | | -# Choose HTTPS when prompted for the preferred Git protocol. |
133 | | -export GITHUB_OWNER="your-github-user-or-org" |
134 | | -mkdir -p "$HOME/src" |
135 | | -cd "$HOME/src" |
136 | | -gh repo create "$GITHUB_OWNER/tau3-nooa-agent" --private --clone |
137 | | -export EXAMPLE_AGENT_REPO="$PWD/tau3-nooa-agent" |
138 | | -cd - |
139 | | -rsync -a --exclude='.env' plugins/nemo-experimentalist/examples/tau3-nooa-agent/ "$EXAMPLE_AGENT_REPO/" |
140 | | -git -C "$EXAMPLE_AGENT_REPO" checkout -b main |
141 | | -git -C "$EXAMPLE_AGENT_REPO" add . |
142 | | -git -C "$EXAMPLE_AGENT_REPO" commit -m "Add the tau3 NOOA example agent" |
143 | | -git -C "$EXAMPLE_AGENT_REPO" push -u origin main |
144 | | -export AGENT_REPO_URL="https://github.com/$GITHUB_OWNER/tau3-nooa-agent.git" |
| 120 | +read -r NEMO_DEFAULT_MODEL NEMO_FAST_MODEL < <( |
| 121 | + uv run --frozen python -c \ |
| 122 | + 'from nemo_platform.config import get_context; c = get_context(); print(c.default_model, c.fast_model or c.default_model)' |
| 123 | +) |
| 124 | +export NEMO_DEFAULT_MODEL NEMO_FAST_MODEL |
145 | 125 | ``` |
146 | 126 |
|
147 | | -Run the Experimentalist against the Git repository inside a Docker Sandbox. The |
148 | | -`@main` suffix selects the source ref to optimize. It clones that baseline, |
149 | | -pushes a validated winner to a new branch, and opens a draft PR or MR against |
150 | | -`main`. To use a different target branch, set `storage.pr_base_branch` in the |
151 | | -configuration. Authenticate GitHub inside the sandbox so it can clone and push |
152 | | -the private repository. |
153 | | - |
154 | | -<Warning> |
155 | | -Clone mode is an integrity boundary, not a confidentiality boundary. The sandbox |
156 | | -can read the cloned host repository and every credential passed with `sbx exec --env`. |
157 | | -Use dedicated, revocable, spending-limited credentials. |
158 | | -</Warning> |
| 127 | +Run the Experimentalist: |
159 | 128 |
|
160 | 129 | ```bash |
161 | | -repo="$(git rev-parse --show-toplevel)" |
162 | | -sbx create --clone --name nemo-experimentalist-git shell "$repo" |
163 | | -gh auth token | sbx exec -i --workdir "$repo" nemo-experimentalist-git \ |
164 | | - gh auth login --with-token |
165 | | -sbx exec --workdir "$repo" nemo-experimentalist-git gh auth setup-git |
166 | | -sbx exec --workdir "$repo" nemo-experimentalist-git \ |
167 | | - git clone "$AGENT_REPO_URL" /tmp/tau3-nooa-agent |
168 | 130 | sbx exec --workdir "$repo" \ |
169 | 131 | --env UV_PROJECT_ENVIRONMENT=/home/agent/.venvs/nemo-platform \ |
170 | | - --env INFERENCE_API_KEY \ |
171 | | - --env INFERENCE_API_BASE \ |
172 | | - --env OPENAI_API_KEY \ |
173 | | - --env OPENAI_BASE_URL \ |
174 | 132 | --env NEMO_DEFAULT_MODEL \ |
175 | 133 | --env NEMO_FAST_MODEL \ |
176 | | - --env TAU2_USER_MODEL \ |
177 | | - --env TAU2_NL_ASSERTIONS_MODEL \ |
178 | | - --env AUT_MODEL_NAME \ |
179 | | - nemo-experimentalist-git \ |
180 | | - uv run --frozen --python 3.13 --package nemo-experimentalist-plugin --with ./plugins/nemo-agents \ |
181 | | - nemo agents experimentalist run \ |
182 | | - --no-insight \ |
183 | | - --agent "${AGENT_REPO_URL}@main" \ |
184 | | - --agent-spec /tmp/tau3-nooa-agent/AGENT-SPEC.md \ |
185 | | - --train-dataset /run/sandbox/source/plugins/nemo-experimentalist/tmp/tau3-airline/experimentalist/train \ |
186 | | - --validation-dataset /run/sandbox/source/plugins/nemo-experimentalist/tmp/tau3-airline/experimentalist/validation \ |
187 | | - --workspace canonical-tau3-airline \ |
188 | | - --framework-skills plugins/nemo-experimentalist/framework-skills/nooa \ |
189 | | - --config /tmp/tau3-nooa-agent/experimentalist-smoke.yaml \ |
190 | | - --experiment-dir plugins/nemo-experimentalist/tmp/tau3-airline-experimentalist \ |
191 | | - --base-url http://host.docker.internal:8080 |
192 | | -``` |
193 | | - |
194 | | -This setup enables `storage.archive_candidates`, which pushes every generated |
195 | | -candidate branch; the default pushes only the winner. After the run, inspect a |
196 | | -non-winning candidate with `git fetch origin`, |
197 | | -`git -C "$EXAMPLE_AGENT_REPO" branch -r --list 'origin/optimizer/*'`, and |
198 | | -`git diff main...origin/optimizer/<run-id>/<candidate>`. |
199 | | - |
200 | | -GitLab is supported too: use a GitLab repository URL and authenticate with |
201 | | -`glab auth login`. The Experimentalist opens a draft PR/MR only when it finds a |
202 | | -changed winning candidate. |
203 | | - |
204 | | -The trace records include the Experimentalist evaluation ID and Tau3 task ID. |
205 | | -After the run completes, inspect the sandbox's |
206 | | -`plugins/nemo-experimentalist/tmp/tau3-airline-experimentalist/eval-and-optimize/run.json` |
207 | | -for the selected winner and compare the `agent-0` and `agent-1` directories to |
208 | | -review the code change that was evaluated. |
209 | | - |
210 | | -### Optional: run locally without creating a PR or MR |
211 | | - |
212 | | -Use this alternative if you do not want to create or push to a repository. It |
213 | | -changes only a private sandbox clone and never creates a PR/MR. The sandbox |
214 | | -uses `host.docker.internal` to reach the NeMo Platform services running on the |
215 | | -host: |
216 | | - |
217 | | -```bash |
218 | | -repo="$(git rev-parse --show-toplevel)" |
219 | | -sbx create --clone --name nemo-experimentalist shell "$repo" |
220 | | -sbx exec --workdir "$repo" \ |
221 | | - --env UV_PROJECT_ENVIRONMENT=/home/agent/.venvs/nemo-platform \ |
222 | | - --env INFERENCE_API_KEY \ |
223 | | - --env INFERENCE_API_BASE \ |
224 | | - --env OPENAI_API_KEY \ |
225 | | - --env OPENAI_BASE_URL \ |
226 | | - --env NEMO_DEFAULT_MODEL \ |
227 | | - --env NEMO_FAST_MODEL \ |
228 | | - --env TAU2_USER_MODEL \ |
229 | | - --env TAU2_NL_ASSERTIONS_MODEL \ |
230 | | - --env AUT_MODEL_NAME \ |
231 | 134 | nemo-experimentalist \ |
232 | | - uv run --frozen --python 3.13 --package nemo-experimentalist-plugin --with ./plugins/nemo-agents \ |
233 | | - nemo agents experimentalist run \ |
234 | | - --no-insight \ |
235 | | - --agent plugins/nemo-experimentalist/examples/tau3-nooa-agent \ |
236 | | - --agent-spec plugins/nemo-experimentalist/examples/tau3-nooa-agent/AGENT-SPEC.md \ |
237 | | - --train-dataset /run/sandbox/source/plugins/nemo-experimentalist/tmp/tau3-airline/experimentalist/train \ |
238 | | - --validation-dataset /run/sandbox/source/plugins/nemo-experimentalist/tmp/tau3-airline/experimentalist/validation \ |
239 | | - --workspace canonical-tau3-airline \ |
240 | | - --framework-skills plugins/nemo-experimentalist/framework-skills/nooa \ |
241 | | - --config plugins/nemo-experimentalist/examples/tau3-nooa-agent/experimentalist-smoke.yaml \ |
242 | | - --experiment-dir plugins/nemo-experimentalist/tmp/tau3-airline-experimentalist \ |
243 | | - --base-url http://host.docker.internal:8080 |
| 135 | + uv run --frozen --python 3.13 \ |
| 136 | + --package nemo-experimentalist-plugin \ |
| 137 | + --with ./plugins/nemo-agents \ |
| 138 | + nemo agents experimentalist run \ |
| 139 | + --profile "$smoke/optimizer.yaml" \ |
| 140 | + --insight "$insight_id" \ |
| 141 | + --workspace "$workspace" \ |
| 142 | + --base-url "$platform_url" \ |
| 143 | + --experiment-dir "$smoke/.nemo-optimizer/example-run" \ |
| 144 | + --config "$smoke/configs/short.yaml" |
| 145 | + |
| 146 | +mkdir -p tmp |
| 147 | +sbx cp "nemo-experimentalist:$repo/$smoke/.nemo-optimizer/example-run" \ |
| 148 | + tmp/smoke-agent-example-run |
244 | 149 | ``` |
245 | | -The sandbox needs outbound access to the package, model, registry, Harbor |
246 | | -dataset, and NeMo Platform endpoints used by the run. `host.docker.internal` |
247 | | -is translated to the host's loopback interface so the sandbox can reach the |
248 | | -NeMo Platform service on port 8080. |
249 | 150 |
|
250 | | -<Warning> |
251 | | -Clone mode protects the host checkout from writes, but it does not isolate |
252 | | -secrets or host services from code in the sandbox. The complete host repository, |
253 | | -including ignored `.env` files, is readable at `/run/sandbox/source`. Values |
254 | | -passed with `sbx exec --env` are readable by the optimizer, candidate agents, |
255 | | -Harbor verifier, and their subprocesses. Use dedicated, revocable, |
256 | | -spending-limited credentials, and do not expose unrelated host services or |
257 | | -network destinations. Optimizer and task code can use any outbound access |
258 | | -granted to the sandbox. |
259 | | -</Warning> |
| 151 | +The Experimentalist studies the Insight, creates possible fixes, and tests them |
| 152 | +against new tasks. Return to the [Insights |
| 153 | +view](http://localhost:8080/studio/workspaces/smoke-agent/optimizer) when the |
| 154 | +run finishes to compare the original agent with the selected fix. This can take quite a bit of time to run. |
260 | 155 |
|
261 | | -The trace records include the Experimentalist evaluation ID and Tau3 task ID. |
262 | | -After the run completes, inspect the run summary and compare the baseline with |
263 | | -the candidate. The `diff` command exits with status 1 when it finds candidate |
264 | | -changes, which is expected: |
| 156 | +Once it finishes, you can examine the improved agent in |
| 157 | +`tmp/smoke-agent-example-run`. |
| 158 | +When you run the experimentalist on a real agent, you would upload these changes |
| 159 | +to a Pull Request. |
265 | 160 |
|
266 | | -```bash |
267 | | -artifact_dir="plugins/nemo-experimentalist/tmp/tau3-airline-experimentalist/eval-and-optimize" |
268 | | -sbx exec --workdir "$repo" nemo-experimentalist \ |
269 | | - sed -n '1,240p' "$artifact_dir/run.json" |
270 | | -sbx exec --workdir "$repo" nemo-experimentalist \ |
271 | | - diff -ru "$artifact_dir/agents/agent-0" "$artifact_dir/agents/agent-1" |
272 | | -``` |
| 161 | +## 5. Clean up |
273 | 162 |
|
274 | | -Copy artifacts you want to retain to the host before removing the sandbox: |
275 | | - |
276 | | -```bash |
277 | | -mkdir -p tmp/tau3-airline-artifacts |
278 | | -sbx cp "nemo-experimentalist:$repo/$artifact_dir" \ |
279 | | - tmp/tau3-airline-artifacts/ |
280 | | -``` |
281 | | - |
282 | | -Stopping preserves the VM, its private Git clone, experiment output, installed |
283 | | -packages, and Docker image/build cache. Remove the sandbox when you no longer |
284 | | -need that state: |
| 163 | +Remove the sandbox when you are done: |
285 | 164 |
|
286 | 165 | ```bash |
287 | 166 | sbx stop nemo-experimentalist |
288 | 167 | sbx rm nemo-experimentalist |
289 | 168 | ``` |
| 169 | + |
| 170 | +To run the loop on your own agent, continue with the |
| 171 | +[agent onboarding guide](/documentation/get-started). |
0 commit comments