- 后端
- Web框架
【免费下载链接】egg
🥚🥚🥚🥚 Born to build better enterprise frameworks and apps with Node.js & Koa. https://307.run/eggcode
packages/skills/是 Egg 框架为 AI Agent 提供的 skills 包,以纯 Markdown 文档承载框架的编码知识与决策逻辑。本文围绕 packages/skills/PLAN.md 中设计的评测方案展开:如何用「静态校验 + 动态评测(LLM-as-Judge)」两套机制,验证 Skill 文件的结构正确性与 AI 基于 Skill 生成回答的质量。读完本文,你将掌握该评测体系的分层设计思路、完整的 Vitest + Claude API 实现代码,以及它在当前仓库中的实际落地形态。
评测体系的两层目标
PLAN.md 明确将评测体系划分为两个层面,二者互补:
- 静态校验—— 验证 Skill 文件的结构正确性、引用完整性。它不依赖任何 LLM 调用,执行快、成本低,可以在每次修改 Skill 后立即运行。
- 动态评测—— 用 LLM-as-Judge 评估 AI 基于 Skill 生成回答的质量。它验证的是"AI 拿到 Skill 之后能不能用对",这是静态校验无法覆盖的。
整个体系全部手动触发运行,不集成 CI。这是因为动态评测依赖外部 LLM API,既有成本又有不确定性,适合作为开发流程中的手动质量闸门,而不是持续集成中的自动化环节。
Skills 目录现状与评测目录设计
在介绍评测方案前,先明确被测对象的现状。packages/skills/采用分层路由模式(见 packages/skills/CLAUDE.md):
- 入口 skill(packages/skills/egg/SKILL.md)—— 分析用户意图,通过关键词匹配和决策逻辑路由到专业 skill;
- 专业 skills—— 提供特定领域的深度指导:
egg-core(核心概念:模块、依赖注入、生命周期、AccessLevel、后台任务)、egg-controller(HTTPController、MCPController、Schedule、Ajv 校验)、egg-unittest(HTTP 接口测试、Service 测试、Mock)。
PLAN.md 为评测体系设计了独立的eval/目录,与 skills 内容物理隔离:
packages/skills/ ├── egg/ ├── controller/ ├── tegg-core/ ├── eval/ # 新增:评测目录 │ ├── static/ │ │ └── validate.test.ts # 静态校验测试 │ ├── dynamic/ │ │ ├── routing.eval.ts # 入口路由评测 │ │ └── quality.eval.ts # 内容质量评测 │ ├── fixtures/ │ │ ├── routing-cases.ts # 路由测试用例 │ │ └── quality-cases.ts # 质量测试用例 │ └── lib/ │ ├── skill-loader.ts # Skill 文件加载器 │ ├── judge.ts # LLM-as-Judge 核心逻辑 │ └── types.ts # 共享类型定义 ├── vitest.config.ts ├── package.json └── tsconfig.json需要说明的是,这是 PLAN.md 中的目标目录设计;仓库当前的eval/目录实际已落地为以 JSON 用例文件为主的形态(详见下文"仓库中的实际落地"一节),两者互为印证:PLAN 提供完整的工程化方案骨架,仓库现状展示了一条更轻量的落地路径。
第一部分:静态校验
校验项
静态校验通过读取并解析每个 SKILL.md 文件,检查五类结构问题:
| 校验项 | 说明 |
|---|---|
| Frontmatter 格式 | 每个 SKILL.md 必须包含name、description、allowed-tools |
| 引用文件存在性 | SKILL.md 中提到的references/*.md文件必须存在 |
| 交叉引用一致性 | 入口 skill 提到的子 skill 目录必须存在且包含 SKILL.md |
| Markdown 结构 | 标题层级合理(以#开头,不跳级) |
| 决策表完整性 | 入口 skill 的路由表中每个 skill 都有对应目录 |
这些校验项与仓库中实际的 frontmatter 约定完全对应。例如 packages/skills/egg/SKILL.md 以name: egg、description: 本技能用于处理 EGG 框架...、allowed-tools: Read开头;packages/skills/egg-core/SKILL.md 的 frontmatter 同样齐备。allowed-tools统一为Read(纯文档指导型,不修改文件),这也是静态校验可以直接断言的内容。
实现方式
使用 vitest + node:assert 编写测试,通过 Node.js fs API 读取文件并解析:
// eval/static/validate.test.ts import { describe, it } from 'vitest'; import assert from 'node:assert/strict'; import { loadAllSkills } from '../lib/skill-loader.ts'; describe('Skill 静态校验', () => { describe('Frontmatter', () => { it('每个 SKILL.md 包含必填字段: name, description, allowed-tools', ...); }); describe('引用完整性', () => { it('SKILL.md 中引用的 references/ 文件均存在', ...); it('入口 skill 引用的子 skill 目录均存在', ...); }); describe('Markdown 结构', () => { it('标题层级不跳级', ...); }); });这里有三点工程细节值得注意:
- 断言库选择
node:assert/strict:Node.js 内置、零依赖,符合 monorepo 的依赖纪律; skill-loader.ts承担文件读取职责:将"读取 + 解析 frontmatter"沉淀为公共模块,静态与动态评测复用同一份加载逻辑;- 引用完整性校验的价值:
references/目录是各专业 skill 的深度文档所在地(如egg-controller下的http-controller.md、mcp-controller.md、schedule.md、ajv-validate.md、middleware.md),SKILL.md 中一旦写出不存在的引用文件名,AI 在运行时就会拿到断裂的上下文——这是静态校验必须拦截的高频错误。
第二部分:动态评测(LLM-as-Judge)
动态评测是这套体系的精华所在:它不检查"文件长什么样",而是检查"AI 用这些文件能产生多好的回答"。评测被拆分为两个子场景,分别对应入口 skill 和专业 skill 的职责。
2.1 路由评测 —— 入口 Skill 是否正确路由
测试egg/SKILL.md的决策逻辑:给定用户查询,判断 AI 是否路由到正确的子 skill。
测试用例结构:
// eval/fixtures/routing-cases.ts export const routingCases: RoutingCase[] = [ { query: '如何创建 HTTP controller?', expectedSkill: 'controller', reason: '明确提到 controller,属于协议实现', }, { query: '@SingletonProto 和 @ContextProto 有什么区别?', expectedSkill: 'tegg-core', reason: '关于对象生命周期,属于核心概念', }, { query: '我需要创建一个可以被 HTTP 控制器使用的服务', expectedSkill: 'tegg-core', reason: '模糊意图,按规则 1(基础优先)应路由到 core', }, // ... 更多用例 ];每个用例由query(用户提问)、expectedSkill(期望路由目标)、reason(判定依据)三要素组成。reason字段非常关键——它把入口 skill 中的决策规则显式编码为可断言的期望,例如"基础优先"规则对应 packages/skills/egg/SKILL.md 中"冲突解决规则 - 规则 1:基础优先"(当问题同时涉及核心概念与控制器实现时,从egg-coreskill 开始)。
测试实现:
// eval/dynamic/routing.eval.ts import { describe, it } from 'vitest'; import assert from 'node:assert/strict'; import Anthropic from '@anthropic-ai/sdk'; import { loadSkillContent } from '../lib/skill-loader.ts'; import { routingCases } from '../fixtures/routing-cases.ts'; const client = new Anthropic(); const AVAILABLE_SKILLS = ['controller', 'tegg-core']; describe('路由评测', () => { // 加载入口 skill 作为 system prompt const entrySkillContent = loadSkillContent('egg'); for (const { query, expectedSkill, reason } of routingCases) { it(`"${query}" → ${expectedSkill}`, async () => { // 1. 将 SKILL.md 作为 system prompt,发送用户查询 const response = await client.messages.create({ model: 'claude-sonnet-4-20250514', max_tokens: 1024, system: [ entrySkillContent, // 约束输出格式,让 AI 只做路由决策 `你是 EGG 框架技能路由器。根据上面的决策指南,分析用户查询并选择应该加载的技能。`, `可选技能: ${AVAILABLE_SKILLS.join(', ')}`, `只输出 JSON: {"skill": "<技能名>", "reason": "<简要理由>"}`, ].join('\n\n'), messages: [{ role: 'user', content: query }], }); // 2. 解析 AI 回答中的路由选择 const text = response.content[0].type === 'text' ? response.content[0].text : ''; const parsed = JSON.parse(text); // 3. 断言路由正确性 assert.equal( parsed.skill, expectedSkill, `路由错误: 期望 "${expectedSkill}" 但得到 "${parsed.skill}"` + `\n 用例理由: ${reason}` + `\n AI 理由: ${parsed.reason}`, ); }); } });这个实现的巧妙之处在于用约束格式把开放问题变成可断言问题:入口 skill 内容作为 system prompt 提供决策依据,附加指令要求 AI"只输出 JSON",从而把"路由是否正确"转化为"JSON 中的skill字段是否等于expectedSkill"的机械比较。断言失败时输出的错误信息同时包含用例理由与 AI 理由,方便人工复盘路由偏差。
仓库中已有真实的路由评测用例集 packages/skills/eval/evals-routing.json,共 11 条,覆盖了各类意图形态,例如:
- 明确协议意图:"帮我写一个接口" →
egg-controller; - 核心概念意图:"我想写个服务,不知道用 SingletonProto 还是 ContextProto" →
egg-core; - 模糊意图:"帮我搭一个新模块,包含增删改查接口和 Service" →
egg-core(基础优先,先建模块再写接口); - 问题排查意图:"我的 @Inject 注入报错了,找不到对象" →
egg-core; - 框架选型意图:"EventBus 和 BackgroundTaskHelper 怎么选" →
egg-core。
2.2 内容质量评测 —— 子 Skill 回答质量
路由评测只验证"选对了 skill",内容质量评测则进一步验证"用对了 skill"。它针对各专业 skill 的领域问题,用评判标准清单(criteria)刻画期望回答中必须出现的要素。
测试用例结构:
// eval/fixtures/quality-cases.ts export const qualityCases: QualityCase[] = [ { skill: 'controller', query: '如何创建一个 POST 接口接收 JSON body?', criteria: [ '使用 @HTTPController 装饰器', '使用 @HTTPMethod 且 method 为 POST', '使用 @HTTPBody() 获取请求体', '包含完整可运行的代码示例', ], references: ['references/http-controller.md'], // 需要加载的参考文档 }, { skill: 'tegg-core', query: '如何让一个服务可以被其他模块访问?', criteria: ['提到 AccessLevel.PUBLIC', '使用 @SingletonProto 装饰器', '解释跨模块访问机制'], references: [], }, // ... 更多用例 ];注意criteria的写法——它写的是"回答中必须出现的技术要素",而不是抽象的质量描述。例如要求"提到 AccessLevel.PUBLIC"而不是"回答要专业",这保证了 Judge LLM 的评分具备可核查性,而不是凭感觉打分。references字段声明回答时需要加载的参考文档,与 skill 的references/目录一一对应。
测试实现:
// eval/dynamic/quality.eval.ts import { describe, it } from 'vitest'; import assert from 'node:assert/strict'; import Anthropic from '@anthropic-ai/sdk'; import { loadSkillContent, loadReference } from '../lib/skill-loader.ts'; import { qualityCases } from '../fixtures/quality-cases.ts'; import { judge } from '../lib/judge.ts'; const client = new Anthropic(); describe('内容质量评测', () => { for (const testCase of qualityCases) { describe(`[${testCase.skill}] ${testCase.query}`, () => { let aiResponse: string; // Step 1: 加载 skill 内容作为 system prompt,向被测 LLM 提问 it('生成回答', async () => { const skillContent = loadSkillContent(testCase.skill); const refContents = testCase.references.map((ref) => loadReference(testCase.skill, ref)); const systemPrompt = [skillContent, ...refContents].join('\n\n---\n\n'); const response = await client.messages.create({ model: 'claude-sonnet-4-20250514', max_tokens: 2048, system: systemPrompt, messages: [{ role: 'user', content: testCase.query }], }); aiResponse = response.content[0].type === 'text' ? response.content[0].text : ''; assert.ok(aiResponse.length > 0, 'AI 应该返回非空回答'); }); // Step 2: 用 Judge LLM 对回答逐项评分 it('通过质量评审', async () => { const result = await judge(client, { query: testCase.query, response: aiResponse, criteria: testCase.criteria, }); // 输出详细评分到 console 供人工查看 console.log(` 得分: ${result.totalScore} (${result.passed}/${result.total})`); for (const item of result.details) { const icon = item.score === 1 ? '✓' : '✗'; console.log(` ${icon} ${item.criterion}: ${item.reason}`); } // 断言:所有 criteria 都应满足 assert.ok( result.totalScore >= 0.8, `质量不达标: ${result.totalScore} < 0.8\n` + result.details .filter((d) => d.score === 0) .map((d) => ` ✗ ${d.criterion}: ${d.reason}`) .join('\n'), ); }); }); } });整个评测被设计为两阶段流水线:第一个it生成回答(被测 LLM + skill 内容),第二个it用独立的 Judge LLM 打分。两个步骤的分离带来两个好处:
- 每个用例可以独立失败、独立重跑,不必为重新打分而重复调用生成接口;
aiResponse在 describe 作用域内共享,为后续人工复查保留了原始回答内容。
console.log的逐项评分输出(✓/✗+ 理由)让每次运行都生成一份人可读的明细,得分阈值设为 0.8,即满足 80% 以上的 criteria 才算通过。
仓库中的 packages/skills/eval/evals-egg-controller.json 和 packages/skills/eval/evals-egg-core.json 就是这种用例思想的 JSON 化落地。以控制器评测为例,其expected_output字段相当于 criteria 的浓缩描述,例如:
- POST 接口用例要求"@HTTPController + @HTTPMethod POST + @HTTPBody + ctx.status = 201,完整可运行代码";
- 参数校验用例要求"从 egg/ajv 导入 Type/Ajv/Static,定义 TypeBox Schema,@Inject() ajv: Ajv,ajv.validate()";
- 中间件执行顺序用例要求解释"函数式和 AOP 分属两个独立执行阶段"的完整时序;
- 大量用例还通过
files字段附带带 bug 的上下文代码,用于考察 AI 的诊断能力。
LLM-as-Judge 核心实现
Judge 是动态评测的"裁判",它接收"用户问题 + AI 回答 + 标准清单",逐条判定每条标准是否满足:
// eval/lib/judge.ts import type Anthropic from '@anthropic-ai/sdk'; import type { JudgeInput, JudgeResult, JudgeDetail } from './types.ts'; export async function judge(client: Anthropic, input: JudgeInput): Promise<JudgeResult> { const criteriaList = input.criteria.map((c, i) => `${i + 1}. ${c}`).join('\n'); const response = await client.messages.create({ model: 'claude-sonnet-4-20250514', max_tokens: 1024, system: '你是 AI 回答质量评估专家。严格按照 JSON 格式输出评分结果。', messages: [ { role: 'user', content: `请根据评分标准,对以下 AI 回答逐项评分。 ## 评分标准 ${criteriaList} ## 用户问题 ${input.query} ## AI 回答 ${input.response} ## 输出格式(严格 JSON) { "details": [ { "criterion": "标准内容", "score": 0 或 1, "reason": "简要理由" } ] }`, }, ], }); const text = response.content[0].type === 'text' ? response.content[0].text : ''; const parsed = JSON.parse(text); const details: JudgeDetail[] = parsed.details; const passed = details.filter((d) => d.score === 1).length; return { details, passed, total: details.length, totalScore: passed / details.length, }; }Judge 的设计有几个值得借鉴的点:
- 评分维度前置:
criteria由测试作者(即 Skill 维护者)编写,把质量期望显式化,避免了 LLM 自由发挥标准; - 0/1 二值评分:每条标准只有 0 或 1 两个取值,
totalScore = passed / total,简单可计算、可断言、可汇总; - 强制 JSON 输出:system 声明"严格按照 JSON 格式输出",用户消息中的输出格式模板进一步约束结构,使结果可以直接
JSON.parse; - 单次调用完成评分:所有标准放进同一次请求,相比逐条调用,成本与延迟都更低。
评测报告
运行评测后生成 JSON 报告,作为人工 review 的数据基础:
{ "timestamp": "2026-02-05T10:00:00Z", "routing": { "total": 10, "correct": 9, "accuracy": 0.9, "failures": [ { "query": "...", "expected": "tegg-core", "actual": "controller", "reason": "..." } ] }, "quality": { "controller": { "cases": 5, "avg_score": 0.85, "details": [...] }, "tegg-core": { "cases": 5, "avg_score": 0.90, "details": [...] } } }报告按routing与quality两大块组织:路由部分给出总数、正确数与准确率,并完整保留失败用例(query、expected、actual、reason)供回归分析;质量部分按 skill 维度聚合平均分,details保留逐条评分明细。这种结构化输出既适合人眼扫读,也方便后续扩展为可视化看板。
第三部分:技术选型与依赖
| 组件 | 选型 | 理由 |
|---|---|---|
| 测试框架 | vitest | 遵循 monorepo 标准 |
| 断言库 | node:assert/strict | Node.js 内置,零依赖 |
| YAML frontmatter 解析 | gray-matter | 成熟的 frontmatter 解析库 |
| LLM 调用 | @anthropic-ai/sdk | 使用 Claude API 做评测和 Judge |
| 报告输出 | JSON 文件 | 简单可读,方便后续扩展为可视化 |
技术选型体现了克制原则:测试框架跟随 monorepo 既有标准(vitest),断言直接用 Node.js 内置能力,只有 frontmatter 解析(gray-matter)和 LLM 调用(@anthropic-ai/sdk)引入外部依赖——前者解决 YAML 解析这个"没必要自己写"的问题,后者是 LLM 评测的必需品。
package.json scripts
{ "scripts": { "test": "vitest run --config vitest.config.ts eval/static/", "eval": "vitest run --config vitest.config.ts eval/dynamic/", "eval:routing": "vitest run --config vitest.config.ts eval/dynamic/routing.eval.ts", "eval:quality": "vitest run --config vitest.config.ts eval/dynamic/quality.eval.ts" } }test— 运行静态校验(快速,无 API 调用)eval— 运行全部动态评测eval:routing— 仅运行路由评测eval:quality— 仅运行内容质量评测
四个脚本的分层很清晰:test是零成本的结构体检,可以高频执行;eval系列依赖外部 API,按需触发。动态评测需设置ANTHROPIC_API_KEY环境变量——这也是 PLAN 明确"不集成 CI"的实操原因之一。
仓库中的实际落地:evals-*.json 与评测工作流
PLAN.md 是工程化方案,而仓库当前的eval/目录已经以 JSON 用例文件的形式落地,并在 packages/skills/CLAUDE.md 中沉淀了完整的评测工作流规范,二者共同构成该评测体系的完整拼图。
评测用例 JSON 格式
落地形态将"用例"从 TypeScript 文件转为 JSON 数据文件:
{ "skill_name": "egg-controller", "description": "控制器评测:覆盖 http-controller、mcp-controller、schedule、ajv-validate", "evals": [ { "id": 1, "prompt": "用户的任务描述", "expected_output": "期望输出的关键要素描述", "files": [{ "path": "相对路径", "content": "文件内容(可选,用于提供上下文或有 bug 的代码)" }] } ] }与 PLAN 中的QualityCase结构相比,JSON 化有两点演进:prompt对应query,expected_output对应合并后的 criteria,并且新增了可选的files字段——允许用例携带完整的上下文文件(甚至是有 bug 的代码),从而支撑"问题排查""存量项目代码生成"这类需要上下文的评测场景。例如 packages/skills/eval/evals-egg-controller.json 中的路由冲突用例,就通过files附带了ApiController.ts源码,要求 AI 诊断"/api/:name与/api/health的匹配冲突"。
对比评测环境:with-skill vs site-docs
CLAUDE.md 规范了一个重要的评测方法论:每个用例需要在两种环境下分别运行,对比 skill 是否真的有效。
| 环境 | system prompt | 可访问范围(prompt 约束) |
|---|---|---|
| with-skill | egg/SKILL.md(入口 skill)的完整内容 | 仅packages/skills/目录 |
| site-docs | 角色声明 +site/docs/的完整文件目录列表(通过find site/docs -name '*.md'生成) | 仅site/docs/目录 |
两组 prompt 的差异仅在于参考资料不同,不包含额外的流程提示(如"先判断使用哪个 skill"),让 AI 自然行动:
你是 EGG 框架开发专家。你只能通过 Read 工具读取 packages/skills/ 目录下的文件,不能访问 site/docs/ 或项目源码。 {egg/SKILL.md 的完整内容} --- {eval prompt}你是 EGG 框架开发专家。你只能通过 Read 工具读取 site/docs/ 目录下的文件,不能访问 packages/skills/ 或项目源码。项目文档目录如下: {完整的 site/docs/ 文件列表,通过 find site/docs -name '*.md' | sort 生成} --- {eval prompt}这个对照实验回答了一个核心问题:skill 的存在是否有增量价值?如果 with-skill 环境的回答质量没有明显优于 site-docs,说明 skill 内容需要改进——要么缺少文档未覆盖的知识,要么与现有文档存在不必要重复。这与 packages/skills/CLAUDE.md 中"Skill 的价值 = 文档 + 实践经验 - 重复内容"的原则一脉相承。
评测用例设计原则:六类场景
CLAUDE.md 要求每个 reference 文档至少覆盖 5 个以上评测用例,并覆盖以下场景类型:
| 场景类型 | 说明 | 示例 |
|---|---|---|
| 泛化需求描述 | 不了解框架术语,用口语化描述需求 | "帮我加个参数校验" |
| 精确需求描述 | 明确指定技术方案和约束 | "用 TypeBox 定义 Schema,email 用 format: email" |
| 使用咨询 | 询问用法、区别、选型 | "Optional 和 Null 有什么区别" |
| 问题排查 | 提供有 bug 的代码(附 files),要求诊断 | "校验跑不起来,帮我看看" |
| 新项目代码生成 | 在全新项目中从零开始生成功能代码 | "帮我写一个创建订单的接口,需要做参数校验" |
| 存量项目代码生成 | 在包含老 egg 代码的项目中生成或迁移代码 | "帮我把这个老的 egg controller 改成 HTTPController 写法" |
| 不常用 API | 需要查外部文档链接才能回答 | "用 Tuple 定义元组校验" |
这个场景矩阵非常实用——它防止评测用例只覆盖"AI 最擅长的情况":口语化的泛化描述考验意图识别,带 bug 的代码考验诊断能力,存量迁移考验对框架新旧写法的理解。检查 packages/skills/eval/evals-egg-controller.json 可以发现这些场景都已落地,例如"帮我给这个 Controller 加一个认证中间件"(精确需求描述)、"MCP Tool 的参数 Schema 写法有问题,帮我看看"(问题排查)、"帮我把这个老的 egg controller 改成 HTTPController 写法"(存量迁移)。
评测输出与迭代流程
评测结果保存到packages/skills/eval/<skill-name>-workspace/iteration-N/目录下(已在.gitignore中通过*-workspace/忽略),由/skill-creatorskill 管理:
packages/skills/eval/ ├── evals-egg-core.json # egg-core skill 评测用例 ├── evals-egg-controller.json # egg-controller skill 评测用例 ├── evals-routing.json # 入口路由评测用例 ├── .gitignore # 忽略 *-workspace/ 目录 └── <skill-name>-workspace/ # 评测输出(gitignored),由 /skill-creator 管理 └── iteration-N/ ├── REPORT.md # 对比评分报告 ├── GRADING.md # with-skill 通过率报告 └── {prefix}-{id}/ # 每个用例一个目录 ├── eval_metadata.json ├── with_skill/outputs/ └── without_skill/outputs/整个评测流程是闭环迭代的:编写评测用例 → 运行评测(with-skill 与 site-docs 双环境并行)→ 评分与展示 → 改进 skill → 开启新一轮 iteration。iteration-N的版本化设计让每次 skill 改进的效果都可回溯、可对比。
实施步骤
PLAN.md 为整个体系给出了清晰的落地路线图,共 8 步,按"依赖先行 → 基础库 → 静态 → 动态"的顺序推进:
- 在 worktree (
egg-skills-eval) 中添加依赖:vitest、gray-matter、@anthropic-ai/sdk - 添加
vitest.config.ts和更新package.jsonscripts - 创建
eval/lib/基础工具:skill-loader、types、judge - 实现
eval/static/validate.test.ts静态校验 - 编写路由测试用例
eval/fixtures/routing-cases.ts - 实现
eval/dynamic/routing.eval.ts路由评测 - 编写质量测试用例
eval/fixtures/quality-cases.ts - 实现
eval/dynamic/quality.eval.ts内容质量评测
步骤 3 的基础工具(skill-loader、types、judge)被刻意前置:静态与动态评测共享 skill 加载逻辑,judge 独立成模块便于单独演进。步骤 4 先落地零成本的静态校验,再进入步骤 5~8 的 LLM 依赖部分——这种"先廉价后昂贵"的推进顺序,让体系在早期阶段就能获得收益。
总结
Egg Skills 评测体系的价值在于把"AI 回答质量"这个模糊目标拆解为可执行、可断言、可回归的工程问题:静态校验用零成本的 Vitest 测试守住 Skill 文件的结构底线;路由评测用约束 JSON 输出验证入口 skill 的决策逻辑;内容质量评测用 criteria 清单 + Judge LLM 的 0/1 评分量化回答质量;双环境对照则从方法论上证明了 skill 相对纯文档的真实增量。PLAN.md 提供了这套体系的完整设计蓝图,而 packages/skills/eval/ 下的 JSON 用例集与 packages/skills/CLAUDE.md 中的工作流规范,则是这套设计在当前仓库中的实际落地证据。对于任何构建 AI Agent Skill 体系的项目,这套"静态把关 + 动态评测 + 对照实验"的组合都具备直接的参考价值。
- 后端
- Web框架
【免费下载链接】egg
🥚🥚🥚🥚 Born to build better enterprise frameworks and apps with Node.js & Koa. https://307.run/eggcode
相关推荐
Agentic Awesome Skills 高级评估实战:用 LLM-as-a-Judge 构建可靠的 LLM 输出评估系统
Agentic Awesome Skills 高级评估实战:用 LLM as a Judge 构建可靠的 LLM 输出评估系统 本指南以开源仓库 agentic
AI 技能AI 插件Code2Prompt 分词机制详解:tiktoken 编码、token 估算与源码级实现
Code2Prompt 分词机制详解:tiktoken 编码、token 估算与源码级实现 本文聚焦 Code2Prompt 项目(Rust 版 CLI 工具,
开发工具AI 应用Worktrunk钩子审批机制全解:团队共享命令安全运行的三道防线
Worktrunk钩子审批机制全解:团队共享命令安全运行的三道防线 Worktrunk 是一个面向 Git worktree 管理的命令行工具,专为多 AI A
开发工具CLI版本控制AI Agent人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考