|
| 1 | +# Rubric-based evaluation |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +Score response quality and tool-use quality against custom yes/no rubrics judged |
| 6 | +by an LLM, with no reference answer required. This sample evaluates the shared |
| 7 | +home-automation agent with two reference-free, LLM-judged criteria: |
| 8 | + |
| 9 | +- `rubric_based_final_response_quality_v1`: judges the agent's final response |
| 10 | + against rubrics about *how good the answer is* (does it name the device(s) in |
| 11 | + the requested location and report each one's on/off status? is it concise?). |
| 12 | +- `rubric_based_tool_use_quality_v1`: judges the agent's tool calls against |
| 13 | + rubrics about *how it used its tools* (does it filter `list_devices` by the |
| 14 | + room the user named? does it avoid changing the temperature when only asked to |
| 15 | + inspect devices?). |
| 16 | + |
| 17 | +Each criterion scores the agent against the custom yes/no rubrics you provide, so |
| 18 | +you evaluate quality directly instead of matching a golden answer. Because the |
| 19 | +judge is an LLM, this sample needs a model credential for the judge (a Gemini API |
| 20 | +key or Vertex), in addition to the credential used for the agent's own inference. |
| 21 | + |
| 22 | +## Sample Inputs |
| 23 | + |
| 24 | +The eval set (`home_automation.evalset.json`) contains one single-turn case: |
| 25 | + |
| 26 | +- `What devices are in the Bedroom?` |
| 27 | + |
| 28 | +## How To |
| 29 | + |
| 30 | +Run the sample from the workspace root: |
| 31 | + |
| 32 | +```bash |
| 33 | +adk eval contributing/samples/evaluation/home_automation_agent \ |
| 34 | + contributing/samples/evaluation/rubric_criteria/home_automation.evalset.json \ |
| 35 | + --config_file_path contributing/samples/evaluation/rubric_criteria/eval_config.json \ |
| 36 | + --print_detailed_results |
| 37 | +``` |
| 38 | + |
| 39 | +`adk eval` takes the agent folder and the eval-set file as two separate |
| 40 | +arguments, so this folder holds only eval data (`home_automation.evalset.json`), |
| 41 | +the criteria config (`eval_config.json`), and this README, with no agent code. |
| 42 | + |
| 43 | +### The `rubrics` list |
| 44 | + |
| 45 | +Both criteria are configured in `eval_config.json` through a `rubrics` list. Each |
| 46 | +rubric is a single yes/no property the judge decides against the agent's |
| 47 | +behavior: |
| 48 | + |
| 49 | +- `rubric_id`: a stable, unique identifier for the rubric (e.g. |
| 50 | + `reports_device_state`). It labels the rubric in the scored output and must be |
| 51 | + unique within the criterion. |
| 52 | +- `rubric_content.text_property`: the natural-language property being judged, |
| 53 | + phrased so the answer is a clean "yes" or "no" (e.g. "The response is concise |
| 54 | + and free of filler."). Write each property as one fair, achievable behavior; |
| 55 | + avoid bundling several requirements into one rubric. |
| 56 | + |
| 57 | +The `rubrics` list must be non-empty: `RubricBasedEvaluator` asserts this at |
| 58 | +init, so a rubric-based criterion with no rubrics fails immediately. |
| 59 | + |
| 60 | +For each invocation the judge is sampled `num_samples` times (here `5`); the |
| 61 | +per-rubric verdicts are combined by majority vote, and the criterion score is the |
| 62 | +fraction of rubrics that pass. The `threshold` then decides the case: |
| 63 | +`rubric_based_final_response_quality_v1` uses `0.8` (a strong majority of its |
| 64 | +rubrics must hold), and `rubric_based_tool_use_quality_v1` uses `1.0` (every |
| 65 | +tool-use rubric must hold). |
| 66 | + |
| 67 | +### Criterion-level vs. per-case rubrics |
| 68 | + |
| 69 | +The rubrics in `eval_config.json` are criterion-level: they apply to every |
| 70 | +eval case scored by that criterion. You can also attach rubrics to a single case |
| 71 | +via `EvalCase.rubrics` in the eval set. Per-case rubrics are filtered by their |
| 72 | +`type` field before they are handed to a criterion: |
| 73 | + |
| 74 | +- `rubric_based_final_response_quality_v1` only consumes rubrics of type |
| 75 | + `FINAL_RESPONSE_QUALITY`. |
| 76 | +- `rubric_based_tool_use_quality_v1` only consumes rubrics of type |
| 77 | + `TOOL_USE_QUALITY`. |
| 78 | + |
| 79 | +The filtered per-case rubrics are then added to the criterion-level list to |
| 80 | +form the effective rubric list for the case. Rubric IDs must be unique across the |
| 81 | +two scopes: a `rubric_id` that appears in both the criterion-level list and a |
| 82 | +case's `EvalCase.rubrics` raises an error: duplicates are not silently |
| 83 | +deduplicated or overridden. Use criterion-level rubrics for expectations shared |
| 84 | +across the whole eval set and per-case rubrics for expectations unique to one |
| 85 | +scenario. |
| 86 | + |
| 87 | +### When quality rubrics beat reference matching |
| 88 | + |
| 89 | +Reach for rubric-based criteria when "correct" isn't a single golden answer or |
| 90 | +trajectory. Reference-based criteria like `response_match_score` (ROUGE-1) or |
| 91 | +`tool_trajectory_avg_score` require you to write the expected answer or the exact |
| 92 | +sequence of tool calls, and they penalize any legitimate variation: a |
| 93 | +reworded-but-correct answer, or a harmless extra tool call. Rubrics instead let |
| 94 | +you state the *qualities* that matter ("confirms the device and its state", "uses |
| 95 | +a location filter") and let the judge decide whether the agent exhibited them, |
| 96 | +regardless of exact wording or an extra step. That makes them a good fit for |
| 97 | +open-ended responses and flexible trajectories where you care about quality, not |
| 98 | +byte-for-byte equality. The trade-off is the usual LLM-judge cost: a model call |
| 99 | +per sample, plus some run-to-run variability that `num_samples` and majority vote |
| 100 | +are there to smooth out. Keep the deterministic reference-based criteria when the |
| 101 | +answer or trajectory really is fixed. |
| 102 | + |
| 103 | +## Related Guides |
| 104 | + |
| 105 | +- Evaluation overview: https://adk.dev/evaluate/ |
| 106 | +- Evaluation criteria reference: https://adk.dev/evaluate/criteria/ |
0 commit comments