Quality LLM URL
A2A Quality Evaluation Policy
Policy Name |
A2A Quality Evaluation |
Summary |
Evaluates A2A agent task responses with an LLM to score quality and completeness |
Category |
A2A |
First Omni Gateway version available |
v1.13.0 |
Release Notes |
|
Returned Status Codes |
No return codes exist for this policy. |
| This policy supports Agent2Agent Protocol (A2A) version v0.3.0. To learn more about A2A versions, see A2A Releases. |
Summary
The A2A Quality Evaluation policy evaluates completed A2A agent task responses using an LLM to score completeness against the original user intent. The policy only adds its verdict as response headers and emits metrics for observability. The policy doesn’t block or modify the agent’s response.
The policy evaluates quality when the final agent response is available:
-
Synchronous responses - When
message/sendreturns a200status with the final response, the quality LLM is invoked inline before the response is returned. -
Asynchronous responses - When
message/sendreturns a202status with a task ID, the policy stores the task metadata. Later, whentasks/getreturns acompletedstate, the policy invokes the quality LLM and caches the verdict for subsequent polls.
This policy supports A2A message/send and tasks/get requests across all transport protocols.
|
Configuring Policy Parameters
Managed Omni Gateway and Omni Gateway Connected Mode
When you apply the policy from the UI, the following parameters are displayed:
| Element | Description | Required | Default |
|---|---|---|---|
OpenAI-compatible chat completions endpoint for quality evaluation. The policy POSTs request to For example: |
Yes |
None |
|
Quality LLM API Key |
Bearer token for authenticating to the quality LLM endpoint. This value is encrypted at rest. |
Yes |
None |
Quality LLM Model |
Model name to use for quality evaluation. The name must be a valid model name supported by the configured endpoint. For example: |
No |
|
Request Timeout (ms) |
Timeout in milliseconds for the quality LLM call. If the call exceeds this timeout, the verdict isn’t attached and the policy logs a warning. |
No |
|
How This Policy Works
The A2A Quality Evaluation policy intercepts A2A requests and evaluates completed agent responses using a separate LLM. The policy works differently for synchronous and asynchronous agent responses.
Request Filtering
The policy only processes requests that meet all of the following criteria:
-
HTTP method is
POST -
Content-Typeheader matches a JSON MIME type -
Request body parses as a valid JSON-RPC request
-
JSON-RPC
methodis eithermessage/sendortasks/get
All other requests pass through without evaluation.
Synchronous Quality Flow (message/send with 200)
When an agent returns a synchronous 200 response to message/send:
-
The policy captures the original user message and the agent’s final response.
-
The policy invokes the quality LLM with a prompt containing both the user message and agent response.
-
The quality LLM returns a verdict with three fields:
-
evaluation:"yes"or"no"(whether the agent fully addressed the user’s request) -
value:"1","2", or"3"(quality score: 1=poor, 2=adequate, 3=excellent) -
explanation: Free-text explanation of the verdict
-
-
The policy adds quality verdict headers to the response.
For header details, see Quality Verdict Headers.
-
The policy emits a
mulesoft_agent_callscounter metric with the verdict tags (see Observability Metrics). -
The response is returned to the client with the original agent response body and added quality headers.
The quality LLM call happens inline, so it adds latency (up to the configured timeout) to the synchronous response path.
Asynchronous Quality Flow (message/send with 202, then tasks/get)
When an agent returns an asynchronous 202 response to message/send:
-
The policy captures the original user message and the returned task ID.
-
The policy stores the task metadata.
-
The response is returned immediately to the client with no quality headers and no LLM call.
Later, when a client polls with tasks/get and the upstream returns state: "completed":
-
The policy invokes the quality LLM, stores the verdict, adds quality verdict headers, and emits the observability metric.
-
The response is returned with the quality headers.
Subsequent polls of the same completed task return the stored verdict without re-invoking the LLM.
Quality Verdict Headers
When a quality verdict is available, the policy adds these headers to the response:
| Header | Description |
|---|---|
|
|
|
Quality score: |
|
Free-text explanation of the verdict provided by the quality LLM. |
Observability Metrics
Every time the quality LLM is invoked (synchronous 200 responses and the first tasks/get request that evaluates a completed task), the policy emits a single increment of the mulesoft_agent_calls counter metric.
The metric includes these tags:
| Tag | Values |
|---|---|
|
|
|
|
|
|
|
One of 20 bounded log-scale labels representing the quality LLM call latency in milliseconds: |
|
Only emitted when |
The metric counts distinct quality LLM calls, not distinct tasks. A task answered synchronously via 200 produces one metric increment. A task accepted as 202 and later polled to completed also produces one metric increment (on the first tasks/get poll that evaluates the completed task). Subsequent polls against an already-evaluated task don’t emit additional metrics.
|
A sustained non-zero rate of task_resolution="unknown" indicates that the quality LLM is unreachable or returning errors. Operators should alert on this condition.
Failure Modes
The policy is designed to fail open — quality evaluation failures do not block agent responses. Instead, failures are logged and reflected in observability metrics.
| Failure | Impact |
|---|---|
Quality LLM unreachable, non-200 response, or parse error |
No quality verdict headers are attached. The metric is emitted with |
Verdict storage fails |
The storage error is ignored. The policy may re-invoke the quality LLM on a subsequent |
Request body is not valid JSON-RPC |
The request passes through unchanged. No quality evaluation is performed. |
Quality LLM call exceeds the configured timeout |
Treated as a transport error. No quality verdict headers are attached. The metric is emitted with |
Constraints and Limitations
-
Synchronous latency - For synchronous
200responses, the quality LLM call happens inline and can add up to the configured timeout in latency. -
Asynchronous poll latency - For asynchronous tasks, the first
tasks/getpoll that returns acompletedstate incurs the quality LLM call latency.
Configuration Examples
The following examples demonstrate common configurations for the A2A Quality Evaluation policy using different LLM models, timeouts, and endpoint configurations.
Basic Configuration
This example configures the policy to evaluate agent responses using the gpt-4o model with a 10-second timeout:
apiVersion: gateway.mulesoft.com/v1alpha1
kind: PolicyBinding
metadata:
name: a2a-quality-evaluation
spec:
targetRef:
kind: ApiInstance
name: my-a2a-agent
policyRef:
name: a-two-a-quality-evaluation-flex
config:
qualityLlmUrl: "https://api.openai.com"
qualityLlmApiKey: "sk-proj-..."
qualityLlmModel: "gpt-4o"
timeout: 10000
Custom Model and Timeout
This example uses a faster model (gpt-4o-mini) with a shorter timeout for lower latency:
apiVersion: gateway.mulesoft.com/v1alpha1
kind: PolicyBinding
metadata:
name: a2a-quality-evaluation-fast
spec:
targetRef:
kind: ApiInstance
name: my-a2a-agent
policyRef:
name: a-two-a-quality-evaluation-flex
config:
qualityLlmUrl: "https://api.openai.com"
qualityLlmApiKey: "sk-proj-..."
qualityLlmModel: "gpt-4o-mini"
timeout: 5000
Using a Custom OpenAI-Compatible Endpoint
This example uses a self-hosted or alternative OpenAI-compatible endpoint:
apiVersion: gateway.mulesoft.com/v1alpha1
kind: PolicyBinding
metadata:
name: a2a-quality-evaluation-custom
spec:
targetRef:
kind: ApiInstance
name: my-a2a-agent
policyRef:
name: a-two-a-quality-evaluation-flex
config:
qualityLlmUrl: "https://custom-llm.example.com"
qualityLlmApiKey: "custom-api-key"
qualityLlmModel: "custom-model-v1"
timeout: 15000
Sample Response Headers
The following examples demonstrate the quality evaluation headers and metrics added by the policy for different response scenarios.
Synchronous Quality Flow
When an agent returns a synchronous 200 response, the policy evaluates the response inline and adds quality headers.
-
The initial request is sent:
{ "jsonrpc": "2.0", "id": 1, "method": "message/send", "params": { "message": { "parts": [ { "kind": "text", "text": "Cancel my order #12345" } ] } } } -
The upstream agent returns
200with the agent’s reply. The policy invokes the quality LLM, which returns:{ "evaluation": "yes", "value": "3", "explanation": "Order cancellation confirmed. The agent successfully canceled order #12345." } -
The policy adds these headers and emits these metrics:
-
Response headers:
x-quality-evaluation: yes x-quality-score: 3 x-quality-explanation: Order cancellation confirmed. The agent successfully canceled order #12345.
-
Metric emitted:
mulesoft_agent_calls{ task_resolution="yes", quality_score="3", method="message/send", latency_bucket="le_300" } 1
-
Asynchronous Quality Flow
When an agent returns a 202 response, the policy stores the task metadata and defers evaluation until the task is polled.
-
Initial request is sent:
{ "jsonrpc": "2.0", "id": 1, "method": "message/send", "params": { "message": { "parts": [ { "kind": "text", "text": "Cancel my order #12345" } ] } } } -
The upstream agent returns
202:{ "jsonrpc": "2.0", "id": 1, "result": { "id": "task-abc-123" } }The policy stores the task metadata. No quality headers are added. No metric is emitted.
-
The client polls the task:
{ "jsonrpc": "2.0", "id": 2, "method": "tasks/get", "params": { "id": "task-abc-123" } } -
The upstream agent returns
200with completed status:{ "jsonrpc": "2.0", "id": 2, "result": { "status": "completed", "message": { "parts": [ { "kind": "text", "text": "Your order #12345 has been canceled." } ] } } } -
The policy invokes the quality LLM, stores the verdict, and adds these headers and emits these metrics:
-
Response headers:
x-quality-evaluation: yes x-quality-score: 3 x-quality-explanation: Order cancellation confirmed.
-
Metric emitted:
mulesoft_agent_calls{ task_resolution="yes", quality_score="3", method="tasks/get", latency_bucket="le_450" } 1
-
Subsequent polls of the same task return the stored verdict and do not invoke the LLM or emit additional metrics.



