Evaluate a Deployed Agent over HTTP
The quickstart evaluated an in-process agent.
This guide evaluates an agent that runs behind an HTTP endpoint — a service you (or someone else)
deployed. Everything else is the same: the same tasks, the same metrics, the same run(). Only the
target changes.
You describe an HTTP agent as a GenericAgent: its URL, the JSON request to send, and where the
answer lives in the response. The evaluator then calls that endpoint over real HTTP for each task.
This guide assumes you’ve done the quickstart
(install, tasks, metrics, run()). It reuses that quickstart’s KeywordMatchMetric and tasks.
1. Describe the agent
A GenericAgent has three parts you configure:
url— where the agent is reachable.body— the JSON request to POST, as a Jinja template rendered against the task’sinputs. Reference them directly: the task’s instruction is{{ instruction }}. The payload is entirely yours — the evaluator sends exactly whatbodyproduces.response_path— a JSONPath into the response that selects the agent’s answer.
Set body and response_path to match your agent’s request and response shape. Uncomment
api_key_secret for an agent that needs a token — for a local run() it names an environment
variable in your process, and for a submitted job it names a platform secret in the workspace; either
way its value is sent as a bearer token on each request. The local stand-in below needs no auth, so
this walkthrough leaves it off.
2. Run it against a local stand-in
To try this end to end without deploying anything, stand up a tiny local HTTP server that plays the
role of the agent. In practice you’d skip this and point url at your real endpoint.
3. Run the evaluation
With an agent target and no inference function supplied, run() generates answers by making real HTTP
calls to the agent’s url.
Point at your real agent
To evaluate your own deployed agent, change three things and drop the local server:
url→ your agent’s endpoint.body→ the request your agent expects (reference the task’s inputs, e.g.{{ instruction }}).response_path→ the JSONPath to the answer in your agent’s response.
Add api_key_secret="MY_AGENT_TOKEN" if it needs auth (an env var for a local run, a platform secret for a job). If your agent is a NeMo Agent Toolkit
workflow, use NemoAgentToolkitAgent instead of GenericAgent — it targets a NAT endpoint’s fixed
protocol, so you don’t hand-write a body template.
Streaming SSE agents
Set stream=True when the endpoint returns JSON Server-Sent Events. The evaluator applies
response_path to every data: payload and keeps the last matching value as the candidate output.
The raw evidence retains event: lines, but only payload fields such as data: become parsed stream
frames. An application-owned stream translator can turn those frames into an ATIF trajectory without
changing the shared HTTP transport.
The following example demonstrates how to evaluate a Hermes agent that streams SSE responses with
GenericAgent.
To set up Hermes locally:
- Follow the Hermes quickstart.
- After the agent is running and tested with
hermes --tui, set up the local gateway to interact with the agent over its API.- Set
API_SERVER_ENABLED=trueandAPI_SERVER_KEY=<key>in~/.hermes/.env. - Start the API server with
hermes gateway. - Export the same key as
HERMES_TOKENfor the evaluator client.
- Set
The complete Hermes example
defines HermesStreamTranslator, which implements the AgentStreamTranslator
protocol, and scores whether the deployed agent returns the requested phrase streaming works:
The SDK sends the bearer token from the HERMES_TOKEN environment variable, preserves the raw stream as evidence, and
passes the extracted output text to the task’s metrics. The Hermes translator reads the terminal
response.completed payload, validates completion, and records user/agent steps plus token usage in
ATIF-v1.7.
Full script
Expected output — the answers came back over HTTP and both contain the expected keyword:
Next steps
- Score the agent’s trajectory (its tool use), not just the final answer.
- Give a task multiple metrics and combine them into a named view.