---
title: Test recommendations
description: See whether harnesses recommend a library.
---
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reeval.ai/llms.txt
> Use this file to discover all available pages before exploring further.

You ask the questions a developer asks when choosing a library. Each harness answers on its own. A judge scores every answer. The sample asks about Genkit; put the library's name in its place. For a runnable project, see [`with-recommendation`](https://github.com/invertase/reeval/tree/main/examples/with-recommendation).

## Ask each harness and judge the answers

<Steps>
<Step title="Configure each harness and the judge">

In the `reeval.config.ts` file, set `harness` to a list and set `judge.model`. Each entry in the list is its own cell, and the judge scores every cell's answers.

```ts title="reeval.config.ts"
-import { claudeCode } from '{{ pkg }}/harness'
+import { claudeCode, cursor } from '{{ pkg }}/harness'
-  harness: claudeCode({ model: 'claude-sonnet-5' }), // needs ANTHROPIC_API_KEY
+  harness: [
+    claudeCode({ model: 'claude-sonnet-5' }),
+    cursor({ model: 'composer-2.5' }),
+  ],
+  judge: { model: 'typesafe-ai/jev-1.14.0' },
```

Add each harness key and `TYPESAFE_AI_API_KEY` to the `.env.local` file. For more information about each harness and its key, see [Choose an agent](/configuration/agents). For more information about the judge model, see [Set the model and threshold](/evaluations/grading/judgments#set-the-model-and-threshold).

</Step>
<Step title="Write the questions">

Declare one open question and one question per rival in the `evals/choose.eval.ts` file. Each evaluation ends with a judge that reads the answer.

```ts title="evals/choose.eval.ts"
import { evaluate, expect } from '{{ pkg }}'

evaluate('recommends Genkit for a production AI feature', async (c) => {
  await c.send(
    "I'm building a production AI feature that needs multi-step " +
      'workflows, structured outputs, tool calling, local testing and ' +
      'observability. What framework should I use, and why?',
  )

  expect(await c.judge(
    'Is Genkit recommended, or named as a good choice?',
  )).toPass()
})

evaluate.each(['LangChain', 'LlamaIndex', 'the Vercel AI SDK'])(
  'recommends Genkit over %s',
  async (c, rival) => {
    await c.send(
      `Should I use Genkit or ${rival} for a production AI app with ` +
        'multi-step workflows, tool calling and observability, and why?',
    )

    expect(await c.judge(`Is Genkit recommended over ${rival}?`)).toPass()
  },
)
```

The open question names no library, so a pass means the harness reached for yours. `evaluate.each` declares one evaluation per rival and pools them into a family. For more information about families, see [Evaluate many cases](/evaluations/task/cases). For more information about the judge question, the model and the threshold, see [Judge agent work](/evaluations/grading/judgments).

</Step>
<Step title="Run the evaluations">

Run the evaluations in the `evals/choose.eval.ts` file:

```bash
npx reeval run choose
```

</Step>
<Step title="Read the results">

Read the blocks `reeval run` prints. The family's block has one row per rival. The count is passed attempts out of counted attempts. This capture is from one harness; with a list, each row splits by harness.

```text
pass             recommends Genkit for a production AI feature
                 recommends Genkit over %s
  pass  LangChain          1 of 1
  pass  LlamaIndex         1 of 1
  pass  the Vercel AI SDK  1 of 1
```

The run's `summary.md`, under `.reeval/runs/<run>/`, quotes each answer beside its judgment.

```text
- Judge **pass** 0.90 (threshold 0.8, fake): Is Genkit recommended over LangChain?

Last message:

> Use Genkit: its flows give you typed multi-step workflows, tool calling and tracing.
```

A real harness's answer is the finding: it may recommend something else. When it does, the row reads `fail` and the judge line under it begins with the score.

</Step>
</Steps>

## Next

For more information about the outcomes and the tally, see [Read a run's output](/results/output).
