serhiykucherenko.dev

← systems · level 2

payments-rag

Two journeys over the same stops: a live question, and the eval that grades it.

question line — what happens when someone asks something

  1. questionplain English, from the demo page
  2. embedone pinned embedding modelPinned and guarded at insert, because changing it later invalidates every stored vector. Chose the small model over one costing several times more.ADR-0003
  3. retrievetop-k over page chunks in pgvectorVectors live in Postgres rather than a dedicated vector database, so citations join to their text in one query. Good to roughly a million vectors, then this gets superseded.ADR-0002
  4. generatethe cheap model tier answers, from retrieved pages onlyThe model name is an env var, so the quality-versus-cost question stays measurable instead of argued.ADR-0005
  5. answer + pagestructured citation, never inline guessworkCitations come back as data, not as markers in prose, so a hallucinated one fails loudly instead of rendering a wrong link. Chunks never span two pages for the same reason.ADR-0006

eval line — runs on demand over the same stops, with known-good questions

  1. golden setquestions with known answers, in the repoGround truth is a file in version control, so editing it to flatter a number shows up in review.ADR-0012
  2. retrievesame retriever, scored on recallHybrid search and a reranker were both measured here. Neither earned a place in the live path.ADR-0014
  3. generatesame prompt path
  4. judgea different vendor grades the answerA model grading its own output shares its own blind spots. Exact match fails on paraphrase and similarity is too kind to wrong-but-close answers.ADR-0007
  5. scorerecall and answer pass rate

runs on

Fly.ioone small machine, auto-stopNeon Postgrespgvector, SEPA corpusClaude · GPTone generates, the other judgesCloudflareproxy, rate limit on /ask