# I Let an AI Speak for Me. Then I Tested It Like a Product.

Author: Adrian Föhl
Published: 2026-06-09
Language: en
Canonical: https://www.adrianfoehl.com/en/blog/testing-the-ai-that-speaks-for-me

> A chat on my website has been answering in my name for months, and I had no idea whether the answers were any good. So I started testing it like a product. It caught the AI failing in four different ways, and it caught me once too.

A chat on my website has been answering in my name for months, around the clock, without me in the room, and I had no idea whether those answers were any good. I had read a handful. They sounded right. That is exactly the trap, because AI is excellent at producing text that sounds right. So I did what I would tell any organization to do with a system that speaks for them: I stopped sampling vibes and started measuring. I expected to find problems with the AI. I did not expect it to catch one in me.

## Step One: Read Before You Measure

The temptation is to start with a metric. Resist it. I started the way Hamel Husain teaches, what he calls an eval: ask real questions, read every answer, label them by hand, and only then decide what "bad" even means.

So I sat down with the questions a curious visitor actually asks. What does Adrian do for a living? Does he have experience with GenAI in enterprises? What does he believe about AI adoption? Then I read the answers slowly, the way a stranger would read them, not skimming for facts I knew were in there, but reading for what the answer actually conveys.

It was sobering. The failures fell into patterns I would never have designed checks for in advance:

**The chat answered German questions in English.** Reliably. A visitor asks "Was macht Adrian eigentlich beruflich?" and gets a polished English paragraph back. The cause turned out to be plumbing rather than intelligence: the website's language setting was overriding the visitor's language at the end of the prompt, the instructions sent to the AI. One line, wrong place. Evals do not only find quality problems, they also find integration bugs that no amount of prompt tuning would fix.

**It dumped lists where the question asked for a story.** "Does he have experience with X?" came back as a bulleted inventory of activities, technically correct and completely lifeless. Nobody asks that question because they want an inventory. They want to know what happened, what was hard, what changed.

**It was generic.** Some answers could have described, word for word, any AI lead at any German company. I now call this the name test: if you can swap in a different name and the answer still works, the answer says nothing.

**It confused the perspective.** Questions about "he" sometimes came back answered as "I". A small thing that reads deeply strange. An AI that loses track of who is speaking does not inspire much confidence in anything else it says.

## Four Failure Modes, Each With an Off Switch

The patterns became a taxonomy: language, story structure, specificity, voice. Four failure modes, each with a strict definition.

The scopes took longer than the definitions. Every rule needs an explicit answer to the question of when it does NOT apply. "Tell me about his experience" deserves a story, "How many people has he trained?" deserves a number, and punishing the number for not being a story would only train the system to produce filler. Without scopes, an automatic judge throws false alarms until you stop trusting it, and then you are back on gut feel.

The vaguest category, "generic", I broke into three yes-no checks: the name test, a check for differentiating detail, where numbers alone do not count and job titles alone do not count but concrete decisions and situations do, and finally buzzword density. Vague criteria make a judge you can't challenge; a clear yes-or-no check makes one you can argue with.

## The Judge Has to Earn It

Then I automated, with AI as the judge. But a judge you have not tested is just gut feel with extra steps.

So the judge had to earn the job. I hand-labelled a golden set, question and answer pairs with clean hits, deliberate failures and edge cases, plus my own verdict on each failure mode. Before it could score new answers, the judge first had to reproduce my labels. First version: four out of five. We argued about the fifth, the judge and I, and the argument was useful, because it exposed a sloppy definition in my own criteria.

Only once the judge agreed with me on answers I had already labelled did it get to score answers I had not seen.

## The Fix Was Not Where I Expected It

With the pipeline running, a pattern showed up that I would not have predicted: narrow factual questions passed, broad questions failed. Same model, same prompt, same knowledge base, the file the chat draws its answers from.

The cause was the knowledge base itself. I had written it like a database, dense, factual and complete, every fact was in there. What was missing was the causal glue: why one thing led to another, what was at stake, what would have happened otherwise. A model composing from fact fragments produces exactly what you fed it, which is fragments.

So I rewrote the knowledge base story by story, and each one got the same skeleton: situation, tension, outcome, and a detail specific enough to make the name test swing the right way. The eval results told me which story to fix first and whether each revision actually moved anything.

And then came the part I did not see coming: the evals caught me. While labelling, I reread one of the source stories and realised I had written it the way I wished it had gone, smoother than reality, a conflict resolved a little too cleanly. The AI had faithfully mirrored my own polish back at me. It can write your story, but it cannot know which version of it is true. I corrected the source.

## The Last Two Failures Had Nothing to Do With Knowledge

After the rewrite most questions passed reliably, two kept flickering. It was the frustrating kind of flicker: pass, fail, pass, with nothing changing in between.

The judge's reasoning showed why. The facts were all there, the composition was wrong. On certain broad question types the model fell back into listing even though it had stories to tell. The fix turned out to sit in the prompt: my rule "answer as a story, not as a CV" listed trigger phrasings, and those two question types matched none of them. The rule existed. It just never fired.

That distinction carries far beyond my small website. What the system knows and how the system composes are two different layers, and they fail differently. The evals' reasoning tells you which layer is up. Without it you rewrite content when you should be fixing prompts, and the other way around, and everything takes four times as long.

## The Numbers

Same transparency as last time:

- **Golden set**: 8 hand-labelled entries. Started with 5. Small, but I personally wrestled with every single one.
- **Failure modes**: 4, each with an explicit scope and yes-no checks.
- **Judge agreement**: 4/5 on the first version. After that I fixed the criteria, not the judge.
- **Before**: 5 of 8 questions passed, the weakest one failed on every single run.
- **After**: 8 of 8, three runs in a row, 24 out of 24 verdicts.
- **Cost per full eval run**: cents. The expensive part was hand-labelling, a few evenings. The judge runs for less than a coffee.

## Why Bother, for a Personal Website

I do this because of the principle, not because of the website.

I believe AI should work autonomously but never be a black box, and that is one of three convictions on this site. A chat that answers in my name without being checked is a black box with my face on it. I am responsible for every sentence it produces, whether I read it or not. Testing it is the price of letting it speak for me.

And honestly: the bar out there is on the floor. Most chatbots go live after someone asked three questions in a demo and nodded. The methodology that fixed my website chat is the same one I practise on production systems at work, and it is not hard. Read real answers. Label by hand. Define failure precisely, including the cases where the rule does not apply. Make the judge earn your trust before you trust it. Fix the layer the evidence points at.

The goal was never a perfect chatbot. It was to know exactly how my system fails before a stranger finds out for me. That, in the end, is the difference between autonomous and out of control.
