Shopify 部署了 River,一个 Slack 原生 Agent。
每 8 个合并的 PR 中就有 1 个由 Agent 共同撰写。30 天内 59,918 次会话。秘密不在于模型 — 而在于 substrate:一种将 Agent 会话视为持久实体、将「大脑」与「双手」解耦、并将每个新 Agent 变成简单 profile 而非平台的基础设施。
以下是每个受监管行业的 CTO 在启动第一个内部 Agent 之前应该研究的 5 个架构决策。
为什么这件事现在很重要
Shopify 在 2024 年做了一个当时看起来荒谬的赌注:将整个公司迁移到单一 monorepo("World"),并在所有地方强制使用 Nix 以实现可复现性。原因是什么?"代码将越来越多地由 AI 编写,我们的基础设施需要成为支撑这一点的 substrate。"
两年后,这个赌注得到了回报。
2026 年 5 月 28 日发表在 Shopify 工程博客上的文章「Under the River」— 并且由 Agent 本人共同撰写 — 详细介绍了使这次部署成为可能的基础设施。
数字如下:30 天内 59,918 次会话,5,170 个 Slack 频道,触达 7,000 多人,合并了 3,536 个由 Agent 共同撰写的 PR。但这对 AI 流程架构师来说重要的不是数字,而是底层的架构。
四层架构
以下是从在 Slack 中向 @River 提问到提交由 Agent 共同撰写的 commit 的完整流程:
slack { # Slack - Interface
n1: circle label:"@River in Slack"
n2: rectangle label:"Public channel question"
n11: rectangle label:"Response received"
n1.handle(right) -> n2.handle(left)
n2.handle(bottom) -> river.n3.handle(top) [label="1. Request"]
}
river { # River - Agent Surface
n3: rectangle label:"Analyzes request"
n4: rectangle label:"Delegates to Aquifer"
n10: rectangle label:"Formats response"
n3.handle(right) -> n4.handle(left)
n4.handle(bottom) -> aquifer.n5.handle(top) [label="2. Session"]
aquifer.n9.handle(top) -> n10.handle(bottom) [label="5. Result"]
n10.handle(top) -> slack.n11.handle(bottom) [label="6. Response"]
}
aquifer { # Aquifer - Foundation
n5: rectangle label:"Harness plans"
n6: rectangle label:"Sandbox executes"
n7: diamond label:"Done?"
n8: rectangle label:"Consolidates"
n9: rectangle label:"Returns result"
n5.handle(right) -> n6.handle(left)
n6.handle(bottom) -> world.n12.handle(top) [label="3. Read/write"]
n6.handle(right) -> n7.handle(left)
n7.handle(top) -> n5.handle(bottom) [label="No"]
n7.handle(bottom) -> n8.handle(top) [label="Yes"]
n8.handle(right) -> n9.handle(left)
}
world { # World - Monorepo
n12: rectangle label:"Executes on repo"
n13: rectangle label:"Runs tests - opens PR"
n12.handle(right) -> n13.handle(left)
n13.handle(top) -> aquifer.n7.handle(bottom) [label="4. Output"]
}
四个层级,六条跨泳道消息。这些层级中没有任何一个是模型。 模型是 Harness 内部的实现细节。架构才是真正重要的决策。
决策 1:Agent 友好 = 人类友好(反直觉的模式)
Shopify 发现每一个为 Agent 所做的改变,对人也同样正确:
| 人类面临的问题 | Agent 面临的问题 | 共享的解决方案 |
|---|---|---|
| 不可复现的开发环境 | Agent 也无法复现任何东西 | Nix everywhere |
| 碎片化的仓库 | Agent 无法跨孤岛查看 | Monorepo "World" |
| 未文档化的知识 | Agent 无法学习这些内容 | 书面的 skills 文件 |
"让代码库对 Agent 可读的工作,正是你欠人类工程师的技术债务。Agent 让这些债务变得可见。" — Shopify Engineering
这对 AI 流程架构师意味着什么: 不要再去构建弥补技术债务的 Agent。构建让代码库变得可读的基础设施 — 对人类和 Agent 都是如此。ROI 是双重用途的。
保险行业的对应场景: 一家保险公司如果为 Agent 记录了核保规则,也就为其人类核保员记录了这些规则。规则库变成了共享资产。
决策 2:私有 Agent 存在天花板
River 有一个激进的约束:它只在公开频道中工作。 没有私信。每次对话都成为可被所有 Shopify 员工搜索的 Slack 索引记录。
为什么?因为私有 Agent 存在天花板:就是键盘前的那个人。
"如果与 Agent 的每次交互都发生在私有窗口中,唯一能学到任何东西的人就是键盘前的那个人。" — Tobi Lütke
Shopify 挖掘这个公开对话语料库。一个开发者的艰难修复成为下一个开发者的起点。Agent 在无需模型微调的情况下不断改进,仅仅通过从语料库中吸收模式。代码库教导 Agent。Agent 教导代码库。
这对 AI 流程架构师意味着什么: 你的下一个内部 Agent 应该默认是公开的。Agent 会话的「隐私」是一种劣势 — 它阻止了集体学习。对话语料库是一种复利资产。
银行业的对应场景: 在银行中,合规 Agent 和开发人员使用不同的频道。一个公开的内部 Agent 强制执行跨职能协作 — 开发者提出的监管问题对整个合规团队可见。语料库成为机构记忆。
决策 3:将大脑与双手解耦
这是 Aquifer 的核心架构决策。Shopify 将基础设施分解为三个实体:
Session(会话) → 持久的。仅追加事件日志。Postgres。权威真相源。 Harness(大脑) → Agent 循环。读取历史记录,调用 LLM,发出工具意图。可任意销毁。 Sandbox(沙箱) → 代码运行的地方。文件系统、Shell、代码仓库。可任意销毁。
dev { # Dev - Slack
n1: circle label:"@River mention"
n2: rectangle label:"Agent request"
n12: rectangle label:"Receives response"
n1.handle(right) -> n2.handle(left)
n2.handle(bottom) -> harness.n3.handle(top) [label:"Prompt"]
}
harness { # Harness - Brain
n3: rectangle label:"Loads history"
n4: rectangle label:"Calls LLM"
n5: rectangle label:"Emits tool intents"
n11: rectangle label:"Responds to dev"
n3.handle(right) -> n4.handle(left)
n4.handle(right) -> n5.handle(left)
n5.handle(bottom) -> sandbox.n6.handle(top) [label:"bash, edit"]
sandbox.n10.handle(top) -> n11.handle(bottom) [label:"Result"]
n11.handle(top) -> dev.n12.handle(bottom) [label:"Response"]
}
sandbox { # Sandbox - Hands
n6: rectangle label:"Sets up environment"
n7: rectangle label:"Runs commands"
n8: diamond label:"OK?"
n9: rectangle label:"Raw output"
n10: rectangle label:"Returns output"
n6.handle(right) -> n7.handle(left)
n7.handle(right) -> n8.handle(left)
n8.handle(right) -> n9.handle(left) [label:"Yes"]
n8.handle(bottom) -> n6.handle(top) [label:"No - retry"]
n9.handle(right) -> n10.handle(left)
}
Harness 位于 Sandbox 之外。Agent 不在代码所在的地方运行。
这种模式并非 Shopify 独有。Anthropic 以其 tool use 和 computer use 进行了不同的形式化 — Agent 从安全上下文向隔离的执行环境发出工具意图。OpenAI 通过 Operator 实现了这一点 — 「大脑」(对任务进行推理的 GPT)与执行操作的「浏览器」解耦。Hermes Agent(Nous Research)通过其 profiles 应用了同样的原则 — SOUL.md(大脑)与 skills 和执行沙箱是分开的。
关键区别在于:Shopify 将解耦一直推到了会话层面。在 Anthropic,会话绑定到进程。在 Shopify,会话的寿命超过进程。
由此产生的三个特性,你无法事后补上任何一个:
- 安全性: Agent 循环不在
rm -rf的爆炸半径内 - 可替换性: 在
Harness端更换模型、运行时甚至语言,而无需触碰Sandbox - 可观测性: 整个决策流存在于
Harness端,在一个地方可见
这对 AI 流程架构师意味着什么: 如果你的 Agent 与代码执行在同一个进程中运行,你将无法事后补上安全性和可观测性。从这个边界开始。
电信行业的对应场景: 电信运营商的网络诊断 Agent 绝不能 直接访问设备。Harness 分析日志并发出意图("检查接口 X"),Sandbox 在具有精确权限的隔离环境中执行。审计追踪在 Harness 中,而不是 Sandbox 中。
决策 4:像对待牲畜而非宠物一样对待进程 — 在会话层面
文章中的关键一句:"Cell 会消亡,Sandbox 会消亡,机器会消亡。但对话不会。"
Aquifer 的会话模型极其简单:
- 一个 Session Cell = 宿主机上的一个短暂进程,运行 Go 运行时和
Harness - 空闲 → 它退出。下次交互 → 全新的 Cell,可能在不同的宿主机上
- 会话身份不变。对话完全保存在 Postgres 中,而非内存中。
"我们不护理单个进程。我们配置、运行、挂起、销毁和重新配置它们,而且我们是在一个使这一切变得廉价的基础上做的。"
这对 AI 流程架构师意味着什么: 不要构建一个把所有内容都保存在内存中的单体 Agent。构建一个将会话视为持久实体、其他一切都视为可任意处置的基础。
与 Hermes 的语义桥梁: Hermes Agent 的 profile 基于同样的原则 — SOUL.md、skills 和持久记忆在会话之间存活。Hermes 进程是可任意处置的。对话和配置是持久的。Shopify 和 Hermes 在没有协调的情况下趋同于相同的模式 — 这表明这是一种架构法则,而非实现偏好。
决策 5:下一个 Agent 是一个 Profile,而非一个平台
一旦 River 上线,其他 Shopify 团队想要自己的 Agent:
- PR 审查 Agent
- 研究 Agent
- 迁移 Agent
- 合规扫描
- 性能调查
都是同一理念的变体:针对 monorepo 的 Agent 工作流,在 Slack 中,持久且多人协作。
Shopify 的答案是:Aquifer,这个平台。 River 是之上的一个 profile。PR 审查是另一个 profile。无头 "pi" Agent 是第三个。
river { # Interactive Mode
n1: circle label:"@River Slack"
n2: rectangle label:"Public session"
n1.handle(right) -> n2.handle(left)
n2.handle(bottom) -> aquifer.n7.handle(top) [label:"via Aquifer"]
}
review { # Automation Mode
n3: circle label:"PR Webhook"
n4: rectangle label:"Automated review"
n3.handle(right) -> n4.handle(left)
n4.handle(bottom) -> aquifer.n8.handle(top) [label:"via Aquifer"]
}
ci { # Batch Mode
n5: circle label:"CI Trigger"
n6: rectangle label:"Ephemeral batch"
n5.handle(right) -> n6.handle(left)
n6.handle(bottom) -> aquifer.n9.handle(top) [label:"via Aquifer"]
}
aquifer { # Aquifer - Shared Foundation
n7: rectangle label:"Session model"
n8: rectangle label:"Sandbox plane"
n9: rectangle label:"Gateway"
n7.handle(right) -> n8.handle(left)
n8.handle(right) -> n9.handle(left)
}
一个 profile = 系统提示词 + skills + 扩展 + sandbox 策略 + 模型默认值。添加一个新 Agent = 添加一个 bundle,而不是构建一个新平台。
这对 AI 流程架构师意味着什么: 如果你的第二个 Agent 需要第二个平台,说明你还没有构建好基础。
跨生态系统的语义桥梁:
- Shopify 称之为 "profile"(包含提示词 + skills + sandbox 策略的 Nix bundle)
- Hermes Agent 也称之为 "profile" — SOUL.md + skills + plugins + cron + memories
- OpenAI 称之为 "custom GPT" — instructions + 知识文件 + actions
- Anthropic 没有直接对应物 — Claude Code 和 Claude API 是不同的产品,而非统一基础上的 profile
Shopify 和 Hermes 在 "profile" 概念上的趋同令人瞩目 — 两个独立的生态系统达成了相同的架构模式。与 Anthropic 的分歧同样具有启发性:没有 "profile" 层,每个新 Agent 都需要新的集成。
AI 流程架构师的路线图
Shopify 证明了大规模内部 Agent 部署不是一个模型问题 — 而是一个架构问题。直接从文章中提取并转化到受监管行业的三个优先事项:
| 优先事项 | 实践中的含义 | 关键行业 |
|---|---|---|
| 1. 将大脑与双手解耦 | Harness 绝不能与 Sandbox 在同一进程中。安全性、可替换性和可观测性不是可选的 — 你无法事后补上。 | 银行业:监管审计追踪存在于 Harness 中。保险业:人类核保员在 Sandbox 执行前验证 Harness 的决策。 |
| 2. 在构建时就让 Agent 支持多人协作 | 私有 Agent 存在天花板:键盘前的那个人。公开 Agent 教会随后的每一次会话。语料库是复利资产。 | 电信业:网络诊断语料库随着每一次事件变得更加丰富。零售业:商户目录问题成为集体知识库。 |
| 3. 将下一个 Agent 视为一个 profile | 新 Agent 的成本应该是在同一基础上的一个新 bundle,而不是一个新平台。 | 所有行业:如果你的合规 Agent 和你的开发者 Agent 不共享同一个基础,你就在构建两次基础设施 — 并创造两个攻击面。 |
以及贯穿整篇文章的元教训:会话是必须存活下来的东西。 不是进程,不是 sandbox,不是模型。是对话。如果你不围绕这个理念来构建,你以后将不得不重建一切。
为什么这种架构对受监管行业很重要
Shopify 的案例研究不仅仅是电商行业的经验。River 记录下的 5 个架构决策可以直接转移到 FlowZap 的三个优先行业:
保险业
一家部署内部 Agent 用于核保或理赔处理的保险公司面临着与 Shopify 相同的问题:如何对 Agent 的行为进行不可变的审计? 答案在决策 3 中 — Harness(包含决策流)与 Sandbox(执行端)是分离的。审计追踪在 Harness 中。审计员不看 Sandbox 做了什么 — 他们看 Harness 决定了什么。
银行业
一家部署 Agent 用于监管合规或信用分析的银行需要决策 2:Agent 必须默认是公开的。 开发者提出的监管问题对整个合规团队可见。Agent 对话语料库成为银行的机构记忆 — 可搜索、可审计、可向监管机构呈现。
电信业
一家部署网络诊断 Agent 的电信运营商需要决策 5:下一个 Agent 是一个 profile,而非一个平台。 N1 诊断 Agent(第一级)和 N2 升级 Agent(第二级)共享同一个类似 Aquifer 的基础。N1 profile 有受限权限(日志只读)。N2 profile 有扩展权限(接口重启)。相同的基础,不同的 sandbox 策略。
