Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Microsoft Autogen Studio Eval Judges

From Leeroopedia
Revision as of 11:33, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/Microsoft_Autogen_Studio_Eval_Judges.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Sources python/packages/autogen-studio/autogenstudio/eval/judges.py
Domains Evaluation, LLM, Agent_Systems, Judging
Last Updated 2026-02-11

Overview

Description

The Studio Eval Judges module provides an extensible framework for evaluating agent task results using large language models as judges. This implementation includes abstract base classes and a concrete LLM-based judge that can assess results across multiple evaluation dimensions.

The module defines:

  • BaseEvalJudge - Abstract base class defining the judge interface with serialization support
  • BaseEvalJudgeConfig - Configuration model for base judge parameters
  • LLMEvalJudge - Concrete implementation that uses an LLM to evaluate results against criteria
  • LLMEvalJudgeConfig - Configuration model including model client settings

The LLM judge can evaluate results across multiple dimensions simultaneously using parallel evaluation, producing structured scores with reasoning for each dimension. It leverages AutoGen's component system for serialization and deserialization.

Usage

Judges are used in evaluation pipelines to assess the quality of agent responses. The LLMEvalJudge takes evaluation tasks and results, along with criteria, and produces EvalScore objects containing dimension-specific scores and overall scores. The judge system is designed to be extensible, allowing developers to create custom judges by extending BaseEvalJudge.

Code Reference

Source Location

python/packages/autogen-studio/autogenstudio/eval/judges.py

Signature

class BaseEvalJudgeConfig(BaseModel):
    """Base configuration for evaluation judges."""
    name: str = "Base Judge"
    description: str = ""
    metadata: Dict[str, Any] = {}

class BaseEvalJudge(ABC, ComponentBase[BaseEvalJudgeConfig]):
    """Abstract base class for evaluation judges."""
    component_type = "eval_judge"

    def __init__(
        self,
        name: str = "Base Judge",
        description: str = "",
        metadata: Optional[Dict[str, Any]] = None
    )

    @abstractmethod
    async def judge(
        self,
        task: EvalTask,
        result: EvalRunResult,
        criteria: List[EvalJudgeCriteria],
        cancellation_token: Optional[CancellationToken] = None,
    ) -> EvalScore

    def _to_config(self) -> BaseEvalJudgeConfig

class LLMEvalJudgeConfig(BaseEvalJudgeConfig):
    """Configuration for LLMEvalJudge."""
    model_client: Any  # ComponentModel

class LLMEvalJudge(BaseEvalJudge, Component[LLMEvalJudgeConfig]):
    """Judge that uses an LLM to evaluate results."""
    component_config_schema = LLMEvalJudgeConfig
    component_type = "eval_judge"
    component_provider_override = "autogenstudio.eval.judges.LLMEvalJudge"

    def __init__(
        self,
        model_client: ChatCompletionClient,
        name: str = "LLM Judge",
        description: str = "Evaluates results using an LLM",
        metadata: Optional[Dict[str, Any]] = None,
    )

    async def judge(
        self,
        task: EvalTask,
        result: EvalRunResult,
        criteria: List[EvalJudgeCriteria],
        cancellation_token: Optional[CancellationToken] = None,
    ) -> EvalScore

    async def _judge_dimension(
        self,
        task: EvalTask,
        result: EvalRunResult,
        criterion: EvalJudgeCriteria,
        cancellation_token: Optional[CancellationToken] = None,
    ) -> EvalDimensionScore

    def _format_task(self, task: EvalTask) -> str

    def _parse_judgment(
        self,
        judgment_text: str,
        max_value: float
    ) -> Tuple[str, Optional[float]]

    def _to_config(self) -> LLMEvalJudgeConfig

    @classmethod
    def _from_config(cls, config: LLMEvalJudgeConfig) -> Self

Import

from autogenstudio.eval.judges import (
    BaseEvalJudge,
    BaseEvalJudgeConfig,
    LLMEvalJudge,
    LLMEvalJudgeConfig
)

I/O Contract

Inputs

Parameter Type Description
task EvalTask The evaluation task containing input, description, and metadata
result EvalRunResult The result produced by running the evaluation task
criteria List[EvalJudgeCriteria] List of evaluation criteria, one per dimension to be judged
cancellation_token Optional[CancellationToken] Token to cancel the judging operation
model_client (LLMEvalJudge) ChatCompletionClient LLM client used to perform the evaluation

Outputs

Return Type Description
EvalScore Composite score containing overall_score (average of dimension scores), dimension_scores (list of EvalDimensionScore objects), and metadata
EvalDimensionScore (_judge_dimension) Individual dimension score with dimension name, score value, reasoning text, and min/max bounds

Usage Examples

Creating and Using an LLM Judge

from autogenstudio.eval.judges import LLMEvalJudge
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogenstudio.datamodel.eval import EvalTask, EvalRunResult, EvalJudgeCriteria

# Create model client
model_client = OpenAIChatCompletionClient(
    model="gpt-4",
    api_key="your-api-key"
)

# Create LLM judge
llm_judge = LLMEvalJudge(
    model_client=model_client,
    name="GPT-4 Judge",
    description="Evaluates responses using GPT-4"
)

# Define evaluation criteria
criteria = [
    EvalJudgeCriteria(
        dimension="relevance",
        prompt="Evaluate how relevant the response is to the query.",
        min_value=0,
        max_value=10
    ),
    EvalJudgeCriteria(
        dimension="accuracy",
        prompt="Evaluate the factual accuracy of the response.",
        min_value=0,
        max_value=10
    ),
    EvalJudgeCriteria(
        dimension="completeness",
        prompt="Evaluate whether the response fully addresses the question.",
        min_value=0,
        max_value=10
    )
]

# Create task and result
task = EvalTask(
    name="Capital Query",
    description="Geography question",
    input="What is the capital of France?"
)

result = EvalRunResult(
    status=True,
    result=task_result  # TaskResult from runner
)

# Run evaluation
score = await llm_judge.judge(task, result, criteria)

print(f"Overall Score: {score.overall_score}")
for dim_score in score.dimension_scores:
    print(f"{dim_score.dimension}: {dim_score.score} - {dim_score.reason}")

Serializing and Deserializing a Judge

from autogenstudio.eval.judges import LLMEvalJudge
from autogen_ext.models.openai import OpenAIChatCompletionClient

# Create judge
model_client = OpenAIChatCompletionClient(
    model="gpt-4o-mini",
    api_key="your-api-key"
)

llm_judge = LLMEvalJudge(
    model_client=model_client,
    name="Mini Judge",
    description="Fast evaluation with GPT-4o-mini"
)

# Serialize to ComponentModel
judge_config = llm_judge.dump_component()
print(f"Serialized judge: {judge_config}")

# Save to JSON
import json
with open("judge_config.json", "w") as f:
    json.dump(judge_config.model_dump(), f, indent=2)

# Deserialize back to LLMEvalJudge
deserialized_judge = LLMEvalJudge.load_component(judge_config)

# Use deserialized judge
score = await deserialized_judge.judge(task, result, criteria)

Creating a Custom Judge

from autogenstudio.eval.judges import BaseEvalJudge, BaseEvalJudgeConfig
from autogenstudio.datamodel.eval import (
    EvalTask, EvalRunResult, EvalJudgeCriteria,
    EvalScore, EvalDimensionScore
)
from typing import List, Optional
from autogen_core import CancellationToken

class RuleBasedJudge(BaseEvalJudge):
    """Custom judge using rule-based evaluation."""

    def __init__(self, name: str = "Rule Judge", description: str = ""):
        super().__init__(name, description)

    async def judge(
        self,
        task: EvalTask,
        result: EvalRunResult,
        criteria: List[EvalJudgeCriteria],
        cancellation_token: Optional[CancellationToken] = None,
    ) -> EvalScore:
        """Implement custom judging logic."""
        dimension_scores = []

        for criterion in criteria:
            # Implement rule-based scoring logic
            score_value = self._calculate_rule_score(task, result, criterion)

            dim_score = EvalDimensionScore(
                dimension=criterion.dimension,
                score=score_value,
                reason=f"Rule-based score for {criterion.dimension}",
                max_value=criterion.max_value,
                min_value=criterion.min_value
            )
            dimension_scores.append(dim_score)

        # Calculate overall score
        overall = sum(ds.score for ds in dimension_scores) / len(dimension_scores)

        return EvalScore(
            overall_score=overall,
            dimension_scores=dimension_scores
        )

    def _calculate_rule_score(
        self,
        task: EvalTask,
        result: EvalRunResult,
        criterion: EvalJudgeCriteria
    ) -> float:
        """Custom scoring logic."""
        # Implement your rule-based scoring here
        if not result.status:
            return 0.0

        # Example: length-based scoring
        if result.result and result.result.messages:
            message_length = len(str(result.result.messages[-1].content))
            return min(message_length / 100, criterion.max_value)

        return 0.0

# Use custom judge
custom_judge = RuleBasedJudge(
    name="Length-Based Judge",
    description="Scores based on response length"
)

score = await custom_judge.judge(task, result, criteria)

Parallel Evaluation Across Multiple Dimensions

from autogenstudio.eval.judges import LLMEvalJudge
from autogenstudio.datamodel.eval import EvalJudgeCriteria

# Define comprehensive criteria
criteria = [
    EvalJudgeCriteria(
        dimension="relevance",
        prompt="Is the response relevant to the user's query?"
    ),
    EvalJudgeCriteria(
        dimension="accuracy",
        prompt="Is the response factually accurate?"
    ),
    EvalJudgeCriteria(
        dimension="clarity",
        prompt="Is the response clear and easy to understand?"
    ),
    EvalJudgeCriteria(
        dimension="completeness",
        prompt="Does the response fully address the query?"
    ),
    EvalJudgeCriteria(
        dimension="helpfulness",
        prompt="How helpful is the response to the user?"
    )
]

# The judge will evaluate all dimensions in parallel
score = await llm_judge.judge(task, result, criteria)

# Access individual dimension scores
for dim_score in score.dimension_scores:
    print(f"\n{dim_score.dimension.upper()}")
    print(f"Score: {dim_score.score}/{dim_score.max_value}")
    print(f"Reason: {dim_score.reason}")

print(f"\nOverall Score: {score.overall_score:.2f}/10.0")

Handling Evaluation Errors

from autogenstudio.eval.judges import LLMEvalJudge
import asyncio

try:
    # Run evaluation with timeout
    score = await asyncio.wait_for(
        llm_judge.judge(task, result, criteria),
        timeout=30.0  # 30 second timeout
    )

    # Check for failed dimensions
    for dim_score in score.dimension_scores:
        if dim_score.score == 0.0 and "Failed to parse" in dim_score.reason:
            print(f"Warning: Failed to evaluate {dim_score.dimension}")

except asyncio.TimeoutError:
    print("Evaluation timed out after 30 seconds")
except Exception as e:
    print(f"Evaluation failed: {e}")

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment