构建生产级 LLM-as-a-Judge 评估 Agent:Agent-Skills-for-Context-Engineering 中 Evaluator Agent 的架构、工具链与偏差缓解实践
【免费下载链接】Agent-Skills-for-Context-EngineeringA comprehensive collection of Agent Skills for context engineering, multi-agent architectures, and production agent systems. Use when building, optimizing, or debugging agent systems that require effective context management.项目地址: https://gitcode.com/GitHub_Trending/ag/Agent-Skills-for-Context-Engineering
本文以 Agent-Skills-for-Context-Engineering 仓库中examples/llm-as-judge-skills示例项目为背景,系统讲解其 Evaluator Agent 的设计与实现:如何用 LLM 作为裁判(LLM-as-a-Judge)对生成内容进行可配置、可复现、可追溯的质量评估。读完本文,你将掌握直接评分(Direct Scoring)、成对比较(Pairwise Comparison)、规则生成(Rubric Generation)三种评估模式的完整输入输出契约、配置参数语义,以及位置偏置、冗长偏置等已知问题的工程化解法,并能在自己的内容生成管线、模型对比与质量监控场景中直接落地。
1. 背景:Evaluator Agent 在整个项目中的定位
Evaluator Agent 是 examples/llm-as-judge-skills 示例项目中的核心智能体,用于评估 LLM 生成回答的质量。它实现的是业界广泛验证的 LLM-as-a-Judge 模式:让一个具备评估指令的大语言模型充当裁判,替代或补充 BLEU、ROUGE 等传统指标。其设计同时支持两种评判范式:
- Direct Scoring(直接评分):针对客观标准(事实准确性、指令遵循、合规性)给出数值化评分;
- Pairwise Comparison(成对比较):针对主观偏好(语气、说服力、风格)判断两个回答孰优孰劣。
该 Agent 并不是孤立存在的,它构建在项目两个基础技能之上:skills/context-fundamentals(上下文工程原理)与 skills/tool-design(工具设计最佳实践)。从示例项目的目录结构可以清晰看到"知识(MD 文档)→ 提示词模板(prompts/)→ 可执行工具(src/tools/)→ Agent 抽象(src/agents/)"的递进关系:
examples/llm-as-judge-skills/ ├── skills/ # 领域知识文档(llm-evaluator、context-fundamentals、tool-design) ├── prompts/ # 提示词模板(direct-scoring、pairwise-comparison 等) ├── tools/ # 工具规格文档(MD 规范说明) ├── agents/ # Agent 文档(evaluator-agent、research-agent、orchestrator-agent) ├── src/ # TypeScript 实现(tools、agents、config) ├── tests/ # Vitest 测试套件 └── examples/ # 可直接运行的使用示例2. Agent 定义:从 ToolLoopAgent 抽象到可运行的 EvaluatorAgent
2.1 文档定义的 Agent 骨架
关联文档 evaluator-agent.md 给出的 Agent 定义为:基于 Vercel AI SDK 的ToolLoopAgent抽象,绑定评估模型并注入四个评估工具,通过系统指令约束裁判行为。其核心指令包含三条硬性要求:对每个标准给出数值评分、用具体证据支撑评估、提供可执行的改进建议;同时明确要求"避免位置偏置(evaluate content not placement)"、"除非冗长确实增值,否则不偏爱冗长回答"——这两条直接对应 LLM 裁判已知的两大偏差(详见第 9 节)。
Agent 骨架(文档视角) ├── 模型:anthropic("claude-sonnet-4-20250514") ├── 指令:客观一致 / 证据驱动 / 考虑原任务上下文 / 避免位置偏置 / 避免冗长偏置 └── 工具集: ├── directScore → 直接评分 ├── pairwiseCompare → 成对比较 ├── extractCriteria → 从任务描述中提取评估标准 └── generateRubric → 生成评分规则(Rubric)2.2 仓库中的实际实现
与文档中的框架级抽象不同,仓库内可直接运行的实现是 src/agents/evaluator.ts 中的EvaluatorAgent类,它把三个已实现的评估工具封装成高层 API,并额外提供端到端工作流与自由聊天式评估两个能力:
| 方法 | 对应能力 | 底层调用 |
|---|---|---|
score(input) | 直接评分 | executeDirectScore |
compare(input) | 成对比较 | executePairwiseCompare |
generateRubric(input) | 规则生成 | executeGenerateRubric |
evaluateWithGeneratedRubric(...) | 先生成 Rubric 再评分(完整工作流) | 组合上述三者 |
chat(userMessage) | 自由文本评估 | AI SDKgenerateText |
从源码结构看,EvaluatorAgent的构造函数接收EvaluatorAgentConfig(model、temperature、maxTokens),默认模型读取自 src/config/index.ts 的环境配置,默认temperature = 0.3。低温度是评估场景的关键设计:裁判输出需要低随机性以保证可复现性。chat方法则在保持专家裁判人设的同时,允许对任意自定义评估问题(如"请评估这段回答的准确性")进行开放式评判。
需要指出的是:文档工具清单中的extractCriteria(从任务描述自动提取评估标准)在 tools/index.md 中被标记为 "No"(未实现),仓库src/tools/evaluation/下只有direct-score.ts、pairwise-compare.ts、generate-rubric.ts三个工具文件;因此该能力目前停留在接口规划层面,实际评估标准仍需由调用方显式提供。
3. 核心能力一:Direct Scoring 直接评分
3.1 输入与输出契约
直接评分用于评估单个回答是否满足既定标准。其输入输出在 src/tools/evaluation/direct-score.ts 中通过 Zod Schema 严格定义:
输入(DirectScoreInputSchema)
| 字段 | 类型/取值 | 说明 |
|---|---|---|
response | string | 待评估的 LLM 回答 |
prompt | string | 生成该回答的原始提示词 |
context | string(可选) | 附加上下文(RAG 文档、对话历史等) |
criteria | array(≥1) | 评估标准数组,每项含name、description、weight(0~1,默认 1) |
rubric | object(可选) | scale取'1-3' | '1-5' | '1-10'(默认'1-5'),可选levelDescriptions逐级描述 |
输出(DirectScoreOutputSchema)
scores[]:每个标准的score、maxScore、evidence[](回答中的具体引用证据)、justification(评分理由)、improvement(改进建议);overallScore:各标准得分的算术平均;weightedScore:按权重加权后的得分;summary:总体评估、优势列表、劣势列表、优先级改进项;metadata:评估耗时、所用模型、标准数量。
3.2 源码中的加权计算与链式思考
从源码实现看,executeDirectScore内部有两处值得复用的逻辑:
分数归一化与加权:先由
scale解析出maxScore,随后计算overallScore = Σscore / N(算术平均)与weightedScore = Σ(score × weight) / Σweight(加权平均),两者都保留两位小数。当各标准权重不相等时,weightedScore与overallScore会出现差异——这正是测试 "should handle multiple weighted criteria" 所验证的行为。证据驱动的链式思考(Chain-of-Thought):系统提示词强制裁判"先寻找具体证据 → 再按 Rubric 打分 → 给出理由 → 提出一条改进建议",且明确要求"基于显式证据打分(Base scores on explicit evidence)"。这是降低评分方差、提升可靠性的关键工程手段。
评分失败的兜底同样完整:任何异常都会被捕获并返回success: false的结构化错误对象,而不会让未处理异常向上抛出(对应 skills/tool-design 中"工具绝不抛出未处理异常"的设计原则)。
3.3 提示词模板与最佳实践
仓库在 prompts/evaluation/direct-scoring-prompt.md 中提供了可直接复用的系统提示词模板(含 Handlebars 变量占位与 JSON 输出格式约定),其 Best Practices 清单值得直接吸收进自己的评估管线:
- Evidence First:先收集证据再打分;
- Rubric Alignment:严格按 Rubric 定义取值,不要自行插值;
- Constructive Feedback:改进建议必须可执行;
- Consistency:跨评估保持同一套标准;
- Calibration:用示例评估作为校准参照。
4. 核心能力二:Pairwise Comparison 成对比较
4.1 输入与输出契约
成对比较接收responseA、responseB、原始prompt、比较标准criteria[],并支持两个关键开关:allowTie(默认true,允许平局)与swapPositions(默认true,启用位置交换去偏)。输出包含winner('A' | 'B' | 'TIE')、confidence(0~1)、逐标准比较明细comparison[]、双方优劣势分析analysis、关键差异点differentiators,以及(开启交换时)positionConsistency一致性报告。完整 Schema 见 src/tools/evaluation/pairwise-compare.ts。
4.2 位置偏置缓解:双次评估 + 一致性校验
这是整个示例项目中最值得借鉴的工程模式。executePairwiseCompare在swapPositions = true时执行两轮评估:
第 1 轮:A 在前、B 在后 → pass1.winner 第 2 轮:B 在前、A 在后 → pass2.winner(映射回原位置语义) 一致性检查:pass1.winner === map(pass2.winner) ? ├─ 一致 → 最终胜者 = pass1.winner,置信度 = 两轮置信度均值 └─ 不一致 → 判定为 TIE,置信度降为 0.5(并报告 inconsistent)其背后的逻辑非常清晰:如果裁判对同一对回答在不同展示顺序下给出不同结论,说明"位置"而非"内容"影响了判断,此时系统宁可判平局也不输出不可靠的胜者。逐标准的比较结果也会做同样的映射合并——只有两轮在某个标准上判给同一方时,该标准才计入胜者,否则记为TIE。同时,系统提示词显式注入反偏置指令:"不要因为回答更长而偏爱它""不要基于位置(第一个 vs 第二个)做判断"。
该机制与 prompts/evaluation/pairwise-comparison-prompt.md 中的三步流程(独立分析 → 逐标准对抗 → 最终裁定)配套使用,后者还给出了"先解释推理再宣布胜者""只有差异明显时才给出高置信度"等校准原则。
4.3 典型输出解读
一次典型的调用会返回类似如下的结构:
{ "success": true, "winner": "A", "confidence": 0.85, "positionConsistency": { "consistent": true, "firstPassWinner": "A", "secondPassWinner": "A" }, "comparison": [ { "criterion": "accuracy", "winner": "A", "reasoning": "..." }, { "criterion": "clarity", "winner": "A", "reasoning": "..." } ], "differentiators": ["accuracy: Response A wins - ..."] }5. 核心能力三:Rubric Generation 规则生成
5.1 输入与输出契约
Rubric 生成工具用于为某个评估标准创建逐级打分明细,从而统一不同评估批次间的评判尺度。输入参数在 src/tools/evaluation/generate-rubric.ts 中定义为:
| 参数 | 类型/取值 | 默认值 | 说明 |
|---|---|---|---|
criterionName | string | — | 标准名称,如 "Code Readability" |
criterionDescription | string | — | 该标准衡量什么 |
scale | '1-3' | '1-5' | '1-10' | '1-5' | 评分量程 |
domain | string(可选) | — | 领域上下文,用于生成领域化术语 |
includeExamples | boolean | true | 是否生成每个等级的示例文本 |
strictness | 'lenient' | 'balanced' | 'strict' | 'balanced' | 评分严苛度 |
输出为结构化 Rubric:每个levels[]项含score、label(如 Poor/Average/Excellent)、description、characteristics[]与可选example;另附scoringGuidelines[](通用评分准则)与edgeCases[](边界情况及其处理建议)。
5.2 strictness 与 domain 的源码语义
strictness通过系统提示词直接改写裁判的标准线:lenient降低及格门槛、balanced采用公平的常规期望、strict提高标准并要求批判性评估;测试 "should respect strictness setting" 分别用lenient与strict生成同一标准的 Rubric,并断言元数据中正确保留所请求的严格度。domain则让生成的术语与示例贴合领域(如软件工程领域会出现 variable、function、comment 等词汇),测试 "should generate domain-specific rubrics" 专门验证了这一点。该工具的生成温度略高于评分工具(0.4),因为 Rubric 生成是创作性任务,允许一定多样性。
6. 配置参数全解析:EvaluatorConfig 与默认值语义
关联文档给出了设计层面的配置接口EvaluatorConfig,它是把 LLM-as-a-Judge 调教成可靠裁判的"旋钮总览":
interface EvaluatorConfig { // 评分模式 scoringMode: "direct" | "pairwise"; useChainOfThought: boolean; // 是否要求链式思考理由 nShotExamples: number; // few-shot 示例数量 // 偏差缓解 swapPositionsForPairwise: boolean; // 成对比较时交换位置 normalizeForLength: boolean; // 是否按长度归一化(缓解冗长偏置) // 输出配置 includeJustification: boolean; // 是否输出评分理由 includeExamples: boolean; // 是否输出证据示例 outputFormat: "structured" | "prose"; // 结构化 JSON 或自然语言 } const defaultConfig: EvaluatorConfig = { scoringMode: "direct", useChainOfThought: true, // 默认开启链式思考 nShotExamples: 2, // 默认 2 个示例 swapPositionsForPairwise: true, // 默认交换位置去偏 normalizeForLength: false, // 默认不做长度归一化(依赖提示词反冗长) includeJustification: true, // 默认输出理由 includeExamples: true, // 默认输出证据 outputFormat: "structured" // 默认结构化输出 };将该设计接口与仓库实际实现对照,可以看到每个配置项在代码中的落点:
useChainOfTruth(链式思考):对应 direct-score.ts 系统提示词中"先找证据再打分"的强制流程;swapPositionsForPairwise:对应 pairwise-compare.ts 的swapPositions参数(默认true);outputFormat: "structured":对应各工具用 Zod 定义输入输出 Schema、强制模型返回可解析 JSON 的工程选择;nShotExamples:在提示词模板与最佳实践中以"Calibration(校准参照)"形式体现。
在运行时配置层面,仓库使用.env文件驱动 src/config/index.ts:
OPENAI_API_KEY=your_openai_api_key_here # 必填,缺失时 validateConfig() 会抛错 OPENAI_MODEL=gpt-4o # 可选,默认 gpt-4o入口处调用validateConfig()可提前校验 API Key,避免在评估中途才发现配置缺失。注意:README 与示例代码中出现的模型名以当前仓库.env默认值gpt-4o为准;若使用其他供应商模型,需按 AI SDK 提供商的接入方式调整。
7. 端到端使用示例
7.1 直接评分(单一回答)
import { evaluatorAgent } from "./agents/evaluator-agent"; const evaluation = await evaluatorAgent.generate({ prompt: `Evaluate the following response: Original Question: "Explain quantum entanglement to a high school student" Response: "${generatedResponse}" Criteria: 1. Accuracy - Scientific correctness 2. Clarity - Understandable for target audience 3. Engagement - Interesting and memorable 4. Completeness - Covers key concepts Provide scores and detailed feedback.` });7.2 成对比较(两个回答)
const comparison = await evaluatorAgent.generate({ prompt: `Compare these two responses to the same question. Question: "What are the benefits of exercise?" Response A: "${responseA}" Response B: "${responseB}" Which response is better? Explain your reasoning.` });7.3 完整工作流:先生成 Rubric 再评分
在实际生产中,更推荐使用EvaluatorAgent.evaluateWithGeneratedRubric(源码见 src/agents/evaluator.ts)——它先为每个标准异步生成 Rubric,再把各等级描述合并进levelDescriptions,最后调用直接评分,让打分严格落在统一标尺上。仓库的 examples/full-evaluation-workflow.ts 演示了三段式流水线:① 为 "Scientific Accuracy / Completeness / Accessibility" 等标准生成 Rubric;② 用加权标准(Accuracy 权重 0.4)对回答评分并打印overallScore与weightedScore;③ 与另一版本回答做swapPositions: true的成对比较,输出胜者、置信度与关键差异。该文件可用npx tsx examples/full-evaluation-workflow.ts运行。
7.4 安装与运行
cd examples/llm-as-judge-skills npm install # 安装依赖(含 AI SDK、Zod、dotenv、Vitest 等) cp env.example .env # 按需填写 OPENAI_API_KEY npm test # 运行评估工具与技能测试套件 npm run build # 编译 TypeScript8. 集成场景:Evaluator Agent 能放在哪里
关联文档明确了 Evaluator Agent 的四类集成点,结合 README 的架构图可归纳如下:
| 集成场景 | 推荐模式 | 说明 |
|---|---|---|
| 内容生成管线(Content Generation Pipeline) | Direct Scoring | 交付前对生成内容做质量门禁,拦截低分输出 |
| 模型对比(Model Comparison) | Pairwise Comparison | 对同一提示下不同模型/版本的输出做偏好裁决 |
| 质量监控(Quality Monitoring) | Direct Scoring + 定时 | 用固定标准跟踪回答质量随时间的变化趋势 |
| 微调数据(Fine-tuning Data) | Pairwise Comparison | 成对胜负结果可沉淀为 RLHF 偏好数据(preference pairs) |
从仓库架构图可以看到,这套系统还可与示例仓库中的 orchestrator-agent(编排)、research-agent(研究)配合,形成"研究 → 生成 → 评估"的完整回路;这与整个 Agent-Skills-for-Context-Engineering 项目"上下文工程 + 多智能体 + 生产级 Agent 系统"的定位一脉相承。
9. 测试验证与可复现结论
示例仓库在 tests/evaluation.test.ts 中提供了 9 个工具层/Agent 层测试(另见 tests/skills.test.ts 的 10 个技能层测试),其断言逻辑本身就是对 Agent 行为的可执行规格说明:
- "should score a response against criteria":好回答(GOOD_RESPONSE,含类比与要点列表)得分应落在 (0, 5] 区间且 ≥ 3;
- "should provide lower scores for poor responses":
GOOD_RESPONSE的得分必须严格高于POOR_RESPONSE; - "should correctly identify the better response":质量差异明显时 winner 必须为
'A'且置信度 > 0.5; - "should handle similar responses appropriately":两个完全相同的回答(
MEDIUM_RESPONSEvs 自身)在swapPositions: true下必须判TIE——这是对位置偏置缓解机制的直接验证; - "should respect strictness setting":生成的 Rubric 元数据必须忠实记录所请求的
lenient/strict。
README 记录的测试运行日志显示 19 个测试全部通过。测试体系印证了四类可复现结论:
- 位置偏置是真实存在的,但双轮交换 + 一致性检查能有效检测并缓解——相同回答判 TIE、不同质量回答跨位置保持一致;
- 链式思考确实提升可靠性——所有评分都带具体证据与超过 20 字符的理由;
- 领域化 Rubric 有意义——软件工程领域的 Rubric 会自然生成该领域的专业词汇;
- 加权标准支持精细化评估——权重不均时
weightedScore与overallScore产生差异,可用于突出核心标准。
10. 实践要点清单:把 Evaluator Agent 用好的关键
综合关联文档、基础技能 skills/llm-evaluator/llm-evaluator.md 与源码实现,以下是可直接采纳的落地建议:
- 按任务选模式:客观任务(事实性、毒性、指令遵循)优先直接评分;主观任务(语气、说服力、连贯性)优先成对比较;
- 始终开启位置交换:
swapPositions: true是成对比较的默认且推荐配置,能同时产出positionConsistency报告供审计; - 用 Rubric 锁标准:先
generateRubric再评分,避免"标准漂移";需要时可调整strictness控制松紧; - 要求证据链:强制裁判引用回答原文作为证据,这是对抗幻觉式评分最有效的手段之一;
- 记录元数据:每次评估都保留
model、evaluationTimeMs、criteriaCount,为质量监控与成本核算提供数据; - 处理失败路径:工具在 API 调用失败时返回
success: false的结构化结果,调用方应据此决定重试、降级或人工介入,而不是直接崩溃。
如果需要在更大规模上进一步降低单一裁判的系统性偏差,可参考 skills/llm-evaluator/llm-evaluator.md 中列出的策略:使用 LLM 评审团(Panel of LLMs, PoLL)、按长度归一化、加入 "don't overthink" 指令、以及采用 CoT + n-shot 提示。基线选择上,应把 LLM 裁判与人类标注者的一致性、以及微调分类器的精确率/召回率作为对照目标,持续校准评估质量。
【免费下载链接】Agent-Skills-for-Context-EngineeringA comprehensive collection of Agent Skills for context engineering, multi-agent architectures, and production agent systems. Use when building, optimizing, or debugging agent systems that require effective context management.项目地址: https://gitcode.com/GitHub_Trending/ag/Agent-Skills-for-Context-Engineering
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考