用 Gemini 4 Argon 通宵优化 20 万行 Python 代码库
Optimizing a 200,000-line Python codebase overnight with Gemini 4 Argon
Google 工程师用 Gemini 4 Argon 在 Google Antigravity 中通宵运行 11 小时,对约 20.5 万行、近 800 个源文件的 google/adk-python 仓库做跨文件性能优化,最终提交的 PR 提出 6 项优化、覆盖 32 个文件,其中 2 项经评审后合入 main。
Google 工程师公开了用 Gemini 4 Argon 通宵优化 20 万行 Python 仓库的完整流程,包括 skills 配置、/goal 模式和代码评审取舍,可迁移到自有代码库。
2026年10月13日
Bo Yang 软件工程师 Google Cloud
当新模型发布时,大多数演示展示的都是从空文件夹构建的全新应用。它们看起来很有趣,但对于一名在职软件工程师来说,它们几乎无法说明该模型如何处理现有代码库。
在 Gemini 4 Argon 发布之际,我们想测试它能否在一个更难的问题上无人值守地通宵运行:在 google/adk-python 中查找并修复跨文件性能瓶颈。Agent Development Kit(ADK)是 Google 用于构建和部署企业级智能体的开源框架。
这个 Python 仓库包含近 800 个源文件、约 205,000 行代码,并有近 17,000 个单元测试作为支撑。
性能工作对模型来说是一项艰难的测试,因为你不能只打开一个文件就发现性能下降的地方。你必须从症状出现的位置之外去观察,并在长时间运行中掌握整个代码库如何组合在一起的全局图景。
本文将介绍这次 11 小时通宵运行中使用的提示词、.agents/skills 规则文件以及人工代码审查决策,这次运行将 ADK 在长会话中的内存会话准备时间缩短了约 40%,并将冷启动包导入速度提升了 21%。你将看到最终合入的两项优化、我们在审查中否决的四项优化,以及如何在你自己的代码库上搭建同样的通宵工作流。

图 1:首次模型请求前 ADK 的开销,在 50 轮和 150 轮后测量。Argon 的改动在两个时间点都将其削减了约 40%,因此随着会话变长,节省的时间也会增加。
用 .agents/skills 和 /goal 模式引导运行
目前大多数使用编码智能体进行的性能工作仍然运行在紧密的人工循环中:工程师运行性能分析器,将模型指向单个热点函数,并指定修复方案。我们想看看,当只给 Argon 团队真正关心的结果时,它会怎么做。
在第一轮中,我们在没有任何自定义仓库指令的情况下测试了 Argon。我们给了它这样一段单段提示词:
让 ADK 不给任何智能体增加明显开销:
在启动时、长会话中、多智能体和
工作流设置中。保持模型接收到的内容
和公共 API 不变,并为每项改动配上
能够捕获回归的测试。
第一轮运行了大约两个小时。Argon 在 7 分钟时编写了一个基准测试脚本,花了 70 分钟测量和阅读代码,之后才编辑了 ADK 源代码的第一行,并发现了会话复制和包导入中的真实瓶颈。第一轮的部分代码进入了我们最终合入的最终提交。
第一轮的不足之处在于维护者约定。由于 Argon 不知道 ADK 团队如何审查代码,它在 ADK 的身份验证模型上附加了一个自定义钩子,微妙地改变了其公共 JSON schema;在自定义复制器中遗漏了模拟事件边界情况;只运行了 216 个附近的单元测试;并且没有在拉取请求描述中留下基准测试数据。
第一轮证明了确实存在真正的加速空间,所以我们做了两处调整,启动了第二轮。首先,我们把团队的维护者指南放进了仓库的 .agents/skills 目录,就像给新工程师准备的入职指南。每个技能都以一个简短的 SKILL.md 索引开头,按需指向聚焦的 references/ 文件,这样我们就不会在每一轮都淹没智能体的上下文窗口。当 Argon 在晚上 9:11 开始运行时(图 2),它在动一行代码之前,先读取了 visibility.md 以了解我们私有的 _-prefixed 模块规则,并读取了 imports.md 以进行我们的懒加载检查。

图 2:Argon 在相同目标下两小时的首次运行与 11 小时的过夜运行对比。第一轮自行发现了真正的加速点,而第二轮遵循了仓库约定,运行了全部 16,892 个单元测试,并开启了一个可供审查的拉取请求。
其次,我们在 Google Antigravity 中开启了 /goal 模式,它会在上下文压缩过程中保留目标,使智能体持续运行直到任务完成。我们还加了两句话,要求提交一个未合并的拉取请求,并附上前后对比数字:
/goal 让 ADK 不给任何智能体增加明显开销:
在启动时、长会话中、多智能体和工作流设置中。
保持模型接收的内容和公共 API 不变,并为每项改动配上能捕获回归的测试。
针对 main 开启一个 ADK 维护者会批准的拉取请求,并在描述中附上前后对比数字。不要合并它。
有了仓库中的 .agents/skills 和激活的 /goal 模式,Argon 在夜间无人值守地运行了 11 个小时(图 3)。

图 3:Argon 在 Google Antigravity 中的过夜 ADK 运行。 /goal 提示固定在窗口顶部和底部,而已完成的工作折叠成摘要块,因此原始规则在数小时的编辑、基准测试和测试运行中始终可见。(截图在公开的 Antigravity 界面中重放,以移除内部工作区细节。)
6 项提案在代码审查后带来了 2 项已交付的改动
第二天早上查看过夜会话日志时,有几个行为立刻引人注目。在接触源代码之前,Argon 阅读了 12 个指南文件,并在四个测试工作负载上运行了基线基准测试:包启动、200 步对话、一个由 20 个子智能体相互交接任务的测试应用,以及一个 12 节点工作流,各运行 30 次。甚至在完成 11 小时运行前三分钟,Argon 仍在审查自己的差异,捕获了自己多智能体缓存中的一个 bug,并重新运行了全部 16,892 个单元测试,然后自行停止。
更重要的是,Argon 完成了性能分析器无法为你做的跨模块工作。性能分析器会告诉你复制会话和导入包需要时间。它不会做的是追踪 40 个文件中的每个调用方、模拟目标和共享引用,以便加速这些路径时不会破坏现有应用。
总的来说,Argon 的拉取请求在 32 个文件中提出了六项优化。其中两项优化干净利落地解决了 ADK 的核心瓶颈,并已交付到生产环境:
1. 在复制之前过滤内存中的会话历史
ADK 运行中的每一步都从加载对话历史开始。此前,ADK 的内存会话服务在每次读取时都会先深拷贝整个已存储的对话,然后再筛选出调用方所需的事件。即使只是列出会话而不包含其事件,也会先拷贝每一个事件。Argon 更新了该服务,使其在拷贝之前先筛选事件,并用一个快速、循环安全的拷贝器替换了 Pydantic 在会话和事件上的通用深拷贝路径,该拷贝器保留了共享状态字典和测试 mock。
2. 仅在需要时加载重量级包
运行 import google.adk 此前会引入实时音频和视频流、OpenTelemetry 追踪以及 Web 服务器(FastAPI 和 Starlette)相关的模块,即使只是运行一个基本的文本 agent 也是如此。仅仅删除框架中的顶层导入会破坏那些直接在模块上 mock 属性的下游测试。当 Argon 的第二轮拉取请求从 llm_agent.py 中移除三个内部 flow 导入时,全部 16,892 个开源测试都通过了,但 25 个 Google 内部测试目标失败了,因为它们 patch 的正是这些属性。最终发布的修复方案使用了惰性模块访问器,因此重量级包只在首次使用时加载,同时每个公共属性在测试期望的位置仍然可被 patch。
Argon 提出的另外四项优化呢?
我们发现模型会提出一些我们原本不会想到的创造性解决方案。其中一些创造性想法会触及框架规则,而在这些地方破坏性变更是不可接受的。

图 4:Argon 上午拉取请求中的六项优化,分为我们发布的两项和我们在代码审查中砍掉的四项。我们保留了能够干净地削减真实开销的会话拷贝和惰性导入变更,并放弃了那四项依赖脆弱状态、库私有内部实现或仅能带来合成收益的变更。
在代码审查期间,我们拒绝了另外四项变更:
- 一个多 agent 事件缓存将合成基准测试提速了 17%,但它依赖一个弱内存引用,如果 Python 在垃圾回收后复用了某个内存地址,就可能跨会话返回过期数据。
- 一项遥测检查读取了 OpenTelemetry tracer 实现上的私有属性,这可能在库的小版本升级时静默失效。
- 重写 ADK 在每次模型调用前格式化对话历史的方式,使一条核心代码路径更难阅读,却没有在我们独立的留出基准测试上改善端到端延迟。
- 为工作流事件重放添加的查找索引增加了状态跟踪的复杂性,却只对合成重放测试有帮助,而非日常的 agent 运行。
这种分工正是该工作流奏效的原因:agent 负责探索,维护者负责做减法。我们将第一轮和第二轮中最好的部分合并为一个包含 22 个文件的变更,并由 17 个新测试函数提供支持。经过 ADK 团队的审查后,它合并到了 main 分支,提交说明为“Argon generated these changes.”
基准测试结果:ADK 中的“turn”是什么,以及为什么 158 个 turn 很重要
要理解提交信息中的数字,有必要先了解 ADK 所称的 turn 是什么。
当工程师输入一个提示并得到最终答案返回时,ADK 将其称为一次 invocation。而 turn 是底层每一次 agent 行动时的内部步骤:调用工具、运行一批并行工具调用,或查询 MCP 服务器。
你使用 agent 框架的原因正是多轮工具调用,在一次运行之下会发生数十或数百个内部 turn。
在两轮运行之前,我们编写了一个 Argon 从未见过的独立留出基准测试(bench_turn.py)。在 bench_turn.py 中,单个会话针对即时模型和即时工具逐轮增长,因此时钟上的每一毫秒都是 ADK 自身的框架开销。每一轮在返回答案之前运行三轮、每轮四个并行工具调用,并在第 0、50 和 150 个先前轮次之后对 5 轮进行计时。下面的每个数字都是 6 到 12 次运行的中位数,并且在每一轮中,模型在更改前后收到的请求都是字节完全相同的。
我们在五个基准测试中针对上一个版本测试了合并后的提交(图 5):

图 5:在 Argon 的更改前后,所有五个留出基准测试中 ADK 框架开销的中位数。在长会话中,会话准备时间下降约 40%,包导入时间下降 21%,而新进程到首次请求的时间保持不变,因为延迟模块会在第一轮加载。
如何为你自己的智能体解读这些数字:
- 导入 google.adk 快 21% 会立即惠及每一位 ADK 用户,加速 CLI 命令、本地开发和测试发现。由于延迟模块在智能体运行第一轮时仍会加载,从全新进程到其首次模型请求的时间保持不变(3.07 秒到 3.09 秒)。在生产服务器上,在接收实时流量之前发送一个预热请求,这样第一个用户调用就不会承担那一次性的导入成本。
- 模型前开销减少 40% 适用于
InMemorySessionService,它为InMemoryRunner、本地评估循环、CI 测试套件以及未配置外部数据库 URI 时的默认 Cloud Run 或 GKE 部署提供支持。在一次耗时数秒的 LLM 调用中,人类不会感觉到 28 毫秒或 78 毫秒。然而,在 158 个内部工具调用交互轮次中,这些副本会累积:移除它们将完整的 158 轮运行从 65.6 秒缩短到 56.1 秒(近 10 秒的纯框架开销)。外部数据库、SQLite、Gemini 平台、Firestore 和 Redis 会话存储从存储反序列化,而不是在内存中深拷贝,因此它们的读取时间在这里没有变化。
试用 Gemini 4 Argon
企业开发者和构建者可以通过 Gemini 平台中的 API 访问 Argon,模型 ID 为 gemini-4-argon,也可在 Google AI Studio 和 Google Antigravity 中访问。
查看模型卡和开发者指南,了解完整的技术规格、token 限制和迁移说明。
试用优化后的 ADK
- ADK 的 Python 快速入门
- 直接在 google/adk-python 中查看合并的拉取请求和基准提交。
- 如果你想在无人值守运行之前将你的仓库的架构规则和 CI 检查交给智能体,请复制 google/adk-python 中的 .agents/skills 布局。
上一页
下一页
来源:Google Developers Blog · developers.googleblog.com