前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
返回 AI 情报前线
All News · 全部资讯8614
  • AWS DevOps Agent实战:故障调查与成本透明化
  • 用 LLM 构建自愈型 TypeScript 爬虫和自动化 Agent
  • Astro 实战:八步优化突破移动端 PageSpeed 100
  • 用 RAG 和 LLM 构建 WhatsApp AI 客服 Agent
  • OpenAI → 替代 API:降本提效的无缝迁移方案
  • RAG 系统如何停止胡说:从检索评估而非 prompt 技巧出发
  • 在生产环境中安全地赋权 AI:allowlist 而非 shell 访问
  • 微软Project Perception: AI驱动的闭环自动安全防御系统
  • AI生成WordPress代码的安全性实验验证
  • AI Agent相互委派:多智能体编排的新范式
  • AMD 开源 16B MoE 模型及完整工程资源
  • AI编码Agent成本优化:Context智能压缩方案
  • 生产AI管道成本削减25%:模型参数调优实战
  • MCP生态稳定性警示:工具契约频繁变更的风险
  • AI代码生成的转义漏洞:上下文决定安全
  • OpenClaw 连接失败?先排查 prompt 和 context 预算
  • Agent 权限蔓延:如何在增量需求中悄悄发生
  • Agent系统架构选择:单体 vs 多体
  • Transformer训练加速:GPU融合与精度优化
  • Python + FastAPI 构建生产级 AI Agent 完整指南
  • 用 AI Agent 构建多租户 SaaS:架构与成本控制
  • AI Agent 金融操作必须人工审批:架构模式
  • PDF 结构提取:AI 为什么读不懂 PDF
  • 开源编码模型对比:性能与自托管权衡
  • Agent 时代的身份认证困局:MCP 安全重思
  • Grok Build 开源后的 Agent 安全审查清单
  • Semantic Release 自动化版本管理和变更日志
  • LLM JSON 输出:Prompt 不如解码约束可靠
  • 编程任务的 LLM 模型选型指南
  • 真实代码库PR任务上的AI编程Agent对标测试
  • LLM函数调用跨提供商差异的可重复测试框架
  • 2026 Prompt管理工具市场洗牌与迁移指南
  • 2026 LLM网关对比:成本、可靠性与市场格局
  • RAG 2026:开源框架与托管平台的架构权衡
  • AI漏洞检测2026:从RCA到自动修复的Agent演进
  • 代码重构显著降低 AI 编程的 Token 消耗
  • AI时代文档成为代码的运行手册
  • AI从检测Bug转向自动修复范式
  • OpenAI Astra 数学成果:从模型输出到可验证代码
  • Agent 系统失败根源:协调瓶颈而非模型智能
  • 开源工具:减少前端 AI Agent 的 token 浪费
  • AI 模型突破数学难题,数学家警示职业风险
  • Agent 持久化记忆与秘密防泄:从入口单次清洗
  • LLM推荐系统成本陷阱与三层优化策略
  • Cursor Windows任意代码执行漏洞,沙箱打开前需谨慎
  • MCP:AI 工具集成的统一标准
  • 同一模型不同运行时效果差异大
  • AI/ML 工程师实战学习路线图与里程碑
  • 本地 LLM 驱动智能合约模糊测试
  • Herdr:Agent 并行管理工具
  • 按不确定性选模型:DeepSeek Flash 用法指南
  • 已加载 51 / 8614
8.0
热点
AI SCORE
技术实践2026-08-02 02:12

用 AI Agent 构建多租户 SaaS:架构与成本控制

dev.to · AI#SaaS#多租户#成本优化
Editor brief · 编辑速览

分享构建多租户 AI Agent 平台(Aulinq)的完整经验,深度讨论模型选择、动态计费、租户隔离、幂等性等硬件基础设施难点,指出基础设施比 AI 能力本身更难复制。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

在 2026 年开始做另一个 SaaS 是件很奇怪的事。舆论说这个赛道已经饱和,AI 摧毁了所有的护城河,剩下的唯一值得构建的东西就是围绕前沿模型打造一个漂亮的着陆页。我读过这些言论,大体同意诊断,但完全不同意结论。包装应用正是第一批死掉的东西。剩下的是底层那些枯燥却难以复制的基础设施——多租户、计费、成本控制、密钥管理、重复交付的幂等性——而这些工作并不会因为模型变聪明就变便宜。

这就是构建这样一个平台的故事。它叫 Aulinq。这是一个多租户、多语言的 AI 智能体平台:可以在 Telegram、WhatsApp 或网页聊天上回答客户,将对话路由到能够处理的最便宜模型,按令牌向租户收费(几分之一分钱),并保持每个租户的数据和密钥与其他租户完全隔离。在这些基础设施之上有三条产品路线——一条白标路线供机构将智能体转售给他们的客户,一条 API 供初创公司将智能体嵌入到自己的产品中,以及一条单租户路线供只想要一个可用的机器人而不想获得基础设施博士学位的独立创始人。生产系统包括多个 Go 服务、一个 Postgres、一个 Redis 和一个 NATS JetStream 总线。我是唯一的工程师,而且我还有一份全职工作。

最后这一点是人们真正想了解的。你如何在还有全职工作的情况下单独交付一个分布式平台?诚实的答案是两件事,都不是"我编码很快"。首先,我不再单独编码,而是开始协调一个 AI 智能体团队——一个规划者、一个实现者、一个审查者、一个验证者,每个都有自己的上下文和自己的工具。其次,我不再试图在每天一小时的增量中做这件事。一个工作日晚上的一小时足以审查差异、批准计划或观看验证程序运行。这不足以研究堆栈决策、起草架构或将失败的服务从漂移状态中拉出来。这些需要一整块不间断的注意力,对我来说这个块是周六,以及家人出门的偶尔周日。

所以方法和运营模式相互依赖。周末批次是思考工作发生的地方——研究循环、架构迭代、库间隙填充、智能体规则。工作日晚上是小的验证和合并任务发生的地方。混淆它们会导致你在周二晚上 11 点做出半研究的堆栈选择,这正是这个方法设计要避免的确切失败模式。

本文就是那个方法,写下来的。不是抛光版本——是保留死胡同和回滚的版本,因为这些是真正教会它的部分。它假设你已经是一个有能力的工程师。AI 智能体不会取代这一点。它们放大你带来的任何判断,也同样快速地放大坏判断。

堆栈问题不是"什么是流行的"

当你问"我应该为分布式 SaaS 使用什么堆栈"时,AI 编码助手会做的第一件事是给你最流行的答案。Python。FastAPI。Postgres。Redis。如果你说"事件驱动",也许还有 Kafka。这对于教程来说是正确的答案,但对于其他 AI 智能体将在未来两年扩展的系统来说,通常是错误的答案。

流行堆栈之所以流行,是因为它对最多的人来说是可理解的。对最多的人来说可理解与对最多的智能体来说可理解是不同的。AI 智能体不从庞大的教程生态系统中受益——它们已经读过了。它们受益于拒绝其错误的类型系统、大声失败的运行时,以及出错的活动部分最少的部署工件。

我通过深度研究(而不是聊天)来处理堆栈问题。四或五次迭代:首先进行广泛的调查,然后缩小到存活的两三个选项,然后对每一个进行深入阅读,然后根据第二个模型进行交叉检查以捕捉第一个模型的偏见。这是我为这个项目中的每一个关键决定遵循的模式,不仅仅是堆栈。它比问一次要慢。它比问一次然后在第四个月重建要快。

Go 赢了。不是因为它在 AI 智能体工具的意义上很流行——它不是,Python 主导那个——而是因为 Go 编译器将一类智能体错误转变为构建错误,而不是凌晨 3 点的堆栈跟踪。当智能体向事件结构体添加字段并忘记更新消费者时,构建会失败。在 Python 的等价物中,消费者无声地反序列化为 None,你在生产中才发现。

权衡是真实的,我想指出它:我放弃了对 Python ML 生态系统的直接访问。平台中的每个模型调用都通过 HTTP API 而不是进程内库进行。这对于 LLM 路由平台来说很好——模型无论如何都在提供商后面——对于做本地推理或繁重预处理的团队来说,这将是一个真正的成本。我将单独写完整的 Go vs Python 论证,包括 Python 本来是正确选择的情况。

当库不存在时,编写它

在堆栈之后,对于每一层都进行相同的研究循环。事件总线:选择 NATS JetStream 而不是 Kafka,因为基于主题的路由是智能体可以推理的字符串,而基于主题的路由带有模式注册表是智能体会出错的构建步骤。持久化:一个带有每个域模式的 Postgres,因为"智能体可以完整读取的一个数据库"胜过"每个都有自己的迁移工具的十个数据库"在智能体可理解性方面。

然后是我后来描述时让人们感到惊讶的部分。我需要的几个库不存在我想使用的形式。一个类型化的 JetStream 发布者,用信封包装每个事件并公开 PublishInbound 而不是原始的 Publish(subject, []byte)。一个带有滑动失败窗口的断路器,而不是幼稚的连续失败计数器。一个多租户密钥保险库,具有信封加密,不向工具层泄露明文。

来自其他工程师的反应通常是"只需使用库 X"。有时这是对的。有时现有的库是一个薄包装,这会迫使智能体在每个服务中围绕它编写相同的样板代码。当缺口是真实的时,编写库不是最大的问题——这是与智能体一起的几个周末,你最终得到的界面正是系统的其余部分期望的。该平台现在有一套内部 Go 库(go-events、go-ai-providers、go-resilience、go-secrets 以及更多),每个服务都导入。每个都存在,因为公开的替代品会让智能体编写更多的样板代码,而不是更少。

断路器是形状的一个很好的例子。我发现的公开 Go 断路器库计算连续失败并在计时器上重置。我想要的是一个滑动窗口——计算最后六十秒内的失败,如果超过阈值则打开,半开以探测,一次成功就关闭。这是 Go 的六十行:

func (cb *SlidingWindowCircuitBreaker) Call(fn func() error) error {
    cb.mu.Lock()
    switch cb.state {
    case cbOpen:
        if time.Since(cb.openedAt) >= cb.cooldown {
            cb.state = cbHalfOpen
        } else {
            cb.mu.Unlock()
            return ErrCircuitOpen
        }
    }
    cb.mu.Unlock()

err := fn()

cb.mu.Lock()
    defer cb.mu.Unlock()
    if err != nil {
        cb.failures = append(cb.failures, time.Now())
        // prune failures older than the window...
        if cb.state == cbHalfOpen || len(cb.failures) >= cb.maxFailures {
            cb.state = cbOpen
            cb.openedAt = time.Now()
        }
        return err
    }
    if cb.state == cbHalfOpen {
        cb.state = cbClosed
    }
    return nil
}

一个智能体一次性写出了那个的第一个版本。我审查了它,发现修剪循环差一个,并让智能体修复它。要点是这个库现在有了系统其余部分调用的确切界面,没有适配器层,导入它的每个服务都得到相同的失败语义。如果我包装了一个流行的库,每个服务都会有不同的临时包装,扩展这些服务的智能体必须学习每一个。关于库本身有一整个系列即将推出——事件发布者、AI 提供商界面、密钥保险库、RAG 选择器——每一个都是公开选项会意味着更多智能体样板代码而不是更少的情况。

架构计划,迭代中

在开发之前,我与智能体一起规划了整个架构。这是大多数人跳过的步骤,也是后来节省最多时间的步骤——尽管它感起来像是最慢的部分。

我学到的关键一点是:你必须尽可能把自己掌握的初始上下文都提供给 AI 智能体,因为 AI 智能体默认倾向于尽可能少做事。让 AI 智能体“为一个多租户 AI 平台设计架构”,你得到的会是一张三层架构图,里面有一个标着“AI Service”的方框。如果你在提问时附上约束条件——这些是需要支持的消息平台,这是按成本层级路由的要求,这些是租户隔离规则,这是我预期的事件流,这是我想避免的设计——那么你得到的才会是真正可以落地构建的方案。

我反复迭代了四轮、五轮、六轮。我会拿到一份方案,读完后针对某个具体决策提出质疑,并要求修改。AI 智能体会为某个选择辩护,我则会给出一个能够让这个选择失效的具体场景,随后 AI 智能体再修改方案。这个过程既无聊又烦人。有时我宁愿直接去写代码。但一份经受住五轮“那这种情况怎么办”拷问的方案,才是一份 AI 智能体能够直接实现,而不必边做边凭空发明架构的方案。

在这些迭代中,我逐渐最看重的一件事,是思考那些我尚未选择的发展方向。当前方案只需要覆盖我现在正在构建的内容,但架构必须能够向我接下来可能构建的东西延展。举个例子:我把 AI 智能体配置设计成“不可变模板 + 每租户覆盖配置”的形式,尽管当时我只有一个租户,严格来说并不需要做这种拆分。六个月后,当第二个租户到来,并出现白标需求时,这套覆盖模型已经能够处理。假如第一版采用的是更简单的“每个 AI 智能体一份配置”,那么后来负责扩展系统的 AI 智能体就不得不在系统承载负载的同时迁移数据模型,而这种任务恰恰是 AI 智能体不擅长的。至于具体的架构决策——为什么选 Go 而不是 Python,为什么选择十个微服务而不是单体架构,为什么选择一个 Postgres 而不是每个服务一个数据库——之后都会分别撰文说明。这篇文章讨论的是过程,而不是为这些选择辩护。

方案稳定之后,开发工作就变成了一份大型顶层计划,并被拆解为具体的小任务。不是“构建消息服务”,而是“给事件库添加 PublishInbound 方法,这是结构体,这是 subject 模式,编写对应的单元测试”。然后是下一个小任务,再下一个。

顺序很重要。先开发库,通过小型示例证明每个库都能正常工作,并使用单元测试锁定契约。然后开发核心服务;一旦有两个服务可用,就让它们互相进行交叉测试。之后才是初版 UI,而这又意味着新一轮调研——这次研究的是前端框架,因为 AI 智能体给出的第一个答案是 React 加上一大堆样板代码,而我想要的是最精简、能够编译为静态文件,并且无需在构建步骤上反复折腾就能处理国际化的方案。

角色分工就是在这里发挥作用的。一个 AI 智能体阅读代码库并为任务编写计划。第二个 AI 智能体按照计划实现。第三个 AI 智能体阅读差异并寻找缺陷。第四个 AI 智能体负责构建、重启和运行测试,而且在实际观察到系统处于健康状态之前,不允许宣布工作完成。任何 AI 智能体都不能自行批准自己的工作。实现者不负责评审,评审者不负责验证,验证者不负责批准。

我不会在这里重新推导这套方法——下一篇文章会详细介绍 AI 智能体团队,包括每个角色发现的具体缺陷,以及那一次整个流水线显得过度复杂的情况。对本文而言,重点是:只有当每项任务足够小,能够让单个 AI 智能体在不丢失思路的情况下完成时,这个循环才能运转。“重构计费服务”不是一个任务。“将信用额度冻结 RPC 提取为独立函数,并添加一个测试,验证被冻结后又释放的额度会让余额恢复到原始值”才是一个任务。AI 智能体完成它,验证者确认测试通过且服务日志干净,然后循环进入下一项任务。

把 AI 智能体规则写下来,并保持简短

构建进行到一半时,我注意到 AI 智能体开始偏离方向。某个本应按租户 ID 路由的服务却按账户 ID 路由。某次迁移添加了一个列,却没有添加相应的权限授予,导致新角色无法读取它。都是些小问题,每一个都能修复,但相同类型的错误在不同会话中不断重现,因为开启新会话的 AI 智能体并不知道这些规则。

于是我把它们写了下来。在代码库根目录放置一个 CLAUDE.md,并刻意保持简短。八条不可妥协的规则,每条只有一句话。多语言意味着后端不能包含任何针对特定语言的代码——LLM 是语言判断的唯一权威,因此后端只使用英文键。修复由你触碰或破坏的测试。代码必须达到生产可用标准,不能使用桩代码。Schema 发生变化后,重置本地技术栈。代码修改后,执行构建、重启并检查日志。使用子 AI 智能体并行工作,并通过循环进行验证。

简短是有意为之。我最初尝试过更长的版本——详细说明每条规则,并配上示例和边界情况——结果 AI 智能体开始忽略列表底部的规则。一条 AI 智能体不会遵守的规则,比没有规则更糟,因为它会给你一种虚假的信心。短版本能够容纳在 AI 智能体的活跃注意力范围内,因此会被遵守。长版本则放在链接的子文档中,只有当任务涉及相应领域时,AI 智能体才会读取。

回报超过十倍的那条规则是:“LLM 是语言判断的唯一权威。”在制定这条规则之前,AI 智能体总是在后端添加西里尔字母计数启发式规则和基于关键词匹配的语言检测,因为每篇聊天机器人教程都采用这种模式。但遇到第一个在对话中途从俄语切换为英语的俄语租户时,这些启发式规则全都失效了。制定规则之后,后端完全不再尝试检测语言,只把文本传给模型,再由模型使用用户输入时所用的语言作答。规则文件里的一句话,就让一整类缺陷不再出现。

如果能重来,我会克制住过早开发 UI 的冲动。在核心服务完成交叉测试之前,我就构建了第一版仪表盘,因为看到屏幕上出现实际内容让人感觉很好。但这并不值得。服务契约稳定后,UI 不得不重写,而负责重写的 AI 智能体总想保留旧的 UI 决策,而不是适配新的契约。如果先完成枯燥的中间部分,把看得见的 UI 留到最后构建,本可以节省一周时间。

我还会在开发第一个服务之前就编写 AI 智能体规则文件,而不是等到项目进行到一半才写。早期会话中的偏离幅度虽然不大,但这些早期决策如今都已经固化在代码里,后续 AI 智能体会在此基础上继续扩展,而它们并不总能分辨哪些决定是有意为之,哪些只是偏离造成的。如果从第一天起就有规则文件,虽然不能捕获所有问题,但至少能给早期的 AI 智能体一个更明确的目标。

这篇文章介绍的是方法。下一篇会详细介绍 AI 智能体团队——包括各个角色发现的具体缺陷,以及那一次整个流水线显得过度复杂的情况。再往后会讨论架构决策(Go 与 Python、微服务与单体架构、NATS 与 Kafka、单一 Postgres 与每个服务独立数据库),然后是我们不得不编写的库,再之后是模型优化和成本层级,最终还会涉及市场进入策略。把这一切写下来的原因在于:对于这样的技术产品,唯一真正有效的传播渠道,就是工程师把真实的构建过程转发给其他工程师。

如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
Python + FastAPI 构建生产级 AI Agent 完整指南
下一篇
AI Agent 金融操作必须人工审批:架构模式