数据在链接里
为什么 URL 是放数据的正确位置——以及数据放进去之后会变什么。
每个仪表盘里的每张图,都是某样东西的照片。这张照片对人很方便,对机器很不友好。 二十年来我们一直在假装不是这样:做出这张图,把它托管起来,然后——当模型或者脚本 需要那些数字的时候——请人 去把数字从图上读下来。
读图这一步,就是准确性开始死掉的地方。
图是瓶颈
图是一张表的有损压缩,做出来是为了给一双眼睛看。表还在——在数据库里,在一次查询里, 在一个 CSV 里——但那个「在」不是你贴出来的那个东西。你贴出来的是一个指针: 它指向一个页面,页面渲染出一张图,图还得再被读一遍。
如果是机器去读,那机器就是在做 OCR,而且是在一个它从来没被设计来解析的版式上做, 而且是「大概」地做。接着有人写下一句「Q3 营收 4.2M」,没有人发现那根柱子其实是 4.18, 标签被四舍五入了。
问题不在模型。问题在格式。图片没有地方放精度、单位、注意事项,也没有地方放第二条序列。
这件事网页在文档上早就解决了
URL 可以是一份文档。不是文档的指针——就是文档本身。
https://example.com/notes.md 就是那份笔记;服务器只是替我们保管并递交给别人的地方。
这是个早已确定、无聊、几十年前就有的想法,也正因为如此,网页才能被引用、被 diff、
被缓存、被争论。
我们把它扩展到数据上却慢了。图是最后一个地方:一份东西的实质,被故意放在它的地址之外。
数据在链接里之后,什么变了
把数据放进链接,几件事会同时发生。
链接本身就是上下文。 不是指向上下文的指针——就是上下文。
agent 拿到 datalink.ac/d?type=pie&labels=TS,Py,Go&values=4821,2312,980,
手里就有数字、标签和问题本身。没有抓取,没有截图,没有一段描述图片内容的话。
链接可以 diff。 两条只差一个参数的链接,字符上就只差一个字符。
values=4821 → values=5120 是一个可以被审阅的改动。
一张图表的 PR,其实就是一条 URL 的 PR。这正是图表该出现在 issue、release note
和 PR 里的原因——不是因为那样好看,而是因为在那里它可以被改。
链接变成一次函数调用。 参数进,图出。没有会话,没有登录,没有仪表盘状态。 agent 想要同一份数据的另一个切面,就改写参数;人想探索,就编辑同一串字符。 谁都不需要为此学一套专门的工具。
图片不再是唯一的读法。 同一条链接可以给浏览器一份渲染好的 SVG, 给 agent 一份 JSON 规格。一个产物,两个读者,中间没有翻译步骤——所以翻译的时候什么也没丢。
让人不舒服的那部分
链接是公开的。链接会被复制、转发、缓存、记录、截图。 如果背后的数据是私密的,那么数据链接就是错的形状,再聪明也改不了。 (这件事我们单独写过——见《URL 会暴露什么》。)
但看看我们已经在怎么用 URL。我们往 issue 里贴查询串。 我们把客户标识放进工单链接。我们给仪表盘加登录,然后再为这个登录花掉真金白银。 实际上,数据早就住在 URL 里了;被抽空的不是链接本身,而是链接的内容。
接下来
数据链接是个小想法,长尾很长。今天它画图表。同一套扁平参数已经能描述结构图、 表格、日历和幻灯片——因为那些是渲染器,而渲染器是链接的细节,不是链接的属性。
接下来要写下来的,是让它成为标准而不只是约定的那些东西:渲染器必须守住的不变量, 以及 agent 可以凭什么做假设。那就是数据链接规范,它现在是草案,欢迎争论。