首页
/ A2UI Atom 推理格式迭代优化实战:run_014「精简目录签名描述」实验记录与源码解读

A2UI Atom 推理格式迭代优化实战:run_014「精简目录签名描述」实验记录与源码解读

2026-09-13 11:27:50作者:农烁颖Land

本文以 A2UI 仓库中一次真实的推理格式优化实验记录(atom 格式 run_014)为主体,完整解读该次优化假设、评测指标、Git Diff 内容及其在 Agent SDK 源码中的落点,并结合优化器技能文档中的评分模型与决策规则,说明为什么一次"快验 100% 通过"的改动最终仍被判定回退,以及如何复现同类实验。

1. 背景:A2UI 的推理格式迭代优化体系

A2UI 是一个让 Agent 以结构化 UI 描述驱动渲染的协议项目。为了让 LLM 生成 UI 载荷时更省 token、更稳定,Agent SDK(Python)内置了多种"推理格式"(inference formats),位于 inference_formats 目录下:

  • direct_json:直接输出 JSON 消息的基线格式;
  • experimental/atomexperimental/expressexperimental/elemental:三种实验性紧凑格式,其中本文聚焦的 Atom 采用 S-Expression(括号表达式)记法,由 format.pyparser.pycompiler.pyprompt_generator.py 等模块组成:提示词生成器负责把组件目录(catalog)的 JSON Schema 编译成 LLM 可读的"签名文本",编译器则把 LLM 输出的 S-Expression 编译回标准 A2UI 消息。

围绕这些格式,仓库内置了一套名为 Inference Format Optimizer 的技能与脚本(SKILL.md),其核心是一套 6 步迭代工作流:

  1. 分析历史:读取 eval/iterative_format_optimizer/history/<format>/history_summary.md,避免重复已被回退的假设;
  2. 实现假设:修改 compiler.pyprompt_generator.pyparser.py
  3. 跑单元一致性测试(pytest);
  4. 执行基准评测python scripts/optimize_format.py --format <format>
  5. 按决策规则评估:必须通过 pytest 且不劣于基线准确率,代码输出 token 膨胀不得超过 +5%,否则回退(git reset --hard HEAD);
  6. 归档与同步--archive 归档运行产物,并用 sync_history.py 更新历史索引。

每次运行的产物(report.mdpatch.diffrun_meta.json)按 run_XXX_<commit短哈希>_<假设slug> 命名归档到 eval/iterative_format_optimizer/history/ 下,本文主角即是 atom/run_014 目录 中的 report.md

2. run_014 实验假设与评测结果

2.1 实验元信息

该次运行使用 atom 格式(策略/格式字段为 atom),评测模型为 google/gemini-3.5-flash,预算档位为 Unbounded。其假设(hypothesis)原文(见 run_meta.json)为:

Streamline catalog component signature property detail descriptions to minimize input token overhead and reasoning search space. (精简目录组件签名中的属性详情描述,以最小化输入 token 开销与推理搜索空间。)

换句话说,本次实验的靶点是 prompt_generator.py 中"组件目录签名"的生成逻辑:签名文本里每个属性会附带一段来自 Schema 的 description 描述,假设是把这些描述删掉、只保留枚举约束,可以显著降低 LLM 的输入 token,且不会伤害准确率。

2.2 快验报告摘要表(report.md 原文数据)

report.md 记录了本次运行的"快验"(Fast Validation)结果,共 6 个样本:

Metric Baseline Current Diff
Pytest Conformance PASS PASS -
Overall Pass Rate 83.3% 100.0% +16.7%
Algorithmic Schema Pass Rate 100.0% 100.0% 0.0%
Inference Duration (sec) 8.45s 8.78s +3.9%
Avg Input Tokens 0 0 -
Avg Output Tokens 0 0 -

报告尾部明确写着 Failure Details (Count: 0 / 6):"All tests passed successfully!"。需要注意两个细节:

  • 快验模式下 Input/Output Tokens 记为 0,即该模式不采集 token 计数(token 对比在完整评测中才产生,见第 5 节);
  • 这里的 Baseline(83.3%)是优化器工作树当前基线的快验通过率,与 unbounded 基线全量数据(255 样本)不是同一口径。

2.3 report.md 中的 "Active Git Diff"

报告核心是一份 Git Diff。结合 patch.diffhistory_summary.md 对照可以确认:report.md 里的 "Active Git Diff" 是优化器工作树相对上一个已提交基线的累计差异(包含此前多个 run 对 ATOM_RULES 提示词规则的修改),而本次 run 自己的补丁是 patch.diff。下面分两部分解读。

(1)累计差异:ATOM_RULES 提示词规则的精简

该 diff 作用于 prompt_generator.py 中的 ATOM_RULES 常量(Atom 格式的系统提示词核心),主要变化有五处:

  1. 哨兵标签指令去重:原来三行重复强调"必须用 <a2ui> / </a2ui> 包裹、禁止输出裸 JSON",合并为一行:
    You MUST surround the entire A2UI Atom block with the sentinel tags `<a2ui>` and `</a2ui>`. Do NOT output raw JSON messages.
    
  2. 数据模型填充规则扩展(Rule 6):从仅支持 (data $/path1 "val1" $/path2 123) 的扁平路径-值序列,扩展为支持 S-Expression 地图写法 (data $/map_path (:key1 "val1" :key2 "val2"))
  3. 动作事件规则收紧(Rule 8):新增"带 action 属性的交互控件必须提供 action 表达式",并给出示例 (ActionComponent :child (ChildComponent "Text") :action (Event "click_action"))
  4. 示例对齐(Example 1/2)::onPress 改为与规则一致的 :action 属性名;数据模型示例从内嵌 JSON 数组 (data $/items [{"id": 1, ...}]) 改为纯 S-Expression 项映射 (data $/items [(:id 1 :name "Item 1")]),消除"JSON 混入 S-Expression"的歧义;
  5. 规则 11 改名为 "Strict Catalog Adherence & Conciseness":删去"严格遵循签名中属性名与枚举值"的表述,替换为 "Output minimal properties required to satisfy the user request"(只输出满足请求所需的最少属性)。

这些改动当前已在仓库源码中生效:可以对照 prompt_generator.py 第 25-84 行 的现文,例如第 26 行的合并后哨兵指令、第 51-52 行的 Rule 6、第 76 行的 S-Expression 数据项示例。

(2)本次 run 自身的补丁(patch.diff):签名描述精简

patch.diff 才是 run_014 假设的直接实现,改动集中在 AtomPromptGenerator 的两个方法 _generate_component_signatures_generate_function_signatures 中生成"属性详情行"的代码块。改动前的逻辑:

if p_desc or enum_vals:
    p_line_parts = []
    if p_desc:
        p_line_parts.append(p_desc)
    if enum_vals:
        enum_vals_str = ", ".join([f"'{v}'" for v in enum_vals])
        p_line_parts.append(f"Must be one of: {enum_vals_str}")
    prop_details.append(f"  - :{p}: {' '.join(p_line_parts)}")

改动后:

if enum_vals:
    enum_vals_str = ", ".join([f"'{v}'" for v in enum_vals])
    prop_details.append(f"  - :{p}: Must be one of: {enum_vals_str}")

即:属性签名详情行只保留枚举约束(Must be one of: ...),彻底丢弃来自 JSON Schema 的属性 description 文本。组件与函数签名两处做了对称修改。

3. 源码级解读:目录签名是如何生成的

理解上述补丁的影响,需要先弄清签名文本的生成机制。在 prompt_generator.py 中:

  • AtomPromptGenerator.__init__ 通过 CatalogSchemaHelper(来自 a2ui.schema.schema_helper,导入失败时回退到 express 格式的同名助手类)封装当前 catalog,形成 schema_helper
  • generate()第 172-217 行)组装最终系统提示词:角色描述 + ## Instructions:(含 ATOM_RULES 与工作流说明)+ ## Component Catalog Signatures: + ## Function Signatures:
  • _generate_component_signatures第 219-262 行)遍历目录中每个组件,为每个属性生成位置参数标签 :property(可选属性带 ? 后缀),跳过 id/component 保留字段,随后拼接组件描述与属性详情行,产出形如:
    - (ColumnName :title :orientation?)
      - 组件描述...
        - :orientation: <属性 description> Must be one of: 'horizontal', 'vertical'
    

枚举值的抽取由 _get_schema_enum 递归完成:除直接读取 enum 键外,还会深入 oneOf/anyOf 子 Schema 寻找枚举定义。

这套机制决定了 run_014 补丁的实质:属性 description 是 LLM 理解"这个属性用来做什么"的主要语义载体。枚举值属于硬约束(选错即违反 Schema,算法校验可拦截),而自由文本属性的取值语义(例如某个 variant 属性在何种场景该选哪个字符串)完全依赖描述文本。这正是后文决策反转的根源。

4. 评分模型与决策规则:为什么 100% 快验仍会回退

优化器不是"看着通过率涨了就收工",其决策模型定义在 scoring_model.md 中,分两层:

正确性护栏(不可妥协,任一不满足必须回退)

  1. pytest 单元一致性测试必须 100% 通过;
  2. 算法 Schema 通过率(SchemaAcc,输出载荷对目标 catalog JSON Schema 的校验)必须不低于基线;
  3. 模型评分质量分(QualityScore,LLM 判分的语义意图匹配)必须不低于基线。

效率回退上限(任一超线必须回退)

  • 代码输出 Token 增长 > +5%;
  • 流式(非推理)输出时延增长 > +10%;
  • 推理 Token 增长 > +15%。

综合得分 SoptS_{\text{opt}}

S_opt = 0.50·SchemaAcc + 0.30·QualityScore
      - 0.15·(CodeTok/BaseCodeTok)
      - 0.05·(ReasonTok/BaseReasonTok)
      - 0.03·(InputTok/BaseInputTok)

决策规则:SoptS_{\text{opt}}(当前) > SoptS_{\text{opt}}(基线) 则保留(KEEP),否则回退(REVERT)。

5. run_014 的最终结局:按 Rule 1 回退(Backtracked)

run_014 是"快验通过、全量评测翻车"的典型案例。run_meta.json 中记录的最终状态为 Backtracked,其 notes 字段原文为:

Input Tokens reduced by -46.3% (2,389 vs 4,447) and Reasoning Tokens by -32.4% (3,212 vs 4,753), but Schema Acc and Quality Score regressed from 100.0% to 75.0% (-25.0%) due to missing property context. Reverted per Rule 1.

history_summary.md 中 run 014 一行的记录与之完全一致(Status: Backtracked,"Reverted per Rule 1")。两个层面的信息:

  • 假设前半部分被验证:删除属性描述后,输入 token 从 4,447 降到 2,389(-46.3%),推理 token 从 4,753 降到 3,212(-32.4%),token 效率收益远超预期;
  • 正确性护栏被击穿:Schema 通过率与质量分双双从 100% 跌到 75%(-25%)——正如第 3 节分析的,失去属性描述这一"语义上下文"后,LLM 在多属性组件上选错属性/取值,触发 Rule 1(正确性护栏),必须回退。

与之形成对照的是同批"精简签名"路线的兄弟实验(均见 history_summary.md):run 015"仅对单属性基元组件截断描述"因推理 token 超 15% 上限被回退;run 019"保留枚举、只删单字符串属性描述"因 LLM 歧义导致推理 token 与时延上升被回退;run 025"紧凑签名参数类型提示"、run 028"签名提示 + 输出简洁指令"、run 030"布尔/枚举参数紧凑格式"也都被回退,其中 run 030 的教训记录最为直白——"为短枚举/布尔省略描述行,在多属性组件中制造了搜索空间歧义",SoptS_{\text{opt}} 从 +0.600 跌至 +0.435。反复实验共同指向一条经验:目录属性描述是高价值的"上下文信息",激进删减虽省 token,却会破坏 LLM 的属性选择正确性;有效的省 token 方向更多落在编译器侧的无损 AST 简化上(如被保留的 run 016"无损 AST 简化:自动省略标准容器节点的默认 key 包装")。

6. 基线参照与复现方式

6.1 全量基线数据

Atom 格式的 unbounded 全量基线归档在 baselines/atom/unbounded_run_meta.json,关键数字(模型 google/gemini-3.5-flash,temperature 0.0,数据集 core_v1_0,5 轮 × 51 样本 = 255 样本):

  • Schema 准确率约 93.73%,质量分约 83.14%;
  • 输入 token 中位数 4,443,推理 token 中位数 4,316;
  • 样本级明细覆盖 deleteSurfaceloginFormproductGalleryflightBookermcpAppProxy 等 51 个用例,可看到复杂用例(如 animalKingdomExplorerclientSideValidation)的 token 与时延显著高于简单用例。

数据集定义位于 core_v1_0.yaml

6.2 复现命令

优化器技能的 CLI 速查表见 SKILL.md,脚本均位于 eval/iterative_format_optimizer/skills/inference-format-optimizer/scripts/

动作 命令
跑快验评测 python scripts/optimize_format.py --format atom
跑完整评测套件 python scripts/optimize_format.py --format atom --full
测试解析/编译 python scripts/optimize_format.py --format atom --compile "(Card (Text \"Hi\"))"
与基线对比 python scripts/compare_results.py --baseline eval/iterative_format_optimizer/baselines/atom/unbounded_run_meta.json <运行日志目录>
归档运行产物 python scripts/optimize_format.py --format atom --archive --hypothesis "..." --status KEEP
同步多 worktree 历史 python scripts/sync_history.py

若要阅读 run_014 的完整材料,从归档目录 atom/run_014_e89102c_streamline_catalog_signature_descriptions 入手即可:report.md(快验报告与累计 diff)、patch.diff(本次假设补丁)、run_meta.json(假设、最终状态与 notes)三件套,配合 history_summary.md 的总索引,可以完整还原"假设 → 实现 → 快验 → 全量评测 → 回退"的一次标准迭代闭环。

7. 小结

run_014 这份看似简短的优化报告,实际上浓缩了 A2UI 推理格式工程化的完整方法论:以 report.md 的指标表与 Git Diff 为"做了什么"的证据,以 prompt_generator.py 的签名生成源码为"为什么这样做"的解释,以 scoring_model.md 的护栏与 SoptS_{\text{opt}} 公式为"该不该保留"的裁决依据。它的结论对任何做 LLM 提示词/格式优化的人都具有参考价值:token 收益必须让位于正确性护栏;目录描述这类"看似可删"的上下文,往往是 LLM 属性选择能力的隐性依赖

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

项目优选

收起
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