aws-samples / aws-samples/sample-GEDD

Proposal: sample-gedd-openeval-adapter — bridge golden datasets/rubrics to EvalPort

Open
#40 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
12
Forks
0
PR merge metrics
No merged PRs in 30d

Description

## Proposal: `sample-gedd-openeval-adapter` — bridge GEDD's golden datasets/rubrics to the EvalPort format

Hi maintainers — this looks like a genuinely useful tool (grounded-theory-driven golden dataset + judge rubric generation is a gap most eval tooling doesn't address). I'd like to propose a small adapter package that converts GEDD's native artifacts to/from **[EvalPort](https://github.com/adhabnr-ux/evalport)**, an open interchange format ("Suite" = test cases + graders, "ResultSet" = per-test-case results) for portable LLM eval data. Spec: https://github.com/adhabnr-ux/evalport/blob/main/spec/SPEC.md

### Why this repo is a good fit

`grounded-evals/src/grounded_evals/models/core.py` already defines exactly the kind of native, reusable data objects an adapter needs — not just notebook output:

- `GoldenDataset` / `GoldenPrompt` — a golden set of prompts with full provenance (`category_id`, `code_id`, `is_edge_case`, `is_adversarial`, `expected_behavior`, `rationale`)
- `JudgeRubric` / `JudgeCriterion` — scoring criteria generated from `axial_coding` output (`generate_rubric()` in `judge_builder/rubric.py`), each with a `scoring_rubric: dict[int, str]` and a `weight`
- `Category` / `Code` / `ParadigmModel` — the qualitative-coding backbone that produces the above

That maps cleanly onto EvalPort's `EvalSuite` (test_cases + graders) with no lossy squeeze, since GEDD's prompt-level provenance fits naturally into `TestCase.metadata` / `tags`, and the rubric's per-criterion scoring bands fit into an `llm_judge` grader's `params`.

### Proposed sketch

```python
# adapters/sample-gedd-openeval-adapter/sample_gedd_openeval_adapter/to_openeval.py
from grounded_evals.models.core import GoldenDataset, GoldenPrompt, JudgeRubric, JudgeCriterion

def _criterion_to_grader(c: JudgeCriterion) -> dict:
rubric_text = "\n".join(f"{k}: {v}" for k, v in sorted(c.scoring_rubric.items(), reverse=True))
return {
"id": f"gr_{c.name.lower().replace(' ', '_')}",
"type": "llm_judge",
"weight": c.weight,
"description": c.description,
"params": {
"prompt": f"{c.description}\n\nScoring rubric:\n{rubric_text}",
},
}

def _prompt_to_testcase(p: GoldenPrompt, grader_ids: list[str]) -> dict:
return {
"id": str(p.id),
"input": p.prompt_text,
"graders": grader_ids,
"metadata": {
"category_id": str(p.category_id),
"code_id": str(p.code_id) if p.code_id else None,
"expected_behavior": p.expected_behavior,
"rationale": p.rationale,
"turn_count": p.turn_count,
},
"tags": [t for t, on in (("edge_case", p.is_edge_case), ("adversarial", p.is_adversarial)) if on],
}

def to_openeval(dataset: GoldenDataset, rubric: JudgeRubric) -> dict:
graders = [_criterion_to_grader(c) for c in rubric.criteria]
grader_ids = [g["id"] for g in graders]
return {
"version": "1.0.0",
"id": f"suite_{dataset.agent_name.lower().replace(' ', '_')}_{dataset.version}",
"name": f"{dataset.agent_name} — GEDD Golden Dataset",
"description": dataset.agent_description,
"graders": graders,
"test_cases": [_prompt_to_testcase(p, grader_ids) for p in dataset.prompts],
"metadata": {"source": "gedd", "gedd_version": dataset.version},
}
```

```python
# adapters/sample-gedd-openeval-adapter/sample_gedd_openeval_adapter/from_openeval.py
# A ResultSet produced by *any* EvalPort-speaking runner can feed straight into
# judge_builder/calibrate.py's calibration loop — treating each grader_result's
# score/passed as the signal to calibrate the GEDD-generated judge against.
def from_openeval(result_set: dict) -> list[dict]:
"""Flatten ResultSet.results[].grader_results into calibration records
keyed by test_case_id + grader_id, ready for judge_builder.calibrate."""
records = []
for r in result_set["results"]:
for gr in r["grader_results"]:
records.append({
"test_case_id": r["test_case_id"],
"grader_id": gr["grader_id"],
"score": gr["score"],
"passed": gr["passed"],
})
return records
```

(Sketch only — I haven't run this against the actual UUID/enum types, just laid out the field mapping for discussion. Happy to build it out properly as a PR if the shape looks right to you.)

### What I'm asking

Would you be open to a PR that adds this as a small, separately-versioned adapter package (own `pyproject.toml`, importing `grounded_evals.models.core` and `grounded_evals.judge_builder.rubric`), living either in this repo (e.g. `grounded-evals/adapters/openeval/`) or as a standalone package that depends on `grounded-evals`? Either is fine by me — whichever fits your structure better. I know AWS sample repos may require a CLA; happy to go through whatever process applies before opening the PR itself.

No pressure either way — just flagging the fit since the data model here is unusually well-suited to this. Thanks for the tool, the grounded-theory approach to golden-set generation is a nice idea.

Contributor guide

Open the contributing guide

Research direction

Start with grounded-evals/src/grounded_evals/models/core.py and grounded_evals/judge_builder/rubric.py, then compare their models with the EvalPort SPEC.md. Confirm the adapter package location and field mappings with maintainers, including UUID and enum handling. Done means a separately versioned adapter can convert GEDD datasets and rubrics to EvalPort suites and flatten ResultSet data for calibration.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
ai, testing-qa, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.