Evalite is deprecated. This lesson still uses it. For evals, use Langfuse instead. You can self-host it.
Now we understand the basics about evals and how you can use LLM as a judge, scorers, and deterministic scorers. I want to put you in a situation where you can do some eval-driven development. We're going to redo an exercise that we did before: generating titles from a chat history.
We have an eval here called chat title generation that simply calls generateText passing in google('gemini-2.0-flash-lite') and says "generate me a title based on an input.":
const result = await generateText({model: google('gemini-2.0-flash-lite'),prompt: `Generate me a title:${input}`,});
Your job, and it is a pretty free-form job, is to improve this prompt by leveraging a dataset that I have prepared for you.
We have a titles-dataset.csv which has two columns: an input and a desired output. Here are some examples from the dataset:
| Input | Output |
|---|---|
| Did Google just release their latest smartwatch? | Google watch release date |
| How do I set up authentication in Next.js? | Next.js authentication setup |
| What are some recent changes to React Query? | React Query recent changes |
| Is there a way to optimize my Tailwind CSS bundle size? | Tailwind CSS optimization |
| When is the next Apple iPhone event? | Apple iPhone event schedule |
I manually wrote the first 5-10 entries and then I got an LLM to generate the rest.
In the eval, I'm reading the CSV file and parsing it into an array with input and output. Then I'm slicing off only the first five of the dataset and mapping that into a format that Evalite expects:
const EVAL_DATA_SIZE = 5;const dataForEvalite = data.data.slice(0, EVAL_DATA_SIZE).map((row) => ({input: row.Input,expected: row.Output,}));
Here's how I recommend you complete this exercise:
EVAL_DATA_SIZE of 5 just to start with.const result = await generateText({model: google('gemini-2.0-flash-lite'),prompt: `Generate me a title:${input}`,});
For instance, in the dataset it might say "react query recent changes" but in your output it might say "react query latest updates." Initially, you can just visually check between the golden output and your output to see if they're good enough.
At this point, the scorer will act more like an assistant - giving you extra feedback while you're manually evaluating the outputs.
They don't have to be exactly the same, but if they're comparable in quality then you can say yes, that's a win.
Consider this your chance to experiment with evals, trying to do some eval-driven development in a very free-form way. Good luck!