Skip to main content
Each script reads SDVM_API_KEY from the environment. The dataset walkthroughs need the examples extra: pip install "sdvm[examples]".

basic.py

Basic example — fix a list of raw text samples using the SDVM API.

fix_text.py

Fix free text with SDVM. Wrap each string as a TextSample, pass the list to Fixer.run(), and get fixed TextSamples back (max 100 per request). Run:

hellaswag.py

Audit then fix HellaSwag with SDVM. HellaSwag is a sentence-completion multiple-choice task (the context is a STEM the correct choice continues), so wrap each row as a MultipleChoiceSample — style defaults to "continuation", which is exactly right here. (See mmlu.py for the "qa" variant.)
  1. Audit (per-sample) -> each sample comes back carrying its audit on .audit. Pass config=AuditorConfig(votes=N) to audit each sample N times and take the majority verdict (denoise).
  2. Aggregate (cross-sample) -> a local dataset-level view: the choice-count distribution and an answer-position bias check (is the correct choice always in one slot?).
  3. Fix with the Fixer -> each sample carries a .fix block {"changes": [...], "flagged": bool, "attempts": int}. The fix is never worse; flagged marks one it could not fully resolve, for you to review. Fix does NOT reaudit to check its own work.
(To run audit -> fix -> reaudit in one call — and see whether the fix actually helped — use the Refinery; see pipeline.py.) HellaSwag is wikiHow text with formatting conventions (markup tokens, uniform lowercasing, intentional truncation), so we pass conventions=... to both steps — otherwise the quality audit reads that formatting as grammar defects (~40% false-alarm vs ~12% with the conventions). Run:

mmlu.py

Audit then fix MMLU with SDVM — the question-answering counterpart to hellaswag.py. MMLU is a knowledge multiple-choice task: the context is a complete QUESTION the correct choice answers (not a sentence stem). Same data shape as HellaSwag, one difference — set style="qa" so the audit reads the context as a question and judges completeness normally (a QA question that is truncated IS a defect, unlike a HellaSwag continuation stem). The flow is identical to hellaswag.py:
  1. Audit (per-sample) -> each sample carries its audit on .audit.
  2. Aggregate (cross-sample) -> choice-count distribution + answer-position bias check.
  3. Fix with the Fixer -> each sample carries a .fix block {"changes": [...], "flagged": bool, "attempts": int}; the fix never makes a sample worse.
Unlike hellaswag.py, MMLU questions are standard-cased, complete prose, so we pass NO conventions — there is no dataset-specific formatting for the quality audit to misread. Run:

conversation.py

Audit then fix a chat SFT corpus with SDVM — the conversation counterpart to mmlu.py. UltraChat-200k is instruction-tuning data in the OpenAI messages shape: a list of {"role", "content"} turns per row. That is exactly what ConversationSample takes, so a row maps onto the type with no reshaping; anything else on the row rides along in extra. The flow is the same as the other examples:
  1. Audit (per-sample) -> each sample carries its audit on .audit: the structural checks (roles, order, empty / repeated / looping turns, open code fences, assistant boilerplate, template placeholders) and the model’s verdicts on the final exchange.
  2. Fix with the Fixer -> each sample carries a .fix block {"changes": [...], "flagged": bool, "attempts": int}; the fix never makes a sample worse.
A sample’s turns="all" widens the model’s verdicts from the final exchange to every assistant turn (reported per turn under audit["turns"]); the default "last" keeps the cost of a conversation independent of its length. Run:

pipeline.py

One-call audit -> fix -> reaudit on MMLU with the Refinery pipeline. The :class:~sdvm.Refinery runs the whole pipeline server-side in a single run() call: audit(votes) -> fix(max_attempts) -> reaudit(votes). Each returned sample carries one block per stage: .audit (the verdict BEFORE the fix), .fix (what the fix did) and .reaudit (the verdict AFTER the fix — did it work?). votes audits each sample N times and majority-votes the verdict (denoise); max_attempts is how many tries the fixer gets at an accepted fix. Compare with mmlu.py, which drives the two steps by hand (Auditor then Fixer); this is the same work — plus the reaudit — in one call. Run:
Last modified on September 18, 2026