feat(tasks): add ComplexConstraints (dataset + 0-shot rubric-judged task) - #78
Open
ethan-scitix wants to merge 2 commits into
Open
feat(tasks): add ComplexConstraints (dataset + 0-shot rubric-judged task)#78ethan-scitix wants to merge 2 commits into
ethan-scitix wants to merge 2 commits into
Conversation
…ask)
Adds the ComplexConstraints benchmark (Surge AI, arXiv:2606.09118): 75
multi-constraint instruction-following prompts, each carrying 10-40 atomic
rubric criteria (1,559 total), graded by an LLM judge rather than exact match.
complex_constraints dataset, hf:surgeai/ComplexConstraints pinned
complex_constraints_0shot_gen 0-shot generative, LLM-judge graded
The Hub repo ships one wide CSV whose 40 sparse `criterion_{i}` columns the
loader collapses into a single `criteria` list; the card's `configs` entry
names a file that does not exist (casing), so the loader reads the staged
snapshot by its real name.
Upstream publishes no eval code and no judge prompt — the paper names
GPT-5-mini as the judge and defines the metrics, nothing more — so the rubric
prompt and verdict parsing are authored here (sieval.community.
complex_constraints) and the task ships status="experimental".
Headline metric is the task pass rate (every criterion satisfied), which is
what the paper's public 75-prompt leaderboard reports; the mean per-criterion
pass rate is reported in both its published macro form and the pooled micro
form, which differ because rubric sizes vary 10-40.
Grading is one judge call per rollout over an indexed PASS/FAIL list. An
unreadable per-criterion verdict scores not-satisfied but is counted as
n_unparsed so judge format drift stays visible; empty responses satisfy zero
criteria without invoking the judge. No new dependencies.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CI runs a bare `ty check` over the whole root; I had only checked the three
new `sieval/` modules, so two test-only diagnostics reached CI:
* `ModelOutput(model=None, ...)` — the field is `ModelMeta`, not optional.
Use the scripted model's own `meta()`.
* `final.feedback_result[...] = 2` — `feedback_result` is `TFeedback | None`,
so it is not subscriptable. `_final` now takes `n_unparsed` and builds the
record with it instead of mutating one afterwards, which also drops a
reach-through into a frozen context.
No production code changed. The unparsed-verdict test additionally pins the
micro rate, so it now checks that unreadable verdicts are counted *inside* the
score rather than only reported beside it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type
Summary
surgeai/ComplexConstraints, CC-BY-4.0):75 multi-constraint instruction-following prompts, each carrying 10–40 atomic rubric criteria
(1,559 total), graded by an LLM judge rather than exact match. Two new registry entries
(
complex_constraintsdataset,complex_constraints_0shot_gentask), no new dependencies.paper's public 75-prompt leaderboard reports (its Table 1). The mean per-criterion pass rate is
reported in both its published macro form (Table 3 caption) and the pooled micro form;
the two genuinely differ because rubric sizes vary 10–40 per prompt.
status="experimental", and the reason is score-affecting: upstream publishes no evaluationcode and no judge prompt. The paper names GPT-5-mini as the judge and defines the metrics,
nothing more, and the dataset card adds nothing — so the rubric prompt and verdict parsing are
authored by this port. Same posture as
aa_lcr, one notch weaker (aa_lcr's templates are atleast the upstream card's own snippets).
reference_impl.notessaysNOT YET VALIDATED and carries the Table 1 baselines to align against.
criterion_{i}columns arecollapsed into a single
criterialist (a reshape, not a rename-for-uniformity — a 40-keymostly-absent TypedDict is unusable as a sample type). The card's
configs.data_files.pathnames
ComplexConstraints_Benchmark_Set.csv, which does not exist (casing), soload_dataset("surgeai/ComplexConstraints")cannot resolve the file at all; the loader reads thestaged snapshot by its real name.
Two design calls worth reviewing
One judge call per rollout, not one per criterion. Upstream never states its call structure, and
"atomic criteria" would argue for per-criterion calls. The framework decides it:
iter_grader_outputscollects
extra[GRADER_OUTPUT_KEY]only when it is aMapping, so a list of N grader outputs isskipped silently and that spend vanishes from
profile.json— and tasks may not modifycore/.Batching keeps a rollout's whole verdict set in the single
ModelOutputthe profiler expects. Theverdicts are emitted as an indexed PASS/FAIL list so misalignment is detectable rather than
silently shifting neighbours.
Unreadable verdicts are counted, not just scored. A criterion the judge returns no readable
verdict for scores not-satisfied (an unreadable verdict must never inflate a score) but is counted
separately as
n_unparsed, per rollout and pooled in the report — so judge format drift staysdistinguishable from a model that genuinely failed the rubric. Empty/whitespace responses satisfy
zero criteria without invoking the judge (
grader_outputabsent there, no call made).Test Plan
Automated
ruff check && ruff format --check)ty check)tests/unitsuite 3219 passedscripts/check_preflight.py— 22 PASS / 0 FAIL (incl.check_meta_index_sync, datasetrevision pinning, task naming/tags, import policy)
sync_meta_index.py --checkandsync_package_stubs.py --checkboth cleanManual
Loader run against the real CSV: 75 rows, 1,559 criteria total — matches the paper's
stated counts exactly; every collapsed criterion a non-empty string.
sieval dataset download complex_constraintssucceeds;sieval task show complex_constraints_0shot_genthen reportsReady: yes.End-to-end
preprocess → infer → postprocess → feedback → reportover real samples with ascripted judge, on the smallest (10), largest (40) and a middle (19) rubric: verdicts
index-aligned with 0 unparsed, and macro (68.64) ≠ micro (68.12) as expected on uneven
rubrics.
Score comparison table vs the published leaderboard — NOT DONE. This needs a real judge
plus a real candidate model (API spend), so no
(model, expected, actual, diff)row existsyet. It is the reason the task ships
experimental, and the alignment targets are recordedin
reference_impl.notesfor whoever runs it:Note the leaderboard snapshot (2026-06-03) does not state a repeat count, and the paper does not
say whether Table 1 used the same GPT-5-mini judge as its training pipeline — so even a matched
run has an unpinned degree of freedom. The port defaults to
n=1.Checklist
Required (all PRs)
type(scope): description)AI-Generated Code - <model> (<provider>)in module docstringcore/(core/untouched)If: New or Modified Benchmark
sieval dataset download complex_constraintssucceeds)__init__.pyistubs andsieval/meta/index.jsonregenerated and committedIf: community/ Changes
sieval/community/complex_constraints.pystates in its docstringthat upstream ships no eval code and no judge prompt, so the template and parser are authored
by this port (contrasted explicitly with
sieval.community.aa_lcr)@sieval_dataset(license=…);no upstream code was vendored, so there is none to attribute