一个 1 vCPU、1 GiB 内存的 Cloud Run Instance,按 Google 给出的配置可以 24 小时在线,一个月大约 5.70 美元。

这个数字很容易让人上头。

你会立刻想到那些一直没落地的小东西,盯 CVE 的安全机器人、夜里跑测试的 CI Agent、收 GitHub Webhook 的发布助手、每天替你扫一遍技术资讯的个人情报站。以前它们总卡在同一个问题上,跑在本机不可靠,买 VM 又嫌太重,普通 Serverless 一没流量就睡过去。

Google 最近给 Cloud Run 增加的 Instances,瞄准的正是这条缝。它保留了容器、HTTPS 地址和托管运维的轻量感,又给了你一个固定的、常驻的实例。

但坦率地讲,5.70 美元不是一张「从此可以不管运维」的通行证。

它只是让一类 Agent 的部署门槛降下来了。状态、并发、重启、密钥和公网入口这些事,还是会原封不动地找上门。把它们处理好,Cloud Run Instances 会是一个挺优雅的中间形态。处理不好,它就是一台价格便宜、故障更隐蔽的小服务器。

普通 Serverless 为什么总和常驻 Agent 别扭

先别急着把 Agent 放上云,先看看它需要什么。

一个真正长时间工作的 Agent,通常至少有三种触发方式。它要按固定间隔自己醒来,接收外部 Webhook 后立刻处理,还要提供一个页面让人看结果或手动触发任务。更麻烦的是,它应该记得自己看过什么、跑到哪一步、失败后该从哪里续上。

普通 Cloud Run Service 做短请求很舒服。请求来了,容器处理,流量低时扩到零。这个设计对 API 很划算,对一个在内部循环里每 30 分钟拉一次 RSS 的后台 Agent 却很别扭。实例缩到零,进程就没了。流量突增时又可能同时起多个实例,两个进程一起改同一份本地状态,轻则重复工作,重则把状态文件写坏。

Google 的文章举了一个 Tech Briefing Agent。它每 30 分钟抓取 Hacker News 和一些 AI 工程来源,把已见 URL 和当天简报放在 /data,收到 POST /api/webhook 后还能即时处理一条分享链接。这个场景很典型,一边需要后台轮询,一边又需要随时接住外部事件。

VM 当然能做。

问题是,许多个人项目和小团队并不缺一台能开机的机器,缺的是不必再维护一台机器。系统更新、SSH、磁盘、反向代理、证书、监控、意外重启后服务没起来,这些琐碎事会一点点把一个本来很轻的 Agent 拖重。Google 对比的标准 1 vCPU VM,月成本常落在 15 到 25 美元,低配分数 CPU 虚机虽可能更便宜,却仍要承担整套主机运维。

Cloud Run Instances 把它放在中间。一个实例持续运行,附带 HTTPS 入口,容器由平台管理,数据可以挂载 Cloud Storage。它不是为了替代所有架构,而是为单 Worker 的长循环任务提供一个不那么别扭的落点。

先看清它承诺的边界

这里有个特别容易误解的地方。常驻,不等于永不重启。

Google 明确写了,Cloud Run Instance 最长运行到大约 7 天仍可能重启。你的应用必须能优雅地恢复自己的调度。这个约束反而很重要,它逼着你从一开始就把 Agent 当成可恢复的 worker,而不是一段只要进程活着就万事大吉的脚本。

我会把这件事写进 Agent 的第一条设计原则。

内存只能当缓存,不能当事实来源。

假设一个 DevOps Agent 正在分析一批告警。它在 RAM 里记录了前 200 条日志,准备调用模型做归因,恰好实例被重启。若任务进度、幂等键和已处理结果都只在内存里,你只能接受重复分析或直接丢数据。更糟一点,若它会触发工单、发消息或改配置,重试可能把动作做两遍。

更稳妥的做法是把状态分三层。

  • 临时上下文放内存,重启丢了也无所谓
  • 任务游标、去重记录、运行结果落到持久化存储
  • 有副作用的动作附带幂等键,先记录意图和结果,再向外部系统提交

Google 示例把 Markdown 简报和已见 URL 存入挂载到 /data 的 Cloud Storage。对个人资讯 Agent 这很合适,成本低,也足够直观。不过官方也提示过一个细节,Cloud Storage FUSE 挂载不适合拿 SQLite 当状态数据库。SQLite 依赖文件锁和本地文件系统语义,放到网络对象存储挂载层,往往会在并发或故障恢复时给你意外惊喜。

这个事儿我也踩过坑。很多人看到「能挂成本地目录」就下意识把本机写法整个搬上去,开发环境没问题,上云后才发现锁竞争和文件一致性并没有照着预期工作。

若你的 Agent 只有一个实例,状态量很小,JSON 或 Markdown 加原子写入可以够用。若任务需要强一致的去重、队列或并发协调,直接用 Cloud SQL、Firestore、Redis 或托管队列会更省心。别为了省一项托管服务,给最脆弱的状态层找麻烦。

真正省钱的不是机器,而是把三种触发收进一个进程

Cloud Run Instances 最有意思的地方,不只是「一直开着」,而是让周期任务、网页面板和 Webhook 可以共用一套状态和进程。

传统做法通常要拆开。Cloud Scheduler 触发 Cloud Run Job 抓取数据,另一个 Cloud Run Service 展示页面、接 Webhook,中间再加消息队列来防止并发写状态。这个架构没有错,甚至在规模起来后更合理。它的好处是各部分独立扩缩容,闲时计算成本能非常低。

但它也会带来更多拼装工作。

两个部署单元,两份权限,调度器,一个队列,任务之间的数据契约,还要处理 Dashboard 冷启动。对一个每半小时运行一次、每次只做几分钟工作的私人 Agent 来说,这套组件的心智成本可能已经高过实际业务。

单 Instance 的模型更像一间小而完整的工作室。asyncio 或你熟悉的任务循环负责定时任务,HTTP server 负责面板和 Webhook,状态就在挂载目录或外部数据库。它并不追求把云资源压到理论最低,而是在为简单性付费。

我一直觉得,个人项目和早期工具最容易犯的错误,是一上来就套一张企业级架构图。你会得到很完整的服务清单,却迟迟没有一个真正持续工作的 Agent。

这时候,一个单实例 Worker 是好起点。

不过别把「单实例」理解成没有并发。一个 Webhook 可以在轮询任务执行时到达,一个手动刷新也可能和自动任务撞车。你需要明确每类任务的并发策略。

对于资讯抓取,常见选择是同一时间只允许一个刷新任务,后来的请求复用正在进行的 job 或返回当前状态。对于告警处理,可以按告警 ID 分区,但对同一资源加锁。对于会产生外部副作用的任务,必须先做去重,再执行。

不要让 Agent 自己靠一句「我应该已经处理过了」来判断。

5.70 美元的配置,前提比数字多

Google 文章里给出的成本来自 1 vCPU、1 GiB 内存和 shared CPU 的组合。官方示例还提醒,如果省略资源参数,默认可能变成 2 CPU、2 GiB,月成本约 11.40 美元。模型 API 调用、Cloud Storage、网络出站和日志费用也不在那张基础算术里。

更现实的是,部署成本只是总账单的一部分。

一个每 30 分钟扫网页、把长文章全量塞给模型的 Agent,真正贵的很可能不是容器,而是 token。示例选择 Gemini 2.5 Flash 来做日常摘要,理由也很朴素,简单摘要任务没必要每次都请最强模型。Google 给出的价格对比里,较新 Flash 模型输入为每百万 token 1.50 美元,而 Gemini 2.5 Flash 为 0.30 美元。

这不是让你一律选便宜模型。

更好的方式是把模型层也做成预算策略。先用规则过滤重复来源、广告页和低质量内容,再对标题、摘要和正文分级。普通资讯用快模型,遇到影响架构决策的长文才升级模型或让人确认。把「是否值得推理」作为系统的一步,而不是每个输入默认 full send。

对 Channing 这种会持续做 AI 日报和技术选题的场景,这个设计尤其有用。RSS 抓取、去重、来源质量检查和候选排序可以在轻模型或规则层完成。真正进入深度写作的主题再进入更昂贵、更慢的研究流程。云上常驻的 Agent 应该帮你减少无效输入,不该稳定地把无效输入放大成 token 消耗。

公网 Webhook 是最容易被忽略的一扇门

示例用 --public 暴露 HTTPS 地址,方便接收手机分享、GitHub Release 或即时链接。这确实方便,可一旦入口公开,你部署的就不只是一个后台脚本,而是一项对外服务。

这里至少有四件事不能偷懒。

  • 验证请求来源,GitHub、Slack、Stripe 一类平台都应校验签名,不要只看一个自定义 Header
  • 给入口限流,避免任何人用一堆请求把你的 Agent 和模型额度打穿
  • 对输入做长度、类型和 URL 校验,Webhook 内容不是可信 prompt
  • 将高风险操作与接收事件分离,收到请求不代表可以直接执行删除、发布或改权限

很多人会把 prompt injection 当成模型层的小毛病。可在一个能抓网页、发请求、调用工具的 Agent 里,它更像输入链路的安全问题。你抓到的文章标题、网页正文、issue 评论,都可能携带让模型忽略原任务的文本。最实用的防线不是再写一条「不要被注入」的 prompt,而是减少不必要权限,把外部文本和系统指令隔离,并让所有敏感动作经过确定性规则或人工确认。

安全这块不要等功能稳定了再补。一个 5.70 美元的服务,照样能造成一笔远高于 5.70 美元的损失。

权限和密钥,别为了方便塞进环境变量截图里

Google 的部署步骤里有两个很正确的默认动作,给 Agent 单独创建 service account,只授予目标 bucket 的 roles/storage.objectUser,再把 Gemini API key 放进 Secret Manager,通过运行身份读取。

这看上去像云厂商教程里的固定台词,但对 Agent 其实格外关键。

Agent 和普通 Web 应用的差别在于,它会尝试更多动作。你今天只让它读资讯,明天可能就想让它创建 issue、发 Slack、更新文档。若一开始给了项目级 Owner 权限,之后每增加一个工具能力,都在放大同一个凭据被误用的半径。

我建议按动作建立服务账号,而不是按应用建立一个万能账号。只读采集器不该能写工单。Webhook receiver 不该能直接读生产数据库。部署 Agent 不该持有账单权限。即使它们暂时跑在同一个实例,也可以通过不同凭据和调用边界把权限切开。

这会让初始配置多几步,但后面排查权限、做审计和收紧范围会轻松很多。

哪些情况别用它

Cloud Run Instances 并不是小 VM 的通用替身。Google 自己列出了三个不适配的方向,我很认同。

大规模并行批处理,例如一次处理 10,000 份文档、需要上百 worker 时,用 Cloud Run Jobs 或 GKE 更符合模型。高突发的公网 API,需要瞬时扩到数百实例并在空闲时归零,标准 Cloud Run Service 更合适。要在容器里托管 70B 开源模型、吃 H100 的场景,则应该看 GKE 或 Compute Engine。

我还会补一个边界,必须做高可用、允许多副本接管的生产控制系统,也别把「单实例常驻」当终局。它天然有单点。可以把它当一个可靠的原型和轻量 worker,但当任务重要到停一个实例就影响用户时,就该引入队列、外部状态和多副本策略。

不是说 Cloud Run Instances 不行,而是别用一个舒服的起点,假装它已经是终点。

一个可以直接拿走的最小清单

如果你准备本周把一个 Agent 放到 Cloud Run Instances,我建议上线前逐项过一遍。

  • 重启后能从持久化状态恢复,内存不保存唯一事实
  • 所有外部副作用都有幂等键和可追踪的结果记录
  • 任务并发规则明确,同一资源不会被两个请求同时改写
  • 密钥只放 Secret Manager,运行身份采用最小权限
  • 公网 Webhook 校验签名、限流、记录审计日志
  • 预算同时覆盖实例、模型 token、存储、日志和网络
  • 告警至少能告诉你进程重启频率、任务失败次数和外部调用错误

这份清单并不酷。

可它会让你的 Agent 在第七天被平台重启时,在半夜收到一条异常 Webhook 时,在模型接口偶发超时时,仍然像一个可以交付的服务,而不是一段碰巧还活着的代码。

每月 5.70 美元当然是个好消息。它把常驻 Agent 从「要不要先开台服务器」变成了「值不值得给它设计一套可靠的运行方式」。

后一个问题,才是工程真正开始的地方。

参考资料