Skip to content

Commit 1a6f625

Browse files
committed
feat(skills): add openjudge skill for building custom evaluation pipelines
Adds a multi-file reference skill under skills/openjudge/ covering: - SKILL.md: entry point with architecture overview and quick start - graders.md: all built-in graders (common/text/code/format/agent/multi-turn/multimodal) plus LLMGrader, FunctionGrader, AgenticGrader, and custom grader guide - pipeline.md: GradingRunner, mapper, WeightedSumAggregator, evaluation strategies (Voting/Average) - generator.md: SimpleRubricsGenerator and IterativeRubricsGenerator - analyzer.md: PairwiseAnalyzer, DistributionAnalyzer, ConsistencyAnalyzer, and all validation analyzers Made-with: Cursor
1 parent 8131b74 commit 1a6f625

5 files changed

Lines changed: 1366 additions & 0 deletions

File tree

skills/openjudge/SKILL.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
---
2+
name: openjudge
3+
description: >
4+
Build custom LLM evaluation pipelines using the OpenJudge framework.
5+
Covers selecting and configuring graders (LLM-based, function-based, agentic),
6+
running batch evaluations with GradingRunner, combining scores with aggregators,
7+
applying evaluation strategies (voting, average), auto-generating graders from
8+
data, and analyzing results (pairwise win rates, statistics, validation metrics).
9+
Use when the user wants to evaluate LLM outputs, compare multiple models,
10+
design scoring criteria, or build an automated evaluation system.
11+
---
12+
13+
# OpenJudge Skill
14+
15+
Build evaluation pipelines for LLM applications using the `openjudge` library.
16+
17+
## When to Use This Skill
18+
19+
- User wants to evaluate LLM output quality (correctness, relevance, hallucination, etc.)
20+
- User wants to compare two or more models and rank them
21+
- User wants to design a scoring rubric and automate evaluation
22+
- User wants to analyze evaluation results statistically
23+
- User wants to build a reward model or quality filter
24+
25+
## Sub-documents — Read When Relevant
26+
27+
| Topic | File | Read when… |
28+
|-------|------|------------|
29+
| Grader selection & configuration | `graders.md` | User needs to pick or configure an evaluator |
30+
| Batch evaluation pipeline | `pipeline.md` | User needs to run evaluation over a dataset |
31+
| Auto-generate graders from data | `generator.md` | No rubric yet; generate from labeled examples |
32+
| Analyze & compare results | `analyzer.md` | User wants win rates, statistics, or metrics |
33+
34+
Read the relevant sub-document **before** writing any code.
35+
36+
## Install
37+
38+
```bash
39+
pip install py-openjudge
40+
```
41+
42+
## Architecture Overview
43+
44+
```
45+
Dataset (List[dict])
46+
47+
48+
GradingRunner ← orchestrates everything
49+
50+
├─► Grader A ──► EvaluationStrategy ──► _aevaluate() ──► GraderScore / GraderRank
51+
├─► Grader B ──► EvaluationStrategy ──► _aevaluate() ──► GraderScore / GraderRank
52+
└─► Grader C ...
53+
54+
├─► Aggregator (optional) ← combine multiple grader scores into one
55+
56+
└─► RunnerResult ← {grader_name: [GraderScore, ...]}
57+
58+
59+
Analyzer ← statistics, win rates, validation metrics
60+
```
61+
62+
## 5-Minute Quick Start
63+
64+
Evaluate responses for correctness using a built-in grader:
65+
66+
```python
67+
import asyncio
68+
from openjudge.models.openai_chat_model import OpenAIChatModel
69+
from openjudge.graders.common.correctness import CorrectnessGrader
70+
from openjudge.runner.grading_runner import GradingRunner
71+
72+
# 1. Configure the judge model (OpenAI-compatible endpoint)
73+
model = OpenAIChatModel(
74+
model="qwen-plus",
75+
api_key="sk-xxx",
76+
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
77+
)
78+
79+
# 2. Instantiate a grader
80+
grader = CorrectnessGrader(model=model)
81+
82+
# 3. Prepare dataset
83+
dataset = [
84+
{
85+
"query": "What is the capital of France?",
86+
"response": "Paris is the capital of France.",
87+
"reference_response": "Paris.",
88+
},
89+
{
90+
"query": "What is 2 + 2?",
91+
"response": "The answer is five.",
92+
"reference_response": "4.",
93+
},
94+
]
95+
96+
# 4. Run evaluation
97+
async def main():
98+
runner = GradingRunner(
99+
grader_configs={"correctness": grader},
100+
max_concurrency=8,
101+
)
102+
results = await runner.arun(dataset)
103+
104+
for i, result in enumerate(results["correctness"]):
105+
print(f"[{i}] score={result.score} reason={result.reason}")
106+
107+
asyncio.run(main())
108+
```
109+
110+
**Expected output:**
111+
```
112+
[0] score=5 reason=The response accurately states Paris as capital...
113+
[1] score=1 reason=The response gives the wrong answer (five vs 4)...
114+
```
115+
116+
## Key Data Types
117+
118+
| Type | Description |
119+
|------|-------------|
120+
| `GraderScore` | Pointwise result: `.score` (float), `.reason` (str), `.metadata` (dict) |
121+
| `GraderRank` | Listwise result: `.rank` (List[int]), `.reason` (str), `.metadata` (dict) |
122+
| `GraderError` | Error during evaluation: `.error` (str), `.reason` (str) |
123+
| `RunnerResult` | `Dict[str, List[GraderResult]]` — keyed by grader name |
124+
125+
## Result Handling Pattern
126+
127+
```python
128+
from openjudge.graders.schema import GraderScore, GraderRank, GraderError
129+
130+
for grader_name, grader_results in results.items():
131+
for i, result in enumerate(grader_results):
132+
if isinstance(result, GraderScore):
133+
print(f"{grader_name}[{i}]: score={result.score}")
134+
elif isinstance(result, GraderRank):
135+
print(f"{grader_name}[{i}]: rank={result.rank}")
136+
elif isinstance(result, GraderError):
137+
print(f"{grader_name}[{i}]: ERROR — {result.error}")
138+
```
139+
140+
## Model Configuration
141+
142+
All LLM-based graders accept either a `BaseChatModel` instance or a dict config:
143+
144+
```python
145+
# Option A: instance
146+
from openjudge.models.openai_chat_model import OpenAIChatModel
147+
model = OpenAIChatModel(model="gpt-4o", api_key="sk-...")
148+
149+
# Option B: dict (auto-creates OpenAIChatModel)
150+
model_cfg = {"model": "gpt-4o", "api_key": "sk-..."}
151+
grader = CorrectnessGrader(model=model_cfg)
152+
153+
# OpenAI-compatible endpoints (DashScope / local / etc.)
154+
model = OpenAIChatModel(
155+
model="qwen-plus",
156+
api_key="sk-xxx",
157+
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
158+
)
159+
```

0 commit comments

Comments
 (0)