I run a digital twin on my website. It answers questions about my life and skills. I gave it one strict rule: never make things up. If someone asks about a skill I do not have, it must admit it does not know. For months, I believed the system was working. I tested it by hand here and there, and the answers looked solid. Then I built a proper evaluation harness. The numbers hit hard. Out of 35 questions, nine contained outright lies. Out of eight questions designed to be unanswerable, the model refused only four. My anti-hallucination prompt failed roughly a quarter of the time. I was shipping a product that lied to its users.
A Dead-Simple Retrieval Setup
I did not spin up Pinecone or any heavyweight vector database. The entire setup sits on a plain JSON file. My code splits my profile into discrete sections. When a question arrives, the system calculates cosine similarity between the query and each chunk of text, selects the closest matches, and stuffs them into the prompt as context. The model then generates an answer based strictly on what it sees in that window.
For a small personal site serving a narrow set of facts, this approach is fast and costs next to nothing. There is no network round-trip to a remote vector store, no indexing overhead, and no complex orchestration. You read the file, score the chunks, build the prompt, and go. But simplicity on the backend does not guarantee honesty in the output. A lightweight pipeline can still produce serious problems when the model decides to improvise. The gap between "here is the context" and "here is what I will say about it" is where hallucinations live. You can hand the model a paragraph about your work history and still get back a confident fabrication about a programming language you have never touched.
The Numbers That Broke My Confidence
For months, I treated manual spot-checking as sufficient coverage. I would open the chat, ask a question I already knew the answer to, and nod when the response looked right. That was my testing strategy. It felt thorough because I was using the interface myself. It was not.
When I finally wrote an evaluation harness that could run systematically, the picture changed. The test suite fired 35 questions at the twin. Nine answers contained lies. I also included eight questions that had no answer anywhere in my profile. The model should have declined them all. It refused only four. My carefully crafted anti-hallucination prompt, the one that included absolute language about never making things up, failed about 25 percent of the time. One in four. That is not a rounding error. That is a broken product.
Stop Testing With Friendly Questions
You cannot find bugs by simply using your own product. You find them by trying to break it. My manual tests were too friendly. I only asked questions where I knew the exact answer, which meant I was subconsciously guiding the model toward safe territory. I never probed the edges. I never asked about skills I wished I had, or about experiences that never happened.
Real testing requires adversarial intent. You have to craft questions designed to make the AI fail. You want it to slip up in the lab so it does not slip up in front of a visitor. A test suite that only confirms what you already believe is just a dressed-up demo. If you are not actively manufacturing edge cases and trap questions, you are not testing. You are hoping.
The Two Mistakes That Mattered
Prompting is not a guarantee. A long, detailed instruction telling an AI not to hallucinate is just a suggestion dressed up as a command. The model may follow it most of the time, but it will ignore the instruction the moment statistical pressure pushes it elsewhere. Temperature, token probability, and the shape of the training data all weigh heavier than a sentence in your system prompt. You must measure obedience with data, not hope. A strong instruction is not a verified fact. It is a request, and requests get denied. If your entire safety strategy rests on wording your prompt firmly, you have built a guardrail out of tissue paper. You need an eval harness that counts how often the model obeys, under what conditions, and why it fails when it fails. Numbers do not care about your tone of voice.
O loop de avaliação estava falho. Aqui está uma armadilha sutil que quase me pegou. Minha ferramenta de teste original executava o processo de recuperação duas vezes. A primeira execução buscava o contexto para comparar com o ground truth. A segunda execução buscava o contexto para a geração real da resposta. Na prática, isso significava que os chunks que o avaliador via poderiam ser diferentes dos chunks que o modelo via. O avaliador estava pontuando a resposta com base em dados que a IA talvez nunca tivesse recebido. Uma avaliação que pontua a entrada errada é pior do que nenhuma avaliação. Isso te dá uma falsa sensação de segurança. Você olha para a pontuação, vê uma alta taxa de aprovação e relaxa. Enquanto isso, seus usuários estão
