- 人工智能
- 大模型
- LLM 网关
- AI Agent
- 即时通讯
【免费下载链接】openclaw-zero-token
OpenClaw: Use All Major AI Models NO API Token! Claude/ChatGPT/Gemini/DeepSeek/Doubao/Grok/Qwen/Manus/Kimi
本文基于 openclaw-zero-token 仓库内vendor/a2ui/specification/0.8/eval目录的官方评估框架,完整讲解其环境配置、命令用法、模型与提示词管理、输出控制以及底层校验原理。读完本文,你将能直接运行pnpm run evalAll对 Gemini / GPT / Claude 三系模型进行 A2UI 消息生成的批量评测,并能深入理解 matcher 校验体系与 summary 报告生成机制。
概述:为什么需要专门评估 A2UI 的 UI 生成
A2UI(Agent-to-User Interface)是一种声明式 JSON 协议,让 Agent 用数据来描述 UI 的"意图",再由客户端用自己的原生组件库渲染,做到"像数据一样安全,像代码一样富有表现力"(见 vendor/a2ui/README.md)。要让不同的大语言模型稳定地输出符合 A2UI v0.8 规范(四种消息类型:beginRendering、surfaceUpdate、dataModelUpdate、deleteSurface)的 JSON 消息,不能只靠人工抽查——需要一套可复现、可量化的评估流水线。
vendor/a2ui/specification/0.8/eval 正是这样一套基于Genkit的评估框架(Genkit Eval Framework for UI generation),它实现了:
- 多模型批量推理:内置 8 个模型配置(GPT、Gemini、Claude 三系);
- 多提示词评测集:内置 18 个覆盖常见 UI 场景的测试提示词;
- 结构化输出约束:通过 Genkit 的
jsonSchema让模型直接产出符合 A2UI 协议的 JSON; - 多层级校验:JSON Schema 级校验 + 语义 matcher 校验;
- 汇总报告:自动生成按模型、按提示词分组的 Markdown 评估摘要。
环境准备与安装
API Key 配置
框架通过三个环境变量读取各家模型的 API Key(见 eval/README.md):
| 环境变量 | 对应模型厂商 |
|---|---|
GEMINI_API_KEY | Google Gemini |
OPENAI_API_KEY | OpenAI GPT |
ANTHROPIC_API_KEY | Anthropic Claude |
在 eval/src/flows.ts 中,框架会按环境变量存在性动态初始化插件:只配置了GEMINI_API_KEY就只注册 Google AI 插件,只配置OPENAI_API_KEY就只注册 OpenAI 插件(openAI()),只配置ANTHROPIC_API_KEY就只注册 Anthropic 插件。也就是说,你可以只评测你有 API Key 的模型,不会因为没有其他 Key 而报错。
配置方式有两种:
- 在项目根目录(此处为
vendor/a2ui/specification/0.8/eval)创建.env文件; - 或在 shell 配置文件(
.bashrc、.zshrc)中 export。
示例.env:
GEMINI_API_KEY=your_gemini_key OPENAI_API_KEY=your_openai_key ANTHROPIC_API_KEY=your_anthropic_key注意:pnpm run eval脚本使用dotenv -- tsx src/index.ts(见 package.json),dotenv-cli会自动加载.env文件,所以.env是首选方式。
安装依赖
pnpm install框架依赖(见 package.json):
genkit(核心运行时)与@genkit-ai/google-genai、@genkit-ai/compat-oai、genkitx-anthropic三个模型插件;@genkit-ai/vertexai(Gemini Vertex AI 通道,按需使用);tsx(直接运行 TypeScript)、yargs(命令行参数解析)、dotenv-cli(加载.env)。
从源码运行无需额外编译步骤:tsx src/index.ts直接执行 TS。
运行评估
运行全部评测
pnpm run evalAll⚠️ 官方 README 特别警告:全量运行会消耗大量模型配额(can use *lots* of model quota)。原因从源码可见:默认情况下evalAll会跑8 个模型 × 18 个提示词 = 144 个推理任务,且每个模型/提示词组合都会调用一次真实的 LLM API。
运行单个评测
快速调试单个模型 + 单个提示词,使用--model与--prompt两个命令行参数:
pnpm run eval -- --model='<model_name>' --prompt=<prompt_name>官方示例——用gpt-5-mini (reasoning: minimal)模型跑generateDogUIs提示词:
pnpm run eval -- --model='gpt-5-mini (reasoning: minimal)' --prompt=generateDogUIs注意:README 示例中的模型名
gpt-5-mini (reasoning: minimal)是文档写作时的命名习惯;当前仓库 eval/src/models.ts 中的模型名是gpt-5-mini(推理配置通过config: { reasoning_effort: "minimal" }注入,不体现在名字里)。运行时请以models.ts中name字段的准确值为准。
命令行参数详解
eval/src/index.ts中通过yargs定义了完整的参数体系(见 eval/src/index.ts):
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--verbose/-v | boolean | false | 打印每次成功生成的完整 JSON 输出 |
--keep=<dir> | string | 无 | 保留每次调用的输入/输出到独立文件;不带路径时自动创建临时目录 |
--runs-per-prompt=<n> | number | 1 | 每个提示词重复运行次数 |
--model=<name> | string[] | 全部模型 | 按精确名称过滤模型,可选值必须是models.ts中定义的名称,可传多次 |
--prompt=<name> | string | 全部提示词 | 按前缀过滤提示词(startsWith匹配) |
几个关键行为(源码佐证):
--model过滤用的是精确匹配,--prompt用的是前缀匹配(index.ts),因此--prompt=login会匹配loginForm等以login开头的提示词;- 若过滤后无匹配,程序会打印
No models found matching: ...或No prompt found with prefix "..."并以退出码 1 终止; - 默认情况下(不加
--verbose),控制台只打印汇总表和生成过程中的错误,成功结果不打印(index.ts); - 结果全部完成后,若指定了
--keep,汇总报告会额外写入<output_dir>/summary.md。
三个内置快捷脚本
package.json 预置了三个快捷命令,方便快速对比三家模型(提示词均为travelItinerary):
pnpm run evalGemini # --model=gemini-2.5-flash --prompt=travelItinerary pnpm run evalGpt # --model=gpt-5-mini --prompt=travelItinerary pnpm run evalClaude # --model=claude-4-sonnet --prompt=travelItinerary控制输出与保留运行产物
--verbose:查看完整 JSON
pnpm run evalAll -- --verbose此时每个成功生成的结果会打印Model / Query (run N)、校验失败列表以及完整 JSON(JSON.stringify(component, null, 2)格式化输出)。注意:即使没有--verbose,校验失败和运行时错误也始终会打印,方便第一时间定位问题。
--keep:保留每次调用的输入输出
pnpm run evalAll -- --keep=output会在output/下按模型名建子目录(模型名中的/、:会被替换为_,见 index.ts),每个提示词生成三类文件:
<prompt>.input.txt:发送给模型的提示词原文;<prompt>.output.json:成功时模型生成的 A2UI JSON;<prompt>.error.json:失败时写入{message, stack, ...error}错误详情。
若--keep不带路径(--keep单独使用),会通过fs.mkdtempSync自动创建a2ui-eval-*临时目录(index.ts)。指定目录时文件按<output_dir>/<模型名>/<prompt>.*的层级存放,同时汇总报告写入<output_dir>/summary.md。这套产物结构非常适合做回归对比:同一提示词在不同模型间的输出可以直接 diff。
模型配置:如何添加 / 调整被测模型
所有被测模型集中定义在 eval/src/models.ts 的modelsToTest数组中,每个条目是一个ModelConfiguration:
export interface ModelConfiguration { model: any; // 由 Genkit 插件工厂创建的模型实例 name: string; // 命令行 --model 过滤使用的名称 config?: any; // 传给 ai.generate 的推理配置 }当前仓库内置的 8 个模型配置:
| name | 底层模型 | 关键 config |
|---|---|---|
gpt-5 | openAI.model("gpt-5") | { reasoning_effort: "minimal" } |
gpt-5-mini | openAI.model("gpt-5-mini") | { reasoning_effort: "minimal" } |
gpt-4.1 | openAI.model("gpt-4.1") | {} |
gemini-2.5-pro-thinking | googleAI.model("gemini-2.5-pro") | { thinkingConfig: { thinkingBudget: 1000 } } |
gemini-2.5-flash | googleAI.model("gemini-2.5-flash") | { thinkingConfig: { thinkingBudget: 0 } } |
gemini-2.5-flash-lite | googleAI.model("gemini-2.5-flash-lite") | { thinkingConfig: { thinkingBudget: 0 } } |
claude-4-sonnet | claude4Sonnet | {} |
claude-35-haiku | claude35Haiku | {} |
从配置可以看出评测设计者的对比意图:同一系列内对比不同规格(gpt-5vsgpt-5-minivsgpt-4.1;gemini-2.5-provsflashvsflash-lite),跨系列对比三家头部模型,并刻意把 Gemini 的thinkingBudget拉开(pro 用 1000 token 深度思考,flash 系用 0 关闭思考)以考察推理预算对 UI 生成质量的影响。
新增模型的步骤(例如接入其他厂商或新版本):
- 在文件顶部 import 对应 Genkit 插件工厂;
- 在
modelsToTest追加一个ModelConfiguration条目; - 重启评估即可通过
--model=<name>单独评测该模型,yargs的choices会自动同步新名称。
提示词评测集:18 个场景全覆盖
所有测试提示词定义在 eval/src/prompts.ts。每个TestPrompt包含四要素:
export interface TestPrompt { name: string; // 提示词名称(--prompt 按此前缀匹配) description: string; // 场景说明 schemaPath: string; // 使用的 JSON Schema 路径 promptText: string; // 发送给模型的提示词正文 matchers: SchemaMatcher[]; // 该校验器(见下一节) }全部提示词统一使用../../json/server_to_client_with_standard_catalog.json(相对 eval/src 的路径,实际文件为 vendor/a2ui/specification/0.8/json/server_to_client_with_standard_catalog.json)。该 Schema 是官方把server_to_client.json与standard_catalog_definition.json合并后生成的"LLM 友好版":把通用的component对象替换为对标准目录中每个组件的严格oneOf定义,让模型在生成时不产生歧义(见 vendor/a2ui/specification/0.8/json/README.md)。
内置 18 个提示词覆盖四类消息与常见 UI 场景:
消息类型覆盖
surfaceUpdate(绝大多数提示词):dogBreedGenerator、loginForm、productGallery、settingsPage、animalKingdomExplorer、recipeCard、musicPlayer、weatherForecast、surveyForm、flightBooker、dashboard、contactCard、calendarEventCreator、checkoutPage、socialMediaPost、eCommerceProductPage、interactiveDashboard、travelItinerary;dataModelUpdate:productGalleryData(填充/products数据)、dataModelUpdate(登录后写入/user/name、/user/email);beginRendering:uiRoot(设置 UI 根组件);deleteSurface:deleteSurface(删除dashboard-surface-1)。
组件类型覆盖:Heading、Text、Image、TextField、Button、CheckBox、Slider、List、Card、Row、Column、Tabs、Modal、Divider、MultipleChoice、DateTimeInput等标准目录组件几乎全部涉及;travelItinerary、animalKingdomExplorer等场景还包含嵌套列表、深层组件层级等"长尾"考验。
评测难度梯度:从简单的单消息(uiRoot只需输出beginRendering)到超长结构化场景(animalKingdomExplorer要求 3 个 Tab × 多级 Card 嵌套且"不许漏掉任何一项",见 prompts.ts),可以横向评估模型对复杂指令的遵循能力。
新增提示词同样简单:在prompts数组中追加对象并定义 matchers 即可,--prompt前缀过滤自动生效。
底层原理:生成 Flow 与校验体系
生成 Flow:结构化 JSON 输出
核心生成逻辑在 eval/src/flows.ts 的componentGeneratorFlow:
const { output } = await ai.generate({ prompt, model, output: { contentType: "application/json", jsonSchema: schema }, config, });关键点:通过output.jsonSchema把server_to_client_with_standard_catalog.json直接作为 Genkit 的生成约束注入,模型被强制输出符合 A2UI 协议的结构化 JSON,而非自由文本。main()会为每个提示词读取并JSON.parse该 Schema 文件(index.ts),再并发调度所有 (模型, 提示词, run) 组合。
校验体系:JSON Schema 之上再叠加语义 matcher
A2UI 的校验分两层,两者结果共同决定一次运行是否"失败":
第一层:协议结构校验(eval/src/validator.ts)
validateSchema首先按顶层消息类型分发到四个子校验函数,同时执行通用规则:
- 顶层必须有且仅有
surfaceUpdate/dataModelUpdate/beginRendering/deleteSurface之一; surfaceUpdate必须含components数组,组件id必须唯一;- 引用完整性:
Card.child、Row/Column/List.children(explicitList或template二选一)、Tabs.tabItems[].child、Modal.entryPointChild/contentChild引用的组件 ID 必须真实存在(checkRefs); - 每个组件必须恰好有一个类型键,且按类型检查必填属性:
Heading/Text.text、Image/Video/AudioPlayer.url、TextField.label、DateTimeInput/Slider.value、MultipleChoice.selections/options、CheckBox.value/label、Button.child/action.name、Divider无必填项等; - 绑定值(bound value)必须是
{literalString | literalNumber | literalBoolean | path}四选一且只选一(validateBoundValue); dataModelUpdate的contents每个 item 必须含key且恰好一个 value 属性(valueString/valueNumber/valueBoolean/valueMap),valueMap内部 item 同理;- 未知组件类型会报
Unknown component type '...'。
第二层:语义 matcher(eval/src/schema_matcher.ts 及三个实现)
SchemaMatcher是一个抽象基类,三个具体实现各有分工:
- message_type_matcher.ts:校验顶层消息类型是否恰好为期望值(例如
deleteSurface提示词要求顶层键只有一个且为deleteSurface); - basic_schema_matcher.ts:按点号路径(如
dataModelUpdate.contents.0.key)在对象树中取值,校验存在性甚至精确值(用JSON.stringify比较); - surface_update_schema_matcher.ts:最复杂的 matcher,在
surfaceUpdate.components中查找指定组件类型,并可选校验属性值与期望值匹配。它有两大"智能"处理:- Button 标签特判:A2UI 中 Button 的标签通常存在于其
child引用的Text组件中,matcher 会顺着properties.child找到子Text组件再比对text值(surface_update_schema_matcher.ts); - 值形态兼容:
valueMatches同时支持旧式直接值、新式{literalString/literalNumber/literalBoolean}对象、数组(如MultipleChoice.options的{label: {literalString...}, value}结构),并支持caseInsensitive大小写不敏感匹配(如dogBreedGenerator中对 "Dog breed name" 的true参数)。
- Button 标签特判:A2UI 中 Button 的标签通常存在于其
以loginForm提示词为例,其 matchers 链(prompts.ts)要求:顶层是surfaceUpdate+ 存在text为 "Login" 的Heading+ 存在 label 为 "username"/"password" 的TextField+ 存在 label 为 "Remember Me" 的CheckBox+ 存在 label 为 "Sign In" 的Button——五条全部通过才算该校验通过。
汇总报告生成
所有运行结束后,generateSummary(index.ts)按模型分组生成 Markdown 表格:每个提示词一行的Avg Latency (ms)、Failed Runs(工具错误或校验失败)、Tool Error Runs,模型级合计Total failed runs,最后是总体统计:工具错误运行数、含任意失败(工具错误或校验)的运行数、Mean/Median 延迟、至少失败过一次的模型列表。这份报告默认打印到控制台,--keep时也会落盘为summary.md。
版本演进视角:0.8 与 0.9 评估框架的差异
仓库同时携带了 0.9 版本的评估框架(vendor/a2ui/specification/0.9/eval/README.md),可作为理解 0.8 设计的参照:
- Schema 注入方式:0.9 把 JSON Schema 直接嵌入提示词,并要求模型在 markdown 代码块中输出 JSON,框架再提取并校验(
extractJsonFromMarkdown);0.8 则依赖 Genkit 的output.jsonSchema结构化约束; - 模型集:0.9 的 models.ts 扩展了
gpt-5.1、gpt-5-nano、gemini-3-pro等更新型号,并为每个模型配置了requestsPerMinute/tokensPerMinute限流参数; - 限流机制:0.9 引入两级限流——本地主动限流(按配额控制请求/令牌速率)与响应式熔断(收到
RESOURCE_EXHAUSTED429 后暂停该模型请求并按重试时长恢复),见 0.9 的 rateLimiter.ts; - 结果输出:0.9 默认打印进度条,日志写入 results 目录的
output.log,并提供--log-level、--results、--clean-results等更多参数。
如果你在 0.8 基础上做大规模评测,可以参考 0.9 的限流与结果管理思路自行增强。
在 OpenClaw 项目中的实际落点
A2UI 评估框架虽然位于vendor/目录,但 A2UI 渲染与交互能力已深度集成到 OpenClaw 本体:
- 框架渲染资产由 canvas-host 静态托管:
src/canvas-host/a2ui.ts将 A2UI 前端资源挂在/__openclaw__/a2ui路径下(A2UI_PATH常量,见 src/canvas-host/a2ui.ts),并通过resolveA2uiRoot在源码/发布目录间解析资源位置; - Agent 工具层提供
a2ui_push与a2ui_reset两个动作(见 src/agents/tools/canvas-tool.ts),分别通过canvas.a2ui.pushJSONL推送 A2UI 消息、canvas.a2ui.reset重置画布,canvas.snapshot则可抓取渲染结果用于视觉验证——这与评估框架"生成 → 校验"的闭环形成了呼应:评估阶段用 matcher 自动判定,运行阶段用快照人工/模型复核。
因此,本指南介绍的评估框架既可以直接在vendor/a2ui/specification/0.8/eval内独立运行以横向对比模型能力,也可以结合 OpenClaw 的 canvas 链路验证"模型生成的 A2UI 消息在真实渲染器中的效果"。
快速上手清单
- 在 vendor/a2ui/specification/0.8/eval 下创建
.env,填入你有权限的 API Key(GEMINI_API_KEY/OPENAI_API_KEY/ANTHROPIC_API_KEY可任选其一或全部); pnpm install安装依赖;- 快速验证单点:
pnpm run eval -- --model=gemini-2.5-flash-lite --prompt=loginForm; - 全量评测:
pnpm run evalAll(注意配额消耗); - 保留产物与报告:
pnpm run evalAll -- --keep=output --verbose; - 查看
output/summary.md分析各模型在各场景下的延迟与失败率。
限制与前提说明:以上命令依赖pnpm、Node.js 及对应模型的 API Key;模型名单以仓库当前 models.ts 为准(README 示例中的gpt-5-mini (reasoning: minimal)写法在现有代码中应写作gpt-5-mini);全量评测消耗大量配额,建议先跑单点验证配置正确后再扩展规模。
- 人工智能
- 大模型
- LLM 网关
- AI Agent
- 即时通讯
【免费下载链接】openclaw-zero-token
OpenClaw: Use All Major AI Models NO API Token! Claude/ChatGPT/Gemini/DeepSeek/Doubao/Grok/Qwen/Manus/Kimi
相关推荐
A2UI v0.9.1 评测框架实战指南:基于 Genkit 的 LLM UI 生成质量评估
A2UI v0.9.1 评测框架实战指南:基于 Genkit 的 LLM UI 生成质量评估 导读 本文围绕 A2UI(v0.9)官方评测框架(位于 speci
人工智能AI Agent前端UI组件基于 Genkit Eval 框架对 A2UI v0.9 多模型 UI 生成能力进行系统评测
基于 Genkit Eval 框架对 A2UI v0.9 多模型 UI 生成能力进行系统评测 A2UI(v0.9)是一套让 LLM 以结构化 JSON 消息描述
人工智能AI Agent前端UI组件使用 Genkit 评测框架对 A2UI v0.8 进行多模型 UI 生成评估:从环境配置到结构化校验
使用 Genkit 评测框架对 A2UI v0.8 进行多模型 UI 生成评估:从环境配置到结构化校验 本篇指南完整讲解当前仓库中 A2UI v0.8 的 Ge
人工智能AI Agent前端UI组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考