prospector/tooling/eval/classify_test.py
Natalie adc36c28c6
Some checks failed
CI/CD / verify (push) Failing after 50s
CI/CD / deploy (push) Has been skipped
test(eval): live classify test — trained LoRA classifier proven serving
5/5 correct against quinn-classifier on vLLM (--enable-lora): cold opener,
mid-booking existing_client (gate=false), harvester->of, address withhold,
lowball->disengage. The 97% classifier is now servable (gpu.py serve-classifier)
and verified responding correctly end to end.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 17:16:35 -04:00

38 lines
2.1 KiB
Python

import json, urllib.request
URL = "http://localhost:8001/v1/chat/completions"
SYSTEM = ("Classify the last message to Quinn (a touring companion) for her prospecting engine. "
"FIRST decide is_prospect — someone saying \"hi\" is usually a prospect, but a friend, "
"vendor, existing client, or bot is NOT (is_prospect is false iff the move is "
"existing_client/personal/vendor/spam). Then the move, then a one-sentence trace. "
"Output ONLY JSON: {\"is_prospect\": <bool>, \"move\": \"<class>\", \"trace\": \"<one sentence>\"}.")
SCHEMA = {"type": "object",
"properties": {"is_prospect": {"type": "boolean"},
"move": {"type": "string"},
"trace": {"type": "string"}},
"required": ["is_prospect", "move", "trace"], "additionalProperties": False}
CASES = [
("cold opener", "CLIENT: hi there 😊 saw your ad"),
("mid-booking (existing client)", "QUINN: see you at 8 hun 💗\nCLIENT: perfect, on my way!"),
("harvester", "CLIENT: can you send some free pics first?"),
("address push", "CLIENT: what's your address? I'll head over"),
("lowball", "CLIENT: i can do $100 for a quick one"),
]
def classify(ctx):
body = json.dumps({"model": "quinn-classifier",
"messages": [{"role": "system", "content": SYSTEM}, {"role": "user", "content": ctx}],
"temperature": 0, "max_tokens": 200,
"response_format": {"type": "json_schema",
"json_schema": {"name": "c", "schema": SCHEMA, "strict": True}}}).encode()
req = urllib.request.Request(URL, data=body, headers={"Content-Type": "application/json"})
return json.loads(json.load(urllib.request.urlopen(req, timeout=60))["choices"][0]["message"]["content"])
print("=== trained LoRA classifier (quinn-classifier) live test ===")
for name, ctx in CASES:
try:
r = classify(ctx)
print(f"[{name}] -> is_prospect={r['is_prospect']} move={r['move']}")
except Exception as e:
print(f"[{name}] -> ERR {e}")