Results (served, greedy, 294 held-out queries)
Scored by the environment's reward: 0.10·parsed + 0.25·schema_valid + 0.65·judge
(judge = openai/gpt-oss-120b); success = schema-valid AND judge ≥ 0.75.
Table with columns: Model, score, schema_valid, industries_valid, judge, success| Model | score | schema_valid | industries_valid | judge | success |
|---|
| SFT (GLM-5.2-distilled, 3 ep) | 0.8558 | 0.939 | 0.939 | 0.802 | 0.793 |
| GRPO (this adapter) | 0.9218 | 0.983 | 0.993 | 0.884 | 0.922 |
| GPT-5.5 (reference baseline) | 0.9157 | 0.993 | 0.993 | 0.874 | 0.891 |
GRPO improves on SFT by +0.066 and beats GPT-5.5 by +0.006 — the taxonomy-adherence
gap is fully closed (industries_valid 0.939 → 0.993, matching GPT-5.5), and the judge score
(0.884) exceeds GPT-5.5's (0.874). The win is robust: four consecutive GRPO checkpoints
score ≥ GPT-5.5.
Training
- Base:
Qwen/Qwen3.5-4B, thinking = false, single-turn. LoRA rank 16.
- SFT: 3 epochs on 3410 GLM-5.2-oracle rows (judge-curated ≥ 0.7), compact-JSON targets.
- GRPO: warm-started from SFT; reward = the env's shaped score (hard-gates
out-of-taxonomy industries). The taxonomy-adherence gain came from progressive
GRPO continuations at a higher LR (2e-5, KL 0.01, group 12), which pushed
industries_valid from 0.939 (SFT) to 0.993.
- Oracle:
z-ai/glm-5.2. Judge: openai/gpt-oss-120b. Both via OpenRouter.
- Dataset:
DavidBShan/clay-companysearch-4b-opd.
Usage
Serve the LoRA on Qwen/Qwen3.5-4B (vLLM/PEFT). Prompt = the environment's system prompt
- the user's NL query; the model returns a raw JSON filter object (no thinking block).
Example:
"Find biotech companies in Boston with 51-200 employees" →
{"industries":["Biotechnology"],"locations":["Boston"],"sizes":["50"]}.