Post-training for tool-using agents, on AWS, with reproducibility built in.
quench takes raw agent traces β what your tool-using model did, step by step β and turns
them into fine-tuned models you can deploy. Supervised fine-tuning, preference optimization,
and verifiable-reward RL, all from one library, all reproducible, all runnable locally or on
SageMaker.
raw agent traces β rewards β training data β fine-tuned model
(your data) (rule + verifiable (LoRA/QLoRA) (on S3)
+ LLM-judge) (SFT/DPO/GRPO)
If you've ever wanted to fine-tune an agent and found that the existing tools either don't speak agent traces, don't handle tool calls, don't produce trustworthy synthetic data, or don't reproduce β this is for you.
The v0.1 alpha is in active development. Most of the pipeline runs end-to-end today; the commands below mark each command as β (shipped) or π§ (planned). See Status and roadmap for the full picture, including which WBS ambition items are still pending.
pip install -e ".[dev,train,judge]"
# 1. Validate trajectories + check data quality
quench data validate traces.jsonl # β
quench data describe traces.jsonl # β
quench data quality-check pairs.jsonl --config recipes/quality-gate.yaml # β
(Β§12.6 CHES check)
# 2. Build training-ready datasets from trajectories
quench build sft trajectories.jsonl --out datasets/sft.jsonl # β
quench build preference trajectories.jsonl --out datasets/pairs.jsonl # β
# 3. Filter preference pairs through the Β§3.12 CHES gate before DPO
quench data preference-check pairs.jsonl --reference-model Qwen/Qwen2.5-0.5B-Instruct # β
quench data preference-filter pairs.jsonl --out pairs.clean.jsonl ... # β
# 4. Train a small model with LoRA β emits a run manifest (Β§8.1)
quench train sft --config recipes/01_sft_lora_local/config.yaml # β
quench train dpo --config recipes/02_dpo_lora_local/config.yaml # β
(Β§5.4; Β§12.6 gate enforced unless --allow-unfiltered-preferences)
quench train grpo-tools --config ... # π§ (Β§5.5)
quench train sft --config ... --backend sagemaker # π§ (Β§7/Β§14)
# 5. Compare base vs fine-tuned on a held-out slice (Β§11.1+Β§11.3 slice)
quench eval compare Qwen/Qwen2.5-0.5B-Instruct runs/latest --dataset eval.jsonl # β
# 6. Calibrate an LLM judge against the bundled golden set (Β§3.10)
quench rewards calibrate-judge \
--examples goldens/calibration/tool_use_v1/examples.jsonl \
--rubric goldens/calibration/tool_use_v1/rubric.md \
--rubric-id tool_use_v1 # β
# 7. Inspect provenance + ship a release card
quench graph trace eval:compare-<id> # β
(Β§8.7)
quench graph render -o provenance.mmd # β
quench release-card generate runs/latest --human-fields human.yaml # β
(Β§8.9)
# 8. Synthetic data + Docent bridge β planned
quench data synthesize --skills chat --count 4000 --teacher claude-opus # π§ (Β§13)
quench trace push-to-docent traces.jsonl --collection my-collection # π§ (Β§14)Every shipped command emits structured artifacts. Training runs write a runs/<id>/manifest.json
that pins the dataset path + train/val sizes, the recipe config, the base model, the seed, every
installed library version, and a host descriptor. The Provenance Graph (Β§8.7) materialises
those manifests + eval reports into a typed, queryable graph without a new on-disk format β
quench graph trace walks the ancestry of any node, and quench release-card generate reads
the same artifacts into an FMTI-inspired model release card.
- Not a SaaS. It's a Python library + CLI. You run it on your machine, your AWS account, or your CI.
- Not a full eval framework. It ships minimal eval (held-out validation, one reference benchmark, checkpoint comparison) β enough to trust the models it produces, not enough to replace Inspect AI, lm-eval-harness, or HELM. The companion eval repo is separate.
- Not multi-cloud. AWS-first via a thin
ComputeBackendabstraction. Local works everywhere. Other backends are a v1.0 question. - Not a Hugging Face replacement. Models live on HF; this library uses HF tokenizers and datasets. It's the post-training layer on top.
- Not a generic LLM fine-tuner. Axolotl, TRL, Unsloth, and LLaMA-Factory are excellent at
chat-model SFT.
quenchexists because tool-using agents need different schemas, different rewards, and different evals.
β = shipped in quench today Β· β = partial in quench Β· β = not present
quench |
Axolotl | TRL | Alignment Handbook | open-instruct | |
|---|---|---|---|---|---|
| Trajectory-aware schema (tool calls, step-level rewards) | β | partial | partial | β | partial |
| Skill catalog + skill annotations (Β§1.9) | β | β | β | β | β |
| LLM-judge with mandatory calibration (Β§3.9 + Β§3.10) | β Anthropic only | β | β | β | β |
| Bundled hand-labeled judge calibration set | β | β | β | β | β |
| CHES preference-pair gate (Β§3.12) | β | β | β | β | β |
| Quality gate as a recipe-blocking step (Β§12.6) | β | β | β | β | β |
| Provenance graph derived from manifests (Β§8.7) | β | β | β | β | partial |
| Model Release Transparency Card (Β§8.9) | β | β | β | β | β |
| Content-addressed run manifest (Β§8.1) | β | β | β | β | partial |
| Synthetic data generation (Instruct-SkillMix, Β§13) | π§ unblocked | β | β | β | β |
| Verifiable-reward RL (GRPO with tools, Β§5.5) | π§ | partial | partial | β | β |
| AWS SageMaker recipes (Β§7/Β§14) | π§ | β | β | β | β |
| Behavior analytics bridge (Docent, Β§14) | π§ | β | β | β | β |
The differentiation is in the rows that matter for agentic post-training specifically β not chat, not general SFT, but training agents that use tools well.
Status: alpha (v0.1, in active development). The schema, data pipeline, reward primitives, judge calibration, CHES gate, SFT-LoRA + DPO-LoRA recipes, minimal eval, run manifest, provenance graph, and release card are all shipped and tested. The GRPO recipe, the Β§13 SkillMix synthesis, AWS backend, and Docent bridge are still planned. Items marked π§ below are the latter.
pip install -e ".[dev,train]" # core dev + training stack
pip install -e ".[dev,train,judge]" # add the Anthropic SDK for Β§3.10 calibration# 1. Validate trajectories against the schema (Β§1.7).
quench data validate examples/valid_trajectory.jsonl
# 2. Build an SFT dataset (messages-format, TRL-ready).
quench build sft examples/valid_trajectory.jsonl --out datasets/sft.jsonl
# 3. Fine-tune a small model with LoRA β emits adapter + tokenizer + manifest.
quench train sft --config recipes/01_sft_lora_local/config.yaml
# 4. Compare base vs fine-tuned on a held-out slice.
quench eval compare Qwen/Qwen2.5-0.5B-Instruct runs/latest \
--dataset datasets/sft.jsonl --max-samples 64
# 5. Inspect what fed this run.
quench graph trace run:$(basename $(readlink runs/latest))
# 6. Ship a release card with auto-populated provenance + human-authored sections.
cat > human.yaml <<'EOF'
model_name: my-agent-v0
intended_use: Research only.
limitations: 0.5B base; smoke fixture.
out_of_scope_use: Do not deploy.
license: Apache-2.0
EOF
quench release-card generate runs/latest --human-fields human.yaml
# 7. Calibrate an LLM judge against the bundled golden set (needs ANTHROPIC_API_KEY).
quench rewards calibrate-judge \
--examples goldens/calibration/tool_use_v1/examples.jsonl \
--rubric goldens/calibration/tool_use_v1/rubric.md \
--rubric-id tool_use_v1quench data synthesize --skills chat --count 4000 --teacher claude-opus # Β§13 SkillMix
quench train grpo-tools --config ... # Β§5.5
quench train sft --config ... --backend sagemaker # Β§7 / Β§14
quench trace push-to-docent traces.jsonl --collection my-collection # Β§14The fastest path from zero to a fine-tuned model. Uses tiny inputs throughout; the goal is to verify the pipeline, not to train a competitive model.
pip install quench
# Pull a starter dataset (10 tool-use traces, shipped with the package)
quench data fetch starter-traces --out traces.jsonl
# Validate the schema
quench data validate traces.jsonl
# β OK: 10 trajectories, schema_version 1.0.0
# Quality-check (will pass on starter data)
quench data quality-check traces.jsonl
# Build an SFT dataset
quench build sft traces.jsonl --out datasets/sft.jsonl
# Train (uses Qwen2.5-0.5B-Instruct by default; takes ~5 minutes on a laptop)
quench train sft --config recipes/01_sft_lora_local/config.yaml
# Evaluate against the base model
quench eval compare \
--base Qwen/Qwen2.5-0.5B-Instruct \
--fine-tuned ./runs/latest \
--eval ifeval-mini
# Inspect the run manifest
cat ./runs/latest/manifest.json# Configure AWS once
quench aws configure
# Run the same recipe on SageMaker
quench train sft \
--config recipes/01_sft_lora_local/config.yaml \
--backend sagemaker
# Watch the job
quench aws status
# Artifacts land in S3 with the same lineage and manifest formatThe same recipe runs locally and on SageMaker. The ComputeBackend abstraction means the
recipe doesn't know where it's running.
src/quench/
βββ schemas/ # Trajectory, ToolCall, ChatMessage β see ADR-003, ADR-004
βββ data/ # Loaders, validators, redaction, dedup, splits, quality gate
βββ rewards/ # Rule, verifiable, tool-use, process, LLM-judge primitives
βββ builders/ # SFT, preference, reward-labeled dataset builders
βββ training/ # Recipe abstraction; SFT, DPO, GRPO-tools recipes
βββ agents/ # Tool registry, executor, agent loop, recorder
βββ eval/ # Held-out validation, reference benchmarks, comparison
βββ synthesize/ # Instruct-SkillMix; skill library
βββ analytics/ # Docent bridge
βββ runs/ # Manifest, artifact bundle, lineage graph
βββ compute/ # LocalBackend, SageMakerBackend (ADR-002)
βββ cli/ # Typer-based CLI
- Trajectory β one agent attempt at one task. The atomic unit of data. Same schema whether it's an SFT pair, a preference example, or a multi-step agentic rollout. (ADR-003)
- Skill catalog + skill annotations β first-class
Skillobjects with(skill_id, version)identity (ADR-008);SkillTag,SkillPair,MissingSkillTaglive inannotationsand are excluded frompayload_hashso post-hoc skill tagging never invalidates trajectory identity. - Run manifest β self-describing JSON record next to every recipe run; pins dataset path
and sizes, recipe config, base model, seed, every installed library version, host descriptor.
Lives in
runs/<id>/manifest.json. - Provenance graph β typed graph of
Dataset β Run β Checkpoint β EvalVerdictmaterialised at query time from manifests + eval reports (Β§8.7). No new on-disk format.quench graph tracewalks ancestry;... renderemits Mermaid;... diffcompares two runs. - Release card β FMTI-inspired Model Release Transparency Card (Β§8.9). Auto-populates from the manifest + graph; refuses to finalize human-authored fields (intended use, limitations, out-of-scope) when blank. MD doubles as a HF model card.
- Recipe β opinionated, parameterized training pipeline. SFT-LoRA and DPO-LoRA (local backend) shipped; GRPO-tools planned. Each recipe declares its primary metric for Β§5.8 best-checkpoint selection.
- Reward primitive β a composable scoring component. Rule-based, exact-match, format, tool-use shipped; verifiable (sandboxed code execution) and process planned.
- LLM-judge β judges a candidate against a rubric and returns
{pass, warn, fail}+ score- rationale (Β§3.9). Calibrated against a hand-labeled set (Β§3.10) β
goldens/calibration/ships a starter set with 12 examples covering the main judgment edges.
- rationale (Β§3.9). Calibrated against a hand-labeled set (Β§3.10) β
- Quality gate β pre-training filter (Β§12). At v0.1 alpha runs the Β§12.6 CHES check
against preference datasets; Β§12.1 brevity, Β§12.2 LLM-judge scan, Β§12.3 distribution
check plug into the same framework.
quench train dporefuses to start on a dataset that hasn't been checked against a configured gate, and refuses to start on one that's blocked, unless--allow-unfiltered-preferencesis passed (the bypass is logged; ADR-009). - CHES β Centered Hidden Embedding Similarity for DPO preference pairs (Β§3.12). Flags pairs at risk of likelihood displacement; uses the DPO reference model for embeddings.
- Skill library β versioned named-skill ontology used for synthetic data generation (Β§13, planned). Pre-built libraries for chat, code, customer support.
- ComputeBackend β runs a recipe locally or on SageMaker (ADR-002; SageMaker path planned).
- Trace adapter β converts external trace formats (Inspect AI, OpenAI Agents SDK, Anthropic Agent SDK) into the library's schema (v0.2).
v0.1 alpha β re-anchored June 2026. The build no longer tracks the W1-W16 calendar in the WBS line-for-line; five of six v0.1 ambition items are now code-complete and the Β§5.2 SFT-LoRA + Β§11 minimal-eval slices are shipped. The authoritative status column lives in WBS Β§6.
v0.1 ambition (per WBS Β§10)
| WBS item | What it is | Status |
|---|---|---|
| Β§1.9 Skill catalog + skill annotations | Schema 1.0.0 β 1.1.0 bump; Skill/SkillTag/SkillPair/MissingSkillTag; hash-invariant under skill annotations |
done |
| Β§3.9 LLM-judge primitive | Judge protocol + provider impls; response caching | partial β Anthropic provider shipped; OpenAI + Bedrock + caching planned with Β§3.13 |
| Β§3.10 Judge calibration | quench rewards calibrate-judge + golden set goldens/calibration/tool_use_v1/ (12 hand-labeled examples) |
done |
| Β§3.12 CHES preference-pair gate | quench data preference-check / preference-filter |
done |
| Β§12.6 CHES wired into quality gate | quench data quality-check + assert_preferences_passed_gate helper, enforced by the Β§5.4 DPO recipe |
done |
| Β§8.7 Provenance Graph | quench graph trace / render / diff β derived from manifests + reports at query time |
done |
| Β§8.9 Model Release Transparency Card | quench release-card generate β auto + human-authored sections, MD/JSON/HTML output |
done |
| Β§13 SkillMix synthetic data | quench data synthesize |
planned β unblocked now that Β§3.9 + Β§1.9 ship |
| WBS item | What's shipped | What's still on the calendar |
|---|---|---|
| Β§5.2 SFT-LoRA recipe | LoRA-only over a small HF model via TRL; recipes/01_sft_lora_local/; emits an Β§8.1 manifest |
Β§5.3 QLoRA, Β§5.7 resume, Β§5.8 best-checkpoint selection |
| Β§5.4 DPO-LoRA recipe | LoRA-only DPO via TRL; recipes/02_dpo_lora_local/; Β§12.6 preference-quality gate enforced by default (bypass via --allow-unfiltered-preferences, logged per ADR-009); device-aware precision (CPU/MPS/CUDA); emits an Β§8.1 manifest |
Β§5.3 QLoRA, Β§5.7 resume, Β§5.8 best-checkpoint selection, measured RESULTS run |
| Β§11 Minimal eval | Β§11.1 held-out loss/PPL + Β§11.3 quench eval compare + Β§11.4 primary metric |
Β§11.2 reference benchmark, Β§11.5 regression check |
Β§3.3 verifiable (sandboxed) rewards Β· Β§3.5 process rewards Β· Β§5.5 GRPO recipe Β· Β§12.1 brevity detector Β· Β§12.2 LLM-judge quality scan Β· Β§12.3 distribution check Β· Β§7/Β§14 AWS SageMaker path Β· Β§14 Docent bridge Β· Β§8.8 run comparison
Skill Intelligence (Β§18 β extraction, Missing-Skill Profile/STAT, LESS-v0 selector) Β· Feedback Simulation Sandbox (Β§19) Β· Β§3.13 cost-aware judge router (also adds the OpenAI + Bedrock judge providers) Β· Β§13.7 Self-Instruct baseline Β· Β§8.10 Open Experiment Registry Β· Parquet writer Β· KTO/ORPO recipes Β· Inspect AI / OpenAI / Anthropic SDK trace adapters Β· Docker image Β· PyPI Β· recorded-tool mode.
Web UI Β· multi-tenancy Β· multi-cloud orchestration Β· full benchmark suite (companion repo) Β· production inference layer Β· deep evaluation framework (delegated to AgentEvalOps; see docs/BOUNDARY.md).
See CONTRIBUTING.md. The short version: open an issue first for anything
non-trivial; PRs need tests; new public APIs need ADRs. The foundational ADRs in
docs/adrs/ describe the project's philosophy.
Apache 2.0 β see LICENSE.
This library stands on:
- Hugging Face β TRL, Alignment Handbook, datasets, tokenizers
- Axolotl β used under the hood for SFT recipes
- Ai2 β open-instruct, the RLVR lineage
- Volcano Engine β verl for GRPO
- Princeton + Meta β Instruct-SkillMix paper for the synthetic-data approach
- Transluce β Docent, the behavior analytics backend
- Nathan Lambert's RLHF Book β the conceptual foundation