A2UI Atom 推理格式迭代优化实战:run_014「精简目录签名描述」实验记录与源码解读
本文以 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/atom、experimental/express、experimental/elemental:三种实验性紧凑格式,其中本文聚焦的 Atom 采用 S-Expression(括号表达式)记法,由 format.py、parser.py、compiler.py、prompt_generator.py 等模块组成:提示词生成器负责把组件目录(catalog)的 JSON Schema 编译成 LLM 可读的"签名文本",编译器则把 LLM 输出的 S-Expression 编译回标准 A2UI 消息。
围绕这些格式,仓库内置了一套名为 Inference Format Optimizer 的技能与脚本(SKILL.md),其核心是一套 6 步迭代工作流:
- 分析历史:读取
eval/iterative_format_optimizer/history/<format>/与 history_summary.md,避免重复已被回退的假设; - 实现假设:修改
compiler.py、prompt_generator.py或parser.py; - 跑单元一致性测试(pytest);
- 执行基准评测:
python scripts/optimize_format.py --format <format>; - 按决策规则评估:必须通过 pytest 且不劣于基线准确率,代码输出 token 膨胀不得超过 +5%,否则回退(
git reset --hard HEAD); - 归档与同步:
--archive归档运行产物,并用 sync_history.py 更新历史索引。
每次运行的产物(report.md、patch.diff、run_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.diff 与 history_summary.md 对照可以确认:report.md 里的 "Active Git Diff" 是优化器工作树相对上一个已提交基线的累计差异(包含此前多个 run 对 ATOM_RULES 提示词规则的修改),而本次 run 自己的补丁是 patch.diff。下面分两部分解读。
(1)累计差异:ATOM_RULES 提示词规则的精简
该 diff 作用于 prompt_generator.py 中的 ATOM_RULES 常量(Atom 格式的系统提示词核心),主要变化有五处:
- 哨兵标签指令去重:原来三行重复强调"必须用
<a2ui>/</a2ui>包裹、禁止输出裸 JSON",合并为一行:You MUST surround the entire A2UI Atom block with the sentinel tags `<a2ui>` and `</a2ui>`. Do NOT output raw JSON messages. - 数据模型填充规则扩展(Rule 6):从仅支持
(data $/path1 "val1" $/path2 123)的扁平路径-值序列,扩展为支持 S-Expression 地图写法(data $/map_path (:key1 "val1" :key2 "val2")); - 动作事件规则收紧(Rule 8):新增"带 action 属性的交互控件必须提供 action 表达式",并给出示例
(ActionComponent :child (ChildComponent "Text") :action (Event "click_action")); - 示例对齐(Example 1/2):
:onPress改为与规则一致的:action属性名;数据模型示例从内嵌 JSON 数组(data $/items [{"id": 1, ...}])改为纯 S-Expression 项映射(data $/items [(:id 1 :name "Item 1")]),消除"JSON 混入 S-Expression"的歧义; - 规则 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 中,分两层:
正确性护栏(不可妥协,任一不满足必须回退)
- pytest 单元一致性测试必须 100% 通过;
- 算法 Schema 通过率(
SchemaAcc,输出载荷对目标 catalog JSON Schema 的校验)必须不低于基线; - 模型评分质量分(
QualityScore,LLM 判分的语义意图匹配)必须不低于基线。
效率回退上限(任一超线必须回退)
- 代码输出 Token 增长 > +5%;
- 流式(非推理)输出时延增长 > +10%;
- 推理 Token 增长 > +15%。
综合得分
S_opt = 0.50·SchemaAcc + 0.30·QualityScore
- 0.15·(CodeTok/BaseCodeTok)
- 0.05·(ReasonTok/BaseReasonTok)
- 0.03·(InputTok/BaseInputTok)
决策规则:(当前) > (基线) 则保留(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 的教训记录最为直白——"为短枚举/布尔省略描述行,在多属性组件中制造了搜索空间歧义", 从 +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;
- 样本级明细覆盖
deleteSurface、loginForm、productGallery、flightBooker、mcpAppProxy等 51 个用例,可看到复杂用例(如animalKingdomExplorer、clientSideValidation)的 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 的护栏与 公式为"该不该保留"的裁决依据。它的结论对任何做 LLM 提示词/格式优化的人都具有参考价值:token 收益必须让位于正确性护栏;目录描述这类"看似可删"的上下文,往往是 LLM 属性选择能力的隐性依赖。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust4.24 K638- DDeepSeek-V4.1-FlashDeepSeek-V4.1-Flash 是一个多模态混合专家(MoE)模型,拥有 5520 亿骨干参数,并支持最多一百万 token 的上下文长度。该模型原生支持图像和文本输入,并以自回归方式生成文本Python670
SlideSCIPPT插件,支持素材库、AI助手、一键添加图片标题,复制粘贴位置、一键图片对齐、一键插入Markdown(加粗、超链接等行内样式、代码块、LaTeX等块级样式)、便捷导出图片!C#230
hello-agents📚 《从零开始构建智能体》——从零开始的智能体原理与实践教程Python52874
new-apiAI模型聚合管理中转分发系统,一个应用管理您的所有AI模型,支持将多种大模型转为统一格式调用,支持OpenAI、Claude、Gemini等格式,可供个人或者企业内部管理与分发渠道使用。🍥 A Unified AI Model Management & Distribution System. Aggregate all your LLMs into one app and access them via an OpenAI-compatible API, with native support for Claude (Messages) and Gemini formats.Go22545
JeecgBoot🔥企业级低代码平台集成了AI应用平台,帮助企业快速实现低代码开发和构建AI应用!前后端分离架构 SpringBoot,SpringCloud、Mybatis,Ant Design4、 Vue3.0、TS+vite!强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE,显著的提高效率,又不失灵活~Java36351