{% extends 'admin/base.html.twig' %} {% block title %}Eval-Cases verwalten{% endblock %} {% block body %}

Eval-Cases verwalten

Neue Regression-Cases separat anlegen oder bestehende Cases entfernen, ohne die Eval-Suite-Übersicht aufzublähen.
Zurück zur Eval Suite
{% for label in ['success', 'danger', 'warning', 'info'] %} {% for message in app.flashes(label) %}
{{ message }}
{% endfor %} {% endfor %} {% if case_draft.source_label|default('') %}
Vorlage geladen: {{ case_draft.source_label }}
Bitte Case-ID, Prompt und Assertions prüfen, bevor du den Case speicherst.
{% endif %}
Kurz erklärt
Ein Eval-Case ist ein wiederholbarer Test. Du trägst ein, was der Nutzer fragt und woran RetrieX gemessen werden soll. Der Test verändert keine Daten im Shop oder im RAG-Wissen, sondern prüft nur, ob ein bekannter Fall weiterhin richtig läuft.
Neuer Eval-Case
Wähle zuerst, was genau geprüft werden soll. Der Typ entscheidet auch, in welche Datei der Case geschrieben wird: tests/evals/cases/<type>.ndjson.
retrieval: prüft, ob die richtige Wissensquelle oder das richtige Dokument gefunden wird.
shop_query: prüft, welche Suchquery an den Shop geschickt würde.
followup: prüft eine Folgefrage, die den vorherigen Chatverlauf braucht.
answer_guard: prüft, dass RetrieX bei Unsinn oder fehlender Evidenz nichts erfindet.
Das ist der interne Name des Tests. Er erscheint später in der Eval-Auswertung, damit du den Fall wiedererkennst. Verwende keine Leerzeichen. Erlaubt sind Buchstaben, Zahlen, _ und -.
Gute Beispiele: retrieval_lieferbedingungen_versand_001, shop_query_testomat808_indikator300_001, followup_testomat808_device_price_001.
Faustregel: typ_thema_ziel_nummer.
Hier kommt genau die Nutzerfrage hinein, die getestet werden soll. Nicht die erwartete Antwort eintragen, sondern den Satz, den ein Nutzer in den Chat schreiben würde.
Tippfehler dürfen bewusst drin bleiben, wenn genau dieser Tippfehler abgesichert werden soll. Beispiel: ich würde gern chlor im schwinnbad messen prüft dann auch die Korrektur Richtung schwimmbad.
Hier steht, was der Test erwarten soll. Das Feld muss gültiges JSON sein, also mit { anfangen und mit } enden. Keine Kommentare und kein Komma nach dem letzten Eintrag.
Wenn eine Shopquery exakt stimmen soll:
{
  "expected_query": "testomat 808"
}
Wenn bestimmte Wörter enthalten sein müssen:
{
  "must_include_terms": [
    "testomat",
    "808"
  ]
}
Wenn ein Dokument gefunden werden muss:
{
  "min_results": 1,
  "must_include_one_of_document_ids": [
    "DOKUMENT-ID"
  ]
}
Nur ausfüllen, wenn die aktuelle Frage den vorherigen Chatverlauf braucht. Für direkte Einzelprompts leer lassen. Das Feld muss eine JSON-Liste sein, also mit [ anfangen und mit ] enden.
Typischer Einsatz: Der Nutzer fragt zuerst nach dem niedrigsten Grenzwert, danach nach dem Indikator und anschließend was kostet der indikator. Dann braucht der Test die vorherigen Fragen und Antworten als History.
[
  {
    "prompt": "mit welchem indikator",
    "answer": "Der Wert 0,02 °dH wird beim Testomat 808 mit Indikatortyp 300 gemessen."
  }
]
Dieses Feld kannst du fast immer leer lassen. Es ist nur für Sonderfälle gedacht, wenn der Test Zusatzkontext braucht, der nicht sauber als History darstellbar ist.
Beispiel für einen Sonderfall: Im vorherigen Ergebnis waren mehrere Shop-Produkte sichtbar, aber keine normale Chatantwort. Für normale Regressionen ist History-JSON die bessere Wahl.
Abbrechen
Bestehende Eval-Cases entfernen

Hier kannst du falsch angelegte oder nicht mehr benötigte Cases aus den tests/evals/cases/*.ndjson-Dateien entfernen. Das Löschen betrifft nur den Eval-Case, nicht das RAG-Wissen, nicht den Shop und nicht die bestehenden Reports.

{% for type, label in types %} {% set cases = cases_by_type[type]|default([]) %}
{{ label }} ({{ cases|length }} Cases) {% if cases is empty %}
Für diesen Typ gibt es aktuell keine Cases.
{% else %}
{% for case in cases %}
{{ case.id }}
{{ case.prompt }}
{% endfor %}
{% endif %}
{% endfor %}
Nach dem Löschen solltest du den betroffenen Eval-Typ einmal ausführen, damit der Report zum neuen Case-Bestand passt.
Welcher Typ ist richtig?
Du willst prüfen, ob das richtige Dokument gefunden wird?
Dann nimm retrieval.
Du willst prüfen, welche Suchwörter an den Shop gehen?
Dann nimm shop_query.
Die Frage bezieht sich auf die vorherige Antwort?
Dann nimm followup und fülle History-JSON aus.
RetrieX soll bei Unsinn nichts erfinden?
Dann nimm answer_guard.
Häufige Assertions
Exakte Query:
{
  "expected_query": "testomat 808"
}
Begriffe müssen enthalten sein:
{
  "must_include_terms": [
    "testomat",
    "808"
  ]
}
Begriffe dürfen nicht enthalten sein:
{
  "must_not_include_terms": [
    "indikator",
    "300"
  ]
}
Dokument muss enthalten sein:
{
  "min_results": 1,
  "must_include_one_of_document_ids": [
    "DOKUMENT-ID"
  ]
}
Vor dem Speichern prüfen
  • Prüft der Case genau einen Zweck?
  • Ist die Case-ID eindeutig und ohne Leerzeichen?
  • Ist der Prompt eine echte Nutzerfrage?
  • Ist Assert-JSON gültiges JSON?
  • Ist History nur bei echten Folgefragen gefüllt?
Empfehlung

Ein guter Eval-Case prüft genau einen Zweck. Lieber mehrere kleine Cases anlegen als einen großen, empfindlichen Case. Wenn du unsicher bist, starte mit expected_query bei Shop-/Follow-up-Fällen oder mit must_include_one_of_document_ids bei Retrieval-Fällen.

{% endblock %}