首页
/ A2UI Express 推理格式迭代优化实录:Pass 9「模板变量解包」编译器补丁与回滚决策全解析

A2UI Express 推理格式迭代优化实录:Pass 9「模板变量解包」编译器补丁与回滚决策全解析

2026-09-13 16:52:06作者:廉彬冶Miranda

本文围绕 a2ui 仓库 eval/iterative_format_optimizer 中一次真实的推理格式优化运行(express 策略 run_014,假设项为「Pass 9: Template variable unwrap in compiler.py」)展开,完整解读其优化报告、pytest 失败现场、补丁 diff 与回滚(Backtracked)决策依据。读完后,你将掌握 A2UI Express DSL 的编译管线结构、eval 评测流水线的指标口径(schema 准确率、质量分、token 效率上限),以及这个「假设 → 补丁 → 评测 → 决策」闭环优化器的工作方式与决策规则。

1. run_014 是什么:一次完整优化循环的归档快照

该次运行的归档目录位于:

  • report.md:优化报告主体(指标对比表、pytest 失败日志、生效中的 Git diff、失败样本明细);
  • run_meta.json:运行元数据(格式、假设、最终状态、关键指标中位数);
  • results.json:inspect_ai 评测框架导出的完整结果(含每个样本的模型输入/输出、编译产物与评分);
  • patch.diff:补丁文件(本例中为空,因为该补丁对应的变更已按优化器流程在工作区中应用/回滚)。

run_meta.json 记录了这次运行的核心信息:

{
  "format": "express",
  "hypothesis": "Pass 9: Template variable unwrap in compiler.py",
  "status": "Backtracked",
  "notes": "Pytest unit test collection failed and output tokens expanded by +13.5% (exceeding 5% limit).",
  "metrics": {
    "schema_acc": 1.0,
    "quality_acc": 1.0,
    "code_tokens_median": 257.0,
    "reasoning_tokens_median": 2280.5,
    "input_tokens_median": 5936.5,
    "latency_seconds_median": 12.95,
    "total_samples": 6
  }
}

两个值得注意的细节:

  1. 策略是 express 而非 atom。报告头部的 "Strategy (Format)" 一行写的是 atom,但 run_meta.json 明确记录 "format": "express",归档目录也位于 history/express/ 下。从源码结构看,这更可能是报告模板沿用自 atom 优化批次时的遗留字段;本文以 run_meta 与目录归属为准。
  2. 最终状态是 Backtracked(回滚)。尽管 schema 准确率与质量分均为 100%,但由于「pytest 单测收集失败 + 输出 token 膨胀 +13.5%(超过 5% 上限)」两个原因,该补丁被判定不予保留。这正是本次运行最有教学价值的部分——准确率全绿也不足以通过决策。

全局优化历史总表 history_summary.md 中对应的一行是:

Format Run 假设 Pytest 整体准确率 算法准确率 延迟 输入 Tok 输出 Tok 状态 备注
express 014 Pass 9: Template variable unwrap in compiler.py PASS 100.0% 100.0% 12.95s 5936 257 Backtracked Pytest unit test collection failed and output tokens expanded by +13.5% (exceeding 5% limit).

可以看到总表中的指标(12.95s、5936、257)与 run_meta 的中位数指标一致,说明归档链路是「评测 → 写 report/results/run_meta → 同步进总表」的自动化流程,同步逻辑可参考 sync_history.pyscripts/README.md

2. 报告指标表:Baseline 与 Current 的对照口径

report.md 的 Summary Table 原文如下:

Metric Baseline Current Diff
Pytest Conformance PASS FAIL -
Overall Pass Rate 0.0% 100.0% -
Algorithmic Schema Pass Rate 0.0% 100.0% -
Inference Duration (sec) 0.00s 9.15s -
Avg Input Tokens 0 0 -
Avg Output Tokens 0 0 -

解读要点:

  • Current 列是真实测量值:评测整体通过率 100.0%、算法 schema 校验通过率 100.0%、单样本推理耗时 9.15s(6 个样本的中位延迟为 12.95s,见 run_meta)。
  • Baseline 列的准确率/耗时/Token 全部为 0 值,属于基线指标缺失时的占位显示(基线一行的 Pytest 为 PASS,但其评测指标未被记入)。因此本报告没有给出 Diff 数值,读者不宜把 0.0% 当作「基线真的只有 0 分」。
  • Current 列的 Pytest Conformance 是 FAIL,这是整份报告的核心事件,下一节展开。
  • 表中的「Algorithmic Schema Pass Rate」对应算法侧(a2ui_scorer)对编译产物的 schema 校验,「Overall Pass Rate」还叠加了模型评审(measured_model_graded_qa)的语义质量评分——两者的评分器定义与打分规则详见 results.json 中的 scorers 字段。

3. pytest 收集失败现场:28 个 ImportError 与运行环境问题

报告中的 "Pytest Unit Test Failures" 一节完整保留了 pytest 输出。其结构是:collected 8 items / 28 errors,随后是 28 条收集期错误(collection errors),全部是导入失败,例如:

_ ERROR collecting agent_sdks/python/a2ui_agent/tests/elemental/test_compiler.py _
Traceback:
agent_sdks/python/a2ui_agent/tests/elemental/test_compiler.py:20: in <module>
    from a2ui.core.catalog import Catalog
E   ModuleNotFoundError: No module named 'a2ui'

失败的模块导入可归为三类:

  1. ModuleNotFoundError: No module named 'a2ui' / 'a2ui.core'——a2ui_agenta2ui_core 两个 Python 包未安装进当前解释器环境(涉及 express、elemental、parser、schema、atom 等测试目录,如 tests/express/test_compiler.py);
  2. No module named 'a2a'No module named 'google'——ADK/A2A 扩展测试缺少 a2agoogle.adk 依赖;
  3. No module named 'yaml'——conformance 测试缺少 PyYAML。

日志尾部还保留了环境线索:

warning: `VIRTUAL_ENV=/usr/local/google/home/gspencer/code/a2ui/atom_format/.venv` does not match the project environment path `.venv` and will be ignored
Using CPython 3.13.14 interpreter at: /usr/bin/python3
Creating virtual environment at: .venv
Installed 22 packages in 90ms

这说明 pytest 实际运行在一个新建的、仅安装了 22 个基础依赖包的 .venv 中(原有的 VIRTUAL_ENV 与项目环境路径不匹配而被忽略),工作树路径为 .../worktrees/opt-atom-run47。因此这 28 条错误是依赖未安装的收集期环境问题,而非被测编译器代码的逻辑回归——但按优化器的决策规则,pytest 无法通过收集就等于「Pytest Conformance = FAIL」,该运行仍会被判回滚。这一点提醒:复现该批次时,应先按 agent_sdks/python/a2ui_agent/pyproject.tomlagent_sdks/python/a2ui_core/pyproject.toml 安装 a2ui_agenta2ui_core 及其可编辑依赖,再运行 pytest。

4. 补丁本体:_compile_event 中的事件名关键字兜底解析

报告的 "Active Git Diff" 一节给出了本次运行生效的完整补丁,原文如下:

diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/atom/compiler.py b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/atom/compiler.py
index 0abbfc01..5d4e0ec2 100644
--- a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/atom/compiler.py
+++ b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/atom/compiler.py
@@ -964,7 +964,14 @@ class AtomCompiler:
         return val

     def _compile_event(self, expr: List[Any]) -> Dict[str, Any]:
-        event_name = str(expr[1]) if len(expr) > 1 else ""
+        event_name = ""
+        if len(expr) > 1 and not str(expr[1]).startswith(":"):
+            event_name = str(expr[1]).strip("`").strip("'")
+        else:
+            for idx in range(1, len(expr) - 1):
+                if str(expr[idx]) in (":name", ":action", ":event") and idx + 1 < len(expr):
+                    event_name = str(expr[idx + 1]).strip("`").strip("'")
+                    break
         context = {}
         i = 2
         pos_idx = 0

逐行拆解其意图:

  • 改动位置:S 表达式编译器的事件编译函数 _compile_event(diff 头显示为 atom 编译器路径,与第 1 节所述报告模板沿袭问题一致;归档所属批次为 express 策略)。事件编译是把模型输出的 Event(...) / S 表达式形式动作,翻译为 A2UI 协议中 {"event": {"name": ..., "context": ...}} 结构的关键一步。
  • 原逻辑:直接取表达式的第 2 个 token(expr[1])作为事件名。当模型按「位置参数」风格输出(如 (event "save_deal" ...) 或带引号/反引号的字符串)时,这行逻辑是成立的。
  • 问题场景(即假设项所称的「template variable unwrap」):当模型在事件名位置输出带命名关键字的模板/变量形式——即第 2 个 token 是 :name:action:event 这类以冒号开头的关键字——原逻辑会把 :name 这样的关键字本身误当成事件名,导致编译出的事件名错误、schema 校验或质量评分失败。
  • 新逻辑
    1. expr[1] 不以 : 开头,仍按原方式处理,并额外 strip("").strip("'")` 剥掉模型可能附带的反引号或单引号包裹;
    2. expr[1]: 开头(说明模型切换成了关键字形式),则从下标 1 开始扫描到倒数第二个 token,找到 :name / :action / :event 关键字,取其后一个 token 作为真正的事件名(同样剥引号),命中即 break

这是一个典型的「编译器侧容错归一化(compiler-side normalization)」补丁:不改 prompt、不改数据集,只让编译器多容忍一种模型输出形态。同族思路在该批次的其它运行中反复出现(例如 express 018「Pass 19: Action event handler string 自动包裹」、022「Pass 25: 组件构造器大小写不敏感匹配」),可见编译器容错是该优化器的主要抓手之一。

对照当前仓库源码可以印证事件编译的既有结构。ExpressCompiler 负责把 Express 纯文本语句词法分析、解析成 AST,再编译为 A2UI v1.0 JSON 消息(文件头 docstring 明确说明「Tokenizes, lexes, and parses A2UI Express plain-text statements into a clean AST, compiling it directly into standard A2UI v1.0 JSON messages」,文法定义见 Express.g4,DSL 设计文档见 a2ui_express.md)。其中对 Event 保留签名的处理(compiler.py#L749-L773)会将第一个位置参数编译为事件名、第二个参数编译为 context map,最终返回 {"event": {"name": ..., "context": ...}}——补丁所修改的 _compile_event 正是这条链路上针对 S 表达式风格事件的入口。

5. 评测结果:6 个样本全部通过,Express DSL 到 v1.0 JSON 的完整链路

results.json 显示该运行基于 a2ui_v1_0_eval 任务(对应数据集 core_v1_0.yaml,任务定义见 tasks.py,执行入口 main.py),使用模型 google/gemini-3.5-flash,共 6 个样本(id 1–6),评测计划(plan)由三个 solver 串联:

  1. a2ui_eval/format_system_promptformat_name: express, version: 1.0)——为样本注入 Express 格式的系统提示(含输出契约、文法规则、组件/函数位置签名、示例);
  2. a2ui_eval/measured_generate——执行模型生成并计量 token 与延迟;
  3. a2ui_eval/compile_format_payload——把模型输出的 Express DSL 编译成标准 A2UI JSON(这一步调用 ExpressCompiler,也是补丁生效的位置)。

随后由两个评分器打分,两者 accuracy 均为 1.0

  • a2ui_scorer(version 1.0):算法侧校验,确认编译产物是合法 A2UI payload;
  • measured_model_graded_qa(评审模型同为 google/gemini-3.5-flash):按 C(正确)/ P(部分)/ I(错误)三级对产物做语义评审,评审指令中明确了若干宽松口径(组件顺序、ID 命名、标签近似文本、可选属性、数据绑定路径结构差异等均可接受)。

报告末尾 "Failure Details (Count: 0 / 6)" 与「All tests passed successfully!」即对应这一结果。模型用量统计(6 样本合计):输入 33,420 tokens、输出 3,743 tokens、推理(reasoning)tokens 18,659、缓存命中 12,210——可见该评测把推理 token 单独计量,这与 run_meta 中 reasoning_tokens_median: 2280.5 的口径一致。

以样本 1(dogBreedGenerator)为例,可以看到完整的「自然语言 → Express DSL → v1.0 JSON」链路。模型按系统提示中的输出契约,产出用 <a2ui> / </a2ui> 哨兵标签包裹的 Express DSL(节选):

<a2ui>
$/breeds = [ {url: "https://.../photo-1543466835..."}, {url: "https://.../photo-1552053831..."} ]
$/generator/name = ""
$/generator/legs = "4"
root = Column([breedCard, generatorCard], "start", "stretch")
breedCard = Card(breedContainer)
breedList = List(_template($/breeds, breedTemplate), "horizontal", "center")
breedTemplate = Image($url, "Breed Thumbnail", "cover", "smallFeature")
genButton = Button(genButtonLabel, "primary", Event("generate_dog", {name: $/generator/name, legs: $/generator/legs, skills: $/generator/skills}))
</a2ui>

这正覆盖了补丁所关心的语法面:_template(...) 动态列表模板、$/... 数据模型绝对路径与 $url 相对绑定、以及带 context map 的 Event(...) 动作。编译后的 v1.0 JSON(节选)把上述结构翻译成标准消息:

[
  {
    "version": "v1.0",
    "createSurface": {
      "surfaceId": "main",
      "catalogId": "https://a2ui.org/specification/v1_0/catalogs/basic/catalog.json",
      "components": [
        { "id": "root", "component": "Column", "children": ["breedCard", "generatorCard"], "justify": "start", "align": "stretch" },
        { "id": "breedList", "component": "List",
          "children": { "path": "/breeds", "componentId": "breedTemplate" },
          "direction": "horizontal", "align": "center" },
        { "id": "genButton", "component": "Button", "child": "genButtonLabel", "variant": "primary",
          "action": { "event": { "name": "generate_dog",
            "context": { "name": { "path": "/generator/name" },
                         "legs": { "path": "/generator/legs" },
                         "skills": { "path": "/generator/skills" } } } } }
      ],
      "dataModel": { "breeds": [ { "url": "https://.../photo-1543466835..." } ],
                     "generator": { "name": "", "legs": "4", "skills": [], "output": "..." } }
    }
  }
]

其中 children 的模板对象 {path, componentId} 对应 DSL 里的 _template($/breeds, breedTemplate)(与 compiler.py#L730-L747_template 的编译逻辑一致:第一个参数必须是 $ 前缀的动态路径,第二个参数为模板组件 ID),action.event.context 中的每个值都是 {"path": ...} 数据绑定引用——这正是「模型只写紧凑 DSL、信封与路径结构由编译器补全」的设计价值。评审模型对该样本给出 GRADE: C,逐项核对了 surfaceId、纵向列表、犬种卡片与生成器表单的全部要素。

6. 决策复盘:为什么 100% 通过仍被判 Backtracked

把 report.md、run_meta.jsonhistory_summary.md 放在一起,run_014 的回滚由两条独立理由共同触发:

  1. Pytest 单测收集失败(第 3 节的环境级 28 个 ImportError)。无论根因是否为环境配置问题,「Pytest Conformance = FAIL」本身就是硬性不通过项;
  2. 输出 token 膨胀 +13.5%,超过 5% 上限(run_meta.notes 原文)。本批次基线输出 token 中位数为 272(见总表中 express 012/013 等相邻运行的 272/296 口径),257 看似更低,但 notes 明确以 5% 上限为判据对「膨胀」做拦截——结合总表其它行的备注可以推断,该优化器执行一套多约束决策规则:
    • Rule 1(正确性护栏):schema 准确率或质量分回退即回滚(总表中多次出现 "Reverted per Rule 1 correctness guardrail");
    • Rule 2(效率上限):代码输出 token 膨胀超 5%、推理 token 膨胀超 15% 即回滚(run_014 即因 5% 上限被拦);
    • Rule 3(综合分 S_opt 不下降):正确性与效率都保住的前提下,还要保证综合优化分不回退。

从总表中相邻运行的对比可以看到这套规则的实际效果:express 016(大小写不敏感枚举归一化)pytest 61/61 通过、输出 token 仅膨胀 +4.64%,判 Kept;express 007/009(同样的 action 绑定归一化假设)质量分虽达 100%,但输出 token 膨胀 +30.6%,判 Backtracked。run_014 属于「评测全绿、效率与单测红线未过」的典型中间态,它的归档价值正在于展示了这条约束边界。优化决策模型与评分公式的完整定义可参考 scoring_model.mdSKILL.md

7. 复现与深入阅读路径

如果你想在自己的环境复现或审计这类优化运行(只读复现,无需改动仓库):

  1. 查看归档history/express/ 下按 run_NNN_<commit>_<假设摘要>/ 组织,每个目录含 report.md / run_meta.json / results.json / patch.diff 四件套;跨批次全貌看 history_summary.md
  2. 理解评测框架:评测入口 eval/main.py、任务定义 eval/tasks.py、v1.0 数据集 eval/datasets/core_v1_0.yaml、格式策略实现 eval/a2ui_eval/strategies/format.py
  3. 理解优化器脚本optimize_format.py(优化主循环)、compare_results.py(结果对比)、sync_history.py(历史同步),工具链说明见 scripts/README.md
  4. 理解编译管线:Express 文法 specification/inference_formats/express/Express.g4、DSL 设计说明 specification/proposals/express/a2ui_express.md、编译器实现 agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/express/compiler.py(重点:ExpressCompiler 类、_templateEvent 的编译分支、错误类型定义 errors.py)。
  5. 复现 pytest:在按 a2ui_agent / a2ui_core 的 pyproject 安装依赖的环境中运行 agent_sdks/python/a2ui_agent 的测试套件,即可复现本批次中 507/61/63 等「Pytest 100% pass」口径;若看到 run_014 那样的 28 个收集期 ImportError,优先检查虚拟环境与包安装是否完整。

小结

run_014 是一份高信息密度的「负面结果」归档:补丁本身(事件名关键字兜底解析)在 6 样本评测上拿到了 100% 的 schema 准确率与质量分,但被 pytest 收集失败与 +13.5% 输出 token 膨胀两条红线拦截回滚。它完整地演示了 a2ui 推理格式优化器的工程约束——正确性是门槛、token/延迟效率是硬上限、综合分 S_opt 是最终裁判——也说明为何 history/ 目录下既保留 Kept 也保留 Backtracked 的记录:这些被回滚的假设同样是后续轮次(如 express 016/018/022 等最终 Kept 的编译器容错补丁)的参照系。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
34
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.21 K
2.81 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
945
1.86 K
docsdocs
暂无描述
Markdown
906
5.84 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
537
607
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
864
1.36 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
4.28 K
1.03 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.39 K
1.48 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
550
401
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.19 K
347