nemo_voice_agent.evaluation.utils
nemo_voice_agent.evaluation.utils
Module Contents
Classes
Functions
Data
_JUDGE_CONTEXT_SYSTEM_STRING_LIMIT
API
LLM-based judge for evaluating voice agent responses.
Uses an OpenAI-compatible chat completions API to score how well a prediction matches a reference answer. Returns a float score between 0 and 1.
Parameters:
The URL of the OpenAI-compatible chat completions endpoint.
The model name to use for judging.
The API key. If None, will be loaded from environment variable.
The environment variable name for the API key (default: “API_KEY”).
Custom default system prompt. If None, uses DEFAULT_PROMPT.
Additional keyword arguments passed to the API payload (e.g., temperature, max_tokens).
Parse the LLM response and extract the judgement JSON.
Returns: A dict with “score” (float) and optionally “reason” (str). Raises: ValueError: If the response cannot be parsed.
Parameters:
The HTTP response from the API.
Judge the similarity between a reference and a prediction.
Returns: A dict with “score” (float between 0 and 1) and “reason” (str). On error, returns {“score”: 0.0, “reason”: “<error message>”}.
Parameters:
The reference answer string.
The prediction answer string.
Optional custom system prompt. Uses default_prompt if not provided.
Judge the similarity between a reference file and a prediction file.
Returns: A dict with “score” (float between 0 and 1) and “reason” (str).
Parameters:
Path to the reference JSON file.
Path to the prediction JSON file.
Optional custom system prompt.
Judge agent performance with full scenario context including conversation history.
Returns:
A dict with “score” (float between 0 and 1) and “reason” (str). When
nl_assertions is non-empty, also includes nl_assertion_verdicts
(list of {index, passed, reason}) and nl_assertion_pass_rate (float).
Parameters:
Optional reference answer string (or JSON string).
Optional prediction answer string (or JSON string).
List of conversation turns, each a dict with “role” and “text” keys.
Agent’s LLM context messages (from
bot_logs_agent/llm_context.json). Contains the agent’s
tool calls + results. Rendered as <agent_context_history>.
Simulated user’s LLM context messages
(from bot_logs_user/llm_context.json). Contains the
user-sim’s own tool calls — essential for dual-side
domains like telecom where reference actions with
side="user" are executed by the user-sim, not the
agent. Rendered as <user_context_history>.
Backward-compatible alias for agent_context_history.
Optional natural-language assertions (tau2 retail). When provided,
each assertion is appended to the prompt and the LLM is instructed to emit
a per-assertion verdict list. The returned dict gains a
nl_assertion_verdicts field (one entry per assertion, {index, passed, reason}`) plus `nl_assertion_pass_rate. Missing/malformed verdicts are
filled with passed=False so the runner can still aggregate cleanly.
When None (or empty), the returned shape is the basic
{score, reason} dict — no per-assertion fields.
Optional custom system prompt. Uses SCENARIO_PROMPT if not provided.
Deterministic local text normalizer used by evaluator matching.
Keep judge input useful without sending full prompt/history dumps.
Filter a tool-call arguments dict by tau2’s compare_args semantics.
compare_args=None → return args verbatim (compare all).
compare_args=[] → return {} (name-only match — empty == empty).
compare_args=[k...]→ return {k: args.get(k) for k in compare_args}.
Pitfall: do NOT write compare_args or "all"-style fallbacks — [] is
falsy and would silently collapse name-only matches into compare-all.
Tau2 stores compare_args: None explicitly (the key is present), so
ref.get("compare_args", "all") also doesn’t fire the default. The
explicit is None check below is the only safe sentinel.
Deterministic action-record match honoring tau2’s compare_args field.
Name must always match. Argument comparison is delegated to _filtered_args
which applies the compare_args filter to both sides before equality.
Reference records that omit compare_args (e.g. eva_airline records) get
the default None from ref.get("compare_args"), which means “compare
all arguments” — preserving existing behavior for non-tau2 domains.
Adapted from https://github.com/sierra-research/tau2-bench/tree/voice-user-sim-v1.0 src/tau2/data_model/tasks.py:175-182
Deterministic local punctuation normalizer used by evaluator matching.
Check if the prediction is matches with the reference answer.
Situations:
- If the reference is a dictionary, and the prediction is a dictionary:
- The prediction should have the same keys and values as the reference.
- Additional keys in prediction are allowed.
- If the reference is a dictionary, and the prediction is a list of dictionaries:
- the last dictionary in the prediction would be matched with the reference.
- If the reference is a list of dictionaries, and the prediction is a list of dictionaries:
- For each dictionary in the reference, there should be a dictionary in the prediction that matches it according to the criteria in Situation 1.
- The order of the dictionaries in the reference/prediction is not important.
- All dictionaries in the reference should be matched with a dictionary in the prediction to be considered as a success.
- If
disallow_extra_itemsis True, the lengths must also match exactly (exact bijection — no extra prediction items tolerated).
Both inputs are first passed through normalize_scenario_payload to
collapse the list-of-1-dict / single-dict shape difference. The remaining
situations 1-3 then handle the post-normalization shapes cleanly.
Returns: True if the task is considered as successful, False otherwise.
Parameters:
The path to the reference json file.
The path to the prediction json file.
Whether to ignore case when comparing strings.
Whether to ignore punctuation when comparing strings.
Whether to clean the text before comparing.
For list-of-dicts comparisons (Situation 3), require
len(reference) == len(prediction). Default False preserves the
lenient behavior where agent extras pass. Note: Situation 2 (single
dict reference, list-of-dicts prediction) is unaffected — the last
prediction dict is still picked and matched.
Check if pred_dict contains all keys and matching values from ref_dict. Additional keys in pred_dict are allowed.
Recursively match a reference value against a prediction value. Handles dicts, lists, strings, and numbers.
Check if each item in ref_list has a matching item in pred_list (order-independent). Each prediction item can only be matched once.
Match the reference and prediction value.
Returns: True if the reference and prediction value match, False otherwise.
Parameters:
The reference value, can be a string or a float.
The prediction value, can be a string or a float.
Whether to ignore capitalization when comparing strings.
Whether to ignore punctuation when comparing strings.
Whether to clean the text by replacing special characters before comparing.
Normalize a scenario payload (reference or prediction) to a canonical shape.
Used by both the deterministic comparator (check_if_task_success) and
the LLM judge prep path (runner.run_dynamic_evaluation) so they apply
the same shape-equivalence rule. Without this, the LLM judge reads the raw
file text and deducts for cosmetic {...} vs. [{...}] differences
that the deterministic comparator already treats as equivalent (its old
“Situation 2” logic). One source of truth, applied to both scoring paths.
Validate judge-related numeric options shared by CLI and library tests.