直接回答
YAML 是具有标量、序列、映射、tag、anchor 和 alias 的序列化语言。文档并不只是由字符串键和值组成的树:tag 会参与类型解析,mapping key 可以是任意节点,alias 可以引用之前 anchor 的节点,表示图还可能含共享或循环引用。应用若只接受一个窄配置对象,应声明允许的语言子集,而不应依赖解析器碰巧采用的默认值。 先固定 Android 实际使用的 parser artifact 和版本,再记录其 YAML 规范支持、schema、加载选项与输出模型。库可能提供组合后的节点图、通用集合或自定义 typed object,这些边界并不相同。YAML 1.2.2 规定语言语义,但不选择应用 schema 或 Java constructor。配置导入通常应先解析为数据节点或原始集合,再按应用自有 schema 校验后才构造领域对象。 自定义 tag 必须有明确 allowlist。tag 为节点类型和语义提供标注,并不等于允许输入文件命名任意 Java class。一些 YAML API 提供把 tag 映射到 Java 对象的 constructor,另一些安全接口只构造常见值或要求显式 tag handler。未经验证,不能用通用 object constructor 解析用户文件。如果确实需要一种自定义 tag,应将其绑定到窄 constructor,检查准确节点类型和字段;未知 tag 直接拒绝,不能按类名动态加载。 重复 key 会造成解释歧义。YAML 规范要求 mapping key 按节点相等规则唯一,但两个写法不同的标量是否相等可能取决于 tag resolution 和 canonical form。解析后放入 Java Map 时也可能被合并,即使 parser 曾接受或转换它们。尽可能配置重复键检测,并使用同一 parser/schema 测试重复的 plain key、quoted key、alias 和解析成相同类型标量的不同写法。对设置文件而言,只允许 string key 往往比支持任意 YAML 节点 key 更容易验证。 alias 是图引用,不是文本宏。单独计算 alias 数不能衡量组合或遍历整张图的全部成本;重复引用可能使下游工作变多,自引用还会形成普通递归校验未预期的循环。如果所选 engine 暴露 alias 和 code-point 上限,应配置它们;同时独立限制字节数、嵌套深度、节点数、集合大小、遍历访问数与耗时。校验时要保留对象图身份或明确拒绝循环,不能用重复字符串替换来展开 alias。 YAML schema resolution 会改变常见标量的类型。同一未加引号的拼写可能按 parser 选用的 schema/version 变为 string、Boolean、number 或 null。YAML 1.1 与 1.2 行为不可互换,库默认 schema 也未必与生成方一致。记录来源节点与解析类型,校验期望的 scalar 类型,并测试 `on`、`yes`、`001`、`0x10`、`null` 及其加引号形式。应用还不知道生成方表达的是文本还是类型值之前,不要先做归一化。 建立绑定准确 engine 的测试矩阵:普通嵌套数据、未知 global/local tag、看似类名的 tag、必要时一个窄的允许自定义 tag、用不同写法重复的 key、非字符串 key、共享 alias、大量 alias、循环引用、深层集合、超长标量、多文档、非法 UTF-8 和不支持 directive。比较构造前节点事件/图信息和构造后的结果,确认被拒绝的数据不会部分写入设置。合成输入不得包含真实 token、prompt、账户 ID 或私有模型路径。 安全导入流程分为字节与编码、YAML parse/composition、tag 和 graph policy、应用 schema、语义规则、重要变更的用户复核、最后持久化。语法有效的图仍可能包含未知设置、越界值或不应改变权限和模型来源的字段。应先校验临时不可变对象,全部通过后再原子应用。源文件保持不变,日志按文档/节点位置报告错误,不回显私有字段值。 不能仅因为文档提到 JVM 或某 Java 版本,就宣称 SnakeYAML Engine 兼容 Android。必须用项目 Android 工具链、min/target API 范围和实际包约束编译与运行准确依赖,再将其列为实现选项。即使构造方式安全,也不证明所得配置可以安全执行。本文只说明 YAML 导入方法,不表示 Cove 接收 YAML 或使用特定 parser。
共享 YAML 预设包含意外 tag 和 alias 图
用户选择同事分享的 YAML 预设。它有嵌套 anchor、同一 mapping key 分别以普通和引号标量写了两次,还有一个看似运行时 Java 类名的自定义 tag。接收应用其实只需要少量推理偏好设置。
决策
以固定的 data-only 配置解析,按所选 schema 检查重复 key,拒绝未知 tag 与循环,再校验允许的字符串键和值范围,最后原子更新设置。
预期结果
导入要么应用一份经过审查的不可变设置对象,要么给出含位置的输入不支持结果;不调用任意 constructor,也不留下部分偏好变更。
需要收集的证据
只有将以下证据与同一模型文件和测试运行关联起来,结论才可复核:
- ANDROID-YAML-CONSTRUCTION-2026-10:YAML mapping 键按节点等价规则应唯一;tag 参与节点类型解析;alias 引用图节点,可形成共享或循环结构,constructor 与 alias 限制取决于具体 parser。
- ANDROID-PRIVACY-01:Android 权限、数据访问、存储与用户控制仍由应用负责。
- PRIVACY-01:端侧推理不证明应用没有其他网络请求;YAML tag 构造是独立的输入边界。
隐私声明需要数据清单和流量证据;“本地模型”标签本身不是证明。
实施流程
- 固定 parser、YAML 版本和 schema. 记录准确依赖坐标、解析版本、YAML directive 行为、schema、编码策略和输出表示。对项目实际 Android build 和 API 做兼容验证,不能假定通用 JVM 说明适用。
- 选择只构造数据的策略. 优先解析节点或原始集合,再自行校验。禁用任意 class construction,仅允许经过审查的 tag handler;拒绝未知本地/全局 tag 与不支持的文档 directive。
- 规定 key、重复键和标量规则. 在可行时将应用 mapping 限制为预期字符串键。按所选 schema 解析 tag 和 canonical scalar 后测试 duplicate key;区分 quoted text 与类型标量,对运行时表示有歧义的值明确拒绝。
- 限制并校验 alias 图. 设置准确版本 parser 暴露的 alias/code-point 上限,并另设字节、节点、深度、集合、遍历和耗时限制。按明确图策略检测或拒绝循环/共享引用;未经访问计数不得递归展开 alias。
- 完整校验后才应用. 先创建临时不可变设置对象,校验允许字段和语义范围,必要时让用户复核重要变更,再原子提交。用合成不可信输入测试解析错误、取消以及失败后无部分偏好写入。
让每个阶段的状态都可观察。失败信息应指出阶段、模型、运行时和恢复动作,同时避免记录用户私密内容。
验收标准
- 记录准确 parser、版本、YAML schema、编码策略、Android 兼容证据与构造表示。
- 未知/自定义 tag 不得指定任意 class;每个允许 tag 都有窄的节点类型和字段校验。
- 实际 schema 下的重复键、非字符串键、别名和不同标量写法都有确定结果。
- alias 数、图访问、深度、字节数、节点/集合大小和耗时由已验证 parser 控制项或应用校验设限;循环有明确结果。
- 导入先校验临时状态;parse、schema 或语义验证失败时不部分修改偏好。
决策对照表
| 维度 | 选择或证据 | 解读方式 |
|---|---|---|
| YAML 语法与组合 | 按声明版本解析为节点图。 | 语法有效并不决定应用允许的 tag、键类型、资源预算或领域 schema。 |
| 安全/数据型构造 | 构造原始值或检查节点,再校验字段。 | 在准确 API 按文档配置时,可避免输入 tag 选择任意应用类。 |
| 自定义 tag allowlist | 为一个明确支持的 tag 注册窄构造器。 | 只增加该 tag 的指定含义;未知 tag 仍拒绝,不隐含按类名分派。 |
| Alias 与图遍历 | 按明确限制保留引用身份或拒绝循环。 | Alias 是图引用,不是无成本文本替换;下游展开工作可能超过 parser 的 alias 计数。 |
| 通用 Java object constructor | 未经精确构造规则审查,不用于不可信文件。 | 部分 API 会根据 tag 构造类型;安全行为取决于具体 library 与版本。 |
需要避免的失败模式
- 把 YAML 解析成功当成仅有字符串键/值、无 tag 或无对象图。
- 用通用 Java 对象构造器解析不可信 tag,或未定义 duplicate key 和非字符串 key 的结果。
- 将 alias 展开为文本来估算工作量,遗漏共享引用、循环与下游遍历成本。
- 仅凭 SnakeYAML Engine 的 JVM 说明宣称 Android 可用。
还要避免静默回退、版本未固定、缺少取消处理,以及把不同配置的结果混在一起下结论。失败运行也应与成功记录一并保存。
最小复现记录
| 层级 | 记录内容 |
|---|---|
| 设备 | 厂商、型号、芯片、内存档位、操作系统版本 |
| 软件 | 应用版本和 Git 提交号 |
| 模型 | 系列、变体、版本、格式、文件长度、摘要、量化方式 |
| 运行时 | 名称、版本、请求后端及实际后端证据 |
| 工作负载 | 样例版本、输入摘要、提示词摘要、输出策略 |
| 结果 | 完成、失败、取消、回退及保护隐私的诊断信息 |
发布检查表
- ☐ 主要搜索问题已回答,且没有未经支持的数字。
- ☐ 所有模型文件和运行时版本均已固定。
- ☐ 代表性任务和失败处理策略均有说明。
- ☐ 生命周期、取消、清理和回退均已测试。
- ☐ 用户内容与网络边界均有说明。
- ☐ 结论只适用于被记录的配置。
- ☐ 新增测试结果时链接到原始方法或证据。
来源与相关证据
- Android privacy and security
- YAML Language Development Team:YAML 1.2.2 规范
- SnakeYAML Engine:项目 README 与构造模型
- SnakeYAML Engine 2.10:LoadSettingsBuilder API
中文部署与排错专题见。奇连 AI 端侧专题。
常见问题
YAML 解析有效就代表只有无害的 map 和 list 吗?
不是。YAML 还包含 tag、任意 mapping key 节点、anchor、alias 和图引用。语法通过不能证明应用 schema、资源开销或构造对象的安全性。
能否用通用 YAML constructor 读取用户选中的文件?
先核实准确 library 和版本的行为。一些 constructor 会实例化带 tag 的 Java 类。优先使用 data-only 节点或原始集合,为自定义 tag 建 allowlist,并拒绝按类名动态分派。
YAML alias 是否只是可以提前展开的文本快捷方式?
不是。Alias 指向表示图中的节点,可能共享身份或形成循环。要限制图遍历并检测循环;简单文本展开会改变语义并增加工作量。
SnakeYAML Engine 文档能证明它兼容 Android 吗?
不能。JVM/版本说明不等于 Android 编译和运行成功。声明可用于 Android app 之前,应通过目标工具链和 API 范围解析并编译确切 artifact。