无障碍功能

在 issue #232 中有人提出了两个问题,本页面将对它们进行解答:

  1. 此处对于残障支持有哪些选项,最佳实践又是什么?
  2. 有哪些选项可以将智能体的问答强制转化为遵循 DMN 逻辑并能服务于多种交互模态的引导式提问?

事实证明,这是从两个不同角度提出的同一个问题,这也是它们共享同一个页面的原因。具体实现的技能为 interaction-modality。

  1. 1. 本文针对的失败模式
  2. 2. 残障支持的选项——实际上摆在桌面上的方案
    1. 2.1 有限的手部功能 / 灵活性
    2. 2.2 低视力
    3. 2.3 音频 / 语音
    4. 2.4 认知负荷与平实语言
    5. 2.5 明确命名的最佳实践,以便进行核对
    6. 2.6 当前已实现的内容
    7. 2.7 尚未完成的内容
  3. 3. 将智能体问答强制转化为引导式提问
    1. 3.1 看起来合二为一的两件事
    2. 3.2 由此获得的四个特性
    3. 3.3 各种选项及其代价
    4. 3.4 明言限制
  4. 另请参阅

1. 本文针对的失败模式

如果智能体以无法使用的方式提出了一个好问题,那就等同于什么都没问。

其常见的表现形式为:一段冗长而开放的提示——“请向我描述您心中的 folio、您期望的内容类型以及您希望如何组织它”——发送给了一位打字缓慢且痛苦的用户。收到的回复非常简短。智能体将简短的回复理解为参与度不高,于是又抛出了另一个开放式问题。在这次交互中,没有人做错任何明显的事情,但对话已经在走向失败。

本仓库的拥有者手部功能极其有限,因此这种情况在这里并非假设。但无论对任何人而言,这一规则都具有普遍意义:

问题的代价是由回答者承担的。 在设计问题时,应当让成本最低的回答依然是一个完整的回答。

对于几乎所有人来说,可供选择的选项都比开放式提问更好,并且对于更愿意直接打字的人也不会带来任何额外成本。如果将其视为一种特殊照顾(accommodation)而非默认做法,就会导致它最终只有在有人不得不提出要求后才会被采用。

2. 残障支持的选项——实际上摆在桌面上的方案

四个独立的维度。一个人可能同时处于多个维度,且它们都不是医学诊断——它们是关于界面的选择。

2.1 有限的手部功能 / 灵活性

这是对智能体行为改变最大的维度,也是最经常被简化为“把按钮做大点”的维度。

应当做原因
每个问题都是带编号的选择题打字是代价高昂的动作
四个或更少的选项超过四个则拆分问题
一个推荐选项,置于首位并标明不想做决策的人可以直接选第一项并且不会出错
说明如果不作回应会发生什么,然后照做沉默绝不能阻碍工作的进行
批量处理决策,使一个回答涵盖多项内容每次往返交互都要耗费按键成本
通告耗时较长的工作;不要为此请求许可确认提示是一种隐形负担
自由文本始终可用,但绝非必填选项列表是保底,而不是上限

在渲染输出中:WCAG 2.2 SC 2.5.8 目标尺寸(最小值)(Target Size (Minimum))——24 × 24 CSS 像素——以及 2.5.7 拖动动作(Dragging Movements):任何可拖动的元素都需要提供非拖动的替代操作。

2.2 低视力

大号字体、货真价实的对比度、绝不单凭颜色传递信息、较短的行长以及较窄的表格——宽表格在 200% 缩放下难以阅读,在屏幕阅读器中体验更糟。ASCII 图表同样无法幸免;请使用带有真实替代文本(alt text)的真实图像。

判定准则:1.4.4 调整文本大小(Resize text,在 200% 缩放下无损)、1.4.3 对比度(最小值)(Contrast (Minimum))、1.4.1 颜色的使用(Use of Colour)、1.4.10 重新排列(Reflow)、2.4.7 焦点可见(Focus Visible)。

2.3 音频 / 语音

朗读起来清晰流畅的回答:正文中不夹杂代码围栏(code fence)、没有表格、不说“参见上图”、标识符在初次使用时逐字拼写或明确展开、每句话表达一个要点,且每次只提一个问题。包含四个选项的列表适合口述朗读;而包含四个列的表格则不行。

2.4 认知负荷与平实语言

更短的句子、在初次使用时展开术语行话、没有嵌套从句,以及可预测的操作顺序。“四个选项”的限制实际上正是源自这里——W3C 的 COGA 指南与 WCAG 3.1——而这对于将英语作为第二语言的读者来说也正是恰当的默认设定,对于世卫组织(WHO)SMART 指南而言,大多数受众正是此类读者。

2.5 明确命名的最佳实践,以便进行核对

不是空谈“遵循无障碍指南”,而是具体指出特定标准规范文档,以便这里的声明可以被验证而不是仅凭信任:

标准涵盖范围适用于此处的原因
WCAG 2.2 Level AA渲染输出——文档站点、查看器、生成的 PDF所有其他内容参考的基线
WCAG 2.2 的新成功准则(SC) — 2.5.7、2.5.8、3.3.7拖动动作、目标尺寸、冗余输入3.3.7 改变了智能体的设计:不要让用户重复输入相同的信息
W3C COGA认知与学习障碍见上文 §2.4
EN 301 549欧盟公共采购在指南落地的场景中使 WCAG AA 成为法律要求
Section 508美国联邦采购在美国同理
ATAG 2.0制作内容的工具通常被忽略的一项。 folio-assistant 是一种创作工具:Part A 是工具本身具备可用性,Part B 是工具协助作者产出具备无障碍特性的输出物

ATAG Part B 值得重点关注,因为这是内容平台能够唯独提供的部分:在已发布的 folio 中检查替代文本的存在性、标题层级顺序、表格表头和语言标记,这些是 QA 全面检查(QA sweep)可以承担的,而无论怎样让编辑器本身无障碍都无法替代它们。

2.6 当前已实现的内容

位置
面向智能体的偏好设置,已提交,在会话启动时读取interaction/interaction.json,由 scripts/session-start-coord-sweep.sh 呈现
智能体在提问时遵循的规则interaction-modality
本站点上面向读者的控制项侧边栏标头中的齿轮图标——更大字号、更高对比度、带下划线的链接、减少动效
无需询问即可遵循减少动效偏好prefers-reduced-motion 媒体查询,并作为面板默认值的种子

这两处偏好设置存储是刻意分开的。 interaction/interaction.json 已提交至版本控制,面向智能体,且关乎对话交互。而站点控制项则是针对每位查看者的 localStorage,绝不离开浏览器,且关乎阅读体验。非作者的读者选择大号字体,绝不能悄悄重置或更改智能体与作者沟通交流的方式。

2.7 尚未完成的内容

公开说明而非含糊暗示,因为半吊子宣称的无障碍功能比根本没有实现还要糟糕:

  • QA 全面检查中尚无 ATAG Part B 检查。 目前还没有机制验证已发布的 folio 是否具备替代文本、正确的标题顺序或表格表头。
  • 未对生成的 PDF 进行审计。 文档渲染路径通过 weasyprint/prince/wkhtmltopdf 进行,尚未对带标签的 PDF(tagged-PDF)输出进行检查。
  • 未进行屏幕阅读器测试。 站点控制项是按照准则构建的,但尚未用 NVDA、JAWS 或 VoiceOver 进行实际测试。符合规格不等于经过验证。
  • 音频模态仅作了描述,尚未实现。 规则已被记录;但尚未接入任何语音通道。

3. 将智能体问答强制转化为引导式提问

第二个问题。其答案在于关注点分离,而这种分离正是整个设计的核心。

3.1 看起来合二为一的两件事

接下来问什么是一个决策。输入是迄今为止已知的事实;输出是下一个问题的 ID,或者在已知足够信息时输出 none。它归属于 DMN 表,可由流程所有者进行审阅,并且对每个用户都是相同的。

如何呈现该问题则是模态。在聊天中是一个带编号的列表;在音频中是逐一朗读的备选选项;在网页上是大号字体的单选按钮。决策表对这一切一无所知。

 facts ──▶ [ next-question.dmn ] ──▶ question id ──▶ renderer(profile) ──▶ user
   ▲                                                                        │
   └──────────────────── answer recorded as a new fact ─────────────────────┘

一种逻辑,四个界面。通过添加渲染器来增加一种模态;访谈提问流程无需改变。通过编辑表格来修改访谈提问;无需更改任何渲染器。

3.2 由此获得的四个特性

  1. 问题集合是有限且可审阅的。 你可以查阅该表格,知晓智能体可能提出的每一个问题。自由发挥的智能体无法提供这种保证,并且在面对用户之前无法对其进行预先审阅。
  2. 它是可终止的。 输出可能为 none 的表格拥有明确的停止条件。
  3. 提问变成了强制性的而非可选的。 这是 folio-intent.dmn 已经使用过的技巧:ask 是表格的一项输出结果,因此智能体无法绕过它进行路由。如果由智能体自行决定是否提问,那么在任何“表现出热心助人”的压力下,它都会倾向于决定不问。
  4. 跳过的问题是可审计的。 事实已被记录;只需重放该决策表,即可查看触发了哪条规则。

3.3 各种选项及其代价

实现此目标的四种方式,按企图心与复杂度递增排列。目前仅构建了第一种。

选项具体内容代价
A — 每个网关一个决策 (已构建)BPMN 中的每个歧义分支点都带有 cat-harness.processes:decision;表格返回分支,包括 ask没有访谈状态机——流程本身即状态。无法表达“以任意顺序询问这四个问题”
B — 单个网关后的问题集一个循环运行直至返回 none 的 next-question.dmn;回答作为事实不断累积多出一张表和一个事实存储;循环是流程自带的,因此无需执行新的机制
C — DMN 驱动的表单同一张表在站点上渲染出表单,而不仅仅是聊天对话需要事实模式(schema)以及针对每种模态的渲染器;表格本身保持不变
D — 完整的 DMN/BPMN 访谈引擎每个主题对应子流程,针对“我改变了主意”设立边界事件真正的引擎级开发工作,且必须扩充 FEEL 子集

3.4 明言限制

  • FEEL 子集很小。 src/workflow/decision-table.ts 实现了相等性、比较以及多选一(one-of)。范围(ranges)、not() 和函数调用会被直接拒绝,而不是悄悄产生错误求值——一个返回了错误答案且与页面上的表不符的决策表,比直接抛出异常的表更糟糕。
  • 开放式问题不是决策。 “这篇论文是关于什么的?”并不属于决策表,强行将其塞入表中只会带来更差的访谈体验。
  • 对话不是向导(wizard)。 用户必须始终能够说出表格未曾预料的内容。这正是“详细告诉我(tell me more)”选项的作用所在,它绝非可有可无的装饰。
  • 引导并不意味着审讯。 能够获得的最大无障碍收益,恰恰是那个你无需提出的问题——智能体从文件系统中读取的每一个事实,都让提问减少了一个。这种收益是隐形的、默默无闻的,但却比任何样式表都更为巨大。

另请参阅


folio-assistant — code under the Apache License 2.0, documentation under CC BY 3.0. Generated schema and API references are rebuilt from source on every push to main.

deployed dev