XunbuOS Podcast:Shopify 工程团队的 AI 基础设施、测试稳定性与性能优化实践
今天的动态来自 Shopify Engineering 博客的多篇文章,聚焦于 AI Agent 基础设施、移动端测试框架重建、UI 扩展性能优化,以及编程语言工具链的实践。核心主题围绕如何在生产环境中持续改进 AI 系统、如何构建可靠的测试体系,以及如何通过架构调整优化性能。
Gisting:压缩 LLM Agent 上下文以提升吞吐量并降低成本
4:1 压缩比的上下文蒸馏
Gisting 将长系统提示词压缩为一组可学习的 token,在保留预测质量的同时显著降低推理成本。Shopify 将 Sidekick GraphQL agent 的系统提示词从约 6,000 token 压缩到约 1,500 个 gist token,压缩比 4:1。
实现方式:通过知识蒸馏学习特殊 token 的嵌入,冻结模型权重,仅训练 gist 嵌入。推理时将完整提示词替换为 gist token 即可,无需自定义 attention mask 或额外编码器。
负载测试数据
在 350 RPM 负载下:
- 首 token 延迟(TTFT)中位数从 438ms 降至 354ms(下降 19%)
- 端到端请求延迟中位数从 6.8s 降至 4.2s(下降约 38%)
- 吞吐量从 20.2 QPS 提升至 23.4 QPS(提升 16%)
- 生产工作负载中 GPU 减少了 14%
与前缀缓存的叠加效应
Gisting 与前缀缓存的优化效果并非互斥,两者叠加使用。前缀缓存无法消除解码成本——每个生成的 token 都要关注序列中的每一个键。Gisting 降低了注意力计算和 KV 缓存读取的成本,在批量大小增大时对吞吐量的影响尤为显著。
Autoresearch 找到最优超参数
Shopify 将 autoresearch 循环指向训练器,自动提出方案、训练、评估并重复。三个关键优化:
- 初始化:用系统提示词分块的均值初始化 gist 嵌入,而非随机噪声,初始损失降低了 7 倍
- 压缩比:4:1 是该领域复杂度的最优比例
- 数据数量与多样性:策划庞大且多样的数据集弥合剩余差距
如何将移动端端到端测试稳定性提升至 98%
旧架构的问题
Shopify 移动应用通过 WebdriverIO 在 Appium 上运行 E2E 测试,使用 React Native Test ID 定位元素。问题在于测试经常因屏幕加载慢一秒而失败,“元素未找到”错误频发。更严重的是,测试在断言错误的东西——断言组件树中存在节点,而非商家真正能看到或使用的体验。
构建器风格测试 API
团队围绕 Appium 构建了一个有主见的封装层:
- 每个步骤都带有断言:不能在没有声明后续屏幕内容的情况下点击或输入
- 可复用步骤片段:
logIntoApp等命名序列可被任何测试引用 - 逃生舱口以
UNSAFE_为前缀:规避护栏的选项被刻意命名以劝阻使用 - 可读性足以让 AI 代理编写测试:API 表面小、语法可预测
计算机视觉替代 Test ID
每个步骤截取屏幕截图,像商家一样在视觉上查找元素。文本识别由 PaddleOCR 处理,OpenCV 将截图与 Polaris 设计系统的 SVG 进行匹配。Test ID 仅作为后备方案,需通过 UNSAFE_testID 显式选择。
稳定性数据
新 API 成为阻塞性 CI 的数周后,测试稳定性达到 98%(旧 API 为 50%)。剩余的失败主要来自偶发网络故障和模拟器启动失败。新测试在进入阻塞性套件前需在专门流水线多次运行,失败率超过阈值即被拒绝。
Sidekick 的持续学习循环
从失败中学习的飞轮
前沿模型不会自行从生产环境学习,但每次失败都是关于产品的宝贵知识。Shopify 构建了持续学习循环,将生产经验压缩到模型权重的连续空间中,同时将服务成本削减 96%。
质量定义作为奖励信号
评分标准(rubric)将产品需求转化为评分标准:完整性、执行、响应质量和安全性。两位最佳标注者盲目标记 25 个随机样本,使用 Cohen's kappa 衡量一致性。每个分数背后的推理过程是校准算法的金矿。
校准评判者
使用 DSPy 和基于反思的优化器(GEPA、Agentic Context Engineering)校准评判者。评判者需通过回溯测试:能恢复已知 A/B 测试的胜负方向吗?运行有针对性的降级测试,故意使行为变差并确认标准做出反应。
自愈管道与强化学习
- 挖掘生产流量中的难负样本:评判者评低分且暴露模型薄弱环节的对话
- 前沿推理模型对失败进行批判性分析,仲裁者合并为修复指令并注入用户回合前
- 重放对话,评判者评分,通过的轨迹成为强化学习数据
- SFT 蒸馏完整轨迹(包括推理过程),GRPO 使用评判者作为奖励信号
- 管道每日运行,全参数微调与 GRPO 交替进行
成本与性能数据
- 服务成本从约 2700 万美元/年降至接近 100 万美元/年(削减 96%)
- Gisting 将系统提示词从约 6,000 token 压缩到约 1,500 token
- TTFT 下降约 19%,端到端延迟下降约 38%
- 相同 GPU 上每秒请求数增加约 16%,GPU 需求减少约 14%
构建一个比模型更持久的 Agentic 框架
Dispatch 框架的九阶段工作流
Shopify 应用安全团队构建了 Dispatch,一个轻量级 Ruby 客户端,将智能体扫描的复杂性从扫描编写者处抽象出来:
- 测试引导:自动发现测试命令并验证套件可运行
- 架构文档化:生成数据模型、API、授权模式等共享上下文
- 文件编目:建立相关文件的扁平清单
- 分区:按领域分组,每个分区控制在上下文窗口的 20%-30% token 量
- 狩猎:并行部署狩猎智能体,支持跨仓库搜索
- 验证:使用不同模型运行验证器,对抗性审查降低误报
- 后处理:去重、严重性评分
- 报告:整合为人类可读输出
- 修复:创建分支编写 PR 描述
关键成果
超过 80 个应用完成全量扫描,包括 Shopify Core(全球最大的 Rails 单体仓库之一)。过去六周内数千次扫描,产生 300 多个发现,保守估计价值超过 40 万美元的 bug bounty 等价回报。
成本方面,全量应用扫描约 50-300 美元,增量 diff 扫描仅需 5-50 美元。
核心经验:编码严格的发现准则
最初尝试的"安全通才"多智能体工作流产生了大量不可用的理论性发现。结论是:必须在智能体中编码严格的发现准则,专门的漏洞类别智能体比通才型更可靠。
升级 Checkout Blocks 应用至 Polaris Web Components
传输体积缩减 40%-85%
Checkout Blocks 的五个高流量结账扩展完成了从 React + Remote UI 到 Preact + remote-dom + Polaris web components 的迁移:
| 扩展 | 传输体积缩减 |
|---|---|
| payment-icons | -84.4% |
| static-content | -54.1% |
| custom-field | -44.6% |
| dynamic-content | -45.2% |
| line-item-actions | -40.5% |
扩展加载时间(ELT)的 P50 降低 8%,P90 降低 7%。
64KB 硬性限制的挑战
2026-01 remote-dom CLI 对每个扩展包强制执行 64KB gzip 硬性限制。旧扩展体积超过限制两倍。关键削减项:
- 移除 react-reconciler(约 89KB):切换到 Preact 后免费获得
- 替换 liquidjs(约 73KB):自研极简 Liquid 解析器 "droplet"(gzip 后 13KB vs 22KB),用 42,000 行生产对等语料验证
- 替换 dayjs(约 12KB):小型内部日期工具
- 保留 markdown-to-jsx(约 15KB):通过 pnpm workspace catalog 将 React 别名到 Preact
过程中修复的 Bug
- ID 碰撞:
useId()生成确定性 ID 导致同一扩展两个实例生成相同 ID,引发模态框错乱。这是唯一一次生产回滚,当天回滚次日修复上线 - 文本对齐:Polaris web components 移除了
textAlign属性,需在 ui-extensions 上重新暴露textAlignment - s-checkbox label 插槽:重构为接受字符串或 HTMLElement,支持带内联链接的条款模式
经验总结
- 硬性包体积限制虽有挑战,但迫使团队做出此前一直推迟的决策
- 指标是真正的回滚信号:纪律性的逐扩展指标加谨慎的每日发布
- 用生产数据验证而非合成用例
- AI 擅长机械性工作:agent skill 处理重复性转换,将团队时间解放给需要判断力的决策
Shopify Hack Days:为音乐产品页面构建音频播放器
原生 Audio 媒体类型的平台验证
13 人团队在第 39 届 Hack Days 中探索了为何音乐人不在 Shopify 销售数字音乐。"音乐与录音"产品在过去一年创造了超过 10 亿美元的 GMV。
团队在三天内构建了原生 Audio 媒体类型(五个 PR 跨 Core、Admin API、admin-web 和 storefront),一个完整的发行管理应用,六个由实时音频驱动的 GLSL 着色器,同步歌词生成,以及带地理定位的巡演日期板块。
架构:metaobjects 作为数据层
发布项目是 metaobject,曲目列表是 JSON metafield,音频文件、可视化配置、歌词是产品变体上的 metafields。具有 storefront: PUBLIC_READ 访问权限的 metafields 可通过 Liquid 自动用于主题扩展。
关键架构决策是全局音频单例:一个单例 audio 元素注入页面主体,带有停靠的迷你播放器,导航到新页面时音频不中断。
Catalog API:聚类数十亿商品
精确率优先策略
聚类将相关变体和产品归入统一通用产品标识符(UPI)。团队选择精确率优先:展示错误结果比结果不完整更糟糕——买家可以原谅遗漏某个变体,但绝不会原谅收到错误商品。
核心价值主张框架
关键判断问题是:买家主要购买这个产品的目的是什么?如果属性不改变答案,它就是变体;如果改变答案,它就成为产品身份的一部分。
例:蛋白粉的口味是变体(买家购买的是营养和健身效果),油漆的颜色是独立产品(买家购买的是外观)。
两阶段 LLM 管道
- Pre-chunking:ANN 检索(FAISS + HNSW)+ 稀疏平均链接(UPGMA),构建最多 200 件商品的相关 chunk
- 第一阶段:LLM 提取品牌 + 型号,相同
brand:model对归入同一 UPI - 第二阶段:异常检测——给定提议的聚类,识别不属于其中的商品。批判比创造容易得多
动态结构化输出 Schema
关键创新是 schema 按每个 chunk 动态生成:为每个产品 ID 定义必填属性,LLM 无法跳过商品。枚举约束防止幻觉——outliers 数组列出簇中所有有效产品 ID,LLM 只能输出真实存在的 ID。
数据策展:用 LLM Judge 共识训练 Sidekick 说"不"
训练数据的盲区
生产训练语料中的每个示例都是成功案例,被拒绝的案例永远不会出现在日志中。结果是模型从未学会说"不"——当被问到无法完成的查询时,模型生成返回零结果的查询而非直接拒绝。
严格共识优于松散置信度
四位前沿 LLM 作为自动化数据裁判,遵循三个原则:
- 校准:使用 Toloka 种子数据集的少样本示例校准,锚定人工标注者实际标记为"不可能"的内容
- 共识门控:四位裁判对结论和推理过程完全一致才接受标签,分歧样本被过滤而非仲裁
- 互斥分类体系:四个互斥类别——需要更多上下文、缺少能力、技能错误、模糊不清
效果数据
- 评估分数从 0.619 提升到 0.798(相对提升 28.9%)
- 拒绝准确率达 86.3%,假阳性率 4.6%
- 四个模型的预测准确率接近 90%,Cohen's kappa 均高于 0.75
数据飞轮闭环
改进后的模型上线后,其生产流量成为下一轮采样池。新模式由裁判组合标注后加入训练语料。每次微调循环都从比上一轮更大、更干净的基础上出发。
Ruvy:用 Ruby 构建 WebAssembly 模块
预初始化 VM 带来 20% 性能提升
Ruvy 构建在 ruby.wasm 之上,利用预初始化 Ruby VM 及预加载文件的性能优势。基准测试(Wasmtime 执行 _start 函数):
| 场景 | Ruby.wasm + wasi-vfs | Ruvy |
|---|---|---|
| Hello world | 56.262 ms | 44.543 ms |
| 包含文件 + 逻辑 | 56.487 ms | 44.763 ms |
Wasm 编译到本地代码的时间减少约 70%(从 1.659s 降至 446ms)。
无需运行时 WASI 参数
Ruvy 创建的模块无需提供文件路径作为 WASI 参数,兼容无法配置额外参数的边缘计算服务。
使用方式
cargo run --package=cli ruby_examples/hello_world.rb -o index.wasm
wasmtime index.wasm
# Hello world
--preload 标志将目录中每个文件包含进 Ruby VM,使定义对输入文件可用。
构建 ShopifyQL 代码编辑器
用适配器连接 ANTLR 与 CodeMirror
ShopifyQL 的语法由 ANTLR 定义,前端语言功能封装在符合 LSP 的 TypeScript 语言服务器中。CodeMirror 使用自己的 Lezer 解析引擎,不符合 LSP。团队创建了适配器,将 ANTLR token 流转换为 Lezer 可理解的缓冲区。
Token 偏移的挑战
ANTLR 的 token 偏移是相对前一个 token 的,而行号可能为负(如注释在主通道解析后处理时,指针需要向上移动)。CodeMirror 的偏移相对于文档顶部,换行符和空白会影响起始偏移。
解决方案是自定义 TokenIterator 类:接收文档并计算每行长度,跟踪当前行和字符,将 ANTLR 风格的行/字符/长度描述符转换为 CodeMirror 风格的起始/结束偏移。
额外语言功能
语言服务器的 doValidate 适配到 CodeMirror 的 linting 插件,doComplete 适配到 autocomplete 插件,doHover 适配到 requestHoverTooltips 插件。
播客全文
女:Hello 大家好,欢迎收听 XunbuOS Podcast,我是小雅。
男:大家好,我是老冯。
女:老冯,今天这期内容有点特别,我们不光聊 Shopify 的更新,还得聊聊 AI 了。最近 Shopify 那边发了好几篇技术博客,我一路看下来,脑子里就一个印象——他们的 AI 基建是真舍得下血本。
男:确实,我读完也有同感。尤其是那篇讲 Sidekick 的持续学习循环的,信息量很大。他们把一个基于前沿模型的 GraphQL Agent,通过自研的飞轮循环,服务成本直接砍了 96%。
女:96%?这个数字有点夸张了吧。
男:一点都不夸张。他们给的估算,如果这个 Agent 直接拿前沿模型来服务,每年大概要 2700 万美元。但是通过飞轮,自己微调小模型,成本直接降到接近 100 万美元。这个差距在 Shopify 的规模下,就是从"这个功能根本不敢开"到"可以放心给每个商家用"的区别。
女:这就很有意思了。但这里面有个问题,我自己做产品的时候特别关心——他们是怎么保证微调出来的模型不比原来的差的?
男:你问到点子上了。他们的做法是,先搞定一个"评判者",就是 Judge。你可以把它理解成一个裁判,用来给模型的回答打分。它不是一个简单的评分器,而是基于一套评分标准,比如完整性、执行、响应质量、安全性这些维度。这套标准不是拍脑袋定的,是产品团队反复打磨出来的。
女:那这个裁判就靠谱吗?毕竟 AI 打分这玩意儿,听起来就很虚。
男:所以他们做了一个特别实际的动作——先让两个最强的产品专家,盲标 25 个随机样本,然后算 Cohen's kappa,就是衡量专家之间意见一致性的指标。如果专家自己都经常意见不合,那说明评分标准本身是模糊的,先回去开会改标准。这个一致性的数值,就是评判者的极限了。如果一个 LLM 评判者能达到和人类专家一样的相互一致性,那就已经够用了。
女:这个思路挺严谨的。那有了裁判之后呢?接下来是怎么把生产环境的失败变成训练数据的?
男:这就要说到他们的自愈管道了。他们的 Agent 在生产环境跑的时候,会遇到很多难啃的硬骨头,比如商家问的问题很模糊、上下文不完整、或者工具调用出了 bug。这些失败的对话,在传统模式下就是报 bug,然后开个 Slack 群聊讨论,最后可能不了了之。但他们的做法是,每晚自动把这些失败的对话捞出来。
女:捞出来干嘛?直接丢给模型再学一遍?
男:没那么简单。他们会先让一组前沿推理模型去批判性地分析每一条失败,然后一个仲裁者模型把所有的批判意见合并成一条修复指令,相当于在用户的原始问题前面加一句提示,比如"你缺少了这部分上下文信息"。加完之后,把这段对话从那个点开始重放一遍,再看看裁判怎么打分。如果分过了,这条修复后的对话就成了强化学习的训练数据。
女:如果重放之后还是不行呢?
男:那就只能交给人工标注了。他们跟 Toloka 合作,让专家标注者去修正那些模型自己搞不定的案例,再喂回训练流程。所以整个流程是自动的,但人始终在关键节点上把关。
女:那训练方面呢?有了这些数据,他们是怎么训练的?
男:两个阶段。先用这些修复过的轨迹做监督微调,就是让模型模仿"标准答案"。但他们不是只学答案,而是把产生答案的整个思考过程都学下来,这叫做思维链蒸馏。然后第二阶段是 GRPO,用裁判的分数当奖励信号,让模型在同一个问题上生成多个回答,做得好的就强化。
女:所以算是一个持续的优化闭环。那前面提到的 gisting,又是什么?我在那篇讲上下文压缩的文章里看到过。
男:这个其实是他们整个体系里非常巧妙的一环。Gisting 就是一种把长系统提示词压缩成一小撮"gist token"的技术。你想,Agent 的系统提示词可能有 6000 个 token,每次请求都要把它读一遍,这很耗资源的。他们用知识蒸馏的方法,训练出一些特殊的 token,用这 1500 个 gist token 去替换原来的 6000 个 token,效果几乎一样,但体积小了很多。
女:那具体能带来什么好处?
男:延迟和成本都是实实在在的收益。在每分钟 350 个请求的负载下,首 token 延迟降了 19%,端到端延迟降了 38%,吞吐量提升了 16%。这意味着处理同样的流量,GPU 能省下大概 14%。
女:这个数字就很灵性了。那这套东西是不是也可以用在别的地方?除了记账和回答问题这种场景。
男:其实这期我们聊的另外几篇文章,都是围着这个生态转的。比如那篇讲 Catalog API 的,他们搞了一个 LLM 聚类管道,把平台上几十亿商品归类到统一的商品 ID 上,让 AI 代理能在不同店铺之间检索和对比商品。这里面也用到了 LLM 和多阶段管道,思路跟 Sidekick 的飞轮很像。
女:那个 Catalog API 的文章我看了,说实话,那个"核心价值主张"的理论我印象很深。就是说,判断一个属性是"变体"还是"独立产品",要看它是否改变了买家购买的核心目的。比如蛋白粉,巧克力和香草口味都是变体,因为买家买的都是营养和健身效果;但油漆就不一样,午夜蓝和鼠尾草绿完全是两个产品,因为买家买的就是颜色。
男:这个框架确实好用。但真正执行起来还是有很多坑,尤其是在几十亿商品的规模下。他们最大的工程挑战,就是怎么让 LLM 在这么大的量级下还保持稳定和可靠。他们最聪明的做法是,不把所有分类工作都丢给 LLM。他们先跑一个单例检测器,就是分析店铺的主题代码,看这个店铺到底是单品还是有多变体,如果本来就是一个个独立的商品,就直接跳过聚类。这一步就过滤掉了大部分店铺,只有一小部分才需要动用 LLM。
女:所以是先在规则层面解决能解决的问题,把 LLM 留给那些真正需要判断力的模糊场景。
男:对。而且就算是需要 LLM 的场景,他们也没有让 LLM 一口气看完整个店铺。那太大了,模型根本处理不过来。他们用了一个两步方案。先把商品用向量检索的方式,分组成一个个不超过 200 件商品的小组,叫做"邻域",让模型能看出店铺的命名规律。然后第一遍,让模型对每个商品提取品牌和型号,相同的归为一组。第二遍再做异常检测,就是重新扫描一下这些已经分好的组,看看有没有什么东西被错放进来。
女:这就像一个过滤器,先粗筛再精审。
男:没错。这第二遍特别有意思。因为批判一个分组,比从零开始创建分组要容易得多。所以第一遍是"提议",第二遍是"审查"。而且为了让模型不产生幻觉,他们用了动态生成的 JSON schema,强制要求模型对每一个产品 ID 都输出品牌和型号,一个都不能漏。这是把可靠性变成了一个工程约束,而不是期望模型自觉。
女:这个思路真的很"工程"。那跟这些 AI 基建的文章比起来,我们是不是也该聊聊更接地气的话题?比如那篇关于移动端 E2E 测试的。
男:那篇太值得聊了。他们花了几周时间重建了移动端测试框架,把稳定性从 50% 拉到了 98%。这背后的故事特别典型,我觉得很多做技术的人都会有共鸣。
女:对,那篇的标题也特别吸引人。我挺好奇,他们原来用 Appium 那套架构到底哪里出了问题?
男:我帮你总结一下,说白了就是旧框架太"自由"了。用 Appium 你可以在任何层级找到元素,点击、等待、输入,几乎没有约束。这给了开发者极大的灵活性,但也给了他们足够的空间去写烂测试。比如最常见的操作就是,点击按钮之后,加一个一秒的硬等待。这个在本地跑没问题,但在 CI 上,只要屏幕加载稍微慢一点点,测试就挂了。这种测试积累多了,整个套件就变成了一个烫手山芋,到最后只能被迫从 CI 阻塞检查里移除,因为它拦下的好 PR 比坏 PR 还多。
女:那他们是怎么重建的?应该不是简单换个测试库吧。
男:对,他们做了一个很有"主见"的封装,叫 Builder 风格的 API。核心原则有两个。第一个,每做一个动作,都必须附带一个断言。你不能"点击"完就完事儿了,你必须声明点击之后屏幕应该出现什么。这样一旦应用偏离预期状态,测试会在第一步就失败,而不是滚了四五个操作之后在一个莫名其妙的地方挂掉。
女:这个好,相当于把"期望"写进了每一步。
男:对,然后第二个更激进的改变,是他们用计算机视觉代替了传统的 Test ID。他们底层用的还是 Appium 驱动设备,但找元素的方式完全变了。每一步都会截屏,然后像人一样看着屏幕去找"保存"按钮或者加号图标,用 OCR 识别文字,用 OpenCV 匹配 Polaris 设计系统里的图标。
女:这个听起来很酷,但会不会很不稳定?比如图标换了主题风格呢?
男:他们提供了后备方案,如果视觉匹配不可靠,你还能用 Test ID,但那个入口被设计得让人很不舒服,前缀是 UNSAFE_testID,名字本身就带着警告。他们在文档里明确说,测试里出现 UNSAFE 前缀的信号,就是要审查这个测试是否真的合理。我觉得这招特别高明,它不是禁止你做某件事,而是让做错事变得有心理负担。
女:那除了稳定性,这个方案对写测试的效率有提升吗?
男:那是相当大的提升。用老的 Test ID 方式,你得打开检查器,钻到组件树里找到或新建一个 ID,然后在测试里连起来。现在,你看着模拟器上有个"保存"按钮,直接写 touch({ text: 'Save' }) 就完了。整个交互循环变得特别短。而且他们发现这玩意儿对 AI 代理也特别友好,因为指令跟屏幕内容是一一对应的,AI 生成测试代码的成功率大幅提高,第一次写就能跑通。
女:这个点很关键。就是说新的架构不仅仅是解决了稳定性问题,还让 AI 能自动生成测试了,对吧?
男:对。而且他们的框架还能在本地、CI 模拟器、以及远端的真机设备农场里,用同一条命令跑同样的测试。这听起来可能只是一个细节,但实际上让开发体验好了很多。
女:说到 AI 代理,今天我们还看到一篇,就是用 AI 代理解析 ShopifyQL,就是 Shopify 的那个查询语言,跟 CodeMirror 编辑器结合的故事。
男:那篇文章更偏"考古"了,是 2023 年的。但里面的技术思路现在看仍然很有参考价值。他们用 ANTLR 定义了 ShopifyQL 的语法,并且在客户端和服务器端共用。前端所有的语言功能都包装在一个遵循 LSP 的 TypeScript 语言服务器里。然后问题来了,CodeMirror 自己用的解析引擎是 Lezer,它不认 LSP,只认自己的语法树。按理说,最直接的办法就是为 ShopifyQL 重写一个 Lezer 语法,但他们没有。
女:为什么没这么做?是因为重写成本太高了吗?
男:对,因为语言的核心逻辑已经用 ANTLR 写好了,重写一个 Lezer 语法就相当于维护两套语法定义。所以他们做了一个适配器,充当翻译官。语言服务器输出 ANTLR 风格的 token 流,这个适配器负责把这些 token 转换成 Lezer 能懂的结构。最头疼的部分是,ANTLR 的 token 偏移量是相对的,就是说一个 token 的"行"和"字符"是相对于上一个 token 的,而不是相对于文档开头的。他们在文章里举了一个例子,特别刁钻,在 SHOW 前面加了五个空格,结果只有 SHOW 的偏移变了,它后面那个 product_title 的偏移完全没变。
女:这个确实挺绕的。
男:所以他们自己写了个 TokenIterator,大概的逻辑就是,先算出文档每一行的长度,然后根据 ANTLR 给的相对偏移,一点一点地更新"当前行"和"当前字符",最后再换算成 CodeMirror 需要的绝对偏移。整个过程相当于实现一个简单的状态机。虽然最后代码不长,但想出这个方案的过程很费劲。
女:这算是从 A 语言生态迁移到 B 语言生态的一个典型案例了。那今天这几篇,一篇是讲 AI 基建的,一篇讲移动端测试的,一篇讲 UI 扩展迁移,还有那篇讲音乐人 Hack Days 的,你觉得哪篇给你的启发最大?
男:如果非要说的话,我觉得是那篇关于持续学习的。因为它指向了一个我认为是行业终局的方向。以前我们都觉得,AI 应用就是用个模型,加几个 Prompt,调一调就完了。但 Shopify 的做法已经把 AI 当成一个需要持续迭代的数据基础设施在做了。它不再是一个静态的模型文件,而是一个每天都会吸收生产环境经验、更新权重的活体系统。这个思路挺颠覆的,它对技术团队的组织能力、数据能力、工程能力要求都很高。
女:确实。那篇讲 UI 扩展迁移到 remote-dom 的文章也是,他们花了很大力气把一个重型的 React 渲染层换成了更轻的 Preact + Web Components,就为了把包体积压到 64KB 以下。这听起来很工程,但背后的商业逻辑很清晰——结账页面是转化率最高的页面,快 1 毫秒都是钱。
男:对。而且那篇文章里他们做的那个对等测试套件,用 42,000 行的真实商家 Liquid 配置来验证自己新写的解析器,这种思路也特别值得参考。不是拿几个通用用例测一下就完了,而是拿生产环境的真实数据来当金标准。这就跟我们刚聊的模型训练是一样的逻辑——用真实数据,不用合成数据。
女:对了,还有那篇讲 Catalyst API 的文章,最后提到下一步是跨店聚类,统一全局 UPI,我觉得这个一旦做成了,对整个电商生态的影响会非常大。以后商家可以在不同店铺之间做商品对比,甚至跨店销售,这在以前是难以想象的。
男:把这个跟今天聊的其他事情联系起来,你会发现,Shopify 是在搭建一个完整的 AI 原生电商平台。一边是像 Sidekick 这样的智能助理,靠飞轮不断提升能力、降低成本;另一边是像 Catalog API 这样的底层数据基建,让 AI 能够理解整个平台的商品结构。再加上像 Dispatch 那样的安全审计框架,用 AI agent 来自动找漏洞。这些动作背后其实是一盘棋——把 Shopify 从一个卖软件的 SaaS 公司,变成一个卖智能的 AI 平台。
女:总结得很到位。那老冯,你觉得对我们这些收听节目的开发者和商家来说,应该关注什么?
男:如果你是开发者,我建议去研究一下 Gisting 和持续学习这两个技术,哪怕只是概念层面的了解,这会是未来几年 AI 应用开发的核心模式。如果你是 Shopify 商家,那你未来选应用的时候可以留一个心眼——问一句,这个应用用 AI 吗?它的 AI 是基于什么模型训练的?如果是一个越来越便宜的、基于生产环境持续迭代的模型,那这个 App 的长期体验大概率是会越来越好的。
女:有道理。好了,今天信息量确实不小,从 96% 的成本削减到 98% 的测试稳定性,再到 AI 驱动的安全审计,Shopify 这家公司真的在开足马力搞 AI 基建。如果收听的朋友们对哪篇文章特别感兴趣,也欢迎去 Shopify Engineering 的博客去看原文。我们下期再见!
男:下期见!
参考链接
- Gisting: Compressing LLM Agent context to ↑ throughput and ↓ cost
- How we raised mobile end-to-end test stability to 98%
- Sidekick's continual learning loop
- Building an agentic harness that outlasts the model
- Upgrading Checkout Blocks app to Polaris web components
- Inside Shopify Hack Days: Building a prototype for music-playing pages
- Clustering billions of products for agentic commerce with Catalog API
- Teaching Sidekick to say no: automated data curation with LLM judge consensus
- Introducing Ruvy
- Building a ShopifyQL Code Editor
迅步科技专注Shopify独立站,Shopify应用及无头网站开发,为您的品牌提供快速、灵活、个性化的电商体验,提升用户转化率与运营效率。欢迎咨询合作。
