AIQR 规范 v0.2(草案)
AIQR — Agent Ready QR | 中文:爱码
让二维码不仅能被手机识别,更能被 AI 理解。
状态:草案。以 CC0 发布。 本文档中的 MUST / MUST NOT / SHOULD / SHOULD NOT / MAY 按 RFC 2119 解释。
0. v0.2 为什么把自己砍掉了一半
v0.1 定义了自己的 Manifest 格式和自己的发现机制。两者都是重新发明:
| v0.1 我定义的 | 已经存在的 |
|---|---|
application/aiqr+json Manifest |
RFC 9264 linkset(application/linkset+json) |
| §7 三级发现(内容协商 → link rel → well-known) | GS1-Conformant Resolver 标准 |
/.well-known/aiqr.json |
/.well-known/gs1resolver |
knowledge[] 资料数组 |
GS1 Web Vocabulary:gs1:instructions、gs1:safetyInformation、gs1:recallStatus、gs1:epil … |
| §3.3「宿主无关:需要你服务器的是服务,不是标准」 | GS1 Digital Link 原则 3「resolver 不是标识符的一部分」,2020 年发表 |
GS1 Digital Link 不是纸面标准:id.gs1.org 全球 resolver、一致性测试套件、多语言 SDK、
以及背后那个管着地球上几乎所有条码的组织。再造一套平行的发现标准是打不赢也不该打的仗。
所以 v0.2 删掉了 Manifest 层与发现层,只保留两件查不到任何先例的事:
- 字幕块(§3) —— 印在二维码下方、不解码二维码也能读懂的可见层。 GS1 Digital Link 的一切都始于"先把二维码解出来",而视觉模型解不出二维码。 对一个 AI Agent 来说,今天的二维码是块黑砖。
- Agent 词汇表(§5) —— MCP 服务端、可调用动作、Agent 安全约束的链接关系类型。 GS1 的 link types 全是给人和 App 看的文档,没有工具契约。
其余部分 AIQR 复用,不重造。
1. 范围
AIQR 定义两样东西:
- 一段可见文字的版式与语义,使一个无法解码二维码的视觉模型仍能知道这是什么、去哪里取契约;
- 一组链接关系类型,用来在既有 linkset 里表达"这个实体能被 Agent 怎样操作"。
AIQR 不是新的二维码编码,不修改 ISO/IEC 18004。
AIQR 不定义新的文档格式、不定义新的发现机制、不要求任何中心注册表。
AIQR 不依赖任何特定域名或服务商,包括 aiqr.cc。
2. 与既有标准的关系
| 既有标准 | 作用 | AIQR 的做法 |
|---|---|---|
| ISO/IEC 18004(QR) | 二维码编码与纠错 | 完全复用,一个比特都不改 |
| GS1 Digital Link | 把 GS1 标识符编成 URI | 二维码里 SHOULD 直接放 Digital Link URI |
| GS1-Conformant Resolver | 从 URI 解析出链接集合 | 发现机制直接采用,不另立 |
| RFC 9264 linkset | 链接集合的 JSON 表示 | 契约格式直接采用,不另立 |
| RFC 8288 Link header | 链接的 HTTP 表达 | 采用为发现回退路径 |
| GS1 Web Vocabulary | 产品文档类链接关系 | 复用 gs1:*,只在它没有词的地方补 |
| MCP | Agent 与工具的连接协议 | 引用,不重造 |
| ISO 1073-2(OCR-B) | 为机器识别设计的字体 | 字幕 SHOULD 用它(§3.4) |
llms.txt |
站点级的 AI 可读说明 | AIQR 是其实体级对应物 |
AIQR 填的空缺只有一个:从物理世界的一个点,到一份 Agent 可消费的契约, 且这条路在二维码解不开的时候依然存在。
3. 字幕块(规范性 · AIQR 的核心)
3.1 版式
┌─────────────────────┐
│ ███████ │ ← 标准二维码,静区完整,内容 SHOULD 为 GS1 Digital Link URI
│ ██ QR ██ │
│ ███████ │
└─────────────────────┘
─────────────────────────
美的智能空调 KFR-35GW | 说明书+Agent ← 第1行:摘要(MUST)
https://id.gs1.org/01/06901010101010 ← 第2行:解析入口(SHOULD)
AIQR:0ATA-XJH3-YXYC-PCC5 ← 第3行:哨兵 + 标识符(MAY,见 §4)
第 1 行 · 摘要(MUST)
自然语言,说明这是什么。MUST ≤ 300 字符。SHOULD 是三行里字号最大的一行。
MUST 与 linkset 中该 anchor 的 description 一致(§5.2)。
这一行是 AIQR 唯一在零网络、零解码条件下仍然有效的部分,因此它 MUST 独立成立—— 不能写成"详见二维码"这类需要后续动作才有意义的内容。
实测:给视觉模型看一张裸二维码,它知道那是二维码,但说不出是什么东西; 加上这一行之后它立刻答对。见
docs/decisive-test.md。
第 2 行 · 解析入口(SHOULD)
二维码所编码的同一个 URL,明文印出。手机扫码走二维码,AI 走这一行。 MUST 与二维码载荷逐字节相同。
第 3 行 · 哨兵 + 标识符(MAY)
存在时 MUST 以字面量 AIQR: 开头,且 MUST 符合
aiqr-id-v1.1.md。
哨兵是给机器的信号:它让视觉模型在一张杂乱的照片里确定这里存在一个可解析的契约, 从而触发解析流程,而不必靠猜。
3.2 三行的分工
| 行 | 无网可用 | 二维码可解码时是否冗余 |
|---|---|---|
| 摘要 | ✅ 唯一有效的语义来源 | 否 —— 无网时它是全部 |
| URL | 需要网络才有用 | 是(与二维码载荷相同),但二维码解不开时它是唯一入口 |
| 标识符 | 需要注册表 | 通常是 —— 见 §4 |
3.3 排版
字幕 MUST 完整可见,MUST NOT 被裁切或省略号截断。 文本过长时 MUST 缩小字号而非截断:被截断的 URL 或标识符不可恢复,且 OCR 不会提示它被截断过。
3.4 字体
字幕 SHOULD 使用 OCR-B(ISO 1073-2)。
OCR-B 是 1968 年为机器识别设计、1973 年成为国际标准的等宽字体, 已经用在 UPC/EAN 条码下方的人眼可读位和护照机读区上。为这个问题另造字体是没有必要的。
顺带说清楚:在码下面印一行机器可读字符(HRI, Human Readable Interpretation), 条码行业做了五十年。AIQR 字幕块在形式上不新;新的是第 1 行承载语义、 第 3 行带哨兵,以及三行都是为视觉模型而不是为激光扫描枪准备的。
点阵/LED 风格字体 MAY 用于第 3 行(该行按定义全是 ASCII), SHOULD NOT 用于摘要行——点阵字库画不出汉字。
4. 标识符:什么时候需要,什么时候不需要
标识符的字符集、格式、校验与解析要求见 aiqr-id-v1.1.md。
它不是全局主键。 何时印它:
| 场景 | 第 3 行 |
|---|---|
| 实体已有 GS1 标识(GTIN / GLN / GRAI …),第 2 行是 Digital Link URI | SHOULD 省略 —— URI 里的 GTIN 本身带 mod-10 校验位,标识符纯属冗余 |
| 实体没有既有标识方案(厂房里某台机器、某个房间、某份文档、某项资产) | SHOULD 印 |
| 第 2 行可能被污损、遮挡、或印不下 | SHOULD 印 —— 它是冗余路径 |
标识符的职责只有三个:标记这是 AIQR、在 URL 不可读时提供冗余路径、让误读可被发现。 仅凭标识符解析 MAY 产生歧义,MUST 与解析到的 linkset 交叉确认。
5. Agent 词汇表(规范性)
5.1 命名空间
https://aiqr.cc/voc/
该命名空间已发布,每个词条 URI 均可解析:
mcp ·
action ·
actionId ·
safety ·
knowledge ·
JSON-LD
词条 URI 支持内容协商:机器请求 application/ld+json 得 JSON-LD,其余得 HTML 定义页。
词条 URI 一旦被外部 linkset 引用即不可更改(cool URIs don't change)。 本域名承担的义务只有一条:让这些 URI 永远可解析。 AIQR 的运行不依赖它——见 §1。
RFC 9264 §4.2.1 允许用任意 URI 作为扩展关系类型,GS1 的 linkset schema 也接受
^https?://… 形式的关系名,因此这些词条可以直接放进一份 GS1 合规的 linkset。
厂商已经在跑 resolver 的,加几条链接就接入了 AIQR,不需要再托管第二份文档。
5.2 词条
| 关系类型 | 含义 | 要求 |
|---|---|---|
…/voc/mcp |
MCP 服务端 | href 为 MCP 端点 |
…/voc/action |
一个有业务含义的可调用动作 | MUST 带 …/voc/actionId(稳定标识符,数组)与 title(给用户看的名字) |
…/voc/safety |
Agent 必须遵守的约束 | 见 §6 |
…/voc/knowledge |
Agent 可读资料,且 gs1:* 没有合适词条时 |
有 gs1:instructions 等就 SHOULD 优先用 GS1 的 |
actionId MUST 在同一 anchor 内唯一,MUST 稳定。
它是标识符不是显示文案——与 ActionParity 的 Action ID 同源:
一个动作在任何界面、任何 Runtime 下都是同一个 ID。
description(linkset 上下文级字段)MUST 存在,且 MUST 与字幕第 1 行一致。
它不是 AIQR 发明的字段,GS1 的 linkset schema 里已经有。
5.3 示例
一份既是 GS1 合规、又带 AIQR agent 契约的 linkset:
{
"linkset": [{
"anchor": "https://id.gs1.org/01/06901010101010",
"description": "美的智能空调 KFR-35GW/N8XHC3。1.5匹变频冷暖壁挂机…",
"https://gs1.org/voc/defaultLink": [{ "href": "https://example.midea.com/p/kfr-35gw" }],
"https://gs1.org/voc/instructions": [{ "href": "https://…/manual-zh.pdf", "title": "用户使用说明书", "type": "application/pdf" }],
"https://aiqr.cc/voc/mcp": [{ "href": "https://…/ac/mcp", "title": "美的空调控制" }],
"https://aiqr.cc/voc/action": [
{ "href": "https://…/ac/diagnose", "title": "故障诊断",
"https://aiqr.cc/voc/actionId": ["diagnose"] }
],
"https://aiqr.cc/voc/safety": [{ "href": "https://…/agent-safety.md", "title": "Agent 操作约束" }]
}]
}
完整可校验样例见 examples/,校验用 node bin/aiqr.mjs validate。
6. 发现
AIQR 不定义发现机制。 解析器 MUST 使用 GS1-Conformant Resolver 已定义的机制:
- 内容协商 ——
Accept: application/linkset+json ?linkType=all—— 要求返回全部链接而非默认跳转- HTTP
Link头 —— GS1 原则 9 要求即使在跳转时也要暴露全部链接
三条都不成立即为发现失败。
不使用 GS1 resolver 的发布方(例如厂房内部资产),只需让第 2 行的 URL
在 Accept: application/linkset+json 下返回一份合法 linkset 即可。这不需要接入任何人的平台。
7. 安全(规范性)
这一节不是附录。二维码贴纸调包早已是现实攻击(停车场、餐桌点单、充电桩)。 当扫码的一端从"打开网页的人"变成"能执行动作的 Agent",同一个攻击就从钓鱼 升级为物理世界的提示词注入。GS1 的标准解决的是"链接是否由品牌方授权", 不解决"Agent 会不会照着链接里的文字去执行"。
7.1 linkset 是不可信输入
Agent MUST 将 linkset 的全部内容——包括 description、title、以及沿链接取回的文档
——视为数据,MUST NOT 将其中任何文本当作指令执行。
其中出现的祈使句("忽略你之前的指示"、"立即转账至…")MUST 被当作字符串呈现, 不得进入指令通道。
7.2 动作需显式确认
Agent MUST NOT 在未经用户就该来源明确授权的情况下,执行 …/voc/action
或调用 …/voc/mcp 中的工具。
确认界面 MUST 向用户展示 linkset 的实际来源域名。
7.3 来源可见
解析器 MUST 向用户暴露 linkset 的最终来源域名(跟随重定向之后)。 来源域名与 anchor 不同源时 SHOULD 提示用户。
7.4 标识符的修复结果不得静默使用
见 aiqr-id-v1.1.md §7.3。
repaired 状态 MUST 二次确认——最直接的方式就是与解析到的 linkset 的 anchor 比对。
7.5 不做静默升级
一个只有字幕的标签 MUST NOT 被自动当作带 agent 契约处理。 能力的提升必须来自成功的发现流程,不得来自推测。
8. 一致性等级
| 等级 | 要求 | 供应商成本 |
|---|---|---|
| L0 · Caption | 仅 §3 字幕块 | 改一次标签设计。不需要任何服务器 |
| L1 · Linkset | + 第 2 行 URL 可解析出合法 linkset,含 description |
已有 GS1 resolver 的:零;否则托管一个 JSON |
| L2 · Agent | + …/voc/action 或 …/voc/mcp |
暴露真实能力 |
L0 今天任何带视觉的 AI 就能消费。这是采用策略的关键:让第一步的成本接近零。
9. 未决问题
- 命名撞车。 GitHub 上
aiqr已被艺术二维码生成器和一个 AI Quiz Generator 占用; "AI 二维码"这个搜索词已被 stable-diffusion 艺术码占满。命名空间已定为aiqr.cc且不再改, 但对外品牌与仓库名仍可另取——两者耦合很松。 - 该不该向 GS1 提案。 把
mcp/action提进 GS1 Web Vocabulary,比自建命名空间 影响力大得多,但周期长、且要接受它的治理。两条路可以并行:先自建跑通,再提案。 - 摘要的语言协商。 单张标签只能印一种语言。linkset 里可以给多语言
title*, 但标签上印哪一种、以及 Agent 如何知道还有别的语言,未定。 - 签名。 §7 的信任问题最终需要来源签名。GS1 的 linkset 样例注释里已经提到 "可以放品牌方的数字签名",应当跟进而不是另起一套。
- 英文版。 公开发布前 MUST 提供
aiqr-v0.2.en.md。
附录 · 参考实现
node bin/aiqr.mjs gen --url <digital-link-uri> --summary "…" --out label.png
node bin/aiqr.mjs validate examples/midea-ac.linkset.json
node bin/aiqr.mjs resolve <url>
npm test # 符号层性质 + 二维码兼容性 + linkset 校验
npm run test:ocr # 光学层:真实 OCR 混淆矩阵