Egg Skills 评测体系设计:静态校验与 LLM-as-Judge 动态评测实战
2026/9/21 14:01:11 网站建设 项目流程
  • 后端
  • Web框架

【免费下载链接】egg

🥚🥚🥚🥚 Born to build better enterprise frameworks and apps with Node.js & Koa. https://307.run/eggcode

项目地址:https://gitcode.com/gh_mirrors/eg/egg
点击查看免费下载

packages/skills/是 Egg 框架为 AI Agent 提供的 skills 包,以纯 Markdown 文档承载框架的编码知识与决策逻辑。本文围绕 packages/skills/PLAN.md 中设计的评测方案展开:如何用「静态校验 + 动态评测(LLM-as-Judge)」两套机制,验证 Skill 文件的结构正确性与 AI 基于 Skill 生成回答的质量。读完本文,你将掌握该评测体系的分层设计思路、完整的 Vitest + Claude API 实现代码,以及它在当前仓库中的实际落地形态。

评测体系的两层目标

PLAN.md 明确将评测体系划分为两个层面,二者互补:

  1. 静态校验—— 验证 Skill 文件的结构正确性、引用完整性。它不依赖任何 LLM 调用,执行快、成本低,可以在每次修改 Skill 后立即运行。
  2. 动态评测—— 用 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 必须包含namedescriptionallowed-tools
引用文件存在性SKILL.md 中提到的references/*.md文件必须存在
交叉引用一致性入口 skill 提到的子 skill 目录必须存在且包含 SKILL.md
Markdown 结构标题层级合理(以#开头,不跳级)
决策表完整性入口 skill 的路由表中每个 skill 都有对应目录

这些校验项与仓库中实际的 frontmatter 约定完全对应。例如 packages/skills/egg/SKILL.md 以name: eggdescription: 本技能用于处理 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.mdmcp-controller.mdschedule.mdajv-validate.mdmiddleware.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": [...] } } }

报告按routingquality两大块组织:路由部分给出总数、正确数与准确率,并完整保留失败用例(query、expected、actual、reason)供回归分析;质量部分按 skill 维度聚合平均分,details保留逐条评分明细。这种结构化输出既适合人眼扫读,也方便后续扩展为可视化看板。

第三部分:技术选型与依赖

组件选型理由
测试框架vitest遵循 monorepo 标准
断言库node:assert/strictNode.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对应queryexpected_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-skillegg/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 → 开启新一轮 iterationiteration-N的版本化设计让每次 skill 改进的效果都可回溯、可对比。

实施步骤

PLAN.md 为整个体系给出了清晰的落地路线图,共 8 步,按"依赖先行 → 基础库 → 静态 → 动态"的顺序推进:

  1. 在 worktree (egg-skills-eval) 中添加依赖:vitest、gray-matter、@anthropic-ai/sdk
  2. 添加vitest.config.ts和更新package.jsonscripts
  3. 创建eval/lib/基础工具:skill-loader、types、judge
  4. 实现eval/static/validate.test.ts静态校验
  5. 编写路由测试用例eval/fixtures/routing-cases.ts
  6. 实现eval/dynamic/routing.eval.ts路由评测
  7. 编写质量测试用例eval/fixtures/quality-cases.ts
  8. 实现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

项目地址:https://gitcode.com/gh_mirrors/eg/egg
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询