shadcn/ui 这一个月往 changelog 里塞的东西,我翻完就一个感觉:它的准星不是对着人了。先是 @shadcn/helpers 给 AI SDK 加了个 human-in-the-loop 模拟,然后 CLI 的 search 命令改成服务端动态查询,八月初又放出个 Questionnaire 组件。单看每一条都像常规迭代,合在一起就不是了。
human-in-the-loop 这个词,我第一次在 changelog 里看到的时候愣了一下。一个组件库的辅助包,操心的居然是"脚本化对话可以暂停,等真人输入或审批,批完再继续流式输出"——这不是平台方该管的事吗。想明白之后才觉得,这功能有它真正的用户:不是坐在编辑器里写页面的人,是配置了一批 agent 去改他们项目、但又不敢让 agent 全自动跑完整个流程的人。
而且你注意那个措辞,"模拟"两个字实诚得很。早几年 human-in-the-loop 是个安全叙事,意思是"AI 不能全自动,得有人把关";现在它变成一个产品功能了。人在这个 loop 里不是一个设计原则,是一个 API 调用——可以被暂停、被等待、被批准,然后再继续。人对这个功能的需求,就是当一个审批节点。
CLI 那个动态搜索也是同一个方向。查询参数直接转发给 registry,不用把整个目录下载下来,选择启用,静态 registry 不受影响——描述写得很克制。但想想谁最需要这个:写代码的人要找组件,文档站上敲两下键盘就完事了。agent 跑在终端里,每下载一次目录就烧一次 token 和时间。这个功能是在给谁省 token,不用我多说。
然后是 base 那摊事。七月份默认组件基础从 Radix 换成了 Base UI,React Aria 也升成头等选项,用户可以在三家中间挑,--base aria 这种参数都配好了。官方说法自然是"选择自由,现有项目仍然受支持"。这剧本,眼熟——去年六月那一轮 radix-ui 的折腾,背后也是同一套话术:兼容、可迁移、老用户不用动。一年之后,默认值直接换人。
得说句公道话,Base UI 做默认不全是给 agent 铺路。它的样式方案和可定制性确实比 Radix 干净,我身边真有人换过去之后删了不少样板代码。但把这几件事放一块看:选项从一家变三家、CLI 开始给 agent 省 token、helpers 里出现审批节点——组件的底层是哪一家,对最终用户来说,判断优先级低得很。既然都无所谓,为什么要在 changelog 里专门写一段"您可以选择"?因为真正要选的人不是用户,是那些想把 shadcn/ui 写进代码生成模板的 agent 生态。跟 agent 说"我们适配了三家底层",比跟人说"我们换了默认值"有吸引力得多。当然,"现有项目仍然受支持"这种话也是要说给老用户听的,就是保质期有多长,我心里打了个折。
Questionnaire 这个组件,倒想岔开说两句。多步骤问题流程,做成一个组件,支持三套底座、八种视觉风格。单看挺奇怪的——流程这个东西,不是组件能包圆的,每个产品的问题逻辑都不一样。但如果你是让 agent 去"引导用户填完一个流程",你就巴不得有个标准骨架,不用每次都让模型从零拼。这个组件真正服务的是哪类开发者,答案写在功能描述里了。
我自己的项目里还躺着一堆 Radix 底的旧组件,每次都说"不着急迁",changelog 只管一页页往前翻。所谓"现有项目仍然受支持",大致意思就是:你可以停在原地,但更新都在往前走。我是它用了好几年的用户,有时候翻完更新日志会短暂恍惚一下,我到底是它的用户,还是它顺手维持的遗产用户。倒不是说它要砍人——但一个库的注意力是有限的,方向往哪偏,不用看 roadmap,看 changelog 里谁的名字出现得多就知道了。
这里立个 flag:再过一年回头看,shadcn/ui 的文档导航里大概率会出一个一级的 AI/agent 入口;Radix 的表述也会从"默认"变成"兼容",再变成"legacy adapter"。到时候回看今天那句"现有项目仍然受支持",意思其实早就在这里了。这不是唱衰,是给同行提个醒:它做给 agent 的东西,比做给你的上心。