Agent platform (Part 1): How we help Grab build and run AI agents at scale智能体平台(第一部分):我们如何助力 Grab 大规模构建和运行 AI 智能体
Part 1: From one support bot to a framework第一部分:从单一支持机器人到框架的演进
At Grab, AI agents have evolved from interesting team prototypes into production services used every day by millions of merchants, drivers, and consumers. Today, more than 500 services run on our internal agent framework, over 50 Model Context Protocol (MCP) servers are registered on our remote MCP framework, and a single Large Language Model (LLM) gateway fronts every model call across the company, handling billions of tokens each month.在 Grab,AI 智能体已从最初的趣味团队原型,演变为数百万商户、司机和消费者每天都在使用的生产级服务。如今,我们的内部智能体框架上运行着超过 500 项服务,我们的远程 MCP 框架注册了超过 50 个模型上下文协议(MCP)服务器,并且公司内部所有的模型调用都由一个统一的大语言模型(LLM)网关处理,每月处理的 Token 数以十亿计。
None of this was designed up front. It began as the plumbing behind one internal support bot, which then expanded because the same problems kept resurfacing for every team trying to ship an agent. This series tells the story of what the platform eventually became. This Part 1 of the blog focuses on the beginning: the architecture of our AI support bot, the specific pain points we hit while scaling and iterating on it, and how each of those failures became a core building block in the framework we now call LLM-Kit.这一切并非预先设计好的。它最初只是一个内部支持机器人背后的“管道”系统,随着每个试图发布智能体的团队不断遇到相同的问题,这个系统逐渐扩展开来。本系列文章将讲述该平台的发展历程。博客的第一部分重点介绍起点:我们的 AI 支持机器人的架构、我们在扩展和迭代过程中遇到的具体痛点,以及这些失败经历如何成为我们现在称为 LLM-Kit 的框架的核心基石。
The bot that started it最初的机器人
Imagine you have a question for the Technical Infrastructure (Tech Infra) team - the engineers who run the cloud platforms, databases, developer tooling, and AI infrastructure behind Grab’s ecosystem. Instead of immediately paging an on-call engineer, a bot first triages the request, checks the team’s documentation, runbooks, and past Slack threads, and tries to answer directly in the thread. If it still cannot resolve the issue, it routes the ticket to the right human, with the relevant context already attached.想象一下,你对技术基础设施(Tech Infra)团队——即负责 Grab 生态系统背后云平台、数据库、开发工具和 AI 基础设施的工程师们——有疑问。与其立即呼叫值班工程师,机器人会先对请求进行分类,检查团队的文档、操作手册(runbooks)和过去的 Slack 讨论记录,并尝试直接在讨论串中回答。如果仍无法解决问题,它会将工单路由给合适的人工处理,并附上相关的上下文信息。
That is what we built with the Tech Infra Support Bot.这就是我们用技术基础设施支持机器人所实现的功能。
In the first half of 2023, Tech Infra handled thousands of support tickets, many of them repeated questions that had already been answered somewhere internally. Before LLMs, the bot’s role was mainly operational; performing tasks like helping track acknowledgments and response times for on-call engineers. With the arrival of GPT-4-32k, we evolved it into a GPT-powered Level-0 support layer that could answer documented questions before a human needed to be paged.2023 年上半年,技术基础设施团队处理了数千个支持工单,其中许多是内部早已解答过的重复问题。在大模型出现之前,机器人的角色主要是运营性的,例如协助跟踪值班工程师的确认情况和响应时间。随着 GPT-4-32k 的问世,我们将它演进为一个由 GPT 驱动的零级(Level-0)支持层,能够在需要人工介入前解答文档中已有的问题。
The first production version was a Go service organized around two planes:第一个生产版本是一个围绕两个平面组织的 Go 服务:
-
A reasoning plane. At Level-0, it was a single-agent loop. It takes the user’s question, decides which tools to call, executes those calls, feeds the results back into the prompt, and returns an answer. The default model at the time was gpt-4.1; today, we have evolved to the latest reasoning models.推理平面(Reasoning plane)。在零级支持中,它是一个单智能体循环。它接收用户的问题,决定调用哪些工具,执行这些调用,将结果反馈给提示词(Prompt),并返回答案。当时默认的模型是 gpt-4.1;如今,我们已经升级到了最新的推理模型。
-
A tool plane. The tools provided the bot’s core working context. Retrieval flowed through Glean, which covered Confluence, TechDocs, internal drives, and Jira. Other tools handled log search through Kibana, GitLab runbook and file access, Slack conversation search, and a small set of Hypertext Transfer Protocol (HTTP) plugins. In the first version, tools and prompts were defined in per-channel JavaScript Object Notation (JSON) configs and resolved at request time. As models became more capable, we later standardized the tool set across channels.工具平面(Tool plane)。这些工具提供了机器人工作所需的核心上下文。检索通过 Glean 进行,涵盖了 Confluence、TechDocs、内部驱动器和 Jira。其他工具则处理通过 Kibana 进行的日志搜索、GitLab 操作手册和文件访问、Slack 对话搜索以及一小部分超文本传输协议(HTTP)插件。在第一个版本中,工具和提示词是在每个频道的 JSON 配置中定义的,并在请求时解析。随着模型能力的增强,我们后来在各个频道之间标准化了工具集。
A trimmed version of that tool config looked like this:精简后的工具配置如下所示:
"agent_plugins": [
{"name": "glean_search", "type": "common", "metadata": {"wiki_space_collection": ["..."]}},
{"name": "runbook_search", "type": "common"},
{"name": "gitlab_runbook_reader","type": "common"},
{"name": "gitlab_read_file","type": "common"},
{"name": "kibana_log_search", "type": "common", "metadata": {"index": "k8s*"}},
{"name": "slack_conversation_tool", "type": "common"}
]
It worked, but it taught us, the hard way, why a demo agent is not a production agent.它确实奏效了,但也让我们以惨痛的代价认识到,为什么演示用的智能体不能直接作为生产级智能体。
What it takes to scale and improve quickly快速扩展和改进所需的条件
As we worked on improving the agent, we kept running into the same kinds of friction. Over time, those pain points formed clear patterns, and they were the same ones we saw other teams run into as well.在改进智能体的过程中,我们不断遇到同样类型的阻力。随着时间的推移,这些痛点形成了清晰的模式,而且我们发现其他团队也遇到了同样的问题。
-
Vibe check is not an evaluation strategy. The bot had a base prompt, and each Slack channel could configure its own prompt, tools, and documentation filters. But the workflow was essentially: configure it, ship it, and hope it reduced toil. There were no real evaluations, just optimism that it would work.“凭感觉”不是一种评估策略。机器人有一个基础提示词,每个 Slack 频道都可以配置自己的提示词、工具和文档过滤器。但工作流本质上是:配置它、发布它,然后祈祷它能减少繁琐的工作。当时并没有真正的评估,只是盲目乐观地认为它会奏效。
-
Fast model and provider switching is essential. The AI landscape moves incredibly fast: a new state-of-the-art (SOTA) model appears on Tuesday, and a highly efficient open-source alternative shows up on Thursday. Switching providers should not feel like open-heart surgery. A unified Software Development Kit (SDK) and an LLM API gateway remove the need to refactor payload schemas, rewrite error handling, or integrate each provider from scratch. If moving from OpenAI to Anthropic, or routing to an open-source model endpoint, takes more than a few config changes, technical debt is already slowing you down.快速切换模型和供应商至关重要。AI 领域发展极快:周二出现了一个新的最先进(SOTA)模型,周四可能就会出现一个高效的开源替代方案。切换供应商不应该像做心脏手术一样复杂。统一的软件开发工具包(SDK)和 LLM API 网关消除了重构负载模式、重写错误处理或从头集成每个供应商的必要。如果从 OpenAI 迁移到 Anthropic,或者切换到开源模型端点需要进行大量配置修改,那么技术债务已经在拖慢你的进度了。
-
Observability cannot be an afterthought. When an answer was wrong, figuring out “why” meant grepping logs across three separate systems: the agent workflow, the tool calls, and the model call. There was no shared trace tying them together. That level of friction is survivable for an internal tool; it is unacceptable for a customer-facing agent.可观测性不能是事后才考虑的事情。当答案出错时,找出“原因”意味着要跨三个不同的系统搜索日志:智能体工作流、工具调用和模型调用。没有共享的追踪(Trace)将它们关联起来。这种摩擦力对于内部工具来说尚可忍受,但对于面向客户的智能体来说是不可接受的。
-
Everything around the agent took longer than the agent itself. Auth (OIDC), secrets management (Vault), per-environment config, vector database integration, LLM tracing, health probes, and metrics were not agent-specific problems. However, they all had to be solved before anything could be shipped. The reasoning loop took a whole afternoon. The production wrapper took two weeks.智能体周边的一切工作所花费的时间,比智能体本身还要多。身份验证(OIDC)、密钥管理(Vault)、环境配置、向量数据库集成、LLM 追踪、健康检查和指标监控,这些都不是智能体特有的问题。然而,在发布任何东西之前,必须先解决这些问题。推理循环可能只需要一个下午就能写好,但生产级的封装却需要两周时间。
The pattern was clear: the hard part of building an agent was not the agent itself, but everything around it that had to be in place before it could safely run in front of users. So we began pulling those shared components out of the bot and consolidating them into a unified framework.模式很清晰:构建智能体的难点不在于智能体本身,而在于在它安全运行于用户面前之前,必须先搭建好周边的一切。因此,我们开始将这些共享组件从机器人中剥离出来,并整合到一个统一的框架中。
Extracting the framework: LLM-Kit提取框架:LLM-Kit
LLM-Kit emerged when we stopped solving these problems service by service and started solving them once, centrally. It is intentionally not a new agent abstraction or a Domain-Specific Language (DSL). Instead, it is a curated set of integrations and scaffolding built around Grab’s existing infrastructure, pipelines, secret management, and observability. Just as importantly, we chose to build a framework rather than a heavy centralized platform. In a space evolving this quickly, a platform would have locked teams into rigid assumptions that would soon become outdated. A framework let us meet developers where they already were: standardizing the plumbing while preserving the freedom to iterate quickly. Looking back, that was the right first choice. Each part of LLM-Kit is a direct response to one of the failures described above.LLM-Kit 的诞生,源于我们停止了针对每个服务重复解决相同问题,转而开始集中统一地解决它们。它并非一种新的智能体抽象或领域特定语言(DSL)。相反,它是围绕 Grab 现有的基础设施、流水线、密钥管理和可观测性构建的一套精选集成和脚手架。同样重要的是,我们选择构建一个框架,而不是一个沉重的中心化平台。在这个发展极快的领域,平台会把团队锁定在僵化的假设中,这些假设很快就会过时。框架让我们能够在开发者现有的工作流中提供支持:在标准化“管道”的同时,保留快速迭代的自由。回过头来看,这是正确的选择。LLM-Kit 的每个部分都是对上述失败经历的直接回应。
We first wrote about LLM-Kit’s structure and code architecture in a 2024 blog post. Two years and a few hundred agents later, the overall shape is still recognizable, but almost every underlying layer has changed. Poetry was replaced by uv; we standardized on the OpenTelemetry stack; LangChain evolved into LangGraph and Deep Agents; and some tools moved onto our MCP framework.我们在 2024 年的一篇博客文章中首次介绍了 LLM-Kit 的结构和代码架构。两年过去了,在构建了数百个智能体之后,其整体形态依然清晰,但几乎所有底层都已发生变化。Poetry 被 uv 取代;我们标准化了 OpenTelemetry 技术栈;LangChain 演进为 LangGraph 和 Deep Agents;一些工具也迁移到了我们的 MCP 框架上。
It starts with a template. The entry point is a user interface (UI) form. An engineer fills in an application name and a few details, and gets back a GitLab repository with the production wrapper already assembled. Under the hood the template stamps out a full FastAPI service:一切始于一个模板。入口是一个用户界面(UI)表单。工程师填写应用程序名称和一些详细信息,就能获得一个已组装好生产级封装的 GitLab 仓库。在底层,该模板会生成一个完整的 FastAPI 服务:
/
├── app/
│ ├── server.py # FastAPI app factory: mounts routes + middleware, boots OTel + statsd
│ ├── agents/
│ │ ├── simple_react_agent.py # a single-agent LangGraph ReAct loop (agent <-> tools)
│ │ ├── mcp_react_agent.py # the same loop, but tools are pulled from remote MCP servers
│ │ └── simple_react_agent.png # auto-exported graph diagram (generated in dev)
│ ├── routes/
│ │ ├── api.py # router aggregator
│ │ ├── health_check.py # liveness/readiness probe
│ │ ├── oidc.py # OIDC login/callback (skipped in proxy-auth mode)
│ │ └── evalshub_eval.py # runs ROUGE / BLEU / LLM-as-judge evals on the agent
│ ├── core/config.py # AppConfig (pydantic-settings) + INI/secret parsing
│ ├── tools/word_length_tool.py # an example tool to copy from
│ ├── utils/prompts.py # prompt/message assembly helpers
│ └── storage/connection.py # Postgres + pgvector engine and connection pooling
├── sdk/ # a generated, typed client SDK (protobuf) other services import
├── configs/
│ ├── dev.ini / stg.ini / prd.ini # one config per environment
│ └── secret.ini.example # secret template; real values resolve from Vault at deploy
├── databases/postgresql/ # SQL migrations (pgvector extension bootstrapped for you)
├── scripts/
│ ├── db.py / db.sh # migration runner
│ └── gunicorn_conf.py # production server/worker config
├── tests/
│ ├── unit_tests/ # starter unit tests (e.g. the health check)
│ └── evalshub_evaluation/ # golden test cases the eval route runs against
├── Dockerfile # multi-stage, distroless
├── Makefile # setup / run / test / lint targets
├── pyproject.toml # uv build backend + pinned deps
└── .pre-commit-config.yaml
Three things are worth pulling out of that tree:有三点值得重点说明:
-
app/agents/is the part you actually own. You get two working agents to fork from rather than a blank file:simple_react_agent.pyis a single-agent LangGraph ReAct loop, andmcp_react_agent.pyis the same loop wired to pull its tools from remote MCP servers. Both compile to a LangGraphStateGraphwith a retry policy and a 30-second per-step timeout, and in dev the graph is auto-exported as a diagram. This is a real step up from the bare LangChain agent initialization we scaffolded in 2024.app/agents/ 是你真正拥有的部分。你得到的不是空白文件,而是两个可供分支的现成智能体:simple_react_agent.py 是一个单智能体 LangGraph ReAct 循环,而 mcp_react_agent.py 是连接到远程 MCP 服务器获取工具的相同循环。两者都编译为带有重试策略和 30 秒单步超时的 LangGraph StateGraph,并且在开发环境中,该图会自动导出为图表。这比我们在 2024 年搭建的原始 LangChain 智能体初始化有了显著提升。 -
app/routes/evalshub_eval.pyships evals on day one. The template comes with an endpoint that runs Recall-Oriented Understudy for Gisting Evaluation (ROUGE), Bilingual Evaluation Understudy (BLEU), and LLM-as-judge evaluators over a set of golden test cases intests/evalshub_evaluation/. The thing we most wished the support bot had, is now in the box before a builder writes a line of their own logic.app/routes/evalshub_eval.py 从第一天起就支持评估。该模板附带一个端点,可针对 tests/evalshub_evaluation/ 中的一组黄金测试用例运行 ROUGE、BLEU 和 LLM-as-judge 评估器。我们最希望支持机器人具备的功能,现在在构建者写下第一行逻辑之前就已经内置了。 -
Everything else is the production wrapper.
core/config.py,storage/,configs/,databases/,scripts/, the distrolessDockerfile, and thepyproject.toml(nowuv, not the Poetry we used in 2024) are the auth, secrets, persistence, packaging, and deploy plumbing that every service needs and that no team should have to write from scratch.其他一切都是生产级封装。core/config.py、storage/、configs/、databases/、scripts/、distroless Dockerfile 以及 pyproject.toml(现在是 uv,不再是我们 2024 年使用的 Poetry)涵盖了身份验证、密钥、持久化、打包和部署等每个服务都必须具备的“管道”工作,而不应让每个团队从零开始编写。
The day-one wiring that used to take two weeks or more now takes about an hour. The rest of this section is what “pre-wired” means, layer by layer.过去需要两周甚至更长时间才能完成的“首日配置”,现在大约只需要一个小时。本节的其余部分将逐层解释什么是“预配置”。
Config and secrets are solved once. Apps declare environment configs as initialization (INI) files with secret interpolation, so secrets resolve from Vault at boot, and a single secret.ini.example is enough to run any LLM-Kit app locally:配置和密钥只需解决一次。应用程序将环境配置声明为带有密钥插值的 INI 文件,这样密钥在启动时会从 Vault 解析,而一个简单的 secret.ini.example 就足以在本地运行任何 LLM-Kit 应用:
[CONFIG]
GRABGPT_API_KEY=${SECRET:GRABGPT_API_KEY}
OTEL_EXPORTER_OTLP_ENDPOINT=<otel-collector-endpoint>
POSTGRES_POOL_RECYCLE=1800
Model access behind one resolver. Every model call goes through the GrabGPT Gateway, which is OpenAI-compatible. LLM-Kit’s job is just to resolve the right endpoint (per environment, and per data tier) and inject the key so application code never hard-codes a provider again:统一解析器背后的模型访问。每个模型调用都通过 GrabGPT 网关,该网关兼容 OpenAI。LLM-Kit 的任务只是解析正确的端点(按环境和数据层)并注入密钥,这样应用程序代码就再也不用硬编码供应商信息了:
from openai import OpenAI
from llm_kit.grabgpt import resolve_grabgpt_base_url, resolve_grabgpt_api_key
client = OpenAI(
base_url=resolve_grabgpt_base_url("prd", "public"), # provider chosen centrally
api_key=resolve_grabgpt_api_key(),
)
That one indirection is what later lets a platform team change which provider serves a model, configure fallback routing, set budgets, and manage cost attribution, without a single application touching its code.这种间接层使得平台团队可以在不触动任何应用程序代码的情况下,更改提供模型的供应商、配置故障转移路由、设置预算和管理成本分摊。
Tracing wired in, not bolted on. A single instrumentor auto-instruments FastAPI, outbound HTTP, LangChain, and MCP, and stamps every span with Kubernetes resource attributes (pod, namespace, image, service version). Structured logs auto-inject the trace and span IDs, so logs and traces correlate in Grafana/Kibana for free:内置而非外挂的追踪功能。单个仪表器会自动对 FastAPI、出站 HTTP、LangChain 和 MCP 进行插桩,并用 Kubernetes 资源属性(Pod、命名空间、镜像、服务版本)标记每个跨度(Span)。结构化日志会自动注入追踪 ID 和跨度 ID,因此日志和追踪可以在 Grafana/Kibana 中免费关联:
exporter = OTLPSpanExporter(endpoint=app_config.otel_exporter_otlp_endpoint)
OTELInstrumentor(exporter=exporter, excluded_urls=["health_check"]).instrument_app(app)
The three systems, no shared trace problem turns into one end-to-end trace across every LLM call, tool call, and retrieval step.曾经“三个系统、没有共享追踪”的问题,现在转变为跨越每个 LLM 调用、工具调用和检索步骤的单一端到端追踪。
Tools can be exposed through MCP servers built on our MCP framework. Instead of hardwiring a large set of tool functions inside the agent process, the agent connects to MCP servers and discovers their tools at runtime. That means adding a new capability can be as simple as registering an MCP server, rather than redeploying the agent.工具可以通过构建在我们的 MCP 框架上的 MCP 服务器公开。智能体无需在进程内硬编码大量工具函数,而是连接到 MCP 服务器并在运行时发现它们的工具。这意味着添加新功能就像注册一个 MCP 服务器一样简单,而无需重新部署智能体。
client = MultiServerMCPClient({
"mcp-gitlab-remote": {
"transport": "streamable_http",
"url": "<remote-mcp-gitlab-endpoint>/mcp/",
"headers": {"Authorization": "Bearer <token>"},
}
})
tools = await client.get_tools() # schema negotiated, no redeploy
An agent is just another service in the ecosystem, with gRPC on both sides. Most of Grab’s backend communicates over gRPC, and agents are rarely standalone; other services call them, and they in turn call other internal services. The template is designed to support both directions.智能体只是生态系统中的另一个服务,双方都使用 gRPC。Grab 的大多数后端都通过 gRPC 通信,智能体很少是独立的;其他服务会调用它们,它们也会调用其他内部服务。该模板旨在支持这两个方向。
On the serving side, the scaffold includes a Protocol Buffers (protobuf) contract (sdk/.../.proto, with a sample Hello remote procedure call (RPC)) and a generated, typed client SDK package that other teams import to call your agent without hand-writing HTTP. make gen-proto regenerates the Python stubs from the .proto, and a gen-proto-check Continuous Integration (CI) step fails the build if the committed stubs drift from the contract. A gRPC server runs alongside FastAPI (default port 8087, multi-worker-safe via SO_REUSEPORT) and ships a standard gRPC health service out of the box:在服务端,脚手架包含一个 Protocol Buffers (protobuf) 契约(sdk/.../.proto,带有示例 Hello RPC)和一个生成的、类型化的客户端 SDK 包,其他团队可以导入该包来调用你的智能体,而无需手动编写 HTTP 代码。make gen-proto 会从 .proto 文件重新生成 Python 存根,如果提交的存根偏离了契约,gen-proto-check 持续集成(CI)步骤会使构建失败。gRPC 服务器与 FastAPI 并行运行(默认端口 8087,通过 SO_REUSEPORT 支持多工作进程),并开箱即用地提供标准的 gRPC 健康检查服务:
$ grpcurl -plaintext localhost:8087 grpc.health.v1.Health/Check
On the calling side, LLM-Kit ships a channel provider so an agent never hardcodes an address. The auto provider tries Istio, then Consul, then a static fallback, health-checks the channel it selects, and runs a background monitor that re-selects after a few consecutive failures:在调用端,LLM-Kit 提供了一个通道提供程序(Channel provider),因此智能体永远不会硬编码地址。自动提供程序会依次尝试 Istio、Consul,最后是静态后备方案,对选定的通道进行健康检查,并运行一个后台监视器,在连续几次失败后重新选择通道:
from llm_kit.grpc.channel_providers.auto import (
AutoGrpcChannelProvider, AutoGrpcChannelProviderConfig,
)
provider = AutoGrpcChannelProvider(logger, AutoGrpcChannelProviderConfig(
client_name="my-agent",
service_key="some-internal-service", # resolved via Istio / Consul
enable_istio=True, enable_consul=True,
))
channel = provider.get_channel() # first healthy channel, auto-reselected on failure
stub = SomeServiceStub(channel)
This is the less glamorous side of being production-ready. Before an agent can deliver value, it needs to both accept calls from and make calls to the rest of the company’s services using the same transport the broader system already relies on.这是实现生产就绪过程中不那么引人注目的那一面。在智能体能够创造价值之前,它需要使用整个系统已经依赖的传输协议,与公司其余的服务进行双向调用。
What’s next下一步
LLM-Kit solved building and shipping one agent. At 500 agents, the problems were no longer framework problems. They were platform problems: who can change which model everyone calls, how one team safely reuses another team’s tools, and how you know an agent got better and not just different after a prompt change. We built three answers for that layer: the GrabGPT Gateway, a remote MCP framework, and an evals platform. Part 2 starts with the gateway — one endpoint, five providers, and what it takes to make “swap the model” a configuration change instead of an incident.LLM-Kit 解决了构建和发布单个智能体的问题。当智能体数量达到 500 个时,问题就不再是框架层面的了,而是平台层面的:谁可以更改每个人调用的模型?一个团队如何安全地重用另一个团队的工具?如何确定智能体在提示词变更后是变得更好而不是仅仅变得不同了?我们为这一层构建了三个解决方案:GrabGPT 网关、远程 MCP 框架和评估平台。第二部分将从网关开始——一个端点、五个供应商,以及如何做到将“更换模型”变成一次配置变更,而不是一次事故。
Join us加入我们
Grab is Southeast Asia’s leading superapp, serving over 900 cities across eight countries (Cambodia, Indonesia, Malaysia, Myanmar, the Philippines, Singapore, Thailand, and Vietnam). Through a single platform, millions of users access mobility, delivery, and digital financial services, including ride-hailing, food delivery, payments, lending, and digital banking via GXS Bank and GXBank. Founded in 2012, Grab’s mission is to drive Southeast Asia forward by creating economic empowerment for everyone while delivering sustainable financial performance and positive social impact.Grab 是东南亚领先的超级应用,服务于八个国家(柬埔寨、印度尼西亚、马来西亚、缅甸、菲律宾、新加坡、泰国和越南)的 900 多个城市。通过单一平台,数百万用户可以使用出行、配送和数字金融服务,包括网约车、外卖、支付、借贷以及通过 GXS Bank 和 GXBank 提供的数字银行服务。Grab 成立于 2012 年,其使命是通过为每个人创造经济赋权,同时提供可持续的财务业绩和社会积极影响,推动东南亚向前发展。
Powered by technology and driven by heart, our mission is to drive Southeast Asia forward by creating economic empowerment for everyone. If this mission speaks to you, join our team today!以技术为动力,以心为驱动,我们的使命是通过为每个人创造经济赋权来推动东南亚向前发展。如果这个使命能引起你的共鸣,欢迎立即加入我们的团队!
Related jobs at GrabGrab 的相关职位
Loading opportunities…
- Principal Machine Learning EngineerEngineering · Singapore, Singapore首席机器学习工程师工程 · 新加坡,新加坡
- Lead Machine Learning Engineer (Foundation Models)Engineering · Singapore, Singapore资深机器学习工程师(基础模型)工程 · 新加坡,新加坡
- Machine Learning Engineer (Fulfilment ETA)Data Science · Petaling Jaya, Malaysia机器学习工程师(履约预计到达时间)数据科学 · 八打灵再也,马来西亚
Browse open roles at Grab Careers
View all engineering roles查看所有工程职位