大约 15% 的生产 PR 走过 Minion,合并线为什么还在人手里?|The Pragmatic Engineer × Udai Kira Mendesi
- 原始标题
- Uber’s AI infra, from the inside
- 节目 / 来源
- The Pragmatic Engineer
- 嘉宾
- Udai Kira Mendesi
- 原始发布日期
- 2026-10-15
- 时长
- 1 小时 34 分钟
- 内容类型
- 工程分享
- 原始内容
- 前往原始来源 ↗
2015 年 5 月,Udai 加入 Uber,工程人数大约刚到第 600 人。他记得核心只有两个服务:Node.js 的 dispatch 接乘客和司机,Python 的 API 在行程结束后处理支付和收据。派单大约每四秒把整份状态推一次。十年后,他说业务大约是当时的十倍,服务数量仍在相近的区间;后台编码智能体 Minion 已经出现在大约 15% 的生产 PR 里。
原始来源:Uber’s AI infra, from the inside。中文深度整理,非逐字翻译。本文依据 YouTube 自动生成的英文字幕,专有名词和数字可能有识别误差。
城市和云端开发机,先于智能体
字幕里的全名听写为 Udai Kira Mendesi,下文称 Udai。他从实时 API 做起,后来做过履约、企业用车、接单方入驻和市场定价。最近一年主要在智能体:给工程师的,也给公司其他人和一部分面向用户的支持。加入时市场团队大约 50 到 60 人。之后工程涨到几千人,现在有 12 个全球技术站点。2018 到 2019 年语言收到 Go 和 Java。业务在扩国家和品类,包括后来的 Uber Eats,现成软件接不住那种规模和变化速度,所以服务、指标、追踪、发布很多是自己做的。两个服务变成数千个量级。做履约平台时,他们又把一部分服务收拢。到现在,服务数量仍在相近的区间,全球仍是一套技术栈,出行和配送共用积木。
早期工具是后来智能体的接口。You Own 用来在故障时查出资产属于哪个团队、谁在值班。设计文档和事故记录被收进同一处。2015、2016 年,指标大约每秒 5 亿条,带上基数之后没有现成系统能接,于是有了后来开源的 M3DB。几百个机器学习模型催生了 Michelangelo,从特征、训练、监控到服务;几个月前他们开源了其中深度学习基础设施的一部分。跨很多天的流程,例如司机入驻或营销活动,各队自己做重试和状态,于是有了持久工作流引擎 Cadence,后来也开源。主持人补充,外面很多人知道的 Temporal,想法和它同源。实验系统 Morpheus 把功能开关和实验嵌进工具。Uber 是双边、有时三边的市场,实验不只有简单的 A/B,还有开关式的 switchback。城市是一等公民:关键平台按城市分片,可以把一座城市切到另一个区域。这只用于需要这种可靠性的部分服务。
开发机的故事从仓库策略开始。微服务早期是一个服务一个仓库,构建和测试系统有两三套,中心团队升级库很痛苦。大约 2017、2018 年改成单体仓库:服务仍是微服务,但按语言各有一个大仓库,Go、Java、iOS、Android 分开。仓库一大,笔记本装环境就痛苦。Dev pod 是云上的开发盒子,一种语言一个口味,带构建缓存,机器比笔记本壮,构建和测试有服务等级。到了模型这一代,智能体要同样的工作区。他们做了装着所有仓库的 mega dev pod,让智能体跨仓库开 PR,也能跨仓库看上下文。构建和测试已经标准化,所以仓库顶上的说明文件(字幕里的 agents MD、cloud MD)写一次,多数团队立刻能用。Cloud Code、Codex、Open Code 预装在盒子里,非工程师也能开一台来试。Udai 的判断是:那些年为工程师铺的平台,同样让智能体好过。
主持人在结尾回忆,大约十年前 Uber 以约 5,000 个服务、约 2,000 名工程师闻名;今天他估计在 4,500 到 5,000 个、尺寸更完整的服务,比十年前更少。这是他离开六年之后的印象,时间跨度他标成 2016 到 2020。Udai 说的是“数千量级”和“仍在相近区间”、业务大约十倍。两套数字都是口述,对不上同一份资产盘点。每秒 5 亿条指标也是“大概”。
所有模型请求走同一道门
Udai 想守住的是与模型和外壳无关的积木。外壳(harness,套在模型外面、负责工具和循环的那一层)和模型都变得很快。模型网关从 ChatGPT 出现时开始做。他先说成 2013 末、2014 初,主持人打断,他改口为 2023 到 2024 年初。网关建在 Michelangelo 上:建一个生成式项目,选定模型,拿到项目编号。对外只暴露一种兼容 OpenAI 或兼容 Anthropic 的接口。开源权重和闭源权重、各家供应商,都在这道门后面。
第一块加进去的中间件叫 AI Guard,用来避免把敏感内容送回用户。安全团队可以在这一个入口上迭代内容、安全和沟通政策的微调模型。他说大约五组,每次请求和每次响应都跑,并有严格的延迟约束。项目都经过这里,就能按人、按调用方归因,后来加上项目和用户的花费档、审计日志和会话追踪。计费和缓存命中也在这里看。Udai 说,Uber 的每一次模型请求都走这道门。模型路由被他当成以后可以用的入口,这次没有讲成已经完成的路由器。
外壳则用内部的 AIX 包起来,字幕里也写成 AIFX、AFX。它预装在 dev pod 上,也可以装到本机。Persona 带上默认插件和技能,工程师不用自己先装一套。设置由中心下发,个人设置在各个环境之间同步,换外壳不必重来。状态栏能在当次会话里看到花费。花费档的做法是:默认有一档,接近上限就申请下一档,经理批一下,对话内容是这笔花费的回报。交互式外壳和后台编码智能体分属不同的档。一个叫 cost check 的插件按使用情况给个人提示,例如这笔会话花在哪、可以怎样收。Udai 要的是反馈,让人知道这些调用要花钱;真正用在项目上的花费,他不想用厚厚的流程挡住。
档位的金额、模型名单,访谈里都没有。五组微调模型是“大约”。日期是在对话里改过的。
工具从接口登记簿里长出来
2025 年 4 月前后,他们开始做 MCP 网关。MCP(模型上下文协议)是让智能体调用工具的一种接口,大约在 Cursor 开始普及时出现。做法和模型网关相同:所有工具走一道门。Uber 的服务早就用 Thrift,后来新服务改用 Protobuf,接口定义在同一本登记簿里。网关据此自动生成 MCP,包括给模型看的字段说明。他们见过一个工具占 3,000 到 4,000 个词元,所以要先把说明压短。打开它只改一份配置和安全策略,服务本身不用改代码。定制的 MCP 也可以代理进来。Google、Slack 这类外部工具同样走这道门,再装进 AIX。近几个月又把这些 MCP 投影成命令行,外壳想用协议或想用命令都可以。做 API 网关的同一队来做这件事,协议转换是他们的本行。
技能放在一个单体仓库里:平台团队的核心技能,加上各队自己的。质量检查一套,用 AIX 安装,就会写进所有外壳的配置,哪怕你眼下没用那个外壳。最近几周,他说大概每天 30,000 次技能执行。两个工程师靠模型,把仓库里的技能改成命令行叫法,因为每个技能都点名 MCP 的话,装两个插件可能把六个 MCP 全塞进上下文。自动安装也省掉每个人再配置一次。从轨迹里自动给技能打改进补丁,他放在正在做的下一步。多数技能走这个仓库,仍有团队自留仓库。
上下文图用来少走弯路。他说是某个 12 月,一位工程师做了助手 Cortana,在网页或 Slack 里询问任何代码库。人们问的远超出读代码:这条查询怎么跑、数据源在哪、谁拥有、能不能做故障分析。轨迹看起来,模型要花很多轮才找到地面,因为任务、值班和资产系统彼此分开。近几个月他们把这些收成一张图:100 多种节点、130 多种边,他说是大约三天前的实时数据。点开一个人,能看到他管的资产、写过的设计文档、在做的功能、值班、配置变更、事故和 Jira。助手先用这张图判断问题落在哪一组服务,再往下读文档。Udai 说,在一批问题类型上,质量上去了,成本和延迟下来了。没有给出百分比。
生产图团队本来就维护一张数十亿节点的图,这张内部图小得多,规模不构成挑战。权限沿用每个人原来就有的访问;没有权限的数据不会出现。主持人记得以前叫 break glass 的审批。Udai 举的例子是:全世界有多少出行行程用现金支付。智能体得先知道有哪些表和列、谁写过查询、是不是出行科学团队、过去 30 天有没有人跑过。人写图查询很痛苦,智能体逛这张图,像用命令逛文件系统。Cortana 也在命令行里,其他国家的运营可以问某件事怎么做、谁在做、历史是什么。问一个服务的健康,它可以看依赖、存储和查询,给出一份全景,仍然只限于提问者本来就能看的范围。
30,000 次是“大概”,质量提升没有对照数字。图刚开始用,他明确说还早。
百分之十五的 PR 仍要人点头
功能的生命周期被重新想过。国家和城市的差异、加上真实世界里的边角,使计划仍然重。产品和工程设计、发布评审、实验评审、上线就绪,放在同一处,并写进那张图,人和智能体都能找到规格。把人和智能体一起改的“联合计划”还在早期。
规格之后交给 Minion,他们的后台编码智能体,现在是第二版。Udai 说,眼下大约 15% 的生产 PR 经过它。可以从网页或 Slack 调用,先做计划再在后台执行,也可以对简单提示直接执行。它用装着全部仓库的 dev pod,按计划开一个或多个跨仓库的 PR。一开始多是维护类任务。他们正在给它加上网页、移动端和后端接口的自测,希望能交出去的任务种类变多。在 Slack 里 @minion,它会回状态,也可以就在线程里改方向。支持频道里,值班的人让它看一个故障,它有时会直接判断根因并改掉,不必再进待办。
Dev pod 的创建被说成秒级。开发用的是分开的多套云和 Kubernetes,镜像是热的,仓库和构建缓存已经在里面,拉起来就能编。全仓库用 Bazel(字幕听成 basil)构建。顶层说明文件里写着同一条命令,工程师和智能体会用同一套方式编译、测试任何一个模块。
PR 量逐年上升。他们看两组周期:把改动做成绿色并开出远程 PR 的内环,以及等人审、等持续集成(CI,合并前的自动构建和测试)通过的外环。评审是瓶颈。一批简单的 CI 被挪进内环,收在一条验证命令后面,字幕里挂在他们的 AI 工具入口上:静态检查、覆盖率、构建、模板。然后是看得见的验证:模拟器、网页、把改动部署到预发再打接口。智能体有技能走这圈。自愈 CI 可以套在全部 PR 或单条 PR 上:链到正在做的问题,看见哪项失败,自动请人审、自动合并、自动修。目的是把周期的中位数和高分位压下去。
Code Inbox 是工程师的待审列表,节目里展示的是一个模拟界面。能看到等你审的、你发出去等别人审的,以及 AI 评审查过什么、健全性测试的截图和视频、构建结果。风险分和爆炸半径还在加。Udai 希望这些信号告诉人:能不能落地,以及该把眼睛放在 PR 的哪一段。
事故对 Uber 很贵,所以即便有这些工具,每条要进去的 PR 仍然要一位工程师审。等风险分更有信心,并且能用多年数据回测,某些低风险类别也许可以走他们叫的绿通道、自动落地。那一步他要求先把各个维度都看准。眼下的优先是把信号放到位。自动落地的比例是下一步。CI 任务量一年比一年翻倍还多,地基也得加厚。15% 没有定义成“完全由 Minion 写成”还是“经手过”。Code Inbox 是模拟画面。周期时间只说他们在优化,没有读出具体分钟数。
自测环先装上,功能速度才算数
人在智能体之前就有一套叫 Slate 的预发。工程师把自己的分支部署成一个实例,把测试账号钉在上面。登录之后走的是这条分支,上下游仍走其他预发。测两三个服务时,这几个走分支,其余照旧。有了它,只要教智能体怎么部署。节目里的演示用命令行创建环境、部署一个测试服务、钉上测试账号,再让浏览器智能体把主干和分支做对照,写出前后报告,截图和视频可以贴到 PR。iOS、Android、网页和后端接口都有对应做法。
难在服务数量。主持人强调,端到端测一个改动,要在几千个服务里把请求送到对的实例。Udai 说这靠分布式追踪 Jaeger(字幕作 Jerger),大约 2017、2018 年做好,现在开源。调用带父片段和子片段,行李可以沿调用栈传递。从 Slate 钉账号,就是往行李里写上待测服务和账号。服务网格看见行李,就把请求送到 Slate。旧服务花了几年才全部接上,新服务则默认带上。可以读成:智能体的自测,用的是当年为人和自动化铺的路由。
更复杂的平台用捕获回放。主持人后来说系统叫 Capri,对白里有一处听成 taper。标准化的语言框架上挂一个中间件,就能抓到这个服务的入站、出站,以及它调用的下游请求和响应。规则把请求标上维度,例如市场类型、业务线、终态。上线前用他们叫的 matchguard,对这个平台正在支持的组合跑一遍,看这次发布的前后差。他举的例子是:会不会只把巴西的现金行程打坏。这种组合,工程师和智能体都很难手测全。修一个只影响旧金山 Uber Eats 的故障时,可以开 Slate,只回放那一条抓到的请求,看差值是不是预期的修复。智能体可以按类型把会话找出来,在自己的环境里组请求,修到差值为止。主持人记得更早的 Deputy 和 Cerberus:一个把生产请求引到测试实例,一个把本地指回预发。有了 Slate,那两套不必再当主路径。捕获回放他讲的是一部分最复杂的平台,没有说每个服务都开了。
边缘网关是当年实时 API 的 Go 版本,外部接口都走这一个入口,自己也有捕获回放,并标出依赖是必需还是可选。告警时,人和智能体都能顺着追踪看哪个节点不健康。
大范围改代码靠 Shepherd(字幕也写成 sheepard)。简单的签名变化用 OpenRewrite;它按模块和所属团队开 PR。JUnit 4 升到 JUnit 5 是一场战役,一份 YAML,负责人能看见每条 PR。模型进来之后,同一套平台可以跑技能,例如把上下文传播补齐,让追踪在每个服务里生效。Fox 接着做每周维护:服务可选择加入死代码、性能或吵闹日志。CI 比较空的时候,他说是每周日,也说每周一,开一条新 PR。现在仍是选择加入,变好之后有的技能可能改成默认开启。他们看维护类 PR 还剩哪些,决定要不要新技能。
Wisdom 收员工在乘客端或接单端上报的故障,先分到负责的团队。员工测试版带上日志和遥测。例子是在设备上模拟另一个国家的位置。系统给出经过的屏幕、期望和实际行为,以及分析、网络和功能开关。托管智能体 debug assist 对照代码库写出根因、影响、证据和时间线。人点头之后交给 Minion,PR 挂到 Jira。评论里改过的根因,变成改进这两边的材料。测试设备还可以重放上报者当时的网络响应。
Udai 说,他做工程以来,工作方式没有哪次变这么多。杰出工程师也自己开 PR。他自己的 PR 比去年多得多。要准备的是上下文、规格和约束,同时在很多会话之间切换,并且很快验完。主持人把它说成:现在问的是怎么让智能体做、怎么让它验。客服政策是例子。从人用的手册变成可执行政策,以前找接口、改配置、手工评估,一条要几周。近几个月把转换原则教给智能体,配置和测试一并自动化,并用过去的上下文造合成评估,变成几天的量级。护栏和人工确认还在。
生产力从代码吞吐、体验调查、事故和覆盖率,转到功能速度。PR 按复杂度和类别标注:功能、缺陷、维护、测试、文档。同比下来,功能类比例在升,维护类在降,他没有给百分比。设计文档到任务的断链,现在用模型补上,以便按复杂度看每一半年的功能周期,并分辨瓶颈在需求、发布还是铺开。过去两到三年都在看。他称为能力过剩的是:模型已经能做的,常常还缺编排和工具。他觉得还早。
Fox 仍是选择加入。捕获回放没有覆盖全部服务。功能比例只有方向,没有数字。主持人在结尾说代码评审正在各处变少;Udai 把现阶段说成每条 PR 仍由工程师决定落地,自动信号用来决定把时间花在哪一条上。