feat(project): add project add evaluator llm-as-a-judge - #2124
Conversation
|
Claude Security Review: no high-confidence findings. (run) |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## refactor #2124 +/- ##
============================================
+ Coverage 97.22% 97.24% +0.01%
============================================
Files 463 466 +3
Lines 28160 28341 +181
============================================
+ Hits 27378 27559 +181
Misses 782 782 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
AgentCore Harness Review
Verdict: Looks good
Nice PR — well-structured and consistent with sibling add subcommands. Highlights:
- Handler is a thin flag-parsing layer;
EvaluatorSchema.safeParseis the single source of truth for validation. - Tests use real temp directories and drive the CLI end-to-end via
createRootHandler(no fs mocks) — mocking is limited toTestCoreClient/TestGlobalConfigAccessorat true I/O boundaries.test.eachcovers all validation branches. - Placeholder validator in
src/projectSchemas/evaluator.tsfails fast locally with a clear message instead of surfacing as a CloudFormation rollback at deploy time.structuredCloneon presets inresolvePresetguards against downstream mutation of the shared table. - Wiring through
AddResourceInput,FsProjectManager.addResource, andtoProjectSpecKeyis correct and matches the existing pattern.
A couple of very minor observations, not blockers:
LEVEL_ALLOWED_PLACEHOLDERSduplicates a list that lives server-side inInstructionValidator; if the service ever expands the allowed set (e.g. lifts the account-feature gate on skill placeholders for non-TOOL_CALLlevels), this table will silently reject valid instructions. A short comment pointing at the service source is already there; consider a follow-up to keep them in sync (or accept unknown placeholders with a warning rather than a hard error).findInstructionPlaceholderstrims whitespace inside{ ... }, so{ context }passes local validation but is sent to Bedrock verbatim. If the service does exact matching, the local check would be a false positive. Cheap fix if it matters: don't trim, or normalize the stored instructions.
Neither of these needs to be addressed before merging.
e14f409 to
defe35b
Compare
|
Claude Security Review: no high-confidence findings. (run) |
| }, | ||
| } as const satisfies Record<string, RatingScale>; | ||
|
|
||
| export type RatingScalePreset = keyof typeof RATING_SCALE_PRESETS; |
There was a problem hiding this comment.
RATING_SCALE_PRESET file should be left under llm-as-a-judge
| "scoring instructions for the judge (inline text, 'file://<path>', or '-' for stdin); must embed at least one level placeholder, e.g. '{context}' for SESSION", | ||
| z.string().optional(), | ||
| ), | ||
| flag( |
There was a problem hiding this comment.
combine --rating-scale and --rating-scales-files flags together
There was a problem hiding this comment.
combined and removed flag
| llmAsAJudge: { | ||
| model: "anthropic.claude-v2", | ||
| instructions: "Judge the answer", | ||
| instructions: "Judge the answer given {context}", |
| try { | ||
| return JSON.parse(raw); | ||
| } catch (error) { | ||
| throw new InputValidationError("'--rating-scale-file' must contain valid JSON", { |
There was a problem hiding this comment.
Doesn't SourceResolver handle this for us.
| }, | ||
| }, | ||
| kmsKeyArn: flags["kms-key-arn"], | ||
| tags: parseJsonFlag<Record<string, string>>("tags", flags["tags"]), |
There was a problem hiding this comment.
there is special helper for this i think...
There was a problem hiding this comment.
uses parseJsonFlagWithSchema(..., TagsSchema) now
| ratingScale: RatingScaleSchema, | ||
| }); | ||
| export type LlmAsAJudgeConfig = z.infer<typeof LlmAsAJudgeConfigSchema>; | ||
| // The CreateEvaluator API templates the judge prompt: instructions must embed at |
| export type LlmAsAJudgeConfig = z.infer<typeof LlmAsAJudgeConfigSchema>; | ||
| // The CreateEvaluator API templates the judge prompt: instructions must embed at | ||
| // least one level-specific placeholder (e.g. "{context}") and use no placeholder | ||
| // outside that level's allowed set. This mirrors AgentCoreEvaluationControlPlaneService's |
There was a problem hiding this comment.
no validation on placeholder emu,s because if evals introduces new ones, customers will get confused why the cli doesn't accepted.
jariy17
left a comment
There was a problem hiding this comment.
apply fixes we discussed offline and in comments and ill approve
Adds a CLI command to attach a custom LLM-as-a-Judge evaluator to a project. The judge is another LLM prompted with scoring instructions and a rating scale, written into spec.evaluators (deployed as an AWS::BedrockAgentCore::Evaluator by the existing CDK constructs). - New `evaluator` subrouter under `project add` with an `llm-as-a-judge` subcommand. - Flags: --name, --level (SESSION|TRACE|TOOL_CALL), --model (Bedrock id/ARN), --instructions (inline/file:///stdin), --rating-scale, --description, --kms-key-arn, --tags. - --rating-scale accepts either a named preset (1-5-quality, 1-3-simple, pass-fail, good-neutral-bad) or an inline JSON rating scale; presets live beside the subcommand and expand into the schema's numerical/categorical shapes. - --tags is parsed via parseJsonFlagWithSchema against TagsSchema. - Instruction placeholder validation is left to the CreateEvaluator service so the CLI never rejects placeholders the service later adds. - Wire the new `evaluator` resource type through AddResourceInput and FsProjectManager.addResource / toProjectSpecKey. Verified end-to-end: preset and inline-JSON rating scales both deploy a real evaluator (CREATE_COMPLETE) and write deployed-state.json.
defe35b to
9bd43e3
Compare
|
Claude Security Review: no high-confidence findings. (run) |
| "required option '--rating-scale <rating-scale>' not specified", | ||
| ); | ||
|
|
||
| if (!isValidBedrockModelId(flags["model"])) |
There was a problem hiding this comment.
Looking at this: https://docs.aws.amazon.com/bedrock/latest/APIReference/API_FoundationModelSummary.html
it looks like foundation models don't have account Id in the ARN, but this validation method expects it.
If this is right, the fix would be simple, just add : before foundation-model in the regex
There was a problem hiding this comment.
real bug let me fix it
| if (isRatingScalePreset(value)) { | ||
| return structuredClone(RATING_SCALE_PRESETS[value]) as RatingScale; | ||
| } | ||
| if (!value.trim().startsWith("{")) { |
There was a problem hiding this comment.
I see we dropped the --rating-scales-files. Do we still intend to support --rating-scale file://...? If so, this resolution method needs to change. File will always be rejected by the starts with { check.
There was a problem hiding this comment.
discussed offline we are not supporting it anymore
Bedrock foundation-model ARNs omit the account id (arn:aws:bedrock:<region>::foundation-model/<id>) while inference-profile ARNs include it. Make the account segment optional in the evaluator model-id ARN validator so a valid foundation-model ARN is not rejected.
|
Claude Security Review: no high-confidence findings. (run) |
…e's account format (#2134) The prior validator made the account segment optional for both resource types, which also accepted impossible combinations (account-scoped foundation-model, accountless inference-profile). Pin each type to its documented shape: foundation-model ARNs omit the account, while (application-)inference-profile ARNs carry it. Also accept application-inference-profile ARNs, which the prior pattern rejected. Follow-up to #2124 (nborges review). Co-authored-by: gitikavj <gitikavj@amazon.com>
What
Adds
agentcore project add evaluator llm-as-a-judge. this attaches a custom LLM-as-a-Judge evaluator to a project. The judge is another LLM prompted with scoring instructions and a rating scale, written intospec.evaluatorsinagentcore.json. The existing CDK constructs render it as anAWS::BedrockAgentCore::Evaluator, soproject deployprovisions it.Command
Details
evaluatorsubrouter underproject addwith anllm-as-a-judgesubcommand (mirrors thecredentialssubrouter pattern). Wires a newevaluatorresource type throughAddResourceInputandFsProjectManager.addResource/toProjectSpecKey.1-5-quality,1-3-simple,pass-fail,good-neutral-bad) that expand into the schema's numerical/categorical shapes with judge-facing definitions, plus--rating-scale-filefor a fully custom scale.file://<path>, or-(stdin) via the sharedSourceResolver.{context}for SESSION) and use no placeholder outside that level's set. This mirrorsAgentCoreEvaluationControlPlaneService'sInstructionValidator, so invalid instructions are rejected locally atadd/buildinstead of surfacing as an opaque CloudFormation rollback at deploy time.Testing
file://instructions, description/KMS/tags, duplicate name, invalid spec, and all validation error paths) and for the schema-level placeholder validation.project add evaluator llm-as-a-judge→project deployprovisions a realAWS::BedrockAgentCore::Evaluator(CREATE_COMPLETE) in a dev account. Test resources were cleaned up afterward.Scope
Spec-write + deploy of the evaluator resource. Consistent with sibling
addcommands.