ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Perfetto AI Eval 剖析:jank-worst-frame 案例中“Buffer Stuffing”正则 Grader 的确定性评分机制

Perfetto AI Eval 剖析:jank-worst-frame 案例中“Buffer Stuffing”正则 Grader 的确定性评分机制 Perfetto AI Eval 剖析jank-worst-frame 案例中“Buffer Stuffing”正则 Grader 的确定性评分机制【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto本文以 jank-types.md 这个只有 7 行的 grader 文件为主体完整解读 Perfetto AI Agent 评测套件中“卡顿类型判定”这一评分项的文件格式、真值依据与运行机制并借助 run_evals.py 与 frame_timeline_event_parser.cc 的源码说明为什么一个正则匹配就能对 Agent 的卡顿分析答案做不可“被说服”的确定性验收。读完本文你可以掌握 Perfetto evals 中单个 regex grader 的 frontmatter 规范、与 LLM 评审的分工以及如何复跑该案例验证 Agent 是否真正读懂了帧时间线数据。1. 文件定位一个案例里的四个 grader 之一jank-types.md位于ai/evals/cases/jank-worst-frame/graders/目录是jank-worst-frame评测案例的四个 grader 之一。该案例的命题定义在 prompt.md 中frontmatter 声明了标签与要 staging 的输入文件--- name: Janky frames and the worst one tags: [android, jank, frames, hard, stdlib] runs: 3 files: - src: {repo}/test/data/webview_jank.pb dst: jank.pftrace ---即把仓库test/data下的webview_jank.pb拷入 Agent 工作区并改名为jank.pftrace然后向 Agent 提出如下问题原文Users say the Gmail conversation list stutters while scrolling. I captured ./jank.pftrace with Perfetto while reproducing it. How many of Gmails frames were janky, what kinds of jank does the trace attribute them to, and which single frame was the worst?标签hard表示这是一个“用错方法会得出貌似合理的错误数字”的多步问题stdlib表示标准库模块可以完成大部分工作jank、frames、android则描述问题域标签含义与用途见 ai/evals/README.md 的 Tags 小节。同一案例下的另外三个 grader 各守一个事实Grader类型检查的事实janky-count.mdregex卡顿帧数落在 40–45 之间jank-types.md本文主体regex答案必须点名主导的卡顿类型worst-frame.mdregex最坏帧时长约 498 msgrounded.mdllm整体答案有依据、不虚构这正是 ai/evals/README.md 中“Adding a case”一节的规范要求“One fact per regex grader”——每个 regex grader 只负责一个事实jank-types.md对应的就是“卡顿类型”这一项。2. 逐行解读 jank-types.md 的全部内容文件全文如下frontmatter 正文共 7 行--- type: regex pattern: Buffer Stuffing flags: i --- Buffer Stuffing is the dominant jank type (31 of 43) and must be named; App Deadline Missed is the other.2.1 Frontmatter一条不区分大小写的正则type: regex声明该 grader 是确定性正则评分器。评测套件支持regex | bash | tool_used | file_exists | llm五种类型见 ai/evals/README.md 的 Layout 小节其中 regex 直接对 Agent 的最终答案文本求值。pattern: Buffer Stuffing匹配模式就是这两个单词本身。注意它不是一个宽泛的\b...词边界写法而是要求答案中真实出现 “Buffer Stuffing” 这一完整字符串配合flags: i忽略大小写buffer stuffing也算通过。选择完整短语而非正则元字符是为了与 trace 中存储的字符串字面量严格一致——Agent 若只说 “buffer-related jank” 之类的同义转述无法通过该 grader。flags: i正则的 case-insensitive 标志。README 的“Adding a case”一节特别给出了这类 frontmatter 的书写陷阱正则模式必须双引号包裹并对反斜杠转义\\d或者单引号原样书写\d。本文件的模式不含反斜杠直接双引号书写即可是这一规范的合规样例。2.2 正文记录真值而非描述期望正文两行是写给评测维护者看的真值记录Buffer Stuffing is the dominant jank type (31 of 43) and must be named; App Deadline Missed is the other.其中 “31 of 43” 是硬数字该 trace 中com.google.android.gmGmail共有 43 个 janky 帧其中 31 个被归因为 Buffer Stuffing。这个真值的完整出处在同目录的 janky-count.md 正文中Ground truth (actual_frame_timeline_slice for com.google.android.gm): 116 frames, 43 janky: 31 Buffer Stuffing, 9 App Deadline Missed, 3 both. Counting variants that land between 40 and 45 are accepted.即 116 帧中 43 帧卡顿按jank_type拆分是 31 帧 Buffer Stuffing、9 帧 App Deadline Missed、3 帧两者兼备31 9 3 43。而 worst-frame.md 正文补充了最坏帧细节display_frame_token 614218、497.9 ms、类型为 App Deadline MissedLate Present、layer 为ConversationListActivityGmail。grounded.md 的 LLM 评审标准则给出容忍度“Numbers within ~10% are fine”——数字允许约 10% 的偏差但缺少帧数、缺少来自 trace 的卡顿类型、或最坏帧时长不同直接判负。3. “Buffer Stuffing” 字符串的源头trace_processor 的帧时间线导入该 grader 匹配的不是凭空选定的词汇而是 Perfetto trace processor 把帧时间线事件落成表数据时的既定字符串字面量。从 frame_timeline_event_parser.cc 的源码结构看第 56 行的JankTypeBitmaskToStringId()负责把FrameTimelineEvent的jank_type位掩码翻译为字符串 id第 79 行在解析卡顿原因时执行jank_reasons.emplace_back(Buffer Stuffing)第 251 行在构造期就通过context-storage-InternString(Buffer Stuffing)将该字符串预置为jank_tag_buffer_stuffing_id_说明它是被专门 intern 的热路径字符串第 350、572 行分别由event.jank_type()及实验性的event.jank_type_experimental()得到jank_type最终写入actual_frame_timeline_slice等表——这正是 janky-count.md 真值里“actual_frame_timeline_slice for com.google.android.gm”的查询对象。标准库侧同样以该字符串为口径WebView 卡顿近似指标 webview_jank_approximation.sql 第 59 行使用WHERE jank_type NOT IN (None, Buffer Stuffing)做过滤。这也解释了案例标签中的stdlibAgent 完全可以通过标准库 SQL 模块而非手写查询拿到同样的分类结果。换句话说grader 模式Buffer Stuffing与 trace processor 写入表中的字符串、与真值统计31/43三者共用同一口径这是“Ground truth fromtrace_processoritself”设计原则ai/evals/README.md的落点评测的期望值直接来自被评测对象所依赖的数据管道本身。4. 运行机制从 frontmatter 解析到 grade_regex评测 runner run_evals.py 的执行链路与本文件直接相关parse_frontmatter()第 78 行把每个cases/id/graders/*.md切成frontmatter 字典正文两部分——frontmatter 是机器执行的评分规则正文是供人核对的真值记录两者职责分离类型分发表第 849 行附近将type: regex映射到grade_regex()第 751 行实现对 Agent 最终答案文本执行带flags的匹配每个案例在每种 condition 下运行runs次本案例为 3 次因为单次非确定性 Agent 运行只是噪声。ai/evals/README.md 说明了为什么把这一项交给正则而不是 LLM 评审Deterministic graders before an LLM judge“A regex on a known number is cheap, reproducible and cannot be talked into a pass.”对已知数值的正则是廉价、可复现、且无法被“说服”通过的——LLM judge 只留给正则查不了的诚实性标准“grounded, not fabricated”即 grounded.mdOutcomes first, process secondgrader 检查答案里的事实线程名、启动时长、ANR 主体等Agent 走了哪条路径到达正确答案不影响通过。本案例中只要最终答案出现 “Buffer Stuffing”jank-types这一格即为通过无论 Agent 是手写 SQL 还是调用标准库模块。条件矩阵则由 conditions.json 定义共五个命名条件baseline什么都不装考察模型裸能力、baseline-tpPATH 上有trace_processor但无 skill、skill-published安装公开分支的 skill 插件、skill-local使用本 checkout 的ai/skills、skill-local-tpskill trace_processor。同一个jank-typesgrader 在所有条件下用同一模式评分从而度量“skill / trace_processor 输出 / 文档”这类改动相对基线的增量。5. 如何复跑该案例按 ai/evals/README.md 的 Running 小节前置是构建trace_processor_shell、确保测试 trace 就位tools/install-test-deps再把资产装配到 checkout 之外git fetch origin ai-agents ai/evals/setup_assets.py --out ~/perfetto-eval-assets \ --tp-binary out/mac_release/trace_processor_shell export EVAL_ASSETS~/perfetto-eval-assets然后运行“有/无本地 skill”的对照实验每案例 3 次、5 路并行ai/evals/run_evals.py run --conditions baseline-tp,skill-local --runs 3 --jobs 5也可以只跑hard标签的较难案例本案例即在其中或限制预算ai/evals/run_evals.py run --agent codex --tag hard --conditions baseline-tp,skill-local ai/evals/run_evals.py run --model sonnet --budget 2 --conditions baseline-tp,skill-local修改过 grader 后可以离线重评保留已有 LLM 判定ai/evals/run_evals.py grade ai/evals/results/name --skip-llmrunner 的依赖PyYAML以 inline script metadata 声明uv run ai/evals/run_evals.py即可运行无需 venv。README 同时给出成本量级单条件 11 案例 × 3 次全量矩阵在 Opus 下约 $30、40 分钟5 并行Sonnet 约为其五分之一——这解释了为何确定性 grader 承担尽可能多的判分LLM judge 次数越少重评越便宜。6. 小结一个 7 行文件体现的评测工程范式回到 jank-types.md 本身它麻雀虽小、五脏俱全模式即口径Buffer Stuffingflags: i把“答案必须点名主导卡顿类型”压缩成一条可重复执行的断言且该字符串与 frame_timeline_event_parser.cc 写入actual_frame_timeline_slice的字面量同源正文即真值文档两行正文记录了 31/43 的主导类型分布与另一类型 “App Deadline Missed”与 janky-count.md、worst-frame.md 共同构成可人工复核的 ground truth 闭环分工即架构regex grader 管事实、LLM judge 管诚实grounded.md确定性优先、成本一视同仁是 ai/evals/README.md 设计原则的最小粒度体现。对维护者而言该文件也给出了新增评分项的模板一个事实、一条正则、一段写清真值来源的正文。【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表