Skip to main content

Packages

PackageContains
io.github.markpollack.judgeCore judge interfaces and utilities
io.github.markpollack.judge.contextJudgmentContext, ExecutionStatus
io.github.markpollack.judge.resultJudgment, JudgmentStatus, Check
io.github.markpollack.judge.scoreScore, BooleanScore, NumericalScore, CategoricalScore
io.github.markpollack.judge.juryJury, Verdict, voting strategies
io.github.markpollack.judge.springaiSpring AI bridge
io.github.markpollack.judge.langchain4jLangChain4j bridge
io.github.markpollack.judge.koogKoog bridge
io.github.markpollack.judge.agentclientAgentClient bridge
io.github.markpollack.judge.aiAI-backed judge infrastructure
io.github.markpollack.judge.ragRAG judges and RagContext

Core Types

Judge

The fundamental evaluation interface. A functional interface for lambda and method reference support.
Use directly as a lambda, or extend DeterministicJudge / LLMJudge for metadata support.

AsyncJudge

Asynchronous variant for non-blocking evaluation:

ReactiveJudge

Reactive variant for Spring WebFlux / Project Reactor:

DeterministicJudge

Abstract base class for rule-based judges. Provides JudgeWithMetadata support:
JudgeWithMetadata extends Judge, so DeterministicJudge is also a Judge.

NamedJudge

Composition wrapper that attaches metadata to any judge (including lambdas):

JudgeWithMetadata

Marker interface for judges that expose identity:
Infrastructure code can use instanceof JudgeWithMetadata for discovery:

JudgeMetadata

Identity record:

JudgeType


Context

JudgmentContext

All evaluation inputs in one immutable record:
Builder methods:
MethodTypeRequired
goal(String)The agent’s task descriptionYes
workspace(Path)Directory the agent modifiedYes
status(ExecutionStatus)Agent execution outcomeYes
startedAt(Instant)When execution beganYes
executionTime(Duration)How long execution tookYes
agentOutput(String)Text output from the agentNo
error(Throwable)Exception if execution failedNo
metadata(String, Object)Arbitrary key-value pairsNo
metadata(Map<String, Object>)Bulk metadataNo

ExecutionStatus

ValueMeaning
SUCCESSAgent completed normally
FAILEDAgent threw an exception or returned an error
TIMEOUTExecution exceeded time limit
CANCELLEDExecution was cancelled
REFUSEDModel declined the request (content filter)
UNKNOWNStatus could not be determined

Results

Judgment

Immutable evaluation result:
Static factory methods:
Builder:
Utility methods:
MethodReturnsDescription
pass()booleantrue if status == PASS
elapsed()DurationElapsed time from metadata
error()ThrowableError from metadata

JudgmentStatus

Check

Granular sub-assertion within a judgment:
Factory methods:

Score Types

Score is a sealed interface with three permitted implementations:

BooleanScore

Simple pass/fail:

NumericalScore

Continuous scoring with bounds:

CategoricalScore

Discrete categories from a fixed set:

Scores Utility

Convert between score types for heterogeneous aggregation:

Composition

Judges Utility

Static methods for creating and composing judges:
MethodDescription
named(Judge, String)Wrap with a name
named(Judge, String, String)Wrap with name and description
named(Judge, String, String, JudgeType)Wrap with full metadata
alwaysPass(String)Test judge that always passes
alwaysFail(String)Test judge that always fails
tryMetadata(Judge)Extract metadata if available (Optional<JudgeMetadata>)
and(Judge, Judge)Short-circuit AND
or(Judge, Judge)Short-circuit OR
allOf(Judge...)All must pass (variadic AND)
anyOf(Judge...)Any can pass (variadic OR)

AI-Core Types

Framework-neutral infrastructure for AI-backed judges. Located in the agent-judge-ai-core module (zero external dependencies).

ModelBackedJudge

Composed AI-backed judge built via builder pattern. Pipeline: render prompt → invoke model → classify response → produce Judgment. No subclassing needed.
Builder MethodRequiredDescription
model(JudgeModel)YesAI backend to invoke
template(JudgePromptTemplate)YesPrompt template with {{variable}} placeholders
classifier(JudgmentClassifier)YesMaps model response to Judgment

JudgeModel

Functional interface for AI model invocation. Framework-specific implementations live in bridge modules.
ImplementationModuleBackend
SpringAiJudgeModelagent-judge-llmSpring AI ChatClient
AgentClientJudgeModelagent-judge-agent-clientCLI agent via AgentClient

JudgePromptTemplate

Loads, validates, and renders prompt templates with {{variable}} placeholders extracted from JudgmentContext.
Builder MethodDefaultDescription
source(TextSource)RequiredTemplate text source (classpath, file, or string)
renderer(JudgeTemplateRenderer)SimpleJudgeTemplateRendererPluggable template engine
missingVariablePolicy(MissingVariablePolicy)STRICTSTRICT, EMPTY_STRING, or LEAVE_PLACEHOLDER
Available variables from JudgmentContext: {{goal}}, {{output}}, {{workspace}}, {{status}}, {{metadata.*}}.

JudgeTemplateRenderer

Pluggable template engine interface:
Default implementation SimpleJudgeTemplateRenderer performs {{variable}} substitution.

JudgmentClassifier

Functional interface that maps a model response to a Judgment:

LabelJudgmentClassifier

Exact normalized label matching with builder pattern:

Supporting Records


Jury System

Jury Interface

SimpleJury

Flat multi-judge aggregation. See Jury System for full usage. Builder:
MethodDescription
.judge(Judge)Add with weight 1.0
.judge(Judge, double)Add with custom weight
.votingStrategy(VotingStrategy)Required
.parallel(boolean)Default true
.executor(Executor)Custom thread pool

CascadedJury

Sequential tiered evaluation. See Jury System for full usage. Builder:
MethodDescription
.tier(String, Jury, TierPolicy)Add a named tier
.build()Validates last tier is FINAL_TIER

Verdict

FieldDescription
aggregatedThe voting strategy’s aggregated result
individualAll individual judge results (ordered)
individualByNameResults keyed by judge name
weightsWeight assigned to each judge
subVerdictsPer-tier verdicts (CascadedJury only)

VotingStrategy

Implementations:
ClassConstructor
MajorityVotingStrategy() or (TiePolicy, ErrorPolicy)
ConsensusStrategy()
AverageVotingStrategy()
WeightedAverageStrategy()
MedianVotingStrategy()

TierPolicy

TiePolicy

ErrorPolicy

Juries Utility


Framework Bridge Evaluators

Each framework bridge provides an Evaluator (one-liner convenience) and a JudgmentContextBuilder (full control). All evaluators follow the same 4-method pattern: Judge/Jury x with/without extra metadata.
RuntimeInput typeEvaluatorContext builder
Spring AIChatResponseSpringAiEvaluatorSpringAiJudgmentContextBuilder
LangChain4jResult<T>LangChain4jEvaluatorLangChain4jJudgmentContextBuilder
KoogAIAgentKoogEvaluatorKoogJudgmentContextBuilder
AgentClientAgentClientResponseAgentClientEvaluatorAgentClientJudgmentContextBuilder
Bridge modules declare framework dependencies with provided scope. Your application must already include the corresponding framework/runtime dependency.

SpringAiEvaluator

Bridges Spring AI ChatResponse output to agent-judge evaluation. Uses Supplier<ChatResponse> because Spring AI ChatClient calls don’t take the goal as an argument at call time.
Metadata extracted (constants in SpringAiMetadataKeys):
KeySource
springai.responseIdChatResponse.getMetadata().getId()
springai.modelChatResponse.getMetadata().getModel()
springai.finishReasonGeneration finish reason
springai.usage.promptTokensPrompt token count
springai.usage.completionTokensCompletion token count
springai.usage.totalTokensTotal token count
springai.hasToolCallsWhether tool calls were made
springai.toolCallsBest-effort tool-call requests (not a full execution trace)
Finish reason mapping: stop → SUCCESS, tool_calls → SUCCESS, length → SUCCESS (indicates truncation; judges may choose to abstain), content_filter → REFUSED, null → UNKNOWN

LangChain4jEvaluator

Bridges LangChain4j Result<T> to agent-judge evaluation. Uses Function<String, Result<T>> because LangChain4j AiServices are dynamic proxies — there’s no common agent interface.
Metadata extracted:
KeySource
langchain4j.tokenUsageResult.tokenUsage()
langchain4j.toolExecutionsResult.toolExecutions()
langchain4j.sourcesResult.sources() (also used as RAG context fallback)
langchain4j.finishReasonResult.finishReason().name()
Finish reason mapping: STOP/TOOL_EXECUTION → SUCCESS, LENGTH → SUCCESS (indicates truncation; judges may choose to abstain), CONTENT_FILTER → REFUSED, OTHER → UNKNOWN

KoogEvaluator

Bridges JetBrains Koog AIAgent to agent-judge evaluation. Calls agent.run(input) directly — Koog’s native Java API is synchronous from the caller’s perspective.
Metadata extracted:
KeySource
koog.agentIdagent.getId()

AgentClientEvaluator

Bridges CLI-delegated agents (Claude Code, Codex, Gemini CLI, Amazon Q, etc.) via AgentClient. Uses Supplier<AgentClientResponse> to keep process execution inside AgentClient.
Metadata extracted (constants in AgentClientMetadataKeys):
KeySource
agentclient.modelresponse.getMetadata().getModel()
agentclient.sessionIdresponse.getMetadata().getSessionId()
agentclient.finishReasonresponse.getMetadata().getFinishReason()
AgentClientJudgmentContextBuilder also maps result text to agentOutput, success/failure to ExecutionStatus, workspace to JudgmentContext.workspace, and metadata duration to executionTime.

JudgmentContextBuilder (All Bridges)

For full control, use the JudgmentContextBuilder directly:
Each bridge’s builder follows the same two-entry-point pattern: from() for pre-existing responses, execute() for wrapping the call. Both have overloads accepting Map<String, Object> extraMetadata for attaching run IDs, experiment tags, etc.

RAG Evaluation

RagContext

Static helper for extracting RAG metadata from a JudgmentContext:
Metadata key constants:
ConstantValueFallback
RagContext.QUESTION_KEYrag.questioncontext.goal()
RagContext.CONTEXT_KEYrag.contextlangchain4j.sources
RagContext.ANSWER_KEYrag.answercontext.agentOutput()
The context() method handles both String and List<?> values — lists are joined with newlines.

RAG Judges

All three RAG judges extend LLMJudge and return ABSTAIN when required metadata is missing:
JudgeEvaluatesRequires
FaithfulnessJudgeIs the answer grounded in the context?context + answer
ContextualRelevanceJudgeIs the context relevant to the question?context
HallucinationJudgeDoes the answer contain unsupported claims?context + answer
See Built-in Judges for usage examples.

Module Coordinates

Judge families:
ModuleArtifactKey Dependencies
Coreio.github.markpollack:agent-judge-coreNone (zero deps)
AI Coreio.github.markpollack:agent-judge-ai-coreNone (zero deps)
Execio.github.markpollack:agent-judge-execagent-sandbox
Fileio.github.markpollack:agent-judge-fileJavaParser, Maven Model
LLMio.github.markpollack:agent-judge-llmSpring AI ChatClient, SpringAiJudgeModel
RAGio.github.markpollack:agent-judge-ragagent-judge-llm
Framework bridges:
ModuleArtifactKey Dependencies (provided)
Spring AIio.github.markpollack:agent-judge-spring-aiSpring AI Model
LangChain4jio.github.markpollack:agent-judge-langchain4jLangChain4j
Koogio.github.markpollack:agent-judge-koogKoog Agents
AgentClientio.github.markpollack:agent-judge-agent-clientAgentClient, AgentClientJudgeModel
Add modules with explicit versions: