Skip to main content
Evaluation closes the loop: you ran traces, you tracked cost, now you need to know how good the answers are. Cognis ships a small evaluation harness under cognis::eval for offline runs over a dataset — pair it with scores to push results into Langfuse.

Mental model

Three moving parts:
  • Cases(input, expected) pairs of type EvalCase<I, O>.
  • A runnable under test — anything Runnable<I, O>. An agent, a chain, or a custom impl.
  • An evaluatorEvaluator<O> produces a score in [0.0, 1.0] for an actual O against a reference O.
EvalRunner invokes every case through the runnable, scores each output, and produces an EvalReport.

Quick example

EvalReport<O> exposes mean(), pass_rate(threshold), passing(threshold), best(), worst(), plus the raw rows: Vec<EvalRow<O>>. Source: examples/observability/evaluation_framework.rs.

Built-in evaluators

LlmJudge takes a Client plus a rubric prompt; see crates/cognis/src/eval/evaluators.rs.

Custom evaluators

The trait is one async method:
Stack evaluators by running multiple EvalRunners over the same cases — most evals run a fast deterministic evaluator (exact match, length check) plus an LlmJudge for nuanced quality.

Pushing scores to Langfuse

Combine the eval report with LangfuseScorer (see Prompts and scores) to push every score record into Langfuse, tied to the trace of each case.
Run cases under a tracing observer to get the run_id per case (case_run_ids above); see Trace with Langfuse for the wiring.

How it works

  • Two passes per run: the runner invokes every case under a concurrency cap, then scores actuals against expecteds.
  • Concurrency follows with_concurrency(n) — defaults to 4. Tune for your provider’s quota when the runnable is a Client-backed chain.
  • Errors per case propagate from runner.run().await?. Wrap your runnable with with_max_retries if you want transient errors absorbed.
  • Reports are read-only summaries. EvalReport and EvalRow aren’t Serialize today — for snapshotting against baselines, build your own thin record from (name, score, actual) and serialize that.

See also

Prompts and scores

Push eval scores into Langfuse.

Trace with Langfuse

See production and eval runs side by side.