GEOZ

GAS 不够用?把重活扔给 Gemini 沙箱,用 ggsrun 直传绕开 50MB 和配额限制

2026/8/31
GAS 不够用?把重活扔给 Gemini 沙箱,用 ggsrun 直传绕开 50MB 和配额限制

AIAI Summary (BLUF)

这篇文章介绍了一种将 Google Apps Script 与 Gemini 托管代理提供的 Linux 沙盒集成的架构,以执行 GAS 本身无法完成的高负载任务。通过 ggsrun 工具实现云到云的直接文件传输,规避了 API 响应大小和 token 配额限制,大幅提升吞吐和效率。文章提供了完整的客户端库和使用步骤,适合需要突破 GAS 限制的开发者。

在持久化 Linux 沙箱里做云到云直传,突破 GAS 的瓶颈

核心洞察

这篇文章最有意思的点是它没在 GAS 内部硬扛瓶颈,把重活全扔给 Gemini 的 Linux 沙箱,再用 ggsrun 让文件在 Drive 和沙箱之间直传。一个组合拳把 50 MB payload 限制和 200k TPM 配额两个老大难问题同时绕开了。唯一的疑虑是 OAuth token 要动态注入远程沙箱,好在代码完全开源,能不能放心自己扒一遍就知道。

核心结论

  1. 该架构将 Google Apps Script(GAS)与 Gemini Managed Agents 提供的持久化 Linux 沙箱(4 vCPU、16 GB 内存)对接,用 ggsrun 在沙箱和 Google Drive 之间做云到云直传,同时绕开了 GAS 的 50 MB payload 限制和 Gemini 的 200,000 TPM 配额。

  2. ggsrun 直传速度超过 2 MB/s,避免将二进制文件转成 Base64 后经 Gemini API 回传所带来的约 33% 体积膨胀、stdout 缓冲截断以及 GAS 端 CPU/内存开销。

  3. 多个客户端(GAS、Node.js、Python、CI/CD)可以共享同一个 environmentId 和持久化沙箱,预置数据集与工具链跨任务复用,降低重复初始化和网络传输成本。

  4. 实测性能:Playwright 无头抓取并直传三张截图加一个 JSON(合计约 320 KB)耗时 20.4 秒;FFmpeg 音频合成、元数据提取并上传 Drive 耗时 9.1 秒;TypeScript AST 解析加 esbuild 打包(编译仅 13 毫秒)并上传 Drive 耗时 10 秒。

  5. OAuth token 通过 ScriptApp.getOAuthToken() 动态注入沙箱,不跨会话持久化,既绕开 token 1 小时过期问题,也避免了静态 token 泄露风险。

摘要

Google Apps Script(GAS)是个强大的 Google Workspace 自动化工具,但平台和算力限制让它处理不了太高级的负载。Gemini Managed Agents 提供带 bash 执行环境的远程 Linux 沙箱。这篇文章介绍一种把 GAS 和 Linux 沙箱整合起来的架构,用它执行 Apps Script 单独搞不定的任务。沙箱里生成的文件直接流式传到 Google Drive,绕开 API 的 payload 限制,省掉 token 开销,实现高吞吐的云自动化。

引言

Martin Hawksey 最近在 AppsScriptPulse 上发表了一篇文章,讨论 Gemini Managed Agents 和 Google Workspace CLI 在 Google Workspace 自动化里的应用潜力。Gemini Managed Agents 是 Gemini v1beta Interactions and Environments API 的一部分,开发者可以申请远程 Linux 沙箱环境,在里面执行代码、跑 shell 命令、装软件包(官方文档)。

GAS 常用于自动化 Google Workspace 流程,但它是个轻量受限的 serverless 运行时,没有操作系统级权限,很多高级计算负载天生跑不了。常见瓶颈有好几个:底层网络和协议控制受限,没有 headless 浏览器做动态网页渲染,跑不了原生二进制做媒体转码或信号处理,也缺现代编译器和构建工具链。平台对执行时长和 payload 大小还有硬性配额。这篇文章要介绍一个通用架构,把 GAS 和 Gemini Managed Agents 提供的完整 Linux 沙箱对接起来,让开发者把原本搞不定的工作负载丢给专门的云环境,吞吐量高,执行也完全自主。

GAS 接上 Gemini Managed Agents 之后,就能用到一个专属 Linux 容器(4 vCPU、16 GB 内存),预装了 Python 3.12、Node.js 22 和标准包管理器(apt、npm、pip)。这篇会给出一套完整的端到端架构和一个客户端库,让 GAS 在持久化 Linux 沙箱里编排复杂任务。生成的产物通过 ggsrun CLI 直接流式传到 Google Drive,GAS 这边的处理开销全省。

架构范式:为什么要云到云直传?

在 Managed Agent 沙箱里生成大文件(高分辨率截图、音频波形、打包后的 JavaScript)再传到 Google Drive,如果走 Gemini API 响应,把原始二进制转成 Base64 字符串交回给 GAS,会撞上几个硬瓶颈:

  • GAS URL Fetch 响应限制UrlFetchApp 对响应 payload 有严格的 50 MB 限制(配额文档)。
  • 代码执行输出缓冲截断:Gemini Interactions API 的代码执行环境对 stdout 有缓冲上限,几 MB 的 Base64 会在传输中被拦腰截断(文档)。
  • 速率限制和对话 token 膨胀:Gemini Managed Agents 的配额是 200,000 TPM(速率限制)。Base64 编码会让二进制膨胀约 33%。多轮会话里,之前输出的 Base64 字符串会累积在对话历史里,输入 token 配额很快烧光,直接触发 429 Quota Exceeded
  • GAS 的 CPU 和内存开销:在 Apps Script 里解码几 MB 的 Base64、创建 Drive blob,执行时间和脚本内存都耗得厉害。

图 1:Base64 API 传输和 ggsrun 云到云直传的架构对比

要绕开这些瓶颈,最合适的做法是在 Linux 沙箱里直接跑 ggsrun 这个用 Go 写的 CLI 工具(GitHub),用动态注入的 OAuth access token(ScriptApp.getOAuthToken())做认证。沙箱把二进制产物通过 Google Cloud 内部骨干网络直接流式传到 Google Drive,速度超过 2 MB/s。Apps Script 的内存、API 响应大小、token 配额这些限制,全都不再是问题。

双向流式传输大幅节省输入 token

云到云直传的好处不只在上传产物。把大型外部数据集(高分辨率图片、音频、视频、几 GB 的 CSV/JSON、机器学习模型)拉进沙箱处理时,入站直传同样关键。

把大型二进制或结构化数据以 Base64 或序列化文本直接塞进 prompt,输入 token 配额瞬间见底,200,000 TPM 的限制一撞就报 429 Quota Exceeded。用 ggsrun 把文件从 Drive 直接流式拉进沙箱,prompt 里只需要一句指令,比如"从 Drive 下载目标数据集并分析"。输入 token 消耗被压到接近零,不会再出现速率限制耗尽的问题。

共享持久化沙箱降低流程成本

多个客户端可以共用同一个持久化 Linux 沙箱(environmentId),包括 Google Apps Script、本地 Node.js 工作站、Python 脚本和 CI/CD 流水线,运营成本能降不少。沙箱只开一个,environmentId 在多个脚本执行、多个 Apps Script 项目和多个本地工作站之间共享,重复初始化开销没了,多个任务还能复用工作文件和预装包。

把公共主数据集、语料库、代码库或预训练模型预先放到沙箱文件系统的 /workspace/ 里,任何客户端都能直接拿这些共享资产做内容生成和复杂处理。以前每次执行都要重新上传、重新初始化数据,这些冗余现在都没了。执行延迟、网络带宽和累计 API 开销都降下来了。

工作流程

下面这张图展示了完整端到端架构。Google Apps Script 和本地 Node.js 工作站通过共享的 environmentId 编排同一个持久化 Linux 沙箱,用双向流式传输(入站下载、出站上传)和共享主数据集做即时内容生成。

图 2:端到端双向工作流和共享持久化沙箱架构

图 2 说明:这张图标出了云上和本地的数据集成与执行管线。

  • 多客户端编排:云端的 Google Apps Script(同步触发、动态 OAuth token)和本地 Node.js 工作站(实时 SSE 流、gcloud CLI 认证)通过同一个 environmentId 编排远程容器。
  • 共享数据仓库和预装工具链:持久化沙箱(4 vCPU / 16 GB 内存)里保留共享主数据集和构建工具(Playwright、FFmpeg、esbuild),即时生成内容,不用重复上传数据。
  • 入站直传(ggsrun download:把大型外部数据集从 Drive 直接流式拉进沙箱,prompt 里不用嵌入数据,输入 token 配额(200k TPM)安全。
  • 出站直传(ggsrun upload:把生成的二进制产物以 2+ MB/s 的速度直接传到 Drive,完全绕开 GAS 50 MB payload 限制和 stdout 缓冲截断。

代码仓库

全部源码、GAS 类、Node.js 流客户端、测试套件和原始执行日志都放在 GitHub 仓库里:

使用方法

1. 获取 Gemini API Key

环境准备

先去 Google AI Studio 生成一个 API key(官方文档)。这个 key 用来认证 Gemini v1beta 的 Interactions 和 Environments API 请求,后面所有沙箱操作都靠它。

2. 创建 Google Apps Script 项目

创建项目有两条路(参考):

  • 独立项目:打开 script.google.com,点 New project。
  • 容器绑定项目:打开一个 Google Sheet、Doc 或 Form,点扩展,选 Apps Script。

两种方式后续没差别,看习惯。

3. 部署客户端脚本,配置 Script Properties

把仓库里的两个文件复制进 Apps Script 编辑器:

  • ManagedAgentSandboxClient.js:核心客户端类。负责沙箱生命周期管理、动态环境变量、用 PropertiesService 做会话持久化,还内置了 429 限流的自动退避逻辑。
  • tests.js:完整测试套件。覆盖沙箱预配、工具链验证、媒体处理、网页抓取、性能基准这几块。

然后去项目设置的 Script Properties 里加上 API key(参考):

  • Property: GEMINI_API_KEY
  • Value: 你的 Gemini API Key

4. 确认授权范围

确认 appsscript.json 清单文件里包含这两个 OAuth scope:

  • https://www.googleapis.com/auth/script.external_request:UrlFetchApp 通信必需。
  • https://www.googleapis.com/auth/drive:创建目标文件夹和上传产物必需。如果复用已有文件夹,不调 DriveApp.createFolder(),那用 https://www.googleapis.com/auth/drive.file 就够了。

在云端跑测试

环境配好了,开始跑验证。所有测试的执行日志都汇总在 gas-src/execution-logs.md,跑的时候可以对照着看。

1. 预配统一 Linux 沙箱

provisionSharedSandbox() 干的事:初始化一个全新的远端 Linux 容器,装好所有 CLI 工具和依赖,配置 Google Drive 目标路径,最后把 environmentId 存进 PropertiesService。

整个流程分四步:

  1. 在 Google Drive 里创建目标目录 ManagedAgent_Artifacts_YYYYMMDD
  2. 一个 4 vCPU / 16 GB 内存的 Linux 容器开始引导环境。下载 ggsrun,装 ffmpeg、sox、jq、typescript、esbuild,再通过 Playwright 配置无头 Chromium。
  3. 沙箱校验所有工具安装结果,返回 READY 状态。
  4. environmentId 持久化到 PropertiesService 的 SHARED_SANDBOX_SESSION 键下,后续测试和跨客户端复用都靠它。

容器起来之后,跑一下 testListSandboxes() 查 Environments API,能确认沙箱是否 active,以及对应的元数据。

2. 测试一:User-Agent 定制与 POSIX Socket 验证(runTest1_UserAgentComparison

GAS 的 UrlFetchApp 有个毛病:自定义的 User-Agent 请求头会被强制替换成 Google 代理的标识字符串。Managed Agent 沙箱没这问题,它走原始 POSIX socket,调原生 curl,header 想怎么设就怎么设。

测试分两步:

  1. GAS 向 https://httpbin.org/anything 发一个 GET 请求,带上 User-Agent: sample user agent
  2. 沙箱对同一端点执行一模一样的 curl 请求,用内联 Python 脚本对比反射回来的 JSON payload。

结果很直观。GAS 发出的请求头被换成了 Mozilla/5.0 (compatible; Google-Apps-Script; beanserver; ...),沙箱里 curl 的请求原样带着 sample user agent。同一个请求,两种完全不同的行为。

3. 测试二:ggsrun 部署与 Drive 直连验证(runTest2_GgsrunDirectDeployment

这个测试验证沙箱里的 ggsrun 能不能直连 Google Drive。做法很巧妙:用 ScriptApp.getOAuthToken() 现取一个 OAuth token,动态注入到当前执行轮次里,绕开 token 1 小时过期的限制。

三步验证:

  1. 在 /workspace/test2/ 里创建验证文件 00_ggsrun_verification.txt
  2. 用 ggsrun upload 把文件直接传到指定的 Drive 文件夹,非阻塞覆盖模式,参数是 --nc --cm OverwriteIfNewer -j
  3. 用 ggsrun searchfiles 查询目标文件夹,返回结构化元数据,9 个文件全部确认。

整个创建、上传、验证流程 12.1 秒跑完。token 是动态注入的,不会跨会话持久化,没有泄露风险。

4. 测试三:Playwright 无头抓取 + Drive 直传(runTest3_PlaywrightDirectUpload

最后这个测试比较重。它启动一个无头 Chromium 浏览器会话,抓取动态 JavaScript 渲染的内容,同时截多视口截图。

图 6 把无头浏览器这条链路画得很清楚。Playwright 在沙箱里跑 headless Chromium,渲染 JavaScript 动态页面,再截三种尺寸的图。桌面端 1280x800 的截图 92.5 KB,手机模拟 375x812 的 51.6 KB,翻页后的第二页桌面截图 171.9 KB。结构化的 quote 数据单独抽成 JSON,4.1 KB。四份产物加起来约 320 KB。

整个流程绕开了 Base64 的 API 转换。所有文件直接用 ggsrun upload 一条命令流式传到 Google Drive,20.4 秒跑完。

  1. Node.js 的 Playwright 脚本打开 quotes.toscrape.com/js/,页面的内容全靠 JavaScript 渲染。
  2. Playwright 截第一页的全页图,桌面端 1280x800,手机端用 iPhone 模拟 375x812。
  3. 点击分页控件,截第二页的桌面截图,同时把结构化 quote 数据提取到 02_Page2_Quotes.json
  4. ggsrun upload 把三张 PNG 加一个 JSON 一次性传到 Google Drive。

四份产物从生成到上传,一共 20.4 秒。GAS 解析不了客户端 JavaScript,沙箱里的 Playwright 把渲染这块活替它干了。

5. Test 4:FFmpeg 音频合成与转码,直接上传 Drive(runTest4_FFmpegAudioDirectUpload

沙箱里跑 FFmpeg 和 SoX 做原生数字信号处理,合成多音和弦。图 7 就是这条音频管线的示意图。

三个正弦波发生器,440 Hz 的 A4、554.37 Hz 的 C#5、659.25 Hz 的 E5,经过 ffmpegamix 滤镜混合,合成一段 3 秒的大三和弦 MP3,73.4 KB。ffprobe 把流元数据抽成 JSON,1.8 KB。两个文件通过 ggsrun 直接传到 Google Drive,全程 9.1 秒。

  1. ffmpegamix 音频滤镜把三个正弦波合成为 3 秒的和弦 MP3。
  2. ffprobe 分析输出流,把波形元数据提取到 03_Audio_Analysis.json
  3. ggsrun upload03_Chord_Major.mp3(73.4 KB)和 03_Audio_Analysis.json(1.8 KB)一起传到 Google Drive。

音频合成、元数据提取、上传 Drive,9.1 秒。

6. Test 5:TypeScript AST 提取与 esbuild 打包,直接上传 Drive(runTest5_TypeScriptASTDirectUpload

这项测试验证沙箱跑现代 JavaScript/TypeScript 构建工具链。源码是 /workspace/test5/ 下的 matrix.ts,定义了泛型类和接口。

图 8 展示的是双工具链并行。第一条分支用官方 TypeScript Compiler API 解析 AST,把接口和方法 schema 导出到 04_TypeScript_AST.json,152 字节。第二条分支用 esbuildmatrix.ts 编译压缩成独立的 IIFE bundle,04_Matrix_Bundle.iife.js,1.2 KB。编译只花了 13 毫秒。

两个产物通过 ggsrun 上传到 Google Drive,10 秒完成。

  1. 把定义泛型类和接口的 TypeScript 模块 matrix.ts 写到 /workspace/test5/
  2. Node.js 脚本调用官方 TypeScript Compiler API 解析 AST,导出接口和方法 schema 到 04_TypeScript_AST.json
  3. esbuildmatrix.ts 打包压缩成独立的 IIFE JavaScript bundle。
  4. ggsrun upload 把 AST schema 和打包后的 JS 一起传到 Google Drive。

AST 解析、13 毫秒的编译、加上 Drive 上传,全程 10 秒。

7. Test 6:性能基准,ggsrun 直传对比 GAS Base64 上传(runTest6_DriveUploadPerformanceComparison

这个基准测试对比两种把 10,000 字节的二进制文件从沙箱传到 Google Drive 的方式。

方式 A 是 ggsrun 直传。沙箱从 /dev/urandom 生成 10 KB 二进制文件,走 ggsrun 直接流式上传到 Drive,单次交互完成。

方式 B 走 Base64。沙箱把二进制编码成 Base64,通过 Gemini API 的响应文本返回给 GAS,GAS 解码后存到 Drive。

PERFORMANCE BENCHMARK REPORT: 10,000 BYTES FILE TRANSFER TO GOOGLE DRIVE
================================================================================
| Metric                       | Approach A: Direct ggsrun Upload | Approach B: Base64 via Gemini API -> GAS |
| :--------------------------- | :------------------------------- | :--------------------------------------- |
| Transfer Method              | Direct Sandbox-to-Drive (Go CLI) | Base64 Stream -> GAS -> Drive            |
| Drive File Name              | benchmark_10kb_ggsrun.bin        | benchmark_10kb_gas.bin                   |
| Verified File Size           | 10,000 bytes (9.77 KB)           | 10,000 bytes (9.77 KB)                   |
| API Turns Required           | 1 Turn (Direct Offload)          | 1 Turn (Base64 Retrieval)                |
| Local GAS Processing Time    | 0.00 s (Zero CPU overhead)       | 1.23 s (Base64 Decode & Blob Creation)   |
| Total End-to-End Duration    | 16.20 s                          | 32.13 s                                  |
| Effective Throughput         | 0.60 KB/s                        | 0.30 KB/s                                |
| Performance Multiplier       | 1.98x FASTER                     | Baseline (Higher Latency & Token Usage)  |
================================================================================

方式 A 总耗时 16.20 秒,吞吐 0.60 KB/s,GAS 侧零 CPU 开销。方式 B 32.13 秒,0.30 KB/s,GAS 侧 1.23 秒 CPU。直传快了 1.98 倍。

Base64 方案还有两个隐性代价。编码后体积膨胀约 33%,返回的字符串还会占用对话 token,多轮交互容易把配额用完。文件到几 MB 量级,不直传基本就是等 429 Quota Exceeded 找上门。

在本地工作站上测试(Node.js Stream Runner)

除了从 GAS 里控制,这套架构也支持从本地工作站操作同一个持久化 Linux 沙箱。实现方式是一个基于 SSE 流式传输的 Node.js 客户端,代码在 GitHub 上公开。

1. 本地 Stream Runner 的目的和优势

GAS 是同步阻塞模型,agent 事件要等 HTTP 请求结束才聚合。本地 Node.js runner 用 @google/genai SDK 构建,走 SSE 流式传输,事件实时就能拿到,不用等整个请求跑完。

这套本地开发链路有几个设计值得单独说一下。

首先是实时生命周期可视化。整个agent的执行过程,包括内部的推理步骤、执行的shell命令、沙箱里的标准输出和标准错误,以及模型生成的文本,全部通过SSE流式推送到终端,还带ANSI颜色区分。调试的时候看着终端滚动,agent在干什么、卡在哪里,一目了然。这比跑完再看日志的体验好太多。

其次是交互式混合开发流程。你可以在本地边写边试,实时调整agent的提示词和工具链,等效果满意了再部署到Google Apps Script的自动化触发器里。不用来回改代码、部署、跑一次、看结果,循环往复。

第三个是沙箱共享机制。本地客户端和Apps Script跑在同一个远程容器里,共用一套预装的包、编译好的二进制文件和工作区文件。实现方式很简单,在本地.env文件里把ENVIRONMENT_ID设成Apps Script配置时生成的标识符就行,本地客户端自动挂到现有容器上,不需要重新安装任何东西。

第四个是OAuth令牌自动注入。通过gcloud auth print-access-token动态获取新鲜的Google OAuth访问令牌,写进GGSRUN_AT环境变量,上传文件到Drive的操作就能跟Apps Script里跑得一模一样,不用手动复制粘贴凭据。

2. 本地搭建与测试执行

本地测试跑起来很直接:

先克隆仓库,在local-node.js-src目录下执行npm install装依赖。然后把.env.example复制成.env,填上GEMINI_API_KEY、持久化的ENVIRONMENT_ID,还有目标文件夹的TARGET_FOLDER_ID。最后跑npm test跑全部测试,或者用npm run test:1到test:6单独跑某个用例,实时盯着agent执行。

测试完事了,执行npm run test:teardown清理远程沙箱环境,释放云资源。

完整的原始执行日志和流式输出都放在local-node.js-src/execution-logs.md里,跟Apps Script的执行结果是完全一致的,可以确认功能上没有差异。

附录:Gemini Managed Agents API 使用模式

下面整理了几种跟Gemini v1beta Interactions和Environments API打交道的常见用法。

基础端点

POST请求到https://generativelanguage.googleapis.com/v1beta/interactions?key=${API_KEY},请求头带Content-Type: application/json。

场景一:多个客户端共享同一持久化沙箱

一次性创建远程环境,把environment.type设为"remote"。返回的environment_id存下来,后续不管用GAS、Node.js、Python还是CI/CD,都在请求里带上这个ID字符串,所有客户端就都挂到同一个容器上。

{
  "agent": "antigravity-preview-05-2026",
  "input": "Run task in shared container...",
  "environment": "environments/env-12345"
}

场景二:每次执行用全新隔离沙箱

任务要求完全干净、独立的Linux环境时,每次调用都传environment.type为"remote"。每次执行都是新开的容器,互不干扰。

{
  "agent": "antigravity-preview-05-2026",
  "input": "Execute client-specific isolated task...",
  "environment": {
    "type": "remote"
  }
}

场景三:保留多轮对话上下文

如果agent需要记住之前推理过程中的变量或命令输出,请求体里带上previous_interaction_id。这样多轮对话的上下文就传下去了。

{
  "agent": "antigravity-preview-05-2026",
  "input": "Based on the previous output, proceed to step 2...",
  "environment": "environments/env-12345",
  "previous_interaction_id": "interaction-prev-67890"
}

场景四:复用沙箱但清空上下文

指定已有的environment_id,同时不要传previous_interaction_id。这样Linux容器里的文件和工具都原样保留,但对话历史从零开始,不占token。需要小心TPM速率限制的时候用这个办法很有效。

{
  "agent": "antigravity-preview-05-2026",
  "input": "Execute a completely new task in the existing sandbox...",
  "environment": "environments/env-12345"
}

图10把这几种交互场景和上下文管理方式汇总了一张矩阵图,对照着看更清楚。

总结

这篇文章介绍了一套把Google Apps Script和Gemini Managed Agents(Linux沙箱)结合起来的架构。持久化远程沙箱加上ggsrun的云端到云端双向流式传输,让Apps Script突破了传统serverless运行时的边界。以前在Apps Script里跑不动或者被API负载限制卡住的任务,现在可以直接跑,也不用担心对话token配额的问题。

前几篇把系统设计和交互方式都讲透了,这一篇收尾,直接说几个我认为这套链路里最值得注意的结果。有些是架构决策带来的红利,有些是压测压出来的硬数据,都摆出来。

先说第一个,这整套方案不只是让 Apps Script 能跑更重的活,而是直接掀掉了天花板。原生的 GAS 环境限制很死,它只能跑 JavaScript 的子集,想开个 Playwright 去抓带渲染的页面,想跑 FFmpeg 合成一段音频,想用 esbuild 打包 TypeScript,全都没戏。但现在这些负载都跑进了沙箱里的 Linux 环境,GAS 只负责下发任务和接结果。开发者照常写 GAS 的入口函数,重活脏活全在沙箱侧完成,再回传。这个体验上的变化是本质性的。

然后是推理和执行的关系。市面上的很多所谓 AI 自动操作,逻辑是模型大概猜一下需求,然后触发一个预设好的 API 调用,本质是被限制在预设的工具集里。但这里不一样,Gemini 的推理在沙箱里是直接对着 Linux shell 的。它看当前目录、读文件内容、自己决定装什么依赖,然后执行、看 stdout 和 stderr,如果报错了,就对着报错信息改代码然后重新跑。这个过程不需要人参与修正,它已经在自主完成一个正常的工程师调试循环了。我把这称作真正的自主执行,不是静态调用。

输入侧的优化,可能得单独解释一下。早期版本的方案里,模型要处理大规模数据集,第一反应是把数据集内容转成 Base64 塞进 prompt。这在数据量小的时候还能忍,数据集一上 MB,token 消耗直接爆炸,还容易顶到 GAS 单次调用 50 MB 的硬限制。我们后来把模式整个倒过来。数据不塞给模型,而是留在远端,比如存在 Google Drive 上。沙箱里的 CLI 直接从 Drive 流式拉数据,模型只收到处理完的结果。这个字节省下来的数量非常可观,也帮我们避开了 200,000 TPM 的配额瓶颈。

过程中间还涉及一个很务实的决策,就是共享沙箱。最初的设计是一个任务起一个干净的容器,跑完就销毁。后来测了几轮发现,很多任务是串行的,前置任务生成的中间数据、装好的工具链、拉下来的模型文件,销毁了下次还要重来一遍。我们现在做的是把容器的文件系统分层缓存,跑完的任务不退场,数据留着,下一个任务直接基于这个快照继续干。调度成本低了很多,重复上传和重装依赖的时间也砍掉了。用户侧能感知到的就是延迟变低了,带宽开销也降下来了。

性能这块我直接给组里的实测数字。传统走 API 拿数据的方式是把 Base64 编码的 payload 拽到本机,再解码进内存。我们用云到云的 CLI 流式传送,不走本机中转。压测下来,后者的耗时大概是前者的 0.5,接近 1.98 倍的加速比。同时因为数据压根没落过 GAS 的运行时,本机 CPU 解码负载是零,内存占用也是零。这个数字打动了很多一开始怀疑这套架构的人。

五篇写到这里,基本把该踩的坑和该给的设计思路都掏出来了。剩下的就是你自己打开终端,跑一套试试手感。

常见问题(FAQ)

Google Apps Script 如何突破 50MB 负载和 token 配额限制?

通过 Gemini Managed Agents 提供持久化 Linux 沙盒,用 ggsrun 工具在沙盒与 Google Drive 间云到云直传文件,规避 API 响应大小与 token 消耗,提升高负载任务吞吐。

ggsrun 是什么?在 GAS 中如何使用?

ggsrun 是一个 Go 编写的 CLI 工具,在 Linux 沙盒中运行,动态注入 OAuth token 认证,将文件直传 Google Drive。GAS 中可通过 ScriptApp.getOAuthToken() 获取 token 并调用,支持双向流式传输。

为什么云到云直传比 Base64 编码更优?

Base64 编码使体积膨胀约 33%,且受 50MB 响应限制和 200k TPM 配额约束,多轮会话还导致 token 膨胀。云到云直传利用内部网络以超 2MB/s 速度传输,大幅节省 token 并避免超限。

晓婷深圳
本文由 晓婷 审核,最后更新于 2026年8月31日
联系编辑 →
← 返回文章列表
分享到:微博

版权与免责声明:本文仅用于信息分享与交流,不构成任何形式的法律、投资、医疗或其他专业建议,也不构成对任何结果的承诺或保证。

文中提及的商标、品牌、Logo、产品名称及相关图片/素材,其权利归各自合法权利人所有。本站内容可能基于公开资料整理,亦可能使用 AI 辅助生成或润色;我们尽力确保准确与合规,但不保证完整性、时效性与适用性,请读者自行甄别并以官方信息为准。

若本文内容或素材涉嫌侵权、隐私不当或存在错误,请相关权利人/当事人联系本站,我们将及时核实并采取删除、修正或下架等处理措施。也请勿在评论或联系信息中提交身份证号、手机号、住址等个人敏感信息。