Skip to main content
Use a custom metric for rules that built-in scoring cannot express. This page integrates a scoring service; Create custom evals provides a complete local scorer, test cases, and unit tests. Custom metrics work with both ADK and LangGraph.

Harnest scoring helper

Create a bare scorer with harnest 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 under criteria 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
Scores default to a 0–1 range. Set metricInfo for another range; it describes scores without rescaling them.
ADK replaces 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.criterion so configuration remains the source of truth.
  • Return NOT_EVALUATED with 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.
A custom metric is trusted application code. Harnest imports and executes the configured function. Do not run an eval configuration or agent repository from an untrusted source.

Troubleshoot registration