ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Windmill ai_evals:AI 生成模式黑盒基准测试的用例编写与运行指南

Windmill ai_evals:AI 生成模式黑盒基准测试的用例编写与运行指南 Windmill ai_evalsAI 生成模式黑盒基准测试的用例编写与运行指南【免费下载链接】windmillOpen-source developer platform to power your entire infra and turn scripts into webhooks, workflows and UIs. Fastest workflow engine (13x vs Airflow). Open-source alternative to Retool and Temporal.项目地址: https://gitcode.com/GitHub_Trending/wi/windmillWindmill 仓库中的ai_evals/是一套针对 AI 生成模式flow、app、script、cli、global的黑盒基准测试框架本文基于 ai-evals 技能文档 展开结合 ai_evals/README.md、用例文件 与核心源码runSuite.ts、judge.ts完整讲解如何编写评测用例、运行基准测试、配置后端代理与理解判定流水线。读完本文你能够独立为 AI chat / copilot 类改动编写 before/after 基准用例并正确解读结果、产物与历史记录。一、框架定位黑盒测试当前生产行为技能文档 开宗明义ai_evals/是一个黑盒基准运行器black-box benchmark runner它总是测试当前 checkout 中的生产提示词、工具与指导文档。每次尝试attempt的完整流水线为走真实的生产路径real production path执行确定性验证deterministic validation执行LLM 判分LLM judging。其核心目标是用贴近真实用户的请求测试当前的生产指导而不是把某一种具体实现形态钉死为唯一正确答案。仓库根目录的 ai_evals/AGENTS.md 也说明编写和运行用例前先加载ai-evals技能Claude Code 读取.claude/skills/ai-evals/SKILL.mdCodex 和 Pi 读取.agents/skills/ai-evals/SKILL.md同一份规范文件完整的用例格式、字段与 fixture 细节保留在 ai_evals/README.md。二、运行基准测试的完整命令面安装与基本命令cd ai_evals bun install # 首次运行frontend 模式还需 cd frontend bun install bun run cli -- models # 列出模型别名 bun run cli -- cases global # 列出某个模式的用例 bun run cli -- run global global-test1-script-create --model sonnetCLI 的公共命令面定义在 cli/index.ts只有三个子命令models、cases [mode]、run mode [caseIds...]。run的全部选项如下与 README 完全一致选项说明--runs n每个用例重复执行 n 次--output path自定义结果 JSON 输出路径仅支持单模型运行--model alias指定被测模型别名与--models互斥--models a,b,c对同一批用例依次跑多个模型别名结束输出 Model summary--verbosefrontend 运行时流式输出助手内容--skip-judge跳过 LLM 判分只做确定性检查--execution-only只要求模型/代理/前端循环跑通跳过验证器、工具期望、后端产物校验与判分--record仅全量套件运行时向ai_evals/history/mode.jsonl追加一行紧凑汇总--backend-validation modeoff或preview仅script和flow模式支持源码中有几处值得注意的硬约束--record与指定 case id 互斥only supports full-suite runs--backend-validation在非 flow/script 模式下直接报错非cli模式在启动前会调用assertWindmillBackendReachable提前检查后端可达性失败即给出配置指引见 cli/index.ts。模型别名体系core/models.ts 中EVAL_MODELS定义了当前别名及其可运行模式别名模型支持模式haikuClaude Haiku 4.5frontend clisonnetClaude Sonnet 4.5frontend cliopusClaude Opus 4.6frontend cli4oGPT-4o仅 frontendgpt-5.5GPT-5.5仅 frontendgemini-3-flash-previewGemini 3 Flash Preview仅 frontendgemini-3.1-pro-previewGemini 3.1 Pro Preview仅 frontenddeepseek-v4-flash/deepseek-v4-proDeepSeek V4仅 frontend关键规则README 与源码一致frontend 模式flow/script/app/global可通过后端代理使用 Anthropic、OpenAI、Gemini、DeepSeek 四类别名cli模式固定走 Anthropic Agent SDK只有 Anthropic 别名可用——resolveEvalModel 会在mode cli且模型没有cli配置时抛出 not supported for cli mode。别名匹配是不区分大小写的findEvalModel先做trim().toLowerCase()。前端模式的后端代理配置Frontend 模式flow/script/app/global的模型调用必须经由某个 Windmill 后端的/api/w/{workspace}/ai/proxy因此需要一个可达的后端WMILL_AI_EVAL_BACKEND_URLhttp://127.0.0.1:port WMILL_AI_EVAL_BACKEND_WORKSPACEintegration-tests \ bun run cli -- run global caseIds... --models sonnet,gpt-5.5,gemini-3.1-pro-preview技能文档强调了一条实操要点务必复用已存在的 workspace。CE 版构建对 workspace 数量有上限临时创建 workspace 会 400reached workspace limit所以应始终设置WMILL_AI_EVAL_BACKEND_WORKSPACEintegration-tests或任意已有 workspace来复用运行的唯一副作用是在该 workspace 下 upsert 一个f/evals/ai/provider资源。Provider key 存放在ai_evals/.env中由 bun 自动加载。从 windmillBackendSettings.ts 可以看到后端 URL 的解析优先级与默认值WMILL_AI_EVAL_BACKEND_URL→WINDMILL_URL→WINDMILL_BASE_URL→REMOTE→http://127.0.0.1:8000登录账号默认adminwindmill.dev/changeme可由WMILL_AI_EVAL_BACKEND_EMAIL、WMILL_AI_EVAL_BACKEND_PASSWORD覆盖。README 还列出后端冒烟验证相关变量WMILL_AI_EVAL_BACKEND_VALIDATIONpreview从 backendValidation.ts 可知轮询参数WMILL_AI_EVAL_BACKEND_POLL_INTERVAL_MS默认 2000ms与WMILL_AI_EVAL_BACKEND_MAX_WAIT_MS默认 120000ms。启用--backend-validation preview时仅 flow/scriptscript评测会在隔离的临时 workspace 中执行真实的后端脚本 previewflow评测只对定义了runtime.backendPreview的用例执行真实 flow preview设置WMILL_AI_EVAL_BACKEND_WORKSPACE后ai_evals会创建/复用该 workspace 作为专用测试空间在每次 preview 前清空f/evals/*下的受管评测资产并重新注入当前用例 fixture。三、用例编写核心规则技能文档的重心技能文档给出五条 Authoring core rules像真实用户请求一样写 prompt优先描述行为、输入、约束与结果而非内部实现确定性验证保持窄而硬narrow and hard语义期望写进judgeChecklist只在结构确实重要时才使用expectedfixture。Prompt 编写好与坏的对照Prompt 应该听起来像用户会自然提出的问题除非用例明确测试老用户工作流否则不要假设用户了解 Windmill 内部结构。文档给出的对照示例好的 promptCreate a flow that routes support requests based on customer tier.Add a reset button that sets the counter back to 0.Create a flow that reuses the existing greeting script instead of duplicating the logic.坏的 promptUsebranchonewith 3 branches and a default branch.Create arawscriptstep with this exact topology.This is a benchmark harness.真实用例集 ai_evals/cases/global.yaml 印证了这一点既有精确路径的power-user式用例如global-test1-script-create明确要求路径f/evals/global/greet_user也有模糊口语化的human式用例如global-test8-human-script-infer-path-language只说需要一个格式化欢迎语的小助手……先以草稿形式准备好不指定路径和语言由模型自行选择合理值——这正是规则 1、2 的直接落地。确定性验证只查硬失败确定性检查只用于硬失败缺少必需文件prompt 明确说不要创建却多出了文件语法错误flow 引用无法解析缺少必需的 special module 或 suspend 配置明显损坏。不要编码某一种偏好的实现坏的硬检查包括创建型 flow 的精确步骤拓扑prompt 只要求路由却写死分支结构多种合理输入形态都可行时却写死输入形态。从 types.ts 看各模式可用确定性规则非常精细flowFlowValidationSpecschemaRequiredPaths/schemaAnyOf接受多种输入 schema 形态、resolveResultsRefs校验results.*引用可解析、requireSpecialModules、requireSuspendSteps等appAppValidationSpec必需前端文件路径、后端 runnable key/类型/内容、runnable 数量下限、datatable 数量下限、forbiddenAppContentglobalGlobalValidationSpecdraftCountAtLeast/draftCountExactly、requiredDrafts可按type/path/language/valueIncludes/valueExcludes等断言草稿、forbiddenDrafts禁止出现某路径草稿cliCliValidationSpecrequiredSkills、requiredSkillsBeforeFirstMutation、requiredProposedCommands、forbiddenExecutedCommands、workspaceUnchanged等跨模式toolExpectToolValidationSpecrequiredToolsUsed、requiredToolsAnyOf任一即可的备选组、forbiddenToolsUsed以及toolCallArgs的参数级断言——stringStartsWithAnyOf对每次调用普适、stringEqualsAnyOf防止$res:f/a/b与$res:f/a/b_backup前缀撞车、stringIncludesAnyOf存在性匹配适合 SQL 中 mutation 与验证 SELECT 混用的场景、nonEmpty、fieldMustBeAbsent该字段在任何一次调用中都不允许出现显式传null也算出现——用于write_variable.value这类补上读不到的字段本身就是失败的部分更新工具assistantExpect断言助手说了什么用于交付物部分是向用户发出警告的用例global judge 只能看到草稿看不到对话文本。[global.yaml](https://link.gitcode.com/i/a3e3a5ab2c9b8278d7023e8cd1ae157c)中的global-test6-secret-variable-draft是这些规则组合的典型例子validate断言恰好 1 个 secret variable 草稿且禁止 resource 草稿toolExpect要求必须用write_variable、禁止write_resource/deploy_workspace_item并且toolCallArgs要求write_variable.value以xoxb-redacted-test-token开头global-test15-human-postgres-resource更进一步用valueExcludes断言密码不得内嵌在 resource 里必须通过$var:引用 secret。judgeChecklist语义期望的正确落点每个非平凡用例都应有judgeChecklist捕获用户可见行为中必须存在的内容、重要约束和关键完成标准——除非确实必要不要写低层实现细节。文档给出的好坏对照好the flow calculates the order total with 8% taxthe flow reuses the existing workspace script instead of rewriting the logic坏usesbranchonecontains arawscriptnode四、判定流水线源码级剖析每次 attempt 的执行顺序core/runSuite.ts 是流水线核心。对每个用例的每次 attempt执行顺序为modeRunner.loadInitial/loadExpected载入 fixture然后modeRunner.run走真实生产路径基础检查run succeeded非--execution-only时追加模式验证器modeRunner.validate、validateToolExpectationstoolExpect、validateAssistantExpectationsassistantExpect若运行成功且模式实现了backendValidatepreview 场景追加后端冒烟检查与backend-preview.json产物若运行成功、未跳过 judge 且用例未设skipJudge调用judgeOutput追加两条检查judge succeeded与judge score threshold阈值取modeRunner.judgeThreshold ?? 80即默认 80一次 attempt 的passed等于所有check 全部通过任何异常都会生成一条run crashed的失败 check。并发由 worker 池实现Promise.all 共享游标并发数取Math.max(1, input.concurrency ?? modeRunner.concurrency)。frontend 模式下若开启--verbose助手消息的开始/分块/结束与每次工具调用都会以FrontendBenchmarkProgressEvent流式回报对应 README 所述Frontend progress streams live while the benchmark is running。LLM Judge 的实现细节judge 是一次独立的 Anthropic 调用与被测模型完全解耦judge.ts 中DEFAULT_JUDGE_MODEL claude-sonnet-4-6需要环境变量ANTHROPIC_API_KEY缺失时 judge 直接返回失败而不是影响被测运行。实现上有几个值得注意的设计temperature: 0、max_tokens: 1024并通过强制工具调用submit_judgementtool_choice: { type: tool }拿到结构化输出score0–100 整数summary系统提示词明确约束 judge 的行为确定性检查已单独跑过judge 只关注最终输出是否满足用户请求expected状态只视为一个合法示例语义等价输出应当得分checklist 是本用例的明确验收标准不得因为输出使用了另一种合法 Windmill 惯用法、命名或等价字段形态而降分也不得在 prompt/checklist/expected 未明确要求时索要精确 id、精确拓扑或精确字段名app模式额外注入规则当 app 产物配置了 datatable 时datatable 持久化是合法模式不得仅因wmill.datatable()用法就判为伪造分数经normalizeScore夹取到 [0, 100]。这也解释了用例中大量skipJudge: true的合理存在例如global-test27-list-recent-runs的注释说明只读任务检查不产生草稿global judge 只能看到草稿产物会把它评成空所以改为用工具调用与参数断言验证global-test26-datatable-script-sdk则说明 judge 缺少 datatable SDK 参考资料会误罚正确的wmill.datatable()用法于是依赖确定性检查。结果、产物与历史记录每次运行都会写出ai_evals/results/下的汇总 JSON如2026-04-09T09-40-33.051Z__flow.json同名的兄弟目录存放生成的产物artifacts。各模式的典型产物flow→flow.jsonscript→script.json 生成的脚本文件app→app.json 前后端文件global→global-drafts.jsoncli→assistant-output.txt、trace.json、wmill-invocations.jsonl 生成的 workspace 文件启用后端验证的 attempt 还包含backend-preview.json。使用--record时CLI 向ai_evals/history/mode.jsonlflow/script/app/global/cli 各一个文件追加一行紧凑记录包含运行元数据createdAt、gitSha、mode、runModel、judgeModel、套件汇总caseCount、attemptCount、passedAttempts、passRate、averageDurationMs、averagePassedDurationMs、averageJudgeScore、平均 token 用量以及cases[]下逐用例指标和failedCaseIds。CLI 头条展示的耗时与 token 均值只统计通过的 attempt全量 attempt 的均值仍会记录让失败可审计但不污染成功路径的成本对比。history/README.md 补充了一个关键语义记录行的gitSha锚定的是产生该结果的基准定义提交——即提示词、评估器与 fixture 所来自的提交后续提交可以只往 JSONL 里追加新行而不改变基准本身。BenchmarkRunResulttypes.ts还包含totalTokenUsage、averageFinalContextTokensPassed、maxFinalContextTokensPassed等字段其中finalContextTokens的定义是 agentic 循环最后一次模型请求占据上下文窗口的输入 token 数input cache-creation cache-read与累计的tokenUsage.prompt互补。五、各模式的运行细节与目录结构各模式的行为差异README Notes 与源码对应Frontend 模式复用生产前端 chat 代码通过 Vitest bridgeai_evals会创建临时后端 workspace或复用WMILL_AI_EVAL_BACKEND_WORKSPACE、在f/evals/ai/provider下 upsert 一个 provider 资源前端请求经/api/w/{workspace}/ai/proxy发出global 模式评估生产全局 AI 工具并验证最终产生的 AI draft store其 initial fixture 还可注入liveEditorDrafts模拟当前打开的编辑器、artifactspreviewTabs配合runtime.sessionChat: true、workspace.variablessecret 默认解密decryptSecret: false时隐藏值、workspace.datatables由内存 SQL 引擎 datatableSqlEngine.ts 驱动CREATE/UPDATE等写入在单用例内是有状态的防止模型重查验证死循环cli 模式创建隔离 workspace把当前 checkout 的指导文档skills /AGENTS.md写入其中基准测试的是真实的 skills 流程并记录结构化的 trace调用的 skill、工具调用、建议的wmill命令、实际执行的wmill命令。目录布局目录内容ai_evals/cases/每个模式一个 YAML 用例文件global.yaml、flow.yaml 等ai_evals/fixtures/initial 与 expected fixturecli 与 frontend 两套ai_evals/core/共享的加载、模型解析、验证、判分、结果写出cases.ts、results.ts、validators.ts 等ai_evals/modes/每个模式一个 runnerflow.ts、cli.ts 等ai_evals/adapters/cli 适配器与 frontend 适配器frontend 适配器构建在生产前端代码之上ai_evals/history/run --record写出的 JSONL 通过率历史ai_evals/results/本地基准输出与产物harness 自身的单测分两条车道bun test adapters/跑纯 TypeScriptbun run test:frontend-graph跑*.vitest.ts覆盖基于 Svelte runes / SvelteKit alias 的适配器——bun 无法直接加载这类前端代码。六、实操清单与常见坑把技能文档与源码约束合起来一次完整的评测运行流程是cd ai_evals bun install cd ../frontend bun install cd .. # 仅 frontend 模式需要 # 准备后端frontend 模式必需 export WMILL_AI_EVAL_BACKEND_URLhttp://127.0.0.1:8000 export WMILL_AI_EVAL_BACKEND_WORKSPACEintegration-tests # CE 版务必复用已有 workspace # ai_evals/.env 中放置 ANTHROPIC_API_KEY 等 provider keyjudge 独立使用 ANTHROPIC_API_KEY bun run cli -- models # 确认别名 bun run cli -- cases global # 找到用例 id bun run cli -- run global global-test1-script-create --model sonnet --verbose bun run cli -- run flow flow-test4-order-processing-loop --runs 3 --record bun run cli -- run flow --models haiku,opus,4o --backend-validation preview常见坑与规避均来自文档/源码约束CE 版 workspace 上限不要依赖临时 workspace400 错误即 reached workspace limit用WMILL_AI_EVAL_BACKEND_WORKSPACE复用--record只能全量跑带 case id 会直接报错--model与--models互斥--output只支持单模型cli 模式只认 Anthropic 别名haiku/sonnet/opus传4o会在resolveEvalModel处抛错judge 缺失 ANTHROPIC_API_KEY 不等于运行失败只会让 judge 相关 check 失败需要确定性结果时用--skip-judge用例设计红线prompt 里不泄露内部术语、确定性检查不钉死实现拓扑、语义期望一律进judgeChecklist——这三条违规会让基准测试结果失去跨模型可比性。七、小结ai_evals技能文档浓缩了这套框架的方法论内核像真实用户那样提问、用窄而硬的确定性检查兜底、把语义判断交给带 checklist 的独立 judge、始终测当前生产行为而非某个实现快照。配合 ai_evals/README.md 的完整字段格式与 cases/ 目录下的真实用例如 global.yaml 中从精确路径到模糊口语、从草稿约束到 secret 防泄露的 30 余个用例这套黑盒基准为 Windmill AI chat / copilot 的任何改动提供了可复现的 before/after 度量手段历史 JSONL 与gitSha锚定机制则让通过率趋势可以按基准定义提交追溯而不是被后续提交悄悄改写。【免费下载链接】windmillOpen-source developer platform to power your entire infra and turn scripts into webhooks, workflows and UIs. Fastest workflow engine (13x vs Airflow). Open-source alternative to Retool and Temporal.项目地址: https://gitcode.com/GitHub_Trending/wi/windmill创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表