Harnest scoring helper
Create a bare scorer withharnest add eval company-quality --metric custom. It creates lib/company_quality.py without changing evaluation config. Implement the stub before registering it below.
Use @metric for sync or async scoring functions. Native ADK scorers still work without the decorator and can share the same configuration.
Add httpx to your dependencies and set EVAL_SERVICE_URL and EVAL_SERVICE_TOKEN. This example expects {"score": 0.9, "reason": "All required facts are present"}; adapt the payload to your service.
lib/company_evals.py
evals/test_config.json
MetricContext provides native ADK metric, actual and optional expected invocation tuples, optional scenario, and the configured threshold.
Choose a MetricScore return policy: one conversation score, one score per turn, or an explicitly unscored result.
Scores pass at or above the threshold. Use finite numbers; declare ranges outside 0–1 with metricInfo. Invalid results and service errors fail the evaluation.
Evidence is saved as ADK rubric rationale in the result JSON. Use the CLI for CI; the playground only scores the final turn.
Use a native ADK scorer
Use the native scorer contract when an existing evaluator needs direct ADK inputs or result control. Both sync and async scorers are supported; use async I/O for network scoring. Actual and expected turn counts can differ, and simulations may have no golden response. Keep aggregate and turn-level scores consistent. The native result contract explains per-turn rows and unevaluated results; the custom evaluation walkthrough shows a complete implementation.Register the function
Use the same name undercriteria and customMetrics. Authored root lib/ modules compile below harnest.lib, so lib/eval_metrics.py becomes harnest.lib.eval_metrics during evaluation.
evals/test_config.json
0–1 range. Set metricInfo for another range; it describes scores without rescaling them.
metricInfo.metricName with the owning customMetrics map key when registering the metric. Keep the two names identical in authored JSON for clarity.
Design a reliable metric
- Make the function deterministic unless model judgment is essential.
- Read the threshold from
metric.criterionso configuration remains the source of truth. - Return
NOT_EVALUATEDwith no score when evidence is genuinely unavailable; do not silently pass. A known violation, such as a missing required answer, can instead receive an explicit failing score. - Preserve actual and expected invocations in per-turn results so failures remain diagnosable.
- Keep network calls explicit and separately authenticated. Harnest’s transport sharing applies to declared judge and simulator models, not arbitrary SDK calls inside a custom function. Your function must configure and clean up any clients it creates. It can read the same process environment as the agent; it should never return credentials in diagnostic evidence.