在 Uber 规模下高效运营软件工厂(中文翻译)

原文标题:Running a Software Factory Efficiently at Uber Scale 作者:@udaykiran(Uber Engineering) 来源:X / Twitter 原文 原文链接:https://x.com/i/article/2090828118454071296 翻译日期:2026-08


引言

如今,AI 工具已嵌入 Uber 软件开发的每一个阶段。超过 70% 的拉取请求(PR)由本地或云端智能体完成。工程师们已在软件开发生命周期(SDLC)中构建了 3,600 多个智能体技能(agent skills),每天执行超过 3 万次智能体技能调用。

在 AI Engineer 2026 大会上,我们分享了「软件工厂」的愿景,以及我们正在生命周期各环节构建的基础模块与托管智能体(managed agents)。随着这一愿景的推进,越来越多的会话不再由人发起,而是由自动化托管智能体发起——它们负责代码审查、自愈 CI 故障、完成带视觉验证的端到端 PR、分诊 on-call 告警、调试新出现的 bug,以及处理各类代码维护任务(并保留人工审查/升级机制)。

如图 1 所示,从 2026 年 2 月到 8 月,所有员工(工程师与非工程师)在所有智能体产品上的周活跃用户增长了 7 倍,周智能体请求增长了 9.4 倍。与此同时,由于全盘的优化,我们的 AI 总支出自 4 月起已相对稳定。由于采用率、工作负载组合和模型升级都在持续变化,要单独度量我们自己的优化收益,就得固定某个模型不变(因为每次升级、换模型家族都会改变行为)。我们确实在 2 月到 7 月这么做了:每 1,000 次模型请求的成本较峰值下降了近 34%,每次会话成本较 6 月峰值下降了 52%。

本文讲述我们如何看待自己的软件工厂:智能体会话运行的四个层级、我们用来分解支出的成本方程、如何度量每一项,以及如何在每一层优化这些项。

本对比中的所有定价和供应商指标均基于公开信息,成本效率的提升来自在标准分层定价内更智能地路由我们的内部 Uber 工作负载。我们测得的成本降幅是针对自身环境的,具体到你的代码库、团队规模和智能体工作流可能有所不同,但「对真实工作做基准测试、并针对准确性与成本做优化」这套方法论是普遍适用的。

软件工厂及其成本方程

智能体使用的四个层级

我们把 AI 使用划分为四个层级,从最专用到最通用。如图 3 所示,层级越高,我们对成本、质量和模型选择的控制力越强。

成本方程

在上述任一层级中,我们都可以把一次智能体会话的成本分解为以下各项,从而可以独立度量、独立优化。前两项代表「采用与参与度」,我们希望它在整个用户群中持续增长——无论用户是交互式使用,还是让智能体代其处理任务。中间三项是优化的机会所在:智能体在工程师实际提出的请求之上,为自身工作所消耗的部分——这是我们大部分精力投入的地方,包括帮助智能体更快规划、减少无用轮次或错误、优化输入 token 等机制。

我们如何度量

下面是我们每周、每月跟踪的完整指标集,让我们能够预测和规划短期与长期的投入。

优化杠杆

以下各节详述我们用来优化成本方程每一部分的关键杠杆,其中一些杠杆会影响成本方程中的一行或多行。

优化「价格 / Token」

token 单价由供应商设定,但由我们决定哪个模型跑哪类工作负载。在我们所有托管智能体的各层级中,我们为每类工作负载挑选帕累托最优(Pareto efficient)的模型。对我们而言,「帕累托最优」意味着综合考虑:每个已完成任务的成本、输出质量、模型可靠性。

基准驱动的模型选择

模型选择分四步,对每个托管智能体都一致:

  1. 用该智能体的真实工作构建一个基准测试(benchmark);
  2. 让智能体在一个统一的 harness(执行环境)上运行,该 harness 可在同一接口下服务任意模型——前沿模型或开放权重模型;
  3. 迁移到帕累托最优的那个模型,并持续迁移——因为前沿每几周就会移动一次;
  4. 展望未来,我们持续利用来自托管智能体的聚合洞察来测试和部署各种模型路由策略。

以 uReview(负责所有 PR 的 AI 代码审查)为例。我们用带已知 bug 的真实 PR 构建基准,并把它们分为简单/中等/困难三档;针对这些 bug 对精确率、召回率、F1 打分,外加每次审查的成本、延迟、超时和噪音。如图 5 所示,切换模型在提升 F1 的同时大幅降低了每个 PR 的成本。图中虚线是帕累托前沿,位于其下方和左侧的一切都会被某个「更便宜或更好」的方案击败。

利用我们大型 monorepo 中数千个真实 PR,我们还内部构建了一个 Uber SWE Benchmark,在不同任务类型上运行前沿模型和开放权重模型,用来指导我们所有 SDLC 托管智能体的模型选择。

默认模型选择

在交互式界面中,token 单价固定;但你可以策略性地管理 token 在不同模型间的分配。两个默认设置主要决定这一分配:初始会话模型和子智能体(subagent)模型。

子智能体的默认设置已被证明是最有影响力的杠杆,而且其重要性还在持续增长。 随着最新模型能力让多智能体编排更有效,发起子智能体的会话占比在稳步上升。由于子智能体执行的是定义明确、输入固定的任务,往往不需要前沿级的推理能力,我们默认给它们配置一个更弱、更便宜的模型(同时允许手动覆盖)。主模型负责任务分解与评估,子智能体负责执行工作。

优化「Token / 请求」

每一轮都会重新发送完整的对话历史、项目上下文和工具结果。任何能减小单次请求载荷的措施,都会在整个会话中产生复利效应。

默认设置

所有交互式 harness 都使用统一的封装来管理安装、配置、认证和成本可见性。两个标准化的默认配置直接降低了单次请求的 token 消耗:

提示词缓存策略

我们的提示词缓存策略由「供应商提示词缓存的读/写经济学」驱动。由于每一轮都会重新传输完整对话历史,缓存前文上下文就能避免反复支付全额成本,把后续读取降到标准输入 token 单价的 0.1 倍。但写入有溢价:5 分钟缓存条目成本 1.25 倍,1 小时条目 2 倍。因此,选择最优 TTL(存活时间)取决于轮次之间的间隔时长。可用的 TTL 选项包括 Anthropic® 的 5 分钟和 1 小时,以及 OpenAI® 的 30 分钟。

由于工程师经常让交互式会话闲置超过 5 分钟,我们把默认的 5 分钟 TTL 切换到了 1 小时窗口——此前这些频繁的空闲间隔会使前缀缓存失效,迫使昂贵地全额重建上下文。相比之下,子智能体保留 5 分钟缓存 TTL,因为它们的执行聚焦于单个短生命周期任务。

通过 Shell 执行 MCP 工具

在 Uber,所有 MCP(模型上下文协议)交互都经过一个统一网关(gateway)。这个单一入口涵盖内部及第三方 SaaS 的 1,000 多个 MCP 服务器,实现了集中式认证与策略执行。

然而,标准 MCP 会把所有工具的 schema 直接加载进每一个会话,无论工程师是否会在该会话中调用它们。例如,安装了 100 多个工具时,这种预加载会给初始提示词增加约 5 万到 7 万 token 的 schema 开销,并且每次上下文轮次都会重复发送。为解决这种上下文膨胀,我们引入了两个互补的优化机制:

Code-Mode(代码模式)

当工具以 shell 命令的形式直接调用函数时,模型可以在单个脚本内批量执行多个动作。这种批处理对「话痨型」工具协议尤其有利。在标准 MCP 工作流下,每个动作都需要单独的一轮模型轮次:发出请求 → 把原始响应加载进上下文窗口 → 顺序处理结果。例如,执行一条 SQL 查询需要提交请求、轮询状态 2 到 5 次、再取回输出。

Code-mode 把整个流程精简为一个自动化的 Python 循环,把中间轮询挡在模型的活跃上下文之外。如图 8 左侧,模型参与了轮询循环,每个响应都进入其上下文;右侧,循环在子进程中运行,只有摘要返回给模型。我们在同一会话中用两条路径分别运行 5 条相同的 SQL 查询进行测量:即便结果集远低于响应大小上限,code-mode 仍减少了超过 50% 的 token 用量。这些收益并非来自绕过大数据载荷,而是来自消除不必要的开销——schema 初始化、多轮轮询、冗余的逐步推理。

批量工作流会放大这一效果:本应是 N 轮模型轮次的循环变成一个脚本,节省可叠加到 90% 以上。通过为我们最常用的 MCP 服务器部署 25+ 个预构建的 code-mode 技能,我们确保标准工作流默认走最具成本效益的路径。

SaaS MCP

管理第三方软件比管理我们自己的服务器要困难得多。供应商设计 MCP 服务器时会暴露完整的产品能力,因为他们无法预料具体客户的使用方式。例如,某个工作套件把 49 个工具塞进单个服务器,需要约 22K token 的 schema;而消息类、项目跟踪类供应商分别提供 34 个和 46 个工具。加载两三个供应商服务器,让智能体在用户还没输入提示词之前,就背负了比「待编辑文件」还大的 schema 开销。

为解决这个问题,我们通过 MCP 网关路由 SaaS MCP 服务器(与内部 MCP 相同的机制),并把所有这些 MCP 都暴露为任何智能体界面都可调用的 CLI。此外,我们在 code-mode 插件中为每个服务器编写专用技能来封装常见工作流,从而在众多 SaaS 供应商上解锁了高效的智能体工作流。

优化「请求 / 轮次」

一个「缺乏上下文根基」(ungrounded)的智能体会缓慢地失败,而不是廉价地失败——它反复发送一个不断膨胀的上下文窗口去多搜索一个位置。预先提供更丰富的信息,仍然是降低这种搜索开销最有力的单一杠杆。

上下文工程(Context Engineering)

在 Uber 庞大的代码库和数据生态(数亿行代码、数千张表)中,智能体把大部分轮次花在「定位信息」而不是「生成代码」上。为此,我们构建了 AI Context Graph(AI 上下文图谱):一个包含 2,400 万个节点、8,000 万条边、86 种节点类型、117 种边类型的统一网络。它整合了 30 多个内部系统的数据——服务、工程团队、事故日志、PR、架构设计文档、部署、数据集、以及表的历史使用查询——并让任何智能体都能用自然语言查询它。

一个有上下文根基的智能体查询了历史使用记录,识别出那张被 50 多位分析师使用过的具体表,38 秒给出答案;而一个无根基的智能体看不到那张表,花了 20 分钟检查服务代码、spawn 了 2 个子智能体、撞上 3 个错误,最后错误地断定该数据集无法查询。

可见性与教育

这里的杠杆是「可见性」和「反馈回路」,它们帮助工程师和智能体更快收敛。

状态栏(Status Line)

我们在 harness 的状态栏里放了一个实时成本计数器,跟踪每个 harness 的实时支出,以及每个用户跨所有 harness 的总支出。

可见性与支出分级

为避免施加严苛的硬性上限,我们实现了实时支出跟踪和自动提醒:

这些机制让工程师能够独立评估任务的 ROI,同时避免失控的支出。

会话分析仪表盘(Session Analysis Dashboard)

状态栏突出的是会话的总支出,却看不到成本驱动因素或可操作的提效步骤。通用指导只能提供高层原则,无法评估单个开发者的工作流。会话分析仪表盘通过直接检查会话工件来弥合这一差距。

它直接内置于运行时,零配置、零 opt-in。执行「成本仪表盘」技能后,会分析该用户在所有 harness(本地和远程云沙箱)上的全部会话 trace。它不是产出一个聚合指标,而是标记出会话中的 16 种不同反模式(anti-pattern),并为每一种配上其财务影响和针对性补救措施。部分类别包括:

接下来做什么?

当前进行中的计划包括:

结论

管控和遏制不断上涨的 AI 编码成本,本身也是一个可解决的工程难题。 通过消除浪费的、零价值的 token 消耗(而不是单纯依赖更低的单价或降级工具),我们在把用量扩大 7 倍的同时,全面降低了单位成本,并维持/提升了输出质量。

核心的战略转变是:从交互式开发者工作流转向完全托管的智能体。 把 SDLC 工作负载迁移到托管环境中,就能对模型路由、执行 harness 和运营支出获得完全的控制。优化一支「专用托管智能体舰队」——每个智能体都配有专门的评估基准和一个帕累托高效的模型——本质上比优化数千名工程师的单个终端会话更具成本效益、也更可扩展。

致谢

这是许多工程师的集体努力,他们在构建「在 Uber 规模下实现软件工厂」的最高效模块,同时确保我们花的每一个 token 都有 ROI。(致谢名单略,见原文)


Anthropic® 是 Anthropic PBC 的注册商标;Claude Code™ 和 Claude® 是 Anthropic PBC 的商标;OpenAI® 及其标识是 OpenAI® 的注册商标。