POST and records the response as feedback on the turn. The result appears as a tag or rating on the Signals tab of the Agents view.
This page covers remote scorers for agent turns. To score calls traced with @weave.op, see Score calls with remote scorers. You configure remote scorers with the Python SDK or the Weave UI. The TypeScript SDK doesn’t include RemoteScorer.
How agent turn scoring works
An agent turn is scored in the following sequence:- A turn ends. When a root span (a span with no parent) ends, Weave treats it as a completed turn and emits a
weave.genai.turn_endedevent. - The agent scoring worker loads the project’s active signals that target
weave.genai.turn_ended, then applies each signal’s filters and sample rate. - For each
RemoteScoreron a matching signal, the worker builds aschema_version: 2request from the turn’s span, including its messages, resolves the scorer’s credentials, checks the endpoint URL against the allowed hosts, and sends thePOST. - The worker validates the response and writes the result as feedback on the turn. Tags and ratings appear on the Signals tab.
Monitor whose op_names is ["weave.genai.turn_ended"], whether you create it in the UI or with the SDK.
If the endpoint returns 5xx, 408, or 429, or the request times out, the worker sends the request again with the same Idempotency-Key, up to three attempts within about 30 seconds. Any other 4xx response isn’t retried. Agent turn scoring requires the structured result format, because Weave stores the tags and ratings as typed feedback columns.
Enable remote scoring
Remote scoring is off until it’s enabled for your organization or deployment, and the scoring worker calls a scorer endpoint only if its host is on an allowlist. How you enable it depends on your deployment type. Multi-tenant Cloud An organization admin or billing admin enables remote scoring for the organization:- Open
https://wandb.ai/account-settings/[ORG]/settings, replacing[ORG]with the organization that owns your project. - Select the Remote scoring tab.
- Turn on Enable remote scoring.
- Under Allowed hosts, click Add host and enter each host that remote scorers may call. Saving with remote scoring enabled requires at least one host. Leave the port blank to allow any port on that host.
- Click Save settings.
weave_workers.remoteScoring. The chart renders them as environment variables on each worker that can call a remote scorer: the online evaluation worker, the call scoring worker, and the agent scoring worker.
Allowed host rules
The scoring worker checks every scorer endpoint URL, and separately the OAuth token endpoint URL when a scorer uses OAuth, against these rules:
- An entry matches an exact host, with an optional port. An entry without a port allows any port on that host.
- An entry that starts with
*.matches subdomains at any depth, but not the domain itself.*.corp.example.commatchesa.corp.example.comanda.b.corp.example.com, notcorp.example.com. The suffix after*.must contain at least two labels, so*.comis rejected. A wildcard can’t be combined with an IP address. - When both an operator allowlist and an organization allowlist exist, the URL must satisfy both. An empty operator allowlist adds no restriction. When no allowlist exists at all, the worker rejects every host.
- Loopback, private, internal, and cloud metadata addresses are rejected.
- HTTPS is required unless the deployment permits insecure HTTP.
- Redirects aren’t followed.
Build the scorer endpoint
Your endpoint accepts a JSONPOST from Weave and returns a JSON score.
Request
Weave sends one HTTPPOST per scored target to the scorer’s endpoint URL, with these headers:
Weave might deliver the same scoring attempt more than once. If your endpoint has side effects, use
Idempotency-Key to deduplicate. The key is stable for one request version, so a V1 and a V2 request for the same call carry different keys.
Every request body has these top-level fields:
Weave omits an optional field with no value rather than sending it as
null. Weave might add optional fields to a version without changing its number, so ignore fields you don’t recognize.
Request and response bodies are limited to 1 MiB each and contain JSON text only, never images, audio, or video. A target that exceeds these limits isn’t sent, so it isn’t scored. Each request carries one target.
For an agent turn, schema_version is 2 and the scored data is under scoring_target, a tagged union with three fields:
type: The kind of target.agent_turnfor a turn, orcallfor a traced call.schema_version: The version of the payload for that type, independent of the top-level version.payload: The data for that type.
schema_version first, then on the pair of scoring_target.type and scoring_target.schema_version. Return 4xx for a pair your endpoint doesn’t implement. The call payload at version 1 is the same object that a V1 request sends as original_call, so one endpoint can accept both by unwrapping the envelope first. Call monitors send V1.
The agent_turn payload at version 1 has these fields:
A turn that ends without an explicit status arrives with
status.code set to UNSET. Treat UNSET as a normal completed turn and ERROR as the failure signal. Each message in input and output has role, content, and finish_reason. content is plain text, or a JSON-encoded array of parts when the message carries structured content such as tool calls.
scoring_target.schema_version for that type, or a new top-level schema_version for changes to the envelope. A new target type joins the V2 union at inner version 1.
Response
Return HTTP200 with a JSON object that has two fields:
schema_version: Integer equal to the request’sschema_version.result: One score object, a list of score objects, or an object of the form{"scores": [...]}.
Weave treats any non-
200 response as a scorer failure and records no feedback for that attempt. Weave doesn’t follow redirects, so a redirect is also a failure. Weave doesn’t parse the body of an error response. Return 4xx for requests your endpoint never accepts and 5xx for temporary problems.
For an agent turn request, the response’s schema_version is 2, and result must use one of the three structured shapes:
Authenticate requests from Weave
Weave authenticates to your endpoint with a bearer token. The request carries no W&B credential. The token proves to your endpoint that the request came from Weave, not the reverse. EachRemoteScorer uses one of two modes:
Store the client secret or bearer token in the secret store of the team that owns the project before you register the scorer. The
RemoteScorer configuration holds only the secret name. The scoring worker resolves the value at scoring time.
The Weave UI also offers Deployment default, which stores no authentication configuration for the scorer and relies on a fallback credential set by the deployment operator. Multi-tenant Cloud sets no fallback credential. Use one of the two explicit modes.
Create a remote scorer signal
Create the signal in the Weave UI or with the Python SDK. Both create aRemoteScorer attached to a monitor that targets weave.genai.turn_ended.
Weave UI
Create the signal from the Agents view:- In the Weave project sidebar, click Agents.
- In the tab bar, click Signals.
- Click New signal, then click Remote scorer. If the project has no inference provider and no signals yet, click Use a remote scorer instead.
- In the Remote scorer drawer, Scored by is set to Remote scorer. Configure the following fields:
- Scorer name: The name shown in the Scorer column of the Signals table. Up to 128 characters.
- Scoring endpoint URL: The URL Weave sends the
POSTto. - Authentication: Static bearer or OAuth client credentials. For static bearer, select or enter the Bearer token secret name. For OAuth, enter the Token endpoint URL, Client ID, Client secret name, and optional Scope. Secret fields take team secret names, not values.
- Config (JSON, optional): A JSON object passed to your endpoint as
scorer.config. - Only score turns matching (Optional): Expand Advanced, then add filters to restrict which turns the signal scores, for example by agent name, agent version, operation name, tool name, or status code. To score every turn, leave it empty. Weave combines multiple filters with
ANDlogic. - Sample rate (Optional): Expand Advanced, then set the fraction of matching turns the signal scores.
- Click Create signal.
Python SDK
Publish aRemoteScorer, then activate a Monitor that lists it in scorers and targets weave.genai.turn_ended in op_names.
OAuthClientCredentialsConfig as auth_config instead. For both authentication classes, see Register a remote scorer.
Test the signal
Log one completed turn, then check the Signals tab. Scoring is asynchronous, so the result appears after a delay.scoring_target.type set to agent_turn, and Weave records the result as feedback on that turn.
Troubleshooting
Sample code
Theexamples/remote_scorer directory in the weave repository is the reference implementation of this contract and the source of truth for the sample code. One endpoint in that sample accepts V1 call requests, V2 call requests, and V2 agent turn requests. For agent turns, these files apply:
scoring_logic.py: Unwraps either envelope withextract_scoring_target, then scores the turn’s last output message.sample_request_v2_agent_turn.json: A complete V2 agent turn request.register_remote_scorer.py --agent-turn: Publishes aRemoteScorerand activates a monitor for completed agent turns.trigger_test_agent_turn.py: Logs one turn withweave.conversation.log_turn.
0.53.0 or later. A local run verifies only the contract. To test with Weave, deploy the endpoint at an HTTPS URL on the allowed hosts and register it as described in Create a remote scorer signal.