support-ticket-triage¶
Causal LoRA SFT example: given a customer support ticket, emit triage JSON.
{
"priority": "p1|p2|p3|p4",
"category": "billing|access|bug|how_to|other",
"team": "payments|identity|platform|docs|general",
"summary": "one-line agent summary"
}
Validator (the contract)¶
triage_plugin/ registers an out-of-model validator with four layers:
- JSON parse: output is a JSON object
- Schema: structure, required fields, and enums (
datasets/schema.json) - Routing contract:
categorymust route to the mandatedteam(billing→payments,access→identity,bug→platform,how_to→docs,other→general) - Summary quality: non-empty, single line, ≤ 20 words
Layer 3 is the point: it ties two fields together by a task rule a plain JSON
schema cannot express. The same validator gates the seed data, scores
maatml evaluate, and can re-check live output at maatml serve
/predict?validate=1.
Lifecycle¶
maatml prepare examples/support-ticket-triage/
maatml train examples/support-ticket-triage/ --smoke
maatml train examples/support-ticket-triage/
maatml evaluate examples/support-ticket-triage/ --gate
Quality gates¶
| Metric | Gate | Meaning |
|---|---|---|
all_layers_pass_rate |
>= 0.95 | every validator layer passed |
category_accuracy |
>= 0.86 | predicted category matches gold |
json_parse_rate |
>= 0.97 | output is valid JSON |
priority_accuracy |
>= 0.64 | predicted priority matches gold |
routing_consistency_rate |
>= 0.95 | category -> team contract holds |
schema_conformance_rate |
>= 0.97 | matches datasets/schema.json |
summary_quality_rate |
>= 0.97 | summary is one line within the word cap |
team_accuracy |
>= 0.88 | predicted team matches gold |
Add more tickets under datasets/samples/seed_samples.jsonl, then re-prepare.
The committed corpus is intentionally small; it demonstrates the causal_sft
path, the routing contract, and the standalone model-folder layout, not
production triage quality. Raise the gates after training on a larger corpus.