EF Core Agent 技能开发:多模型子代理测试、A/B 对比与 Writer-Critic 收敛方法论
【免费下载链接】efcoreEF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.项目地址: https://gitcode.com/GitHub_Trending/ef/efcore
EF Core 仓库在.agents/skills/目录下维护了一套面向 GitHub Copilot 的 Agent Skills 体系,其中 make-skill 技能 负责脚手架式创建新技能,其 Step 8「Test with Multi-Model Subagents」将测试环节委托给参考文档 testing-patterns.md。本文以该文档为主体,完整拆解其多模型子代理测试流程(选模型、构造测试提示、并行发射、结果综合、行动分级)、A/B 前后对比测试、Writer-Critic 收敛循环、Waza 量化评估与误报甄别等全部方法论,并给出可直接复制的提示词模板、task工具调用示例与 GraphQL 评审线程操作脚本,帮助你为任意 Agent 技能建立可重复、可度量的质量验证闭环。
文档定位:EF Core 技能体系中的测试方法论
从仓库结构看,.agents/skills/目录下并存着多个真实技能,如 testing(EF Core 测试基础设施实现细节)、migrations、query-pipeline、servicing-pr 等,它们正是多模型测试方法论要验证的对象。
make-skill技能的 SKILL.md 在第 8 步中规定:
- 从 2–4 个不同模型家族中各选顶级模型;
- 给每个模型相同的工作流测试提示;
- 通过
task工具的model参数并行发射; - 综合结果:多个模型的共识发现即高置信度;
- 先修错误,再修警告,最后考虑建议;
- 复盘:当某个模型误用技能指引时,让同一模型解释其选择原因——其自我分析能暴露指引缺口,可用针对性的反模式(anti-pattern)来弥补;
- A/B 测试:修复问题后重跑同一任务,验证改进效果。
该文档同时注明:这一方法论在 EF Core 团队的迭代式技能开发中被独立验证,也在 stephentoub 的 code-review 技能中得到印证——多模型评审在该技能中是一等公民流程。文档与同目录的 anti-patterns.md(经验性设计反模式清单)互为补充:前者回答「怎么测」,后者回答「测出来的问题哪些是真问题、哪些是误报」。
为什么需要多模型测试
不同模型存在不同的盲点,这是多模型测试的立论基础:
- 有的模型擅长代码正确性,但会漏掉 UX 问题;
- 有的模型能抓住其他模型忽略的边缘情况;
- 有的模型会产生误报(false positives),而另一些模型能正确忽略;
- 共识发现(被 2 个及以上模型同时标记的问题)几乎总是真实问题。
这一思路的核心价值在于:用模型间的独立性换取发现置信度——单模型的判断可能是其自身盲点造成的幻觉,而跨家族模型的共识则大幅降低了这种概率。
五步多模型测试流程
第 1 步:选择模型
选择每个可用模型家族中的顶级模型,至少 2 个、至多 4 个。跳过快速/廉价档位——你要的是每个家族最好的推理能力,而不是吞吐量。文档给出的示例选择:
claude-opus-4.6 (Anthropic) gpt-5.3-codex (OpenAI) gpt-5.4 (OpenAI, alternative perspective)文档附有一条稳定性警示(以当前仓库文档为准):gemini-3-pro-preview在通用任务代理上频繁出现 400 错误,建议在 Gemini 稳定性改善前优先使用 OpenAI 或 Anthropic 模型。
第 2 步:构造测试提示词
给每个代理相同的提示词,其中应包含三部分:
- 技能的目的与上下文;
- 一个能充分锻炼该技能的真实任务;
- 按严重度报告发现的指令。
文档按技能类型给出三套可直接套用的模板:
面向脚本驱动(script-driven)技能——让代理运行技能并评估输出:
Use the skill at {path} to {task}. After running, evaluate: 1. Did the skill produce correct, useful output? 2. Are there edge cases it mishandled? 3. Is the output clear and actionable? 4. Any bugs, errors, or misleading information? Report findings as: ❌ error / ⚠️ warning / 💡 suggestion面向知识驱动(knowledge-driven)技能——让代理应用技能的规则并评估规则本身:
Read the skill at {path} and use it to {task}. After applying, evaluate: 1. Were the instructions clear enough to follow? 2. Did any rules conflict or create ambiguity? 3. Were there gaps — situations where the skill gave no guidance? 4. Any rules that seem wrong or overly broad? Report findings as: ❌ error / ⚠️ warning / 💡 suggestion面向 SKILL.md 本身——请求结构化评审:
Review the skill at {path} as if you were a developer evaluating whether to adopt it. Consider: trigger description quality, section organization, completeness, accuracy, actionability. Would you trust this skill's guidance?三套模板的共同设计点是三级严重度标注(❌/⚠️/💡),它使后续的综合与分级步骤有统一的输入格式。
第 3 步:并行发射
使用task工具配合不同的model参数发射多个代理:
task agent_type="general-purpose" model="claude-opus-4.6" prompt="..." task agent_type="general-purpose" model="gpt-5.4" prompt="..." task agent_type="general-purpose" model="gemini-3.1-pro-preview" prompt="..."尽可能全部并行启动(mode="background"),以压缩墙钟时间。
第 4 步:综合结果
所有代理完成后执行四个动作:
- 去重:把描述同一问题的发现归组;
- 共识升权:被 2+ 模型标记的问题 → 高置信度,优先修复;
- 保留独特捕获:达到置信度门槛的单模型发现也予以保留;
- 丢弃噪声:没有具体证据支撑的模糊建议直接丢弃。
第 5 步:行动分级
| 优先级 | 判定标准 |
|---|---|
| 立即修复 (Fix now) | 任一模型的 ❌ 错误,或 2+ 模型的 ⚠️ 警告 |
| 尽快修复 (Fix soon) | 单模型带清晰证据的 ⚠️ 警告 |
| 考虑 (Consider) | 有共识或强理由的 💡 建议 |
| 跳过 (Skip) | 单模型无证据的 💡 建议、纯风格反馈 |
这张分级表把「多模型投票」直接映射为修复排期,避免了「收到一堆评论却不知从何下手」的常见困境。
A/B 测试:前后对比验证改进
在技能迭代过程中,用同一任务在改动前后各跑一次,以量化改进、并捕获「修了一个问题却在别处引入回归」的情况。
流程设置
- 挑选可复现的任务——以已知正确答案的真实调查任务最佳;
- 记录「before」运行——用当前技能发射一个子代理,记下:耗时、工具调用次数、是否得出正确答案、走了哪些弯路;
- 应用技能改动(编辑 SKILL.md、references、脚本);
- 执行「after」测试——相同提示、相同模型、相同任务;
- 对比结果。
度量指标
| 指标 | 度量方式 | 良好信号 |
|---|---|---|
| 正确性 | 代理是否得出正确结论? | Before: ❌ → After: ✅ |
| 耗时 | 代理完成时间(秒) | 快 30% 以上 |
| 工具调用 | 工具调用总次数 | 更少 = 更高效 |
| 错误弯路 | 未对答案做出贡献的步骤 | 更少 = 指引更好 |
文档中的真实案例(ci-analysis 技能改进)
Task: "Compare Csc args between passing and failing Helix binlogs" Round 1 (before fixes): 623s, wrong root cause (Debug/Release noise) Round 2 (after fixes): 272s, correct root cause (extra analyzerconfig arg) Changes made: Added "focus on arg count, not value differences" to binlog-comparison.md delegation prompt template.仅通过往委托提示模板中加入一句「关注参数个数而非取值差异」的指引,就把耗时从 623 秒压到 272 秒,且根因判断从错误(Debug/Release 噪声)修正为正确(多出的 analyzerconfig 参数)——这是「一条精准指引同时提升正确性与效率」的典型样本。
实操提示
- 前后使用同一模型——不同模型能力不同,无法归因;
- 已知答案任务最佳——正确性可以客观评分;
- 不要只优化速度——慢但对的答案胜过快而错;
- 保存 before 提示词——after 运行必须逐字复用同一提示。
Writer-Critic 收敛循环
对于技能创建或大规模重构,单轮评审往往会漏掉只有实际应用反馈时才会浮现的结构性问题。Writer-Critic 模式让两个代理迭代执行,直到技能收敛:
- Writer 代理创建或修改技能(SKILL.md、脚本、references);
- Critic 代理评审结果——产出带 ❌/⚠️/💡 的结构化反馈文档;
- Writer 代理读取反馈并应用修复;
- Critic 代理再次评审——只标记新增或遗留的问题;
- 重复直到批评者没有有意义的发现(通常 2–3 轮)。
任务编排
用两次串行(而非并行)的task调用完成一轮——后者依赖前者的输出:
# Round 1: Writer creates the skill task agent_type="general-purpose" prompt="Create a skill at {path} that {does X}..." # Round 1: Critic reviews task agent_type="general-purpose" model="{different-model}" prompt="Review the skill at {path}. Report ❌/⚠️/💡 findings. Save feedback to {path}/feedback.md" # Round 2: Writer applies feedback task agent_type="general-purpose" prompt="Read {path}/feedback.md and apply the feedback to the skill at {path}. Delete feedback.md when done." # Round 2: Critic reviews again task agent_type="general-purpose" model="{different-model}" prompt="Review the skill at {path}. Only flag NEW or REMAINING issues..."关键设计决策
- Writer 与 Critic 使用不同模型——同模型配对过于「投契」,批评会失去张力;
- 人工留在环内——轮次之间由人来把握方向、否决糟糕建议;
- 反馈落盘为文件(如技能目录下的
feedback.md)——Writer 代理获得完整上下文,无需人工转述; - 应用后删除反馈文件——它是临时产物,不属于技能的一部分;
- 当 Critic 只剩 💡 建议时停止——那就是收敛。不要追逐零发现。
Writer-Critic 与多模型评审的分工
| 场景 | 方法 |
|---|---|
| 用真实任务测试现有技能 | 多模型评审(并行、单发) |
| 从零创建新技能 | Writer-Critic 循环(2–3 轮) |
| 技能大重构 | Writer-Critic 循环 |
| 小修小补或渐进改进 | 多模型评审 |
| Writer-Critic 收敛后的最终验证 | 以多模型评审收尾 |
两种方法互补:Writer-Critic 负责创建与迭代,多模型评审负责验证。
Waza Eval 量化测试
对于需要可重复、可量化的技能测试,文档推荐waza-eval技能,它提供:
- 结构化评估套件——定义带提示词、预期输出与评分器的任务集;
- 进展测试——从 git 历史对比不同技能版本间的工具效率;
- 会话捕获——把结果转录提交为黄金会话(golden sessions),用于回归检测;
- CI 集成——以评估通过率对 PR 设卡。
分工原则:需要度量技能改动是否改善行为时用 waza eval;需要定性的结构化反馈时用多模型评审(上文各节)。
回归判据
对比 before/after 评估结果时:
| 指标 | 阈值 | 处置 |
|---|---|---|
| 任一任务工具调用增加 > 20% | 🔴 回归 | 回滚该改动 |
| 工具调用减少 > 10% | 🟢 改进 | 记录为证据 |
| 耗时增加 > 30% | 🔴 回归 | 排查瓶颈 |
| 之前对、改后错 | 🔴 回归 | 回滚——正确性高于效率 |
| 模型误用新指引 | 🔴 回归 | 需要补充反模式或改写措辞 |
| 一个模型变好、其他不变 | 🟡 部分改进 | 大概率可接受 |
触发测试结构
评估套件应包含触发测试(技能是否被正确激活):
- 应当触发(8–12 条提示):技能用法的多种措辞变体,附高/中置信度评级;
- 不应当触发(6–8 条提示):相邻技能、属于别处的相似关键词;
- 边缘情况(3–5 条提示):措辞模糊的提示,须写明期望行为与理由。
提交前检查清单
发布技能改动前逐项核对:
- Description 与触发测试一致(USE FOR 短语出现在 should-trigger 提示中);
- 停止信号(stop signals)显式且带数值边界;
- 存在领域示例(而非仅有工具 schema);
- 满足 token 预算(SKILL.md 编排型 < 4K / 知识型 < 15K);
- 多模型验证 ≥ 4/5,且覆盖 2+ 模型家族。
其中 token 预算的分档与配套文档 anti-patterns.md 中「Bloated SKILL.md」一节呼应:知识驱动的 SKILL.md 可以大(stephentoub 的达 54KB),但前提是内容每次任务只应用一遍;编排型 SKILL.md 应保持紧凑(2K–4K tokens),把深度内容下沉到按需加载的references/*.md。
自动评审的常见误报
文档汇总了实战中自动评审反复误判的类别,并给出标准应对话术。对使用多模型评审的团队,这一节是「噪声过滤器」:
PowerShell 兼容性
- 误报:
-UseBasicParsing「在 pwsh 中不支持」; - 事实:它在 pwsh 中是 no-op(被接受并静默忽略),但在 Windows PowerShell 5.1 中是必需的;
- 应对:「保留——pwsh 中 no-op,WinPS 5.1 必需,可避免 IE COM 依赖。」
API 字段名
- 误报:
gh pr checks应使用--json conclusion而非--json state; - 事实:
conclusion不是合法字段,state直接包含SUCCESS/FAILURE; - 应对:用
gh pr checks --json的错误输出验证——会报 "Unknown JSON field: 'conclusion'"。
训练数据过期
- 误报:「该 API/方法不存在」或「已弃用」;
- 事实:模型有知识截止点,该 API 可能正是当前版本;
- 应对:「已验证——该 API 存在且可用,可能是模型训练数据过期。」
MCP 工具名前缀
- 误报:技能文档应使用全限定 MCP 工具名(如
hlx-hlx_status、github-mcp-server-list_workflow_runs)而非短名; - 事实:技能应优先使用领域语言("search the console log"、"get job pass/fail summary"),映射到代理实际拥有的任意工具(MCP、CLI 或 API 回退);工具名不可避免时(如反模式示例)用短名,服务前缀是实现细节;
- 应对:「领域语言优先。它把技能与工具描述建立语义连接,而不是与跨 MCP 版本会变化的名字字面耦合。」
过度资源释放(over-disposal)
- 误报:每个 HTTP 响应/客户端都需要 try/finally/dispose;
- 事实:有时确实需要,但评审者常建议增加无价值复杂度的释放模式(例如释放一个函数返回即将出作用域的客户端);
- 应对:长运行函数或循环中应用释放模式;函数末尾的一次性简单调用则跳过。
评审线程工作流:程序化处理 PR 评审
当需要以程序化方式处理 PR 评审评论时,文档给出基于gh api graphql的两段 PowerShell 脚本。
回复线程
$body = "Your evidence-based reply" | ConvertTo-Json $query = @" mutation { addPullRequestReviewThreadReply(input: { pullRequestReviewThreadId: "$threadId", body: $body }) { clientMutationId } } "@ gh api graphql -f query="$query"解决线程
$query = @" mutation { resolveReviewThread(input: { threadId: "$threadId" }) { clientMutationId } } "@ gh api graphql -f query="$query"最佳实践
- 先读完所有线程再回复——其中可能有重复项;
- 先回复再解决——保留对话上下文;
- 同一问题跨多个线程批量回复;
- 附带证据——「通过运行 X 验证」或「已对真实 API 测试」;
- 保持简洁——每条回复通常一段话足够。
方法论选型总结
testing-patterns.md 实际提供了三层递进的验证工具,可按场景组合使用:
| 层次 | 工具 | 回答的问题 | 适用场景 |
|---|---|---|---|
| 定性结构评审 | 多模型并行评审 | 技能有哪些真实缺陷? | 测试现有技能、小修小补、收敛后终验 |
| 创建/迭代闭环 | Writer-Critic 收敛循环 | 如何让技能从零达到可用? | 新建技能、大重构(2–3 轮) |
| 量化度量 | waza-eval + A/B 对比 | 这次改动是否真的变好了? | 版本对比、CI 卡点、回归检测 |
贯穿三层的核心原则有三条:共识即置信(2+ 模型标记优先修)、正确性高于效率(慢而对胜过快而错)、人工留在环内(轮次之间由人把关方向)。配合 anti-patterns.md 的误报甄别经验与 make-skill/SKILL.md 的前置验证清单,这套方法构成了一条从技能脚手架、多模型验证到量化发布的完整质量链路。
【免费下载链接】efcoreEF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.项目地址: https://gitcode.com/GitHub_Trending/ef/efcore
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考