使用 GPT-6 系列维护软件
每个不断增长的代码库都需要维护:移除未使用的代码、清理已完成的实验,以及修复测试。在 OpenAI,编码代理帮助我们更快地构建,这也增加了我们的维护需求。
我在 OpenAI 的核心实验团队工作,我们构建并维护支持全公司实验的软件,涵盖从前端更新到模型服务效率改进的各个方面。
GPT-6 Astra 的发布帮助我们更快地构建和维护软件,而 GPT-6.1 Sol 以更低的成本取得了类似的效果。在本文中,我将分享我们如何使用这些模型来寻找清理机会、收集证据并准备变更以供审查。
移除未使用的代码
在代理式编码出现之前,许多软件工程团队依赖于与运行时日志集成的复杂静态分析系统来检测和移除未使用的代码。即使有这些系统和仔细的代码审查,错误仍然会发生。我记得有几次事故是由于错误的代码移除造成的。需要考虑的边缘情况太多了,比如反射会干扰静态分析,或者一条未使用的代码路径可能被激活以缓解未来的事故。
在 Codex 中使用 GPT-5.6 Sol 时,我可以指定一个调查区域和明确的验证标准,然后让模型编写静态分析并移除死代码。这些有针对性的提示比我们现有的静态分析系统更容易开发和维护,可靠性也相当。
当我们获得 GPT-6 Astra 的访问权限时,我们想看看它是否能从更广泛的请求中工作,找出该查看什么以及需要什么证据来证明每次移除的合理性。我们从一个简短的 Codex 提示开始,这个提示对于 GPT-5.6 Sol 来说太模糊了,无法完全处理。以下是提示原文,包括拼写错误:
Astra 很好地处理了模糊性。它查看了过去的 PR,从 Slack 讨论串中收集了上下文,并检查了内部项目跟踪器。它读取了生产性能分析表,以确认被删除的行从未被执行过。Astra 还解释了每次删除的理由,这加快了我们的审查速度。
一旦我们看到 Astra 的表现有多好,五名工程师就合作在各个代码库中运行该提示的变体,我们合并了超过 1,400 个拉取请求,删除了超过 80 万行代码。我们在两周内利用业余时间完成了这部分工作,主要精力仍在其他项目上。代码审查被分发给各个团队,并附带了每个受影响项目的上下文。这些删除带来了可衡量的收益。例如,一个服务的容器镜像从 3.31GB 缩小到 1.72GB,减少了 48%,另一组清理从我们的测试套件中移除了大约 400 个视觉快照变体。
追踪过时的实验
软件维护中一个更难的问题是清理过时的实验。这些实验并不一定是未使用的:它们的代码可能仍在生产环境中运行,或者依赖于可能随时发生变化的资格评估,这使得静态分析变得更加困难。历史上,我们团队通过确定性静态分析结合数据库查询来清理过时的实验,并使用我们最强大的模型(当时是 GPT-5.6 Sol)来构建和改进相关脚本。我们知道这会导致许多假阴性,即我们的分析无法识别出真正过时的实验。
鉴于我们使用 GPT-6 Astra 清理死代码的成功经验,我决定尝试另一个简短的提示词来处理过时的实验。我不确定该如何开始,于是与 Astra 进行了头脑风暴,并请它写一个简短的提示词,以便在新会话中尝试:
Astra 遵循了提示词中的安全准则,并准备了可供我们团队审查的更改及证据。我在其拉取请求上发表了评论,然后让 Astra 查看我的评论、采纳我的反馈,并开发一个新的提示词来扫描我们的整个代码库。我担心有太多东西需要清理却无从确定优先级,所以我也请 Astra 帮我解决这个问题。Astra 提出了以下提示词:
生成的报告很有前景。利用我们的检测工具,Astra 调查了每个过时实验的 CPU 成本,排名靠前的几项结果是巨大的效率提升,这些提升与多年来无人识别为过时的实验相关。我仔细验证了这些较大的结果,并继续进行全面清理,移除了数百个实验和功能开关。
有一个例子体现了 Astra 的判断力:几年前,我们的一位工程师创建了一个 Statsig 功能开关,允许内部开发人员出于测试目的覆盖我们所有与新功能相关的其他功能开关。该配置通过一行 Python 代码实现,将该开关映射到所有其他功能。这行代码与数百个类似的功能开关映射并存,看起来毫不起眼。
Astra 发现上述代码行导致了显著的 CPU 扇出,因为它将该开关映射到了所有功能。它调查了 CPU 成本,但由于该开关在我们的功能开关管理控制台中被明确标记为“永久”,且可能仍具有运维用途,因此将此发现提交给人工审查。经过审查,我们移除了该开关,预计在主要受影响的服务中节省了 0.42% 的 CPU。
使用 GPT-6.1 Sol 提升成本效益
最近,我们在相同的工作流上测试了 GPT-6.1 Sol,看看它能否在效率更高的同时达到 GPT-6 Astra 的效果。
为了在过时实验清理方面比较这些模型,我在不同的模型/努力程度组合上运行了上述相同的提示词,要求 Codex 审计我们某个仓库中的特定子目录以查找过时实验。这些子目录涵盖了超过 6,000 个文件和 100 万行 Python、TypeScript、Go 和 Rust 代码。我审查了这些发现以进行验证。下图显示了 3 种模型/努力程度组合的结果:
API 成本
- GPT-6 Astra Ultra
- $109.06
- GPT-6.1 Sol Ultra
- $15.12
- GPT-6.1 Sol Medium
- $5.27
发现数量
- GPT-6 Astra Ultra
- 142
- GPT-6.1 Sol Ultra
- 131
- GPT-6.1 Sol Medium
- 86
每项发现的成本
- GPT-6 Astra Ultra
- $0.77
- GPT-6.1 Sol Ultra
- $0.12
- GPT-6.1 Sol Medium
- $0.06
成本采用标准 API 定价,并包含研究子代理以及 Codex 在实现每个目标过程中自动运行的后续轮次。
在这项对比中,GPT-6.1 Sol Ultra 以 GPT-6 Astra Ultra 14% 的 API 成本,产出了其 92% 的发现。GPT-6.1 Sol Medium 以更低的成本产出了更少的已接受发现。
我审查了各模型/effort 组合之间的差异,发现了一些模式。例如,Ultra 上模型之间的大多数差异,是由于用作其他 feature flag 依赖项的常量 feature flag 所致。GPT-6 Astra 识别出了这些,而 GPT-6.1 Sol 则遗漏了它们。
发现此类错误模式有助于我们开发出能纠正它们的提示词,从而让更具成本效益的模型达到与更昂贵模型相似的结果。同时,未来的模型版本可能会使这些纠正失效,因此在新模型发布时重新审视提示词很重要。
其他可尝试的思路
我最喜欢的一些 Codex 发现都始于这样的简短提示词。用 GPT-6.1 Sol Medium 试试它们,如果结果有希望,再考虑为更广泛的审计提高 effort。
修复不稳定测试:
改进 agentic 上下文:
降低持续集成的成本和运行时间:
最后一个思路帮助我们缩短了 CI 时间。在运行它并跟进其建议后,我们合入了约 30 个 CI 优化 PR。我们看到 CI 完成时间中位数从大约 10 分钟降至 4.5 分钟,而第 90 百分位数从 12.5 分钟降至 6 分钟。在后续的一次修复中,添加一个缺失的 mock 将一个 63 个测试的 resolver 套件的运行时间从 592.6 秒缩短到 29.8 秒——减少了 95%,且全部 63 个测试均得以保留。
从小处着手,审查,然后扩展
GPT-6 系列改进了我们 Core Experimentation 团队大规模维护软件的方式,并带来了多项效率提升。
迄今为止,我们的团队已合并了超过 1,400 个源自 GPT-6 提议的维护 pull request。这带来了更快的测试执行、更小的镜像、更低的 CPU 利用率以及许多其他好处。然而,一些提议带来的复杂性超出了其预期收益所能证明的程度,因此优先级排序和度量始终是我们工作流程的重要组成部分。
在更大的代码库中,我们发现很容易被 GPT-6 模型能找到的优化数量所淹没。借助度量工具和上述提示词技巧,Codex 帮助我们对这些改进进行了优先级排序。
如果你想在自己的代码库中尝试,我会从一个小的维护任务开始:一些未使用的代码、一个过时的 feature flag,或一个不稳定测试。让 Codex 找到一个实例,收集证据,并起草一个小的 PR。针对这个小任务比较不同的模型和 effort,因为更便宜的配置可能就足够了。
当小范围的尝试运行良好后,将其扩展到子目录或范围明确的项目。在每一步,都让 Codex 将你的代码审查反馈纳入下一个提示词。当你对模型的表现有信心时,再扩展到整个代码库。
我们的 Core Experimentation 团队正在招聘工程、数据科学和产品管理岗位。如果这篇文章让你感到兴奋,请通过我们的 careers page 申请!