Problem
Using a NeMo Gym agent as a Switchyard target requires writing all the glue
yourself. For one agent we had to build:
- an adapter translating Chat Completions to Gym's Responses API and back
- a buffered-to-streaming shim, because Gym answers in one shot
- a credential proxy, so the provider key stays out of the agent process
- a usage object shaped exactly as Gym's response model demands, or the whole run
is rejected after it completes
That is ~600 lines sitting between two NVIDIA projects that already speak
compatible protocols.
Why it matters
NeMo Gym is where NVIDIA agents are built, and Switchyard is where traffic is routed. In biology, the harness matters as much as the LLM itself. Many complex workflows require complex agent harness (such as biomni) rather than just a fine-tuned LLM.
Proposed behavior
A Gym agent as a target directly:
targets:
biology-search:
kind: gym_agent
agent: simple_scientific_literature_search_agent
base_url: http://127.0.0.1:9101
Switchyard would own the Responses API translation, the buffering, and the usage
contract — the parts that are identical for every Gym agent.
Example (very raw) implementation
Here switchyard routes to:
- Opus (LLM endpoint): default
- simple lit search agent: a simple arxiv/pubmed search agent implemented inside NeMo Gym. Nemotron Ultra 3 powers it underneath.
- biomni: a complex, deep research and biology AI scientist agent , impelmented inside Nemo Gym. Claude Opus powers it underneath
Orchestrator/Classifier model:
Nemotron 3 Ultra NVFP4 - chosen due to large context length, very fast performance, great reasoning capability.
Additional fixes
- Increase context length from default 16K to 200K, so classifier model can read into more context & make better routing decision
- Added the
[running] visual cues. Biomni agent runs for longer time, user could use a cue that it is invoked. In/Out token stats only returns after it finishes.
- Increase various timeouts
- Other bugs, still WIP
Setup
- Create the separate Gym and BioMni UV environments once:
source .venv/bin/activate
bash examples/gym_biology_agent/setup_gym.sh
- In terminal A, start the agent stack and leave it running. This launches the NeMo Gym with 2 agents running.
source .venv/bin/activate
bash examples/gym_biology_agent/run_agent_stack.sh
- In terminal B, launch switchyard
switchyard launch claude \
--model demo/biomni-agent \
--config examples/gym_biology_agent/routes.yaml
Q1 : Write a Python merge-sort function
Routes to Opus LLM
Q2 : Explain the mechanism of mRNA splicing
Routes to simple lit search agent in Gym
Gym trace:
Switchyard + Claude Code interface (note the [running] visual cue):
Q3: Compute BSA protein's basic protparam parameters: MW, pI, aa composition, extinction coeffcient (cys all reduced vs cys all forming pairs), half life, instability index
Routes to biomni agent in Gym
Gym trace:
Switchyard + Claude Code interface (note the [running] visual cue):
Results in the UI:
Preserving original hooks
Some users might have hooks with CC or Codex. These hooks might invoke memory bank search, such as below for the hindsight memory plugin. I had to make a few fixes so that the classifier passes the memory blocks (as shown below) to the agents.
Below shows a correct example of memory generated from hindsight OnPromptSubmit hook, being carried over to the agent (as displayed inside Gym trace):

Problem
Using a NeMo Gym agent as a Switchyard target requires writing all the glue
yourself. For one agent we had to build:
is rejected after it completes
That is ~600 lines sitting between two NVIDIA projects that already speak
compatible protocols.
Why it matters
NeMo Gym is where NVIDIA agents are built, and Switchyard is where traffic is routed. In biology, the harness matters as much as the LLM itself. Many complex workflows require complex agent harness (such as biomni) rather than just a fine-tuned LLM.
Proposed behavior
A Gym agent as a target directly:
Switchyard would own the Responses API translation, the buffering, and the usage
contract — the parts that are identical for every Gym agent.
Example (very raw) implementation
Here switchyard routes to:
Orchestrator/Classifier model:
Nemotron 3 Ultra NVFP4 - chosen due to large context length, very fast performance, great reasoning capability.
Additional fixes
[running]visual cues. Biomni agent runs for longer time, user could use a cue that it is invoked. In/Out token stats only returns after it finishes.Setup
source .venv/bin/activate bash examples/gym_biology_agent/setup_gym.shsource .venv/bin/activate bash examples/gym_biology_agent/run_agent_stack.shQ1 : Write a Python merge-sort function
Routes to Opus LLM
Q2 : Explain the mechanism of mRNA splicing
Routes to simple lit search agent in Gym
Gym trace:
Switchyard + Claude Code interface (note the
[running]visual cue):Q3: Compute BSA protein's basic protparam parameters: MW, pI, aa composition, extinction coeffcient (cys all reduced vs cys all forming pairs), half life, instability index
Routes to biomni agent in Gym
Gym trace:
Switchyard + Claude Code interface (note the
[running]visual cue):Results in the UI:
Preserving original hooks
Some users might have hooks with CC or Codex. These hooks might invoke memory bank search, such as below for the hindsight memory plugin. I had to make a few fixes so that the classifier passes the memory blocks (as shown below) to the agents.
Below shows a correct example of memory generated from hindsight OnPromptSubmit hook, being carried over to the agent (as displayed inside Gym trace):