@@ -60,6 +60,13 @@ type Judge struct {
6060 model provider.Provider
6161 runConfig * config.RuntimeConfig
6262 concurrency int
63+
64+ // judgeWithSchema is a provider pre-configured with structured output.
65+ // Created lazily on first use and reused across all relevance checks.
66+ // Protected by judgeWithSchemaMu; only cached on success so that
67+ // transient errors (e.g. context cancellation) can be retried.
68+ judgeWithSchema provider.Provider
69+ judgeWithSchemaMu sync.Mutex
6370}
6471
6572// NewJudge creates a new Judge that runs relevance checks with the given concurrency.
@@ -141,16 +148,37 @@ func (j *Judge) CheckRelevance(ctx context.Context, response string, criteria []
141148 return passed , failed , errs
142149}
143150
144- // checkSingle checks a single relevance criterion against the response.
145- // It returns whether the check passed, the reason provided by the judge, and any error.
146- func (j * Judge ) checkSingle (ctx context.Context , response , criterion string ) (passed bool , reason string , err error ) {
151+ // getOrCreateJudgeWithSchema returns a provider pre-configured with structured output.
152+ // The provider is created once and reused across all relevance checks.
153+ // Unlike sync.Once, transient failures (e.g. context cancellation) are not
154+ // cached, allowing subsequent calls to retry.
155+ func (j * Judge ) getOrCreateJudgeWithSchema (ctx context.Context ) (provider.Provider , error ) {
156+ j .judgeWithSchemaMu .Lock ()
157+ defer j .judgeWithSchemaMu .Unlock ()
158+
159+ if j .judgeWithSchema != nil {
160+ return j .judgeWithSchema , nil
161+ }
162+
147163 modelCfg := j .model .BaseConfig ().ModelConfig
148- judgeWithSchema , err := provider .New (
164+ p , err := provider .New (
149165 ctx ,
150166 & modelCfg ,
151167 j .runConfig .EnvProvider (),
152168 options .WithStructuredOutput (judgeResponseSchema ),
153169 )
170+ if err != nil {
171+ return nil , err
172+ }
173+
174+ j .judgeWithSchema = p
175+ return j .judgeWithSchema , nil
176+ }
177+
178+ // checkSingle checks a single relevance criterion against the response.
179+ // It returns whether the check passed, the reason provided by the judge, and any error.
180+ func (j * Judge ) checkSingle (ctx context.Context , response , criterion string ) (passed bool , reason string , err error ) {
181+ judgeWithSchema , err := j .getOrCreateJudgeWithSchema (ctx )
154182 if err != nil {
155183 return false , "" , fmt .Errorf ("creating judge provider with structured output: %w" , err )
156184 }
0 commit comments