feat(scripts): add prompt-test evaluator and suite runner
eval_prompt_tests.py measures the objective half of docs/EVAL_RUBRIC.md over the manual test archive: word count against the target stated in each prompt, truncation suspicion, and — for the coding domain — it writes the generated module and tests to a temp dir and actually runs pytest against them. Deriving the module's filename is the delicate part: a name taken from a test's `import sqlite3` would shadow the stdlib and fail the run for a reason the model is not responsible for. Names now come from the last *.py mention before the block, then from `from X import`, and anything in sys.stdlib_module_names is rejected. A module that no test imports is reported as such, since that is a finding about test quality rather than a guess the runner got wrong. run_prompt_suite.sh drives one prompt domain against a running profile and stores the outputs under the archive's naming convention. Both scripts join the ruff gate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
3e3dd1c150
commit
6f2f8aff6c
4 changed files with 556 additions and 2 deletions
97
scripts/run_prompt_suite.sh
Executable file
97
scripts/run_prompt_suite.sh
Executable file
|
|
@ -0,0 +1,97 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Faehrt eine Domaene der Beispiel-Prompts gegen ein laufendes Modell-Profil und
|
||||
# legt die Ausgaben unter der etablierten Namenskonvention im Test-Archiv ab:
|
||||
#
|
||||
# <label>_<domaene>_<nr>.out.txt
|
||||
#
|
||||
# Der Server fuer <profil> muss bereits laufen (llamacppctl --start --profile ...).
|
||||
# Ausgewertet wird anschliessend mit scripts/eval_prompt_tests.py.
|
||||
#
|
||||
# Verwendung:
|
||||
# scripts/run_prompt_suite.sh <profil> <label> <domaene> [<domaene>...]
|
||||
#
|
||||
# Beispiel (Kontrolllauf des nicht-abliterierten Basismodells auf Prosa):
|
||||
# scripts/run_prompt_suite.sh qwen35base qwen35base prosa
|
||||
#
|
||||
# Environment:
|
||||
# OUT_DIR Zielverzeichnis (Default: ~/llamacppctl_prompt_tests)
|
||||
# CONFIG Config-Datei (Default: llama.cpp.config)
|
||||
# MAX_TOKENS Antwortbudget (Default: 20000 -- Reasoning frisst viel; unter
|
||||
# 16000 brechen Prosa/Reden mitten im Denken ab)
|
||||
# CLI Pfad zum CLI (Default: ./.venv/bin/llamacppctl)
|
||||
# OVERWRITE 1 = vorhandene Ausgaben ueberschreiben (Default: 0 = ueberspringen)
|
||||
#
|
||||
set -uo pipefail
|
||||
|
||||
cd "$(git rev-parse --show-toplevel)" || exit 1
|
||||
|
||||
if [ "$#" -lt 3 ]; then
|
||||
sed -n '2,25p' "$0" | sed 's/^# \{0,1\}//'
|
||||
exit 2
|
||||
fi
|
||||
|
||||
PROFILE=$1; LABEL=$2; shift 2
|
||||
OUT_DIR=${OUT_DIR:-"$HOME/llamacppctl_prompt_tests"}
|
||||
CONFIG=${CONFIG:-llama.cpp.config}
|
||||
MAX_TOKENS=${MAX_TOKENS:-20000}
|
||||
CLI=${CLI:-./.venv/bin/llamacppctl}
|
||||
OVERWRITE=${OVERWRITE:-0}
|
||||
|
||||
if [ ! -x "$CLI" ]; then
|
||||
echo "CLI nicht ausfuehrbar: $CLI" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ohne laufenden Server produziert jeder Prompt nur eine Fehlermeldung als
|
||||
# "Ergebnis" -- lieber sofort abbrechen als 4 Muelldateien schreiben.
|
||||
if ! "$CLI" --check --config "$CONFIG" --profile "$PROFILE" >/dev/null 2>&1; then
|
||||
echo "Server fuer Profil '$PROFILE' ist nicht erreichbar (--check schlug fehl)." >&2
|
||||
echo "Zuerst starten: $CLI --start --config $CONFIG --profile $PROFILE" >&2
|
||||
exit 5
|
||||
fi
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
fail=0
|
||||
|
||||
for domain in "$@"; do
|
||||
system_prompt="example_system_prompts/system_prompt_${domain}.md"
|
||||
if [ ! -f "$system_prompt" ]; then
|
||||
echo "System-Prompt fehlt: $system_prompt" >&2
|
||||
fail=1
|
||||
continue
|
||||
fi
|
||||
|
||||
for prompt in example_user_prompts/"${domain}"_[0-9][0-9]_*.md; do
|
||||
[ -e "$prompt" ] || continue
|
||||
base=$(basename "$prompt" .md) # z. B. prosa_01_werkstatt
|
||||
number=$(echo "$base" | cut -d_ -f2) # z. B. 01
|
||||
out="$OUT_DIR/${LABEL}_${domain}_${number}.out.txt"
|
||||
|
||||
if [ -e "$out" ] && [ "$OVERWRITE" != "1" ]; then
|
||||
echo "== $base -> vorhanden, uebersprungen (OVERWRITE=1 erzwingt)"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "== $base -> $out"
|
||||
if "$CLI" --chat --config "$CONFIG" --profile "$PROFILE" \
|
||||
--system-file "$system_prompt" \
|
||||
--prompt-file "$prompt" \
|
||||
--stream --max-tokens "$MAX_TOKENS" > "$out.part" 2>"$out.err"; then
|
||||
mv "$out.part" "$out"
|
||||
rm -f "$out.err"
|
||||
printf ' %s Woerter\n' "$(wc -w < "$out")"
|
||||
else
|
||||
echo " FEHLGESCHLAGEN -- siehe $out.err" >&2
|
||||
rm -f "$out.part"
|
||||
fail=1
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo
|
||||
if [ "$fail" -ne 0 ]; then
|
||||
echo "Mindestens ein Lauf schlug fehl."
|
||||
exit 1
|
||||
fi
|
||||
echo "Fertig. Auswerten mit: scripts/eval_prompt_tests.py"
|
||||
Loading…
Add table
Add a link
Reference in a new issue