Saltar para o conteúdo

Num mercado, os riscos convergem inevitavelmente para duas questões fundamentais: quem é esta pessoa e qual é o nosso grau de confiança de que esta ação é legítima? Eis alguns exemplos do que queremos dizer com isto: um agente de apoio que avalia um pedido de reembolso precisa de saber estas respostas. Um mecanismo promocional que decide se deve prolongar uma oferta não pode avançar sem esta informação. Um sistema de mitigação de bots que analisa uma tentativa de início de sessão para detetar tráfego automatizado fica de mãos atadas sem estes dados. Os pormenores diferem — o canal, o sinal, o limiar — mas as questões centrais não mudam. 

Embora estas questões não sejam novas, a IA tem vindo a exercer uma pressão cada vez maior de ambos os lados da equação; os mesmos avanços que facilitam a geração de comportamentos falsos convincentes em grande escala também tornam possível identificar os intervenientes com sinais mais ricos do que nunca.

No entanto, a identidade nunca foi tratada como uma capacidade horizontal própria. Em vez disso, a maioria dos sistemas foi construída com uma abordagem centrada no produto — um motor de risco para encomendas, um modelo para a segmentação de promoções ou uma regra para a deteção de apropriação de contas. Cada um responde implicitamente a uma versão da pergunta «quem é esta pessoa?» para os seus próprios fins, mas nenhum deles partilha essa resposta. Isto resulta num conjunto de visões parciais da mesma pessoa, cada uma precisa para o seu próprio fim, mas isolada dentro do seu próprio sistema.

A inteligência de identidade parte de uma premissa diferente: se a questão é partilhada, o sinal que a responde também deve sê-lo. Trata-se de um problema de plataforma — resolvido uma vez, de forma centralizada — que é distinto da forma como um determinado sistema opta por agir com base na resposta, o que varia consoante o contexto em que é aplicado. Tratada como uma capacidade horizontal de primeira classe — e não como um subproduto de um determinado produto —, a identidade torna-se um fio condutor presente em quase todos os casos de utilização relacionados com a integridade. Essa é a nossa tese central: a identidade é uma das capacidades com maior impacto, mas menos valorizadas no âmbito da integridade, precisamente porque ninguém a desenvolve como algo autónomo.

A identidade ganha o seu verdadeiro significado

Se essa questão de «quem é este?» é tão universal, por que razão a identidade não foi tratada como uma infraestrutura fundamental desde o início?

No passado, cada superfície de integridade — risco de encomendas, risco de contas ou risco promocional — resolvia primeiro o seu próprio problema e à sua maneira, com os seus próprios sinais de dispositivos, lógica de ligação e definição prática de «a mesma pessoa». É assim que os problemas especializados tendem a ser resolvidos: com uma regra aqui e um modelo ali, cada um concebido para um fim específico e de rápida implementação. Uma camada de identidade partilhada é um tipo diferente de investimento: não pertence a nenhuma área específica, pelo que nenhuma delas está naturalmente posicionada para a construir, apesar de todas elas beneficiarem com isso.

O resultado até à data tem sido um sinal de identidade que não é reutilizável tal como está. Cada nova equipa que pretendesse essa resposta tinha de a implementar do zero, através de uma integração personalizada e única, em vez de se ligar a uma interface padrão. Durante anos, os sinais de identidade existiram em todo o lado, mas não pertenciam a ninguém; cada equipa pagava para voltar a obter uma resposta parcial, enquanto ninguém captava o valor acumulado de responder à pergunta uma única vez e partilhá-la.

Criação de uma plataforma de inteligência de identidade

Na DoorDash, decidimos colmatar essa lacuna através da conceção de uma nova infraestrutura. Em vez de cada sistema criar a sua própria lógica de ligação com base nos seus próprios sinais, queríamos que a identidade se tornasse algo criado uma única vez e utilizado em todo o lado.

Na prática, isso significava criar três camadas sobre uma base de dados de sinais partilhada:

  • Em primeiro lugar, a resolução de identidades: um gráfico de resolução de entidades com mais de mil milhões de arestas, construído principalmente com técnicas de agrupamento não supervisionado e de previsão de ligações, que investiga quais as contas que poderão corresponder à mesma pessoa. 
  • Em segundo lugar, inteligência relacional: uma questão relacionada com os gráficos, mas diferente: que pessoas, contas, dispositivos e ativos estão associados entre si? Esta camada reconhece que duas contas podem estar ligadas de forma significativa sem corresponderem à mesma pessoa. 
  • Em terceiro lugar, os modelos de tomada de decisão: normalmente modelos de aprendizagem supervisionada, tais como classificadores com reforço de gradiente, treinados com base em resultados conhecidos para um caso de utilização específico. Esta camada utiliza as duas primeiras camadas para fornecer uma resposta em tempo real à pergunta: este evento específico, para esta decisão específica, é legítimo?
FIGURA 1: UMA MEMÓRIA DE SINAL PARTILHADA ALIMENTA DOIS GRÁFICOS — QUEM É UMA PESSOA E COM QUEM ESTÁ LIGADA — CUJA SAÍDA É TRADUZIDA POR UMA CAMADA DE AVALIAÇÃO NUMA ÚNICA DECISÃO.

Vamos usar um dos casos mais complexos de resolução de identidade como exemplo — um cliente que acabou de se registar, faz a sua primeira encomenda e apresenta um pedido de apoio. Não há histórico com o qual comparar, nem é provável que haja uma correspondência forte com uma conta existente; a resolução de identidade, por si só, não tem muitos elementos em que se basear. O que a conta possui, desde o momento em que é criada, é um conjunto de atributos de identidade, tais como um dispositivo, um número de telefone, uma morada ou um cartão registado. A plataforma já regista em que contas cada um desses atributos apareceu, pelo que uma sobreposição em qualquer um deles é visível imediatamente, sem ter de esperar por uma única encomenda ou pedido de assistência. Um endereço partilhado, por exemplo, é um ponto de partida, mas um simples indicador de «partilhado ou não» é demasiado vago para se agir com base nele; não indica se esse endereço está associado a duas contas ou a 200, se todas surgiram no mesmo dia ou ao longo de anos, ou se esse padrão é sequer invulgar. É essa a função da inteligência de relações: não identificar quem é uma pessoa, mas caracterizar o grau de interligação entre elas. Ela analisa minuciosamente mais de 100 sinais derivados calculados por conta, cada um captando quantas outras contas partilham um determinado atributo, há quanto tempo e quão anómalo isso parece quando comparado com um cliente comum.

Mas mesmo tudo isto não constitui uma decisão. Um simples facto sobre o gráfico — como, por exemplo, o facto de este endereço ter 40 contas associadas, a maioria criada na última semana — não constitui um veredicto sobre este pedido de apoio específico. Transformar um facto num veredicto é a função do modelo de tomada de decisão. Este é treinado com base em resultados para saber até que ponto esse padrão deve ser relevante para este tipo específico de pedido; a sua conclusão é disponibilizada em tempo real, para que esteja pronta no momento em que o pedido for recebido.

É por isso que a plataforma precisa das três camadas, e não apenas da primeira. A resolução de identidade determina se duas contas pertencem à mesma pessoa, enquanto a inteligência de relações fornece uma resposta útil mesmo quando a resolução não produz resultados; nenhuma delas constitui uma decisão até que um modelo criado para esse caso de utilização específico a transforme numa decisão.

A plataforma separa o cálculo do sinal da atribuição de pontuação (Figura 2). As características são agregadas de forma assíncrona e ficam prontas poucos minutos após qualquer alteração. Um ponto de verificação recupera o que precisa em 10 a 15 milissegundos, em vez de esperar por qualquer tarefa que o tenha produzido. A pontuação ocorre então onde a margem de latência da superfície o permitir; é executada em linha quando há espaço disponível, ou pode ser acionada assim que as características forem disponibilizadas, para que a pontuação seja armazenada e lida no momento da decisão.

Figura 2: OS SINTAIS DE IDENTIDADE SÃO CONSTRUÍDOS COM BASE NO SEU PRÓPRIO RELÓGIO E ARMAZENADOS UMA ÚNICA VEZ, PELO QUE NENHUMA DECISÃO DEPENDE DA AGREGAÇÃO SUBSJACENTE.

Uma base, vários casos de utilização

Os sistemas a jusante — por exemplo, um fluxo de apoio, um motor promocional ou um portal de finalização de compra — nem todos necessitam da mesma camada. Alguns sistemas podem obter uma resposta diretamente do gráfico de identidades e relações; outros precisam que essa resposta seja refinada através do modelo de decisão adequado, transformando-se numa pontuação em tempo real concebida para essa decisão específica. Estes sistemas nunca precisam de saber como é o gráfico subjacente.

O agrupamento de identidades de consumidores é o exemplo mais claro dessa plataforma em ação. Essas contas parecem pertencer a pessoas diferentes, mas, na realidade, são da mesma pessoa. Trata-se, especificamente, de resolução de identidade: determinar se duas contas correspondem a uma única pessoa, e não apenas se estão, de alguma forma, ligadas. Nos bastidores, o agrupamento de identidades avalia a fiabilidade de cada sinal que liga duas contas e a improbabilidade de duas pessoas diferentes partilharem esse sinal por coincidência. Quanto mais improvável for um sinal partilhado, maior será o peso que este tem por si só; sinais mais comuns ou mais fáceis de partilhar só têm peso em combinação, quando vários deles se somam. Como funciona continuamente em relação ao gráfico de identidade da DoorDash, em vez de ser uma tarefa em lote periódica, pode ser verificado no momento em que é recebido um pedido de início de sessão, finalização de compra ou reembolso.

Assim que esse agrupamento existe, o mesmo sinal subjacente de identidade e relação — reutilizado em vez de reconstruído — surge em toda a restante área de cobertura da integridade. Nos fluxos de trabalho de apoio, esse mesmo agrupamento ajuda a distinguir uma falha de serviço genuína de uma situação em que uma pessoa apresenta reclamações aparentemente semelhantes em várias contas. Nas promoções, determina a elegibilidade ao distinguir um novo cliente de uma pessoa que já tenha usufruído de uma oferta sob uma identidade diferente. Na segurança das contas, sinaliza um início de sessão com a palavra-passe correta que não se comporta como o titular da conta. Ampliada de uma pessoa para muitas, uma camada relacionada, mas distinta — a inteligência de relações, e não a resolução de identidade — é o que revela abusos coordenados; isto pode assumir a forma de uma rede de contas que parecem independentes individualmente, mas que se revelam agir como uma única operação depois de as suas ligações serem mapeadas. Na mitigação de bots, distingue um ser humano a lidar com atritos de um script a funcionar em grande escala. 

Nenhuma destas situações exigia um novo tipo de sinal, mas sim o mesmo, encaminhado para uma decisão diferente em cada ocasião. É isso que uma plataforma partilhada torna possível: um único substrato, múltiplas decisões. E, uma vez que essa plataforma existe, não tem de se limitar a identificadores diretos.

A identidade é mais do que um identificador

Os identificadores diretos eram, naturalmente, o ponto de partida óbvio — um ID de dispositivo, um número de telefone, um e-mail ou um cartão registado no sistema. Trata-se de sinais poderosos, difíceis de falsificar e que, muitas vezes, por si só, são suficientes para responder com segurança à pergunta «quem é este?». No entanto, um malfeitor suficientemente determinado ainda consegue contorná-los com um novo dispositivo, um novo número, um novo e-mail ou um novo cartão — fazendo com que o rasto direto se perca.

O comportamento ajuda a colmatar essa lacuna. A forma como uma pessoa se move num mercado — o ritmo das suas ações, os seus padrões de navegação, as ações de finalização de compra ou as interações com o apoio ao cliente — também constitui uma forma de identidade, que tende a persistir mesmo quando os identificadores que a rodeiam são substituídos. Não substitui os sinais diretos; é uma camada complementar para os casos em que os sinais diretos, por si só, não são suficientes.

Esta nova perspetiva é importante porque altera a definição de «a mesma pessoa». Duas contas com dispositivos e métodos de pagamento completamente diferentes podem, ainda assim, ser reconhecidas como pertencendo à mesma pessoa, se o comportamento for tido em conta. Duas contas que pareçam não ter qualquer relação, com base em todos os identificadores diretos, podem, ainda assim, justificar uma análise mais aprofundada, se o seu comportamento for demasiado semelhante para ser uma coincidência.

O futuro da IA na área da identidade

A forma mais clara de avaliar uma plataforma como esta não reside numa única conquista, mas sim nos clientes que nem sequer se apercebem de que algo aconteceu, mas que, ainda assim, beneficiam de uma experiência mais simplificada. A inteligência de identidade elimina os obstáculos que os clientes honestos têm sido obrigados a suportar; um sistema mais seguro, capaz de chegar mais rapidamente a uma conclusão sobre com quem está a lidar, alivia-os desse fardo. 

Esta mesma ideia pode ser aplicada a dados de entrada mais ricos. Atualmente, os nossos sinais comportamentais ainda dependem em grande medida de resumos numéricos. No entanto, os modelos LLM e de IA generativa poderão permitir-nos, no futuro, extrair informações a partir de texto não estruturado, imagens e conversas informais, com custos de desenvolvimento muito mais baixos do que anteriormente. 

Ao contrário do que acontece nos modelos tradicionais de redes neurais, em que os subcomponentes de texto e imagem têm de ser criados do zero, agora podemos utilizar endpoints de IA gerativa já disponíveis ou aproveitar a camada de saída de modelos de grande dimensão pré-treinados para gerar características relacionadas com texto/imagem, tais como a descrição de problemas, a análise de sentimentos ou a verificação de imagens duplicadas. Além disso, podemos explorar arquiteturas de modelos baseadas em transformadores para selecionar embeddings de identidade do utilizador que possam potencialmente revolucionar a forma como definimos clusters no gráfico de identidade. Na arquitetura acima, estes apresentam-se como dois caminhos separados (Figura 1): um LLM a extrair características diretamente de recursos de forma livre e embeddings de texto a tornarem-se um novo tipo de aresta no gráfico de identidade. 

Dito isto, os mesmos avanços na IA que facilitam a criação de um sinal de identidade fiável também facilitam a sua falsificação, com comportamentos sintéticos mais convincentes, variações automatizadas entre contas ou respostas adversárias mais rápidas às nossas novas políticas. Tratar a identidade como uma plataforma, em vez de um conjunto heterogéneo de verificações pontuais, permite acompanhar o ritmo, oferecendo um único local para integrar um novo tipo de sinal, em vez de depender de uma dúzia de sistemas separados, cada um à espera da sua vez para se atualizar.

Em última análise, o nosso objetivo é reduzir a necessidade de respostas personalizadas e pontuais em matéria de identidade, desenvolvendo uma base consistente de identidade e relações que sirva todos os pontos de decisão que dela necessitem.

Mantenha-se informado com as actualizações semanais

Subscreva o nosso blogue de Engenharia para receber actualizações regulares sobre todos os projectos mais interessantes em que a nossa equipa está a trabalhar

Quando um consumidor pede ao Ask DoorDash para«voltar a encomendar os meus produtos habituais», o pedido parece simples. O DoorDash já tem o histórico de encomendas desse consumidor; por que não recuperar os produtos que compra com mais frequência e colocá-los numa lista de compras?

A repetição de encomendas é um dos nossos casos de utilização mais populares, representando cerca de uma em cada três encomendas. No entanto, o percurso original baseado em agentes podia demorar dezenas de segundos a gerar uma lista. Ao antecipar o raciocínio histórico estável antes do pedido e ao utilizar uma execução determinística, em que o produto já conhece a intenção do consumidor, reduzimos o tempo de um percurso de repetição de encomendas de cerca de 16 segundos para cerca de 2 segundos e duplicámos a taxa de visualização da lista resultante pelos consumidores. 

A transferência do raciocínio histórico para o ambiente offline também aliviou a restrição de latência na geração, permitindo-nos utilizar modelos mais avançados para produzir resultados habituais de maior qualidade. Essa melhoria traduziu-se num aumento de cerca de 34% na taxa de encomendas para o fluxo.

O desafio reside no facto de que acelerar o processo de repetição de encomendas não pode significar simplesmente reproduzir o histórico. O histórico de encomendas regista o que uma pessoa comprou, não o que precisa a seguir.

O leite comprado uma vez por semana é provavelmente uma necessidade recorrente. Um pacote grande de toalhas de papel comprado com aproximadamente a mesma frequência pode não ser. Seis unidades compradas numa única entrega são um indicador diferente de uma unidade comprada ao longo de seis entregas. Um iogurte que um consumidor compra repetidamente pode ser um produto de base; três sabores comprados uma vez cada podem ser uma forma de experimentar.

Responder à pergunta«comprar os meus produtos habituais»requer, portanto, uma avaliação do comportamento anterior. Ao mesmo tempo, a resposta final tem de se basear num catálogo em constante mudança: os artigos ficam esgotados, as fichas de produto alteram-se e o produto exato que um consumidor comprou anteriormente pode não estar disponível na loja onde está a fazer compras hoje.

No caso de um pedido típico de reabastecimento em formato livre, o agente do Grocery carrega a competência de reabastecimento, recupera o contexto do consumidor e o histórico de encomendas necessários para o pedido, decide quais as compras anteriores que devem fazer parte do próximo cesto de compras, satisfaz essas necessidades com base no catálogo atual e compila a lista de compras. Esta flexibilidade permite que o mesmo fluxo processe uma variedade de pedidos de reabastecimento, ao mesmo tempo que integra várias partes diferentes do sistema Ask DoorDash para produzir uma lista de compras aparentemente simples.

Os artigos anteriores desta série abordaram, um a um, os temas «Inteligência», «Avaliação», «Plataforma» e «Experiência do Utilizador». A «Reordenação» é o fluxo em que todos os quatro têm de estar em sintonia ao mesmo tempo: a lista tem de ser personalizada, verificável, rápida e permitir a compra. Este artigo acompanha um único pedido ao longo de cada uma dessas etapas.

A função «Reorder» é mais do que apenas «replay»

O Ask DoorDash suporta vários tipos de pedidos de repetição de encomendas. Um consumidor pode escrever«Que produtos de mercearia costumo comprar?»,«Repetir a minha encomenda habitual de mercearia»,«Que leite comprei da última vez?» ou«Repetir os meus produtos habituais, mas mais baratos».

Estes pedidos parecem semelhantes, mas implicam decisões diferentes na prática. Procurar um produto da última encomenda é diferente de decidir quais as compras que representam os hábitos habituais de um consumidor; pedir versões mais baratas acrescenta outro conjunto de restrições.

Conforme descrito na nossa visão geral de engenharia, a arquitetura multiagente da DoorDash encaminha, em primeiro lugar, um pedido de compras de mercearia para o agente «Grocery». Quando o pedido envolve uma nova encomenda, o agente pode ativar a funcionalidade «Reorder».

A competência «Reorder» fornece ao agente instruções específicas para cada tarefa, para que este possa tratar estes pedidos utilizando o contexto e as ferramentas de que dispõe. Em vez de definir um fluxo de trabalho distinto para cada formulação possível, esta competência proporciona ao agente um processo geral para determinar o que o pedido exige e transformar o resultado numa lista de compras prática.

Do ponto de vista conceptual, esse processo tem cinco fases:

  1. Estabelecer o contexto. Determinar a loja onde se vai fazer compras, caso ainda não se saiba qual é, e obter informações relevantes sobre o consumidor.
  2. Recuperar o histórico. Ler o histórico de encomendas de mercearia necessário para o pedido e reformulá-lo de forma a obter uma representação sobre a qual o modelo possa raciocinar.
  3. Selecione o que é relevante. Decida quais as partes desse histórico que respondem ao pedido do consumidor. No casodos «clientes habituais», isto significa distinguir as necessidades recorrentes das compras pontuais.
  4. Identificar produtos. Pesquisar no catálogo atual da DoorDash, mantendo detalhes como marca, tamanho e variante sempre que possível.
  5. Elabore o resultado. Faça uma pergunta de esclarecimento ao consumidor quando ainda houver uma escolha verdadeiramente ambígua e, em seguida, crie a lista de compras editável.

Outras competências podem integrar-se nesse fluxo. Se um consumidor pedir os seus produtos habituais «mas mais baratos», por exemplo, a competência «Reorder» pode determinar o que normalmente precisa, enquanto a análise de acessibilidade financeira tem em conta os produtos e preços disponíveis no momento.

Esta flexibilidade é importante para a linguagem de forma livre. Um utilizador que escreve no Ask não selecionou uma operação da API; expressou uma intenção, e o agente tem de determinar que tarefa essa intenção requer.

Cada uma dessas cinco etapas pressupõe algo que a funcionalidade não tem em conta. Em que loja fazer compras, que marca preferir, se este consumidor sequer quer azeite esta semana — nada disso é um facto relacionado com a nova encomenda. É um facto relacionado com o consumidor.

Informações: O que o agente já sabe sobre si 

O histórico de encomendas indica-nos o que um consumidor comprou, mas não nos diz como interpretar cada compra. Tal como descrito em «Building Ask DoorDash (Parte 2): Inteligência», o Ask DoorDash consegue obter contexto, como preferências de lojas, afinidades com marcas, preferências alimentares e o estado da despensa, a partir da memória de longo prazo, da memória conversacional e da memória da sessão.

No que diz respeito à reposição de encomendas, esses sinais não constituem uma fonte adicional de produtos. Ajudam a interpretar o histórico de compras do consumidor. Se alguém comprar sempre uma determinada marca de leite, por exemplo, essa preferência deve ser refletida na lista resultante. Se, recentemente, tiver indicado ao Ask que tem um bom stock de azeite, esse contexto pode fazer com que o azeite seja excluído da sua próxima reposição de encomendas, mesmo que apareça com frequência no seu histórico.

Isso é importante porque os consumidores já sabem quais são os seus«produtos habituais». Pequenas discrepâncias na loja, na marca ou no estado da despensa são imediatamente visíveis e podem rapidamente minar a confiança no resto da lista.

A Inteligência confere, portanto, à competência «Reorder» um melhor ponto de partida, mas não responde à questão central: quais são as compras no histórico do consumidor que realmente se consideram necessidades recorrentes? Essa decisão ainda tem de ser tomada — e avaliada de forma consistente.

Avaliação: Verificar se a lista está correta

Precisávamos de uma forma de avaliar a decisãorelativa aos «habituais» antes de esta chegar ao consumidor. Tal como descrito em «Building Ask DoorDash (Parte 3): Avaliação», a avaliação do agente analisa tanto o percurso de execução como o resultado. No caso de uma nova encomenda, isso significa verificar se o agente recuperou o contexto e o histórico corretos, se seguiu o fluxo esperado e se produziu uma lista de compras exequível — bem como se os itens dessa lista refletem efetivamente as necessidades recorrentes do consumidor.

Essas verificações de seleção são concretas. Se um consumidor encomendar repetidamente três iogurtes, a lista mantém esse padrão e essa quantidade? Um artigo que apareceu apenas uma vez fica de fora dos seus«produtos habituais»? Se o consumidor tiver indicado que já tem algo em casa, isso reflete-se no resultado?

Uma vez que o histórico de encomendas em tempo real se altera ao longo do tempo, utilizamos o Simulador de Conversação baseado em cenários para reproduzir cenários de novas encomendas com base num histórico de compras fixo. As rubricas em formato de lista de verificação permitem-nos, então, testar artigos recorrentes, compras pontuais, quantidades e preferências conhecidas, comparando-as com os mesmos dados de referência à medida que a implementação vai evoluindo.

Uma lista correta só é útil se chegar enquanto o consumidor ainda estiver a fazer compras. O nosso fluxo inicial demorava cerca de 16 segundos.

Plataforma: A decisão não precisa de ser tomada enquanto espera 

Essa latência deveu-se, em parte, à forma como o Ask DoorDash lida com os pedidos dos agentes. Conforme descrito em «Building Ask DoorDash (Parte 4): Uma Plataforma para a Criação e Evolução de Agentes», numa única ronda do consumidor, o modelo pode tomar uma decisão, aceder a uma ferramenta, analisar o resultado e utilizar essa informação para decidir o que fazer a seguir. Num fluxo representativo do serviço de compras de mercearia, isso pode exigir 6 a 8 chamadas ao LLM, juntamente com várias chamadas a ferramentas.

Essa flexibilidade é importante quando cada etapa depende de informações obtidas durante o pedido. No entanto, a reordenação mostrou-nos que várias dessas etapas dependiam de dados históricos que mudam lentamente.

Os consumidores costumam voltar sempre a um conjunto relativamente pequeno de supermercados. Em vez de selecionar uma loja, consultar o histórico de encomendas dessa loja e determinar as necessidades recorrentes do consumidor em cada pedido, podemos fazer esse trabalho antecipadamente, recorrendo aos dados históricos.

Outras partes do fluxo têm de permanecer ativas. O inventário e os preços variam, os produtos podem ficar indisponíveis e as listagens do catálogo podem sofrer alterações entre visitas.

Isso proporcionou-nos um limite natural: calcular antecipadamente as lojas prováveis do consumidor e as suas necessidades recorrentes e, em seguida, utilizar o percurso da solicitação em tempo real para satisfazer essas necessidades com base no catálogo atual e criar a lista de compras.

Essa divisão serviu de base para o nosso fluxo de trabalho «offline para online».

Figura 1: O Ask DoorDash atribui cada pedido de nova encomenda a um percurso de execução com base no âmbito em que se insere. Para «reencomendar o meu último carrinho», um âmbito de sessão tipado permite que um plugin de backend recupere o carrinho anterior sem utilizar o modelo para a seleção de ferramentas. Para compras recorrentes, um pipeline diário combina 90 dias de histórico de encomendas com sinais do perfil relevantes para a tarefa, seleciona consumidores com evidência suficiente, executa inferência LLM em lote e valida o resultado num pacote reutilizável de produtos habituais. «Reencomendar os meus produtos habituais» lê esse pacote diretamente, enquanto «reencomendar os meus produtos habituais, mas mais baratos» o complementa com preços atuais, promoções, tamanhos de embalagem, stock e restrições do consumidor. Os três percursos convergem na resolução do catálogo em tempo real, que tenta primeiro o ID do artigo da loja, depois o ID do produto no catálogo e, por fim, um termo de pesquisa antes de criar uma lista de compras editável. O agente Grocery permanece disponível para esclarecer escolhas ambíguas, explicar substituições e recuperar-se de resultados em falta ou inutilizáveis.

Gerar itens habituais antes de o consumidor as solicitar. 

Seleção de coortes e materialização de entradas

Nem todos os históricos de encomendas contêm dados suficientes para inferir necessidades recorrentes. Uma única entrega de compras de supermercado indica-nos o que um consumidor comprou uma vez, mas não se algum desses artigos é de consumo habitual. A aplicação deste processo a todos os consumidores implicaria, portanto, um aumento dos custos, ao mesmo tempo que produziria resultados com baixo nível de confiança.

Consideramos a seleção de coortes tanto como um critério de qualidade como um mecanismo de controlo de custos. Uma tarefa diária do Spark identifica os consumidores com atividade recente suficiente em compras de supermercado ou no retalho para sustentar a geração.

Para cada consumidor selecionado, preparamos dois conjuntos de dados: um perfil resumido que contém os sinais a longo prazo mais relevantes para a repetição de encomendas, tais como interesses em categorias de artigos e afinidades com marcas, e o histórico de encomendas ao nível dos artigos dos últimos 90 dias.

Ambos têm finalidades diferentes. O perfil fornece contexto sobre o consumidor; o histórico de encomendas fornece os dados ao nível do evento necessários para inferir necessidades recorrentes. A preferência por uma marca pode indicar-nos qual o iogurte que um consumidor provavelmente irá preferir, por exemplo, enquanto o histórico de compras nos diz se o iogurte faz, de facto, parte dos seus produtos habituais.

Seguindo a abordagem de redução do contexto específica para cada tarefa, resultante do nosso trabalho sobre modelos de linguagem de grande escala (LLMs) offline para personalização online, enviamos apenas os sinais do perfil relevantes para essa tarefa, em vez do perfil completo do consumidor. Isso reduz o custo de entrada e evita que o contexto não relacionado interfira nas evidências de compra nas quais a decisão se baseia.

Definir«Os seus habituais»

Elaborar uma lista ordenada é simples, uma vez definido o que se entende por«normal». Definir isso foi a parte mais difícil.

A frequência é um ponto de referência razoável, mas indica o que um consumidor comprou com mais frequência, em vez do que é provável que venha a precisar novamente. O leite e um pacote grande de toalhas de papel podem aparecer no mesmo número de encomendas, embora tenham padrões de reposição muito diferentes. Seis garrafas numa única entrega também constituem uma evidência menos forte de um hábito recorrente do que uma garrafa comprada ao longo de seis entregas separadas. A recência, por si só, também não resolve a ambiguidade.

Utilizamos um LLM porque estes sinais interagem de formas que são difíceis de captar numa única regra de classificação. O modelo segue uma ordenação qualitativa explícita: a frequência em entregas distintas é o principal sinal de uma necessidade recorrente, a atualidade indica se essa necessidade ainda está ativa e as características de reabastecimento ajudam a distinguir os produtos de consumo rápido dos produtos duradouros. A afinidade com a marca pode refinar a escolha, mas não se sobrepõe às evidências diretas de compra.

O stock disponível acrescenta mais uma dimensão. Um multipack de um produto durável adquirido recentemente pode descer na lista, enquanto um produto perecível que aparecia regularmente no passado, mas que não tem sido comprado ultimamente, pode subir na lista.

Organizar a decisão num conjunto de documentos

O modelo aplica esse raciocínio de forma independente para cada loja relevante e apresenta os artigos recorrentes que identifica. O número máximo de artigos é um limite máximo, não uma meta: se os dados indicarem apenas alguns artigos habituais, o modelo apresenta o conjunto mais reduzido, em vez de preencher a lista com suposições menos fundamentadas. Se o histórico não permitir identificar um conjunto útil, o modelo pode abster-se totalmente.

O resultado está limitado aos dados provenientes da entrada. Os identificadores da loja e dos artigos têm de provir do histórico do consumidor; as compras recorrentes têm preferência em relação às pontuais; e as variantes quase idênticas são agrupadas, em vez de ocuparem várias posições no pacote. Para cada artigo, retemos indicadores como a frequência de compra, a data mais recente da compra e a quantidade habitual, para que o resultado possa ser apresentado sem necessidade de repetir o raciocínio histórico em tempo real.

Indique a necessidade, não o SKU

Um artigo bem classificado continua a ser inutilizável se o catálogo for alterado antes de o consumidor voltar. A ficha específica desse artigo pode ser republicada com um novo identificador específico do comerciante ou desaparecer por completo. Manter apenas o ID histórico do artigo na loja tornaria o pacote frágil; manter apenas um termo genérico, como «leite de aveia», faria com que se perdesse a especificidade do que o consumidor realmente compra.

Por conseguinte, representamos cada necessidade em três níveis: o ID do artigo na loja, para a correspondência mais precisa; um identificador de produto ao nível do catálogo, para o mesmo produto subjacente em todas as listagens; e um termo de pesquisa genérico, como alternativa. No momento do pedido, o percurso de resposta experimenta-os do mais específico para o mais geral e pára no primeiro produto atual elegível.

Essa hierarquia reflete claramente a distinção entre o mundo offline e o mundo online. O modelo offline determina qual das necessidades, com base no histórico do consumidor, vale a pena ter em conta; o sistema online decide qual o produto que pode satisfazer essa necessidade neste preciso momento.

Antes da publicação de um pacote, a validação determinística ocorre entre a geração do modelo e o contrato de disponibilização. Distingue uma abstenção explícita de resultados malformados, remove identificadores inutilizáveis, normaliza quantidades e filtra resultados que não cumprem os requisitos para um pacote útil. O modelo toma a decisão semântica; o código determinístico decide se o resultado é seguro para ser disponibilizado.

Geração e distribuição em grande escala

A geração destes pacotes numa vasta coorte de consumidores requer um sistema de processamento em lotes capaz de tolerar falhas parciais. Utilizamos uma infraestrutura Metaflow fragmentada, para que os lotes possam ser executados de forma independente e os fragmentos com falha possam ser repetidos sem descartar o trabalho bem-sucedido.

Após a validação, os pacotes resultantes são publicados num armazenamento de chave-valor de baixa latência. O caminho de serviço pode então recuperar o pacote de um consumidor para um determinado armazenamento sem repetir o raciocínio histórico, enquanto que os pacotes em falta ou inutilizáveis resultam numa resposta vazia, em vez de provocarem uma falha na etapa «Grocery».

Uma vez que o pacote é gerado independentemente do Ask, o mesmo sinal também pode ser utilizado noutras superfícies personalizadas sem que seja necessário repetir a inferência.

Nada disto é visível para o consumidor. O que este vê é uma lista de compras — e, dependendo da forma como entrou no fluxo, poderá vê-la em cerca de dois segundos.

Experiência do utilizador: uma lista, várias formas de aceder

Um consumidor nem sempre chega à opção de repetir a encomenda pelo mesmo caminho. Pode escrever«repetir a minha encomenda habitual»diretamente no Ask, ou pode aceder através de uma interface contextual em que a DoorDash já tem alguma informação sobre o que o consumidor pretende fazer.

Essa distinção é importante porque o contexto fornecido pela experiência pode eliminar trabalho da conversa. Conforme descrito em «Building Ask DoorDash (Parte 5): Uma Interface Baseada na Realidade para Agentes de Compras», o cliente atribui um âmbito a um pedido, transmitindo informações como o tópico e a loja a partir da qual o consumidor acedeu. O sistema pode utilizar esse contexto em vez de pedir ao consumidor que repita informações que o produto já conhece.

No caso de um pedido em formato livre, como«repor os meus produtos habituais», o agente «Grocery» continua a interpretar o pedido através da skill «Reorder». No entanto, quando um consumidor acede através de uma ação dedicada«Reorder my usuals», a intenção já está definida. Conforme ilustrado abaixo, atribuímos um âmbito predefinido que é invisível para o consumidor e encaminhamos o pedido por um percurso determinístico.

Em combinação com o pacote pré-calculado da secção «Plataforma», isso reduz o trabalho em tempo real à recuperação do pacote e à resolução dos seus itens em relação ao catálogo atual. O percurso já não necessita que o LLM interprete o pedido ou reconstrua os hábitos do consumidor a partir do histórico, reduzindo a latência de cerca de 16 segundos para cerca de 2 segundos.

Quer o consumidor aceda através de texto livre ou de um ponto de entrada contextual, o resultado é o mesmo: uma lista de compras estruturada. A partir daí, pode alterar quantidades, remover algo que já tem, trocar um produto ou adicionar a lista finalizada ao carrinho. Essas edições estruturadas são efetuadas diretamente na própria lista, sem necessidade de mais uma interação com o LLM.

O agente continua disponível quando o pedido exige maior capacidade de discernimento. Um consumidor pode pedir, por exemplo,«o de sempre, mas mais barato», e o agente pode partir das mesmas necessidades recorrentes, ao mesmo tempo que analisa os preços atuais e as alternativas.

Diferentes pontos de entrada podem dar origem a volumes de trabalho muito diferentes nos bastidores, mantendo, no entanto, uma experiência de reordenação contínua.

Conclusão

«Encomendar os meus produtos habituais»parece um pedido simples, mas para que seja útil é necessário tomar as decisões certas no momento certo. O contexto do consumidor ajuda a interpretar o histórico de compras; as necessidades recorrentes podem ser calculadas com antecedência; o inventário, os preços e a resolução do catálogo são atualizados em tempo real; e os pontos de entrada contextuais podem eliminar o trabalho que o produto já realizou.

A lição mais ampla é que melhorar um agente nem sempre significa pedir ao modelo para fazer mais. Significa decidir sobre o que se deve raciocinar no momento do pedido, o que pode ser sabido antecipadamente e o que deve ser determinístico.

Quando esses limites são bem definidos, a complexidade desaparece para o consumidor. Este pede à DoorDash para voltar a encomendar os seus pratos habituais e recebe uma lista que parece personalizada, atualizada e pronta para fazer a compra.

Mantenha-se informado com as actualizações semanais

Subscreva o nosso blogue de Engenharia para receber actualizações regulares sobre todos os projectos mais interessantes em que a nossa equipa está a trabalhar

Como uma frota de referência reutilizável tornou a configuração do Triton mensurável em centenas de modelos de produção e de simulação, com o aumento médio do QPS a passar de 1,75x com 4 vCPU para 6,78x com 32 vCPU.

Parte 1 de uma série composta por várias partes. Esta parte aborda os modelos Triton baseados na CPU. Num próximo artigo, iremos abordar a forma como estamos a alargar o sistema à inferência por GPU.

Num modelo de produção, o mesmo artefacto em execução no mesmo pod de 32 vCPU apresentou 68 QPS ou 863 QPS, dependendo apenas da sua configuração de serviço. Após o ajuste, a latência p99 baixou de 126 ms para 14 ms e a utilização da CPU baixou de 67% para 16%.

1,75-6,78xaumento médio do QPS resultante do dimensionamento de instâncias, por nível de CPUCentenasmodelos de produção e de sombra suportados20,1% contra 0%taxa de regressão grave: um caso contra um por vCPU252espaços reutilizáveis para pods de benchmark

Quando uma maior potência do processador tornou os modelos mais lentos

Na DoorDash, os modelos PyTorch são executados no NVIDIA Triton Inference Server em diversos cenários de utilização, tais como pesquisa, classificação, despacho, deteção de fraudes e publicidade. Cada modelo dispõe de várias opções de implementação: arquitetura da CPU, tamanho do pod, número de instâncias do Triton, número de threads OpenMP e concorrência de pedidos. Uma configuração padrão adequada para um modelo pode resultar em desperdício de capacidade ou na violação dos objetivos de latência para outro. 

A análise atualizada incluiu 264 modelos com dados de varredura utilizáveis. Entre os modelos com resultados comparáveis em instância única, 44 dos 219 registaram uma redução para metade ou menos do seu débito de 4 vCPU no nível de varredura mais elevado. Entre os 206 modelos com resultados comparáveis em «uma instância por vCPU», nenhum registou essa redução. 

O erro foi considerar o tamanho do pod como o principal fator determinante do desempenho. Na prática, o tamanho do pod interage com o número de instâncias do modelo Triton e com o número de threads utilizadas por cada instância. Um maior número de núcleos pode gerar mais contenção quando essas configurações não estão coordenadas. 

Qual é a configuração completa de servidores que proporciona o débito e a latência necessários com o menor custo em termos de recursos?

Responder a essa pergunta para um modelo é um ponto de referência. Responder de forma consistente para centenas de modelos requer um sistema. 

Um sistema de afinação reutilizável

Criámos uma plataforma de ajuste automático que compara os artefactos dos modelos de produção e os dados de entrada representativos com uma matriz de configurações controlada e, em seguida, seleciona a configuração de menor custo que cumpre os requisitos de latência e capacidade do modelo. 

  1. Orquestração
    Um AutoTuneFlow determina o artefacto do modelo, as entradas representativas, o tráfego de produção, o objetivo de latência e a matriz de configurações candidatas. 

  2. de medição Um conjunto partilhado de benchmarks submete os candidatos ao mesmo ambiente de execução do Triton utilizado em produção e regista o débito, a latência e a utilização da CPU no cgroup. 
  3. Seleção
    O fluxo rejeita os candidatos que não cumprem os limites de latência ou de CPU, combina as medições de capacidade restantes com o QPS de produção e emite substituições de implementação. 

As equipas de modelos não precisam de compreender o funcionamento do conjunto de referências, e a camada de medição não precisa de conhecer o contexto empresarial subjacente à meta de latência de um modelo. A camada de orquestração integra essas questões numa recomendação pronta para produção. 

O plano de dados de referência contém 252 slots de pod pré-provisionados distribuídos por 21 grupos de implementação nas arquiteturas amd64 e arm64.

Um conjunto fixo em vez de uma infraestrutura específica para cada modelo

Cada grupo de implementação contém 12 slots dedicados que abrangem quatro níveis de CPU (4, 8, 16 e 32 vCPU) e três números de instâncias Triton para cada nível. Uma execução adquire um grupo disponível e executa as combinações de nível e número de instâncias em paralelo. Diferentes modelos podem utilizar diferentes grupos de implementação ao mesmo tempo. 

Um bloqueio suportado pelo S3 coordena o acesso. Se um grupo estiver ocupado ou com problemas, o orquestrador passa para outro grupo disponível. Isto proporciona-nos dois tipos de paralelismo: os candidatos são executados em simultâneo dentro de uma varredura e vários modelos podem ser ajustados em simultâneo em toda a frota partilhada. 

O conjunto fixo de 252 slots permite o ajuste em centenas de modelos de produção e de simulação. O aumento do número de modelos aumenta a utilização da plataforma, e não a infraestrutura necessária para cada execução individual. 

Teste de desempenho com o perf_analyzer da NVIDIA

Cada pod de benchmark invoca o perf_analyzer da NVIDIA através de um pequeno modelo de benchmark que é executado em paralelo com o modelo alvo. O perf_analyzer envia pedidos gRPC assíncronos através do localhost em cada nível de simultaneidade solicitado, enquanto o executor regista o débito e a latência e lê os contadores de CPU do cgroup do pod. Isto produz uma medição consistente de QPS, latência p99 e o mesmo sinal de CPU que o HPA do Kubernetes deteta. 

O «in-pod runner» combina a geração de tráfego, as medições do modelo e a utilização da CPU do cgroup num único resultado para cada configuração candidata.

Reconfigurar o Triton sem reiniciar os pods

Os pods de referência executam o Triton no modo explícito de controlo de modelos. Para cada candidato, o otimizador carrega o modelo alvo através da API de controlo de modelos do Triton e passa a configuração do modelo candidato (ModelConfig) como uma substituição. Em seguida, pode descarregar o modelo e reutilizar o pod para a próxima iteração. 

Esse ciclo de vida evita uma edição no S3, um atraso na consulta do repositório ou o reinício do pod para cada candidato. Uma única medição segue a mesma sequência: 

  1. Selecionar um grupo de referência.
  2. Carregue o executor do teste de desempenho e o modelo de destino.
  3. Validar os dados de entrada e aquecer o modelo.
  4. Execute o perf_analyzer em diferentes níveis de concorrência.
  5. Registe as medições de QPS, latência e CPU.
  6. Descarregue o modelo e liberte o grupo.
Cada nível e cada espaço para o número de instâncias seguem este ciclo de vida em paralelo. Os resultados regressam ao mesmo fluxo para a configuração e a seleção de custos.

O número exato de medições depende das arquiteturas da CPU, dos níveis de desempenho, do número de instâncias, do tamanho dos lotes e dos níveis de simultaneidade solicitados. Uma vez que as combinações mais exigentes em termos de nível de desempenho e número de instâncias são executadas em paralelo, o aumento da matriz de pesquisa não se traduz diretamente em tempo real. 

Por que é que a configuração alterou tanto o desempenho?

A inferência do PyTorch na CPU apresenta duas formas de paralelismo. O Triton pode executar várias cópias de um modelo em paralelo, enquanto cada cópia pode utilizar várias threads OpenMP no âmbito de uma inferência. Estes controlos são úteis individualmente, mas devem ser ajustados em conjunto. 

O padrão predefinido num pod de N núcleos consiste, frequentemente, numa instância do Triton que utiliza N threads. Para muitos dos nossos modelos, um padrão mais adequado consistia em N instâncias de thread único: 

instance_group.count = vCPU
OMP_NUM_THREADS = 1
OMP_DYNAMIC = FALSE
INTRA_OP_THREAD_COUNT = 1

Isto transforma um único trabalhador de inferência com muitos threads em vários trabalhadores independentes. Além disso, evita o pior cenário possível, em que várias instâncias do Triton criam, cada uma, um conjunto de threads de tamanho total e competem pelos mesmos núcleos. 

Por conseguinte, o otimizador trata o número de instâncias e o número de threads como uma única decisão de configuração. Em geral, mantém: 

instance_group.count × OMP_NUM_THREADS ≠ vCPU

A escolha entre mais instâncias e mais threads continua a depender do modelo, razão pela qual a avaliamos em vez de definir uma resposta única para toda a frota. 

ConfiguraçãoQPSlatência p99CPU
1 instância, 32 threads68126 ms67%
32 instâncias, com 1 thread cada86314 ms16%

Ao longo da análise atualizada, a comparação entre uma instância Triton por vCPU e uma única instância no mesmo nível produziu aumentos médios de QPS bruto de 1,75x com 4 vCPU, 2,31x com 8 vCPU, 3,65x com 16 vCPU e 6,78x com 32 vCPU. O artefacto do modelo e o nível de hardware mantiveram-se inalterados; apenas a configuração de serviço foi alterada. 

O benefício de configuração medido aumentou com o tamanho do pod. Verificaram-se regressões significativas na taxa de transferência em 44 dos 219 resultados comparáveis com uma única instância e em nenhum dos 206 resultados com uma instância por vCPU.

A documentação do PyTorch sobre threads na CPU descreve com mais pormenor a interação entre o paralelismo inter-op e o paralelismo intra-op. 

O que aprendemos em toda a frota

Deixemos que o Sweep escolha o nível da CPU

A análise atualizada dos 264 modelos revelou que a configuração de 4 vCPU foi a mais frequente, com 71,8%, seguida pela de 8 vCPU, com 14,9%, pela de 16 vCPU, com 10,2%, e pela de 32 vCPU, com 3,1%. Os níveis de configuração superiores representaram 28,2% dos modelos. 

Cada nível de CPU disponível revelou-se ideal para, pelo menos, alguns modelos.

Quatro vCPU são uma boa opção inicial, mas não constituem uma configuração padrão de produção. O otimizador avalia os níveis disponíveis e seleciona aquele que oferece a melhor capacidade ajustada ao custo, cumprindo simultaneamente a meta de latência do modelo. 

A CPU, por si só, nem sempre é indicativa de saturação

O HPA do Kubernetes estima normalmente a capacidade dimensionando o débito observado proporcionalmente à utilização da CPU: 

QPS previsto = QPS atual × (CPU alvo / CPU medida)

Isso funciona quando a CPU é o recurso limitante. Deixa de funcionar quando a taxa de processamento atinge um patamar máximo. Num teste com 8 vCPU, a utilização da CPU estabilizou nos 26%, pelo que uma meta de HPA de 40% implicava uma capacidade de 1 252 QPS. O modelo atingiu a saturação nos 829 QPS, o que representa uma sobreestimativa de 1,5 vezes. 

O Triton disponibiliza sinais de fila, tais como o nv_inference_pending_request_count e a duração da fila, que descrevem a saturação de forma mais direta. Estamos a avançar para um sinal de autoescalonamento que combine a utilização da CPU com a pressão na fila. 

Dos resultados dos testes de desempenho à configuração de produção

O otimizador faz mais do que apenas classificar as linhas dos resultados dos testes de desempenho. Combina a capacidade medida por pod com o intervalo de QPS de produção do modelo, calcula os requisitos de réplicas e o custo previsto, valida a alteração proposta e gera as substituições de implementação utilizadas pelo fluxo de trabalho de entrega. 

  • Arquitetura da CPU e nível de vCPU
  • Alocação de memória
  • Número de instâncias do Triton
  • Definições de threads do OpenMP
  • QPS previsto e latência p99
  • Número mínimo e máximo de réplicas
  • Imagem de apresentação
  • Custo previsto

Isto colmata a lacuna entre um teste de desempenho e uma configuração de produção operacional. Além disso, torna a recomendação reproduzível: as medições, a configuração selecionada e os dados relativos aos custos são armazenados em conjunto, em vez de ficarem apenas no caderno de notas de um engenheiro. 

Apoio às migrações de plataformas e à formação contínua

O tuner suporta agora dois fluxos de trabalho recorrentes da plataforma. Durante as migrações de plataforma, atribui a cada modelo uma configuração adaptada ao ambiente de produção de destino, em vez de transferir pressupostos da plataforma anterior. Essa mesma integração permite que os fluxos de trabalho de treino contínuo reavaliem novos artefactos do modelo à medida que estes são produzidos, para que as definições de produção possam evoluir em conjunto com o modelo. 

Ambos os fluxos de trabalho utilizam o conjunto partilhado de testes de desempenho e a mesma lógica de seleção. Isto proporciona à migração e ao retreinamento um percurso consistente de validação do desempenho, sem que as equipas responsáveis pelos modelos tenham de criar infraestruturas de testes de desempenho separadas. 

A lição mais ampla

A configuração do serviço faz parte do desempenho do modelo. O retreinamento e a otimização do código são importantes, mas nenhum deles é necessário para recuperar a capacidade perdida devido às predefinições de tempo de execução. 

À escala da frota, a capacidade importante não é uma regra isolada, como «utilizar pods de 4 vCPU» ou «definir o OpenMP para um». Trata-se de um sistema repetível, capaz de testar essas premissas em todos os modelos, em condições consistentes, e de transformar o resultado numa configuração pronta a ser implementada. 

No que diz respeito à nossa frota, esse sistema identificou aumentos médios de QPS que variaram entre 1,75x e 6,78x nos diferentes níveis de CPU, demonstrou por que razão o nível de CPU deve ser avaliado por modelo e substituiu o dimensionamento manual por um processo de otimização comum, aplicável a centenas de modelos. O conjunto de testes de desempenho manteve-se inalterado, apesar do aumento do número de modelos que o utilizavam. 

O que se segue

Este primeiro artigo centrou-se nos modelos Triton baseados em CPU. Na próxima parte, iremos abordar a forma como estamos a alargar o mesmo fluxo de trabalho de ajuste automático aos modelos baseados em GPU, incluindo o espaço de configuração da GPU, os sinais de capacidade específicos do acelerador e as alterações necessárias na camada de medição. As camadas de orquestração e seleção continuam a ser reutilizáveis, proporcionando aos modelos baseados em GPU o mesmo percurso repetível, desde o artefacto do modelo até à configuração de produção validada. 

Agradecimentos

  • Plataforma de Serviço de ML Arvind Kalyan, Kyoungah Kim, Haifeng Geng, Emmanuel Khayat, Jeffery Ni, Songze Li, Teer Ying, Feijin Deng, Zhe Liu, Zhengyang Wang
  • Equipa de ML de Publicidade: Utsaw Kumar, Kin Sum Liu, Benjamin Yang, Praveen Gondhi

Mantenha-se informado com as actualizações semanais

Subscreva o nosso blogue de Engenharia para receber actualizações regulares sobre todos os projectos mais interessantes em que a nossa equipa está a trabalhar

A equipa de Dados da DoorDash é responsável por gerar análises precisas dos dados e respostas a questões-chave do negócio: 

  • Por que razão o volume de encomendas diminuiu na Califórnia na semana passada? 
  • Como tem sido o desempenho de um novo produto desde o seu lançamento? 
  • Quais são os comerciantes que correm o risco de abandonar os nossos produtos de marketing?
  • Mostra-me as encomendas canceladas por hora nos últimos 90 dias no Arby’s

Os modelos de agentes de fronteira, combinados com plataformas de agentes como o Codex e o Claude Code (CC), são ferramentas poderosas para interagir com os nossos dados e responder a essas questões. No entanto, apresentam frequentemente um desempenho abaixo do ideal quando confrontados com o vasto volume de dados semiestruturados, comum em empresas de grande escala. É um desafio garantir que todas as funções empresariais — incluindo operações, engenharia, marketing e produto — tenham acesso a dados atualizados e corretos, a partir dos quais possam tirar as conclusões certas.

«O problema é, na verdade, que as nossas fontes de dados a montante estão extremamente fragmentadas», observou um gestor sénior de análise ao analisar as nossas ferramentas anteriores. Essas ferramentas ou eram muito específicas num determinado domínio ou eram abrangentes, mas superficiais. 

Como resultado, criámos a Vera, um agente interno de dados conversacional. Constatámos que a criação e o aperfeiçoamento de todas as partes do fluxo de trabalho — formulação de perguntas, classificação e recuperação, bem como competências específicas do domínio — conduziram a melhorias significativas de desempenho em relação aos agentes padrão com conectores de dados simples. «Tem funcionado bem para questões financeiras estratégicas em todos os níveis de dificuldade. Fiquei muito impressionado», afirmou um diretor financeiro após várias semanas a testar a Vera.

Por que razão desenvolvemos internamente

Os agentes contemporâneos conseguem, geralmente, responder a perguntas relacionadas com dados num ambiente limpo. No entanto, uma camada de dados semânticos sólida é fundamental para garantir que esses agentes obtenham respostas fiáveis nas quais a empresa possa confiar. Eliminar ambiguidades e resolver conflitos de significado semântico em toda a organização não é tarefa fácil; trata-se de um desafio premente para expandir essa camada de dados, mantendo simultaneamente a precisão. 

A chave para expandir a Vera, na nossa opinião, é permitir que os responsáveis pela área — as pessoas mais próximas dos dados — contribuam e validem as avaliações. Um responsável pela área é o especialista na matéria responsável pela forma como uma área de negócio é avaliada. Construir esse ciclo fechado é mais fácil quando temos um controlo firme sobre a pilha tecnológica. 

Neste artigo, analisamos detalhadamente o desenho geral e as medições de desempenho do Vera, discutindo as escolhas arquitetónicas e apresentando estudos comparativos entre diferentes tipos de modelos e abordagens de raciocínio.

Tabela 1: Uma execução completa do benchmark, com todos os modelos no mesmo conjunto de testes. Os modelos de vanguarda apresentam pontuações muito próximas uns dos outros, pelo que a latência, o número de passos e os tokens são os aspetos que os distinguem.

O nosso conjunto de dados de avaliação abrange 19 áreas verticais nas esferas de vendas, finanças, produto e operações da DoorDash, com mais de 1 900 avaliações contribuídas. Estas variam em termos de complexidade, sendo que algumas perguntas exigem várias chamadas à ferramenta e um raciocínio mais aprofundado. 

O modelo de produção atual – o GPT 5.5 – obteve a pontuação global mais elevada no teste de desempenho. Isto não é surpreendente, uma vez que otimizámos os prompts e as competências especificamente para este modelo, algo que pretendemos replicar em breve em todas as famílias de modelos.  

As respostas finais são avaliadas por um juiz LLM com base em três critérios: utilização da ferramenta, seleção da tabela e exatidão geral da resposta. Nos casos em que as avaliações não incluem uma consulta SQL inequívoca, os especialistas na área fornecem critérios de avaliação detalhados. A pontuação máxima neste modelo é de 3,0; como mostra a Tabela 1, os modelos de ponta da Anthropic e da OpenAI ficam a poucos pontos um do outro.

Também apresentamos os resultados das chamadas às ferramentas e as taxas de conclusão. Como os modelos geram o seu próprio código SQL, uma execução completa lança muitas consultas pesadas em simultâneo. Algumas atingem os limites de tempo da base de dados, o que conta como falhas na taxa de sucesso, e não como respostas erradas.  

A variação entre execuções do índice de referência é de cerca de quatro pontos percentuais na taxa de sucesso, independentemente do modelo; diferenças inferiores a esse valor são consideradas ruído. Um dos colaboradores mantém as próprias avaliações atualizadas. Uma avaliação que especifique um intervalo de tempo relativo — por exemplo, «Qual foi o volume de pedidos desta loja na semana passada?» — fica rapidamente desatualizada.

Embora os modelos de ponta apresentem um bom desempenho com o nosso conjunto de testes neste benchmark, existem diferentes considerações de compromisso em termos de latência, utilização de ferramentas e custo, dependendo do modelo e do fornecedor. Optamos pelo modelo de produção da Vera com base nesse compromisso, em vez de nos basearmos apenas na pontuação principal, voltando a executar o benchmark à medida que novos modelos são lançados. Estas ablações são executadas num subconjunto de 100 perguntas, pelo que diferenças de alguns pontos se enquadram na nossa definição de ruído. Em todos os tipos de modelos, um maior esforço de raciocínio melhora a pontuação.

Figura 1: Precisão em função do número de tokens por pergunta no subconjunto de 100 perguntas. Todas as linhas aumentam com o esforço e convergem para o topo, pelo que o esforço é importante a par da escolha do modelo e tem um custo em tokens.

A diferença de desempenho no limite é pequena, com os modelos da OpenAI e da Anthropic a atingirem pontuações semelhantes com um esforço redobrado. Naturalmente, aumentar o orçamento de raciocínio leva a um aumento da latência.

Figura 2: Tempo de resposta mediano e p90 para os mesmos modelos e níveis de esforço. Um maior esforço traduz-se em maior precisão, mas a custa de mais tempo real.

Embora um maior esforço de raciocínio aumente de forma monótona a pontuação no teste de desempenho, o efeito pode ser prejudicial para o sistema no seu conjunto, traduzindo-se em respostas mais demoradas ao utilizador e em chamadas mais frequentes da ferramenta ao repositório de dados, o que aumenta a probabilidade de tempos de espera excedidos e de resultados parciais. Observámos as seguintes distribuições de tempos entre os modelos, conforme ilustrado na Figura 3:

Figura 3: Distribuição dos tempos de resposta por modelo na execução completa. É a cauda, e não a mediana, que determina os tempos de espera e os resultados parciais.

No nosso ambiente de teste, a latência de cauda dos modelos da Anthropic foi superior à dos seus equivalentes da OpenAI. Hospedámos uma instância interna do GLM 5.3 Flash através dos endpoints do Modal, a título de comparação aproximada, embora a sua natureza não otimizada tenha resultado em tempos de espera significativos sob carga elevada. 

O Claude Fable 5 necessitou de menos etapas de ferramenta do que os modelos GPT, mas demorou mais tempo por etapa e praticamente duplicou o tempo de execução. Isto torna-se evidente quando se comparam as trajetórias das ferramentas dos vários modelos, conforme ilustrado na Figura 4:

Figura 4: Média de chamadas à ferramenta e de etapas do agente por pergunta. Um número menor de etapas não significa uma resposta mais rápida, uma vez que os modelos que requerem menos etapas demoram mais tempo em cada uma delas, como mostra a Figura 3.
Embora, historicamente, tenhamos observado melhorias graduais nas pontuações de referência para novas variantes de modelos, o impacto dos lançamentos tem vindo a estabilizar-se progressivamente, como se pode ver na Figura 5:
Figura 5: Taxa de aprovação por modelo, de março a setembro, com as alterações que a influenciaram.

Isto constitui um forte indicador de que a inteligência do modelo em si já não é o principal fator que contribui para as melhorias da Vera e de que o conjunto de ferramentas do modelo — que inclui a integração do contexto empresarial, a recuperação de conhecimento, a modelação de dados, a validação de SQL e a execução — é o vetor dominante para as melhorias futuras. 

Para validar esta hipótese, testámos tanto o Claude Code como o Vera com um modelo comum, o Opus 4.8. Dotámos o CC das nossas ferramentas de acesso SQL e das mesmas competências que o Vera utiliza.

Submetemos 100 amostras representativas a cada sistema. O Vera obteve uma pontuação de 2,60/3,0, o que corresponde a uma taxa de aprovação de 73%, enquanto o CC obteve uma pontuação de 2,16/3,0, o que corresponde a uma taxa de aprovação de 48%. Esta diferença situou-se bem fora da dispersão de ruído estimada. Constatámos que o CC teve dificuldades em consultar tabelas modeladas de forma eficaz para tirar conclusões corretas, o que realçou a necessidade de uma camada de dados eficaz, incluindo um catálogo de tabelas modeladas, heurísticas de padrões de junção e similares. A seguir: Como construímos e consultamos essa camada. 

Recuperação e classificação

Mais de 10 000 pessoas na DoorDash contam com um ecossistema de dados que cresceu até incluir mais de 200 000 conjuntos de dados, 350 petabytes de dados e 10 fontes de conhecimento institucional, desde repositórios de código até wikis. Com tantos dados disponíveis, o desafio pode residir em saber o que utilizar e quando. A etapa de recuperação e classificação fornece essas fontes de dados atualizadas, precisas e sem conflitos. 

Figura 6: O percurso da Vera, desde uma pergunta até uma resposta fundamentada. A recuperação realiza duas pesquisas em paralelo: uma no conhecimento criado por humanos e outra nas tabelas modeladas, e todo o processo subsequente é condicionado por esse modelo.

Por uma questão de simplicidade, é utilizado um único modelo de incorporação em todas as bases de conhecimento. As tabelas de dados principais são indexadas offline com regularidade, o que nos permite filtrar consultas de baixo impacto e eliminar conteúdo repetitivo. Aprendemos padrões de junção e outros aspetos semânticos a partir dos padrões de utilização restantes, dos metadados das tabelas, das referências de código e das páginas wiki, para construir um modelo de dados abrangente. 

O modelo de dados impõe restrições ao comportamento em tempo de execução; o acesso a fontes não modeladas ou não verificadas é bloqueado ao nível do harness. Uma desvantagem é o atraso entre o momento em que os dados ficam disponíveis e o momento em que a Vera os pode consultar. As novas tabelas são detetadas e indexadas tanto de forma automática no momento da inferência como periodicamente em segundo plano. A compensação em termos de precisão compensa, uma vez que a grande maioria das tabelas essenciais ao negócio tem uma longa duração e já se encontram indexadas. 

Também precisamos de considerar como gerir a adição de novas informações. Como decidimos quando novos padrões de junção ou incorporações de documentos são úteis para as consultas dos utilizadores? Por predefinição, estas fontes são marcadas como inativas e têm de ultrapassar um limiar de avaliação antes de um proprietário de domínio as promover. Os proprietários de domínio também podem ativar a promoção totalmente automatizada para a sua área. 

Além disso, cada fonte de conhecimento e cada competência codifica a sua proveniência até ao material de origem; um processo de deteção de alterações verifica regularmente se existem diferenças em relação ao material de origem. As alterações significativas resultam numa proposta de alteração que passa por uma fila de aprovação e está sujeita aos mesmos critérios de aprovação que as avaliações.

Avaliações e classificação

Foram enviadas mais de 1 900 avaliações, tanto por proprietários de domínios como por utilizadores comuns; cada proprietário de domínio analisa cada contribuição do utilizador antes de esta ser considerada válida. Cada avaliação é classificada por um juiz do LLM com base em três perguntas: 

  1. O agente utilizou as ferramentas adequadas?
  2. A abordagem utilizou as tabelas corretas?
  3. A resposta final estava correta?

Apresentamos a média ponderada destas respostas como pontuação global. O modelo de avaliação foi calibrado de forma iterativa em várias etapas. O desvio mais notável foi uma tendência para penalizar excessivamente as respostas corretas quando as tabelas eram equivalentes, mas não exatamente iguais. As recalibrações garantiram que o modelo fosse robusto face a imprecisões numéricas, aceitasse fontes de dados equivalentes e ignorasse pequenas diferenças de formatação. 

A questão operacional fundamental: Como podemos obter avaliações em toda a empresa que sejam significativas, não redundantes e representativas do trabalho analítico real, sem sobrecarregar os responsáveis pelas áreas? 

Incorporámos ferramentas no Vera que complementam as avaliações manuais, analisando os resultados do trabalho quotidiano, tais como conversas no Slack e tickets do Jira. Um modelo de vanguarda analisa cada produto de trabalho e elabora uma proposta de avaliação completa, incluindo a pergunta, uma consulta SQL ou uma rubrica e uma classificação de complexidade. 

Os proprietários dos domínios analisam, em seguida, cada proposta e decidem se a incluem ou a excluem do conjunto de avaliações. Constatámos que esta é uma forma mais eficaz de aproveitar o tempo dos especialistas do que pedir-lhes que redijam avaliações a partir do zero. Isto resultou num número significativamente maior de avaliações, proporcionando uma cobertura mais abrangente, como se pode ver na Figura 7: 

Figura 7: Crescimento do conjunto de avaliação, com as três adições que o moldaram. Os dois picos correspondem a importações em massa revistas pelos proprietários dos domínios, e a subida constante após julho deve-se ao processo de mineração e promoção.

Garantir a qualidade a esta escala torna-se mais desafiante. Eliminamos automaticamente as perguntas quase idênticas através de um indicador de similaridade; os responsáveis pela área aceitam 95% das perguntas restantes durante a revisão. 

Lidar com a complexidade

Embora o foco da Vera seja responder a perguntas de caráter coloquial, o conhecimento geral e os comportamentos adquiridos após o treino dos modelos subjacentes permitem-lhe abordar perguntas significativamente mais complexas. Utilizamos uma taxonomia aproximada da dificuldade dos problemas:

  • Nível 1: Perguntas descritivas com definições conhecidas e padrões pré-definidos, incluindo extração de métricas, tendências, segmentações e verificações de validade
  • Nível 2: Análises que podem influenciar decisões empresariais ou relativas a produtos, incluindo a definição de prioridades, a identificação de públicos-alvo, a avaliação do potencial de oportunidades e a afetação de recursos
  • Nível 3: Questões que exigem uma interpretação mais aprofundada e responsabilização, incluindo análises causais, resultados de experiências, previsões comprometidas e apoio à tomada de decisões de alto risco

Uma vez que a sobreposição entre os níveis é elevada, pode ser difícil classificar as consultas em categorias distintas, mas isso é revelador quando se analisa o esforço despendido pelo modelo nas consultas mais complexas, tal como se pode ver na Figura 8: 

Figura 8: Tempo de resposta em função dos dados obtidos em cada execução pelas ferramentas. As perguntas de nível 2 e 3 concentram-se em cargas úteis maiores e execuções mais longas, pelo que as perguntas mais difíceis exigem mais dados e tempo, e não apenas raciocínio.

No que diz respeito às consultas mais complexas do Nível 3, constatámos que os modelos tendiam a parar prematuramente e de forma otimista. Havia informação relevante para responder à consulta, mas o modelo, muitas vezes, apresentava respostas superficiais — embora plausíveis — sem aprofundar a análise. 

Para estas questões, criámos um fluxo de análise, que levou o modelo a proceder à identificação do problema e ao planeamento antes da execução, conforme ilustrado na Figura 9: 

Figura 9: Fluxo de análise da Vera relativamente a uma questão sobre tendências de comerciantes. O plano é apresentado antes da execução de qualquer consulta e nada é executado até que o utilizador o aprove ou o ajuste.

É aqui que o agente define os prazos, as métricas pretendidas, o âmbito relevante e quaisquer restrições que o utilizador pretenda impor. Constatámos que uma etapa de planeamento estruturada melhora o desempenho destas avaliações de Nível 3, mas com uma grande variação — entre 64 % e 100 % de taxa de aprovação — numa pequena amostra de 14 casos, o que demonstra a necessidade de um feedback mais abrangente e aprofundado por parte de especialistas nestas áreas. 

Daqui em diante, iremos abordar, como prioridade principal, estas questões mais complexas e subjetivas no Nível 3. 

Conclusões

Ao longo do projeto, a taxa de sucesso passou de 43 % para 90 %, enquanto a dimensão do conjunto de avaliação duplicou duas vezes. As melhorias na inteligência dos modelos subjacentes contribuíram para impulsionar o desempenho, mas foi a engenharia de dados em torno do conjunto de dados que se revelou mais determinante. 

Continuam a existir várias questões em aberto:

  1. Como podemos continuar a manter a qualidade e, ao mesmo tempo, reduzir o custo por resposta?
  2. Como podemos desenvolver avaliações em torno de questões e relatórios de análise de dados mais complexos?
  3. De que forma uma análise mais rápida e de melhor qualidade influencia os principais indicadores de desempenho da empresa?

À medida que desenvolvemos a inteligência de análise de dados na DoorDash, iremos abordar estas questões em aberto em publicações posteriores desta série.

Colaboradores: Pavel Astakhov, Andy Fang, Jash Radia, Naveen Srinivasan, Helen Lin, Lokesh Sharma, Adnan Sheikh, Gun Johnson, Harsha Venkat Annapa Reddy

Na DoorDash, contamos com várias equipas de engenharia que apoiam os nossos domínios de engenharia. Este documento apresenta uma visão geral das nossas áreas de domínio e das equipas que as apoiam:

  1. Dasher & Logística
  2. Fundamentos
  3. LaunchPad e Investigação em IA
  4. Mercado
  5. Plataforma para Comerciantes e Consumidores
  6. Novas Verticais
  7. Excelência Operacional
  8. Serviços de Plataforma
  9. DashOS
  10. Dinheiro
  11. Anúncios e promoções

Esperamos que estes perfis possam servir de referência útil para que possa responder ao nosso inquérito de correspondência de equipas. 

Uma vez que as nossas equipas estão em constante evolução, este documento constitui um retrato da nossa atual organização de Engenharia. Tenha em conta que é provável que haja alterações entre o momento atual e a sua data de início. Por isso, ao tomarmos decisões relativas à afetação às equipas, iremos centrar-nos no tipo de trabalho em que está interessado. Para além das suas preferências e experiência técnica, teremos em consideração a capacidade das equipas e outros fatores organizacionais.

Nota: Ao longo do documento, aparecem várias abreviaturas para os nossos principais pilares de clientes – Comerciante (Mx), Consumidor (Cx), Entregador (Dx) – para além de Restaurantes (Rx).


Dasher & Logística

A equipa da Dasher & Logistics (DxLx) constitui o coração da rede de entregas da DoorDash, impulsionando a execução de cada encomenda com inteligência, precisão e escala. Desde o «cérebro» logístico que define os percursos dos Dashers e equilibra a oferta e a procura, até às plataformas e produtos que criam uma experiência coesa e gratificante para os Dashers, esta equipa garante que todas as entregas sejam realizadas de forma eficiente e fiável.

A nossa visão é construir uma rede de logística da mais alta qualidade e com os custos mais baixos, tornando-a a primeira escolha para trabalhadores independentes e comerciantes em todo o mundo. A DxLx assenta em dois pilares principais:

  • Logística: Cria uma plataforma global de logística de última milha de classe mundial, que opera na vanguarda da engenharia, da ciência e das infraestruturas. A equipa ultrapassa continuamente os limites em termos de velocidade, custo, eficiência e fiabilidade, possibilitando milhões de entregas todos os dias.
  • Dasher: Dedicada a proporcionar aos Dashers liberdade de escolha, estabilidade e oportunidades. Esta equipa está a criar a melhor plataforma de trabalhos pontuais do mundo, promovendo a retenção, o crescimento e a satisfação através de modelos de emprego inovadores, recompensas e programas de envolvimento.

A DxLx está no centro da experiência DoorDash – transformando a forma como as mercadorias circulam pelas cidades e tornando a vida mais prática para milhões de pessoas em todo o mundo.


Fundamentos

A equipa de Foundations desenvolve a infraestrutura central, os dados e as plataformas para programadores que sustentam todos os produtos e serviços da DoorDash. Enquanto espinha dorsal de engenharia da empresa, esta equipa combina infraestrutura e dados para criar uma base integrada, segura e escalável, assente no nosso ecossistema de nuvem AWS. A organização assenta em três pilares fundamentais:

  • Plataforma para programadores: Permite aos engenheiros avançar rapidamente e desenvolver com confiança, através de uma experiência de programador de primeira classe, assente em plataformas modernas, fiáveis e de alto desempenho.
  • Infraestrutura Central: Fornece sistemas seguros, eficientes e resilientes que permitem aos engenheiros criar produtos de excelência com rapidez e em grande escala.
  • Dados Fundamentais: Reúne o trabalho de engenharia de dados e da plataforma de dados para garantir que a empresa funcione com base em dados fiáveis e de alta qualidade e para acelerar a inovação de produtos orientada por dados em toda a DoorDash.

Em setembro de 2025, as equipas da Foundations da DoorDash e da Wolt uniram-se para expandir o Pedregal e construir o futuro em conjunto, guiadas por princípios comuns: manter o negócio a funcionar, liderança unificada, responsabilidade geográfica, respeito pelos fusos horários e alinhamento dos talentos certos com os desafios certos.

A «Foundations» é a plataforma sobre a qual toda a empresa funciona, e ainda há muito espaço para moldar a forma como esta se expande à medida que a DoorDash cresce — promovendo a fiabilidade, o desempenho e a rapidez em tudo o que fazemos.


LAUNCHPAD E INVESTIGAÇÃO EM IA

A missão do LaunchPad é inovar, experimentar e incubar ideias ousadas. A equipa foi criada para agir com rapidez, transformando rapidamente ideias promissoras em protótipos reais, para que a DoorDash possa descobrir em que vale a pena investir mais. A par do LaunchPad, a DoorDash AI Research é uma equipa de investigação aplicada que explora como as mais recentes capacidades de IA podem mudar a forma como o negócio da DoorDash funciona.

A organização abrange duas áreas principais:

  • Projetos «0 a 1»: O LaunchPad dedica-se a ideias novas e de elevado potencial em todo o ecossistema de produtos da DoorDash, o tipo de projetos que podem vir a tornar-se um novo negócio de grande relevância ou a proporcionar uma nova capacidade significativa à plataforma. 
  • Investigação em IA: Explora a forma como as mais recentes capacidades de IA podem melhorar a DoorDash, desde aumentar a produtividade dos engenheiros, passando pela criação de agentes de IA capazes de agir em nome dos clientes, dos comerciantes e dos Dashers, até ajudar a empresa a compreender e a utilizar melhor os seus próprios dados.

Uma vez que tanto o LaunchPad como a AI Research se dedicam a testar o que está para vir antes de se tornar uma parte consolidada do negócio, integrar-se nesta organização significa trabalhar em algumas das ideias mais iniciais e exploratórias da DoorDash.

A LaunchPad é liderada por Andy Fang, cofundador da DoorDash.


Mercado

Visão geral do mercado  

A organização Marketplace facilita a troca de bens entre compradores e vendedores em vários setores — proporcionando confiança, qualidade e experiências fluidas em grande escala. A sua missão é criar componentes fundamentais e extensíveis que permitam às equipas lançar funcionalidades inovadoras com confiança e rapidez. O Marketplace está organizado em torno de três pilares centrais, cada um dos quais impulsiona a experiência do consumidor de formas únicas e impactantes:

  • Core Consumer: É responsável por todo o percurso do pedido — criando uma experiência de compra rápida, intuitiva e agradável para todos os clientes, em qualquer lugar.
  • Crescimento da base de clientes: Acelera a expansão da DoorDash através de análises baseadas em dados, experimentação e otimização contínua — desde o início de sessão até ao pagamento e muito mais.
  • DashPass: Supervisiona o nosso negócio de subscrições, com foco no crescimento, no envolvimento e na retenção. A equipa de Envolvimento promove a integração e a adoção precoce, ajudando os clientes a perceberem o valor do DashPass desde o primeiro dia, enquanto a equipa de Retenção garante que os membros se mantenham ligados e continuem a perceber o valor ao longo de toda a sua experiência.

A equipa do Marketplace constrói a base da experiência DoorDash — ligando milhões de clientes aos estabelecimentos locais de que gostam, de forma mais rápida e fiável do que nunca.


PLATAFORMA PARA COMERCIANTES E CONSUMIDORES

A equipa da Plataforma MxCx desenvolve plataformas de nível mundial que aceleram o desenvolvimento de produtos e garantem uma fiabilidade, observabilidade e segurança excecionais. A sua missão é capacitar os nossos clientes, ao mesmo tempo que impulsiona o crescimento da DoorDash em todas as experiências.

A equipa concentra-se tanto na experiência dos comerciantes (Mx) como na dos consumidores (Cx), impulsionando tudo, desde a integração de comerciantes até às aplicações de alto desempenho para clientes. As áreas-chave incluem:

Aquisição de comerciantes: Identifica e integra novos restaurantes parceiros através da utilização de dados inteligentes e de ferramentas de autoatendimento intuitivas.

  • Mx Tablet: O hardware e a aplicação que permitem a gestão de encomendas na loja para os comerciantes.
  • Business Manager: Uma aplicação móvel que permite aos empresários gerir e expandir os seus negócios a qualquer hora e em qualquer lugar.
  • Plataforma de Encomendas: A base para a gestão do ciclo de vida das encomendas da DoorDash, permitindo aos engenheiros desenvolver novas funcionalidades com rapidez e fiabilidade.
  • Plataforma MxCx Client: Permite aos engenheiros de aplicações para consumidores criar, de forma segura e eficiente, aplicações de alto desempenho e fiáveis para a Web, iOS e Android – promovendo a qualidade e a consistência em grande escala.

A equipa da Plataforma MxCx está a construir a espinha dorsal do ecossistema DoorDash – criando as ferramentas, os sistemas e as plataformas para clientes que impulsionam o crescimento de milhões de utilizadores e empresas todos os dias.


NOVOS SETORES

A equipa da New Verticals (NV) está a expandir a DoorDash para além dos restaurantes – a construir uma plataforma para o comércio local e a permitir que os clientes tenham acesso a tudo o que a sua cidade tem para oferecer. Desde produtos alimentares e artigos de conveniência até produtos para animais de estimação, bebidas alcoólicas, artigos para o lar e produtos de beleza, a NV está a redefinir a forma como as pessoas fazem compras a nível local.

A nossa missão é tornar a DoorDash o parceiro de eleição para os bens essenciais do dia a dia, ajudando famílias e particulares a obter o que precisam, quando precisam. A equipa enfrenta desafios complexos próprios da logística de retalho, ampliando sistemas para gerir inventários enormes e dinâmicos, melhorando a precisão dos dados e otimizando a experiência dos Dasher para diversos modelos de entrega, como compras de mercearia e entregas de artigos individuais.

No âmbito da NV, existem cinco pilares principais (NV Categories, NV Consumer, NV Fulfillment, NV Merchant + Selection e NV Machine Learning), com várias sub-equipas a impulsionar a inovação. Além disso, a equipa da DashMart é responsável pela própria mercearia virtual e loja de conveniência da Dash, que é integralmente detida, operada e gerida com o objetivo de proporcionar a próxima geração de compras «tudo a pedido».

Os engenheiros da equipa da NV nunca se cansarão de procurar novos desafios e têm oportunidades incríveis para deixar a sua marca no comércio local!


EXCELÊNCIA OPERACIONAL 

A missão da equipa de Excelência Operacional (OpEx) é criar confiança e promover a eficiência através da inovação e da automatização. Se os consumidores, os comerciantes ou os entregadores não puderem confiar que o mercado é justo e fiável, o nosso negócio não tem futuro. A OpEx é composta por quatro áreas principais:

  • Experiência de entrega: Garante um acompanhamento e um apoio eficientes e transparentes após a realização de uma encomenda.
  • Fraude: Mantém a equidade do mercado, prevenindo e detetando atividades fraudulentas.
  • Confiança e Segurança: Promove a confiança entre os Dashers, os comerciantes e os consumidores, através da verificação da identidade e do cumprimento das normas.
  • Plataforma de Risco e Identidade: Amplia estes esforços de forma eficiente através de plataformas dedicadas ao risco, aos dados, às contas e a soluções de ML/IA.

Como engenheiro da equipa de Engenharia de OpEx, irá impulsionar os sistemas que mantêm a nossa plataforma eficiente, justa e segura em grande escala. Seja a combater a fraude em tempo real, a garantir pagamentos sem interrupções, a melhorar as experiências de entrega ou a reforçar a confiança e a segurança, o seu trabalho terá impacto em milhões de pessoas. Irá desenvolver código significativo, colaborar de forma interfuncional e crescer rapidamente num ambiente dinâmico e de grande autonomia.


SERVIÇOS DA PLATAFORMA

A equipa de Serviços de Plataforma está a desenvolver o sistema operativo para todos os restaurantes, mercearias e retalhistas – capacitando as empresas locais a prosperar na economia da conveniência. A sua missão é criar o software e o hardware que ajudam os comerciantes a impulsionar e a expandir os seus próprios negócios diretos. Os engenheiros da equipa trabalham em cinco áreas de grande impacto:

Encomendas digitais: Uma solução de marca branca que tira partido da tecnologia e da escala da DoorDash para ajudar os comerciantes a aumentar as suas vendas diretas online.

  • Fidelização omnicanal: Um programa de fidelização com a marca do comerciante que permite aos clientes ganhar e resgatar recompensas de forma integrada – online, na loja e no DoorDash.
  • Encomendas por voz: Um serviço de voz de alta qualidade que permite aos funcionários da loja concentrarem-se nos clientes, enquanto nós tratamos das chamadas.
  • Drive: um serviço de logística como serviço que permite aos comerciantes recorrer à frota Dasher para entregar encomendas feitas diretamente junto deles.
  • DoorDash for Business (DDfB): Soluções empresariais que permitem às empresas oferecer aos seus colaboradores benefícios alimentares, como o DashPass for Work, refeições a cargo da empresa, encomendas em grupo e cartões-presente corporativos.
  • A equipa de Serviços da Plataforma está a construir as bases para a próxima geração do comércio local – ajudando todos os comerciantes a estabelecer contacto com os clientes a qualquer hora e em qualquer lugar.

DashOS

A DashOS é uma equipa de engenharia criada para ligar os comerciantes aos seus consumidores de ponta a ponta. A equipa reúne numa única equipa as funcionalidades que, anteriormente, estavam dispersas por produtos e regiões distintos.

O DashOS abrange três áreas principais:

  • Operações na loja: Os sistemas que os comerciantes utilizam para gerir as suas atividades no dia-a-dia — pontos de venda, quiosques e sistemas de visualização na cozinha.
  • Loja virtual para comerciantes e programas de fidelização: As ferramentas que permitem aos comerciantes criar a sua própria loja virtual com a marca da empresa e gerir os seus próprios programas de fidelização e recompensas.
  • Refeições fora de casa e reservas: A vertente do negócio voltada para o consumidor — ajudar as pessoas a descobrir, reservar e desfrutar de experiências gastronómicas e de hospitalidade.

Uma vez que o DashOS reúne equipas que antes trabalhavam separadamente, integrar-se nesta organização significa ajudar a construir plataformas partilhadas à escala global — sem deixar de moldar a experiência do produto que os comerciantes e os clientes vivem em cada mercado local.


Dinheiro

A missão da equipa Money é oferecer produtos de pagamentos e serviços financeiros inovadores e que proporcionem uma experiência agradável para os clientes (Cx), os utilizadores (Dx) e os parceiros (Mx), e ser um catalisador para o crescimento do negócio, tanto em termos de receitas como de resultados financeiros.

Atuando tanto como plataforma como equipa de produto, a sua principal responsabilidade é gerir todas as transações financeiras na nossa plataforma. Isto inclui tudo, desde a cobrança aos clientes até ao pagamento a Mx e Dx, garantindo sempre que cada dólar seja contabilizado com precisão.

A organização assenta em três pilares:

  • Pagamentos: a infraestrutura central subjacente a todas as transações na DoorDash — a forma como os clientes pagam, como os Dashers e os comerciantes recebem os seus pagamentos e como são faturadas as subscrições, como o DashPass.
  • Produtos financeiros: Produtos financeiros que servem diretamente os Dashers, os consumidores e os comerciantes — como cartões-presente, o cartão Crimson e outros benefícios para os Dashers, bem como financiamento para comerciantes.
  • Conformidade Financeira: Assegura que cada dólar que passa pela DoorDash seja devidamente monitorizado, reconciliado e esteja em conformidade com a regulamentação financeira em todo o mundo.

A equipa Money processa milhares de milhões de dólares anualmente, e as suas inovações em matéria de pagamentos, como os cartões-presente, contribuíram com milhões de dólares para o aumento do Valor Bruto das Encomendas anual, o que destaca o impacto significativo dos sistemas e produtos financeiros da equipa Money nos negócios da DoorDash!


Anúncios e promoções

A equipa de Publicidade e Promoções ajuda restaurantes, comerciantes e marcas a chegar aos clientes e a expandir os seus negócios na DoorDash. A organização está estruturada em duas vertentes: publicidade e promoções.

  • Anúncios: Ao combinar dados poderosos com um posicionamento inteligente, a equipa de Anúncios liga os anunciantes aos públicos-alvo certos – impulsionando a visibilidade, a conversão e o crescimento. Assenta em três pilares: Oferta (a experiência do cliente), Procura (a experiência do anunciante) e Entrega (o motor alimentado por aprendizagem automática que liga os dois em tempo real). A equipa gere duas linhas de negócio – os Anúncios para Restaurantes, que ajudam os restaurantes a destacarem-se perante clientes com fome, e os Anúncios para Produtos de Grande Consumo, que dão destaque a marcas do quotidiano –, apoiadas pelas equipas da Ads Foundation e da Ads Data nos bastidores.
  • Promoções: Permite a implementação dos descontos e ofertas que os clientes vêem em toda a aplicação — desde a página inicial até ao checkout —, ajudando os comerciantes a gerar mais encomendas e permitindo que os clientes poupem dinheiro.

Olhando para o futuro, a equipa está a trabalhar para integrar mais estreitamente os Anúncios e as Promoções numa única experiência, mais automatizada, para os comerciantes. Ambos os negócios estão a crescer rapidamente e estamos apenas a começar — junte-se a nós na construção do próximo motor de crescimento da DoorDash.


Este artigo aborda os limites do cliente e da plataforma subjacentes à experiência do utilizador e às interações com o Ask DoorDash: como passámos dos carrosséis de hackathons para esse modelo, como um único artefacto serve três leitores e como o contexto e o estado se mantêm consistentes à medida que os consumidores navegam pelo DoorDash. Segue-se «Construir o DoorDash Assistant: Uma Visão Geral da Engenharia» e às nossas análises aprofundadas A criação do Ask DoorDash (Parte 2): Inteligência, A criação do Ask DoorDash (Parte 3): Avaliação, e A criação do Ask DoorDash (Parte 4): Uma plataforma para a criação e evolução de agentes.


O Ask DoorDash transforma pedidos como «prepara-me um jantar de 60 dólares para 10 pessoas», «ajuda-me a fazer tacos de frango» e «petiscos para a semana» em listas de compras editáveis. Gera uma lista com produtos disponíveis para compra, preços, fotografias, controlo de quantidades e botões simples para substituir qualquer artigo e concluir a compra. No caso de pedidos de restaurantes, são apresentados estabelecimentos e pratos que se integram no fluxo de compras nativo. Ambas as funcionalidades funcionam no mesmo cliente e na mesma infraestrutura da plataforma. Este artigo centra-se no caso de utilização de compras de supermercado, uma vez que este é o que coloca maior pressão sobre todas as principais complexidades da criação de uma interface intuitiva para compras orientadas por um agente. As listas de compras de supermercado contêm normalmente dez ou vinte itens, passam por várias rondas de revisão e têm de lidar facilmente com restrições do consumidor, como orçamentos e restrições alimentares.

As sessões de utilizadores de julho de 2026 revelaram que, nas sessões relacionadas com compras de mercearia em que era apresentada uma lista de compras, os consumidores realizaram, em média, cerca de duas interações com a interface do utilizador cada um. Cerca de um terço dessas sessões culminou na aplicação da lista a um carrinho de compras. O assistente capta a intenção geral dos consumidores e sintetiza-a. O resultado são componentes nativos, que permitem um refinamento granular por parte dos consumidores. As edições simples atualizam imediatamente um artefacto de referência, enquanto as alterações que exigem raciocínio dão início a uma nova ronda do agente.

Para criar uma experiência de compras colaborativa e eficaz entre o consumidor e o agente, os agentes de compras têm de se integrar numa interface interativa baseada em dados de comércio em tempo real e no contexto atual da aplicação do consumidor. Quando um consumidor está a fazer compras numa aplicação, espera ver, à primeira vista, artigos reais que possa adquirir. O texto pode descrever esse ambiente, mas os componentes interativos baseados em imagens permitem que os consumidores o percorram efetivamente. O contexto também é importante. Os consumidores que abrem a DoorDash têm expectativas diferentes das que têm em relação a uma aplicação de chat de uso geral. Fazem compras navegando, passando de lojas e páginas, em vez de descreverem o que querem. Ir ao encontro deles onde se encontram é uma peça essencial do quebra-cabeças.

As grandes coisas têm um início modesto

O assistente de compras da DoorDash começou por ser um projeto de hackathon. Sabíamos desde o início que a integração dos componentes existentes da DoorDash seria um elemento fundamental de tudo o que viéssemos a construir. As primeiras versões baseavam-se fortemente em carrosséis: primeiro, uma lista de lojas próximas em potencial; depois, um carrossel de resultados de pesquisa para cada artigo que o agente procurava. Eram apresentados em linha, cada um com o respetivo termo de pesquisa associado. O resultado era, essencialmente, um registo de conversa com resultados comerciais colados nele.

Em termos de funcionalidade, era semelhante ao que lançamos hoje. No que diz respeito à experiência do utilizador, era mais rudimentar, e vale a pena analisar os pormenores.

Depois de encontrar um conjunto de lojas, o assistente perguntou qual delas explorar e aguardou que a resposta fosse digitada. Cada carrossel representava um único artigo de que o consumidor precisava, e escolher uma opção adicionava esse artigo ao carrinho. Cada um aparecia com as opções dispostas em toda a largura do ecrã e a escolha ainda em aberto. Assim, organizar as compras para uma semana significava percorrer a lista, uma seleção de cada vez, sem possibilidade de selecionar um conjunto de artigos de uma só vez.

Por trás de tudo isto estava uma falha que se manifestava em ambos os sentidos: a interface tinha sido concebida principalmente para apresentar o trabalho do assistente. Cada carrossel era encabeçado pela consulta que o tinha gerado e os resultados apareciam na ordem em que tinham sido recuperados. Os termos de pesquisa e os conjuntos de resultados em bruto são o material de trabalho de um agente. Apresentar os resultados diretamente é o equivalente, na interface, a imprimir um rastreio da pilha. O assistente submetia-se com a mesma facilidade à interface, trabalhando um item de cada vez, porque uma pilha de carrosséis por item era o que o ecrã conseguia mostrar. Cada um tinha sido concebido em função das limitações do outro, em vez de ser concebido em função do utilizador.

A lição não foi que reutilizar componentes existentes fosse errado; a familiaridade que estes transmitem é precisamente a razão pela qual o assistente se assemelha ao DoorDash. Simplesmente, tínhamos criado o contentor errado para eles. É o contentor que determina a ordem em que aparecem, ao lado de que outros elementos se situam e o que um consumidor pode fazer com eles. Acima de tudo, um utilizador precisa de uma superfície de compras, em vez de uma interface de conversação. Tínhamos criado uma interface de conversação que, por acaso, continha componentes de compras. A reutilização de componentes deu-nos o vocabulário. Compô-lo numa superfície foi a parte mais difícil.

O que sobreviveu ao hackathon foi a base: a mesma infraestrutura de streaming que foi criada é aquela em que a experiência funciona atualmente. Entretanto, a camada de descodificação que transformava os resultados das ferramentas na interface do utilizador não perdurou. O assistente já não apresenta, de todo, os resultados das ferramentas. Em vez disso, investimos tempo na construção de uma arquitetura de artefactos que separa os requisitos dos utilizadores dos requisitos de armazenamento e dos agentes. Por outras palavras: deixámos de descodificar o material de trabalho do agente para o apresentar e começámos a construir em torno das necessidades dos diferentes componentes e utilizadores do sistema.

Figura 1: O mesmo pedido de compras, com um ano de diferença. A versão criada no hackathon apresentava um carrossel por artigo, cada um encabeçado pela consulta que o gerou; a seleção ficava a cargo do consumidor. Atualmente, o assistente apresenta cada lista como um cartão na conversa, com os artigos mais populares já selecionados.

Um objeto, três lentes

Uma lista de compras tem três leitores: o serviço que a armazena, o agente que a revê e a pessoa que faz as compras. Cada um precisa de ver algo diferente. Manter essas informações separadas é o que permite que a edição feita pelo consumidor apareça imediatamente e se mantenha válida sem exigir mais uma iteração do modelo.

O formulário guardado é o sistema de registo: um blob JSON armazenado como um artefacto no Managed Agent Services, conforme descrito na publicação da plataforma. Tem de estar completo e é a única cópia oficial.

O agente não lê esse blob diretamente. Uma lista de compras interativa contém muito mais detalhes do que um modelo necessita para a maioria das respostas. Repetir o nome de cada produto, preço, quantidade, substituição e cada elemento de metadados de apresentação a cada turno entraria em conflito com o que o consumidor realmente pediu. Assim, quando um agente emite um widget, o que permanece no contexto da conversa é um resumo compacto: a loja e o que a lista contém. Quando uma resposta requer o estado exato, o agente lê o artefacto e obtém uma visão reduzida, sem os metadados de exibição. Essa visão é inequívoca e suficientemente pequena para ser analisada de forma eficiente. Uma lista média ocupa entre 40 e 60 KB de JSON. O que permanece no contexto da conversa é uma única linha de cerca de 240 caracteres, aproximadamente 250 vezes menor.

O que o consumidor vê é diferente, e assume várias formas. Na conversa, a lista é apresentada como um widget compacto: a loja, o nome da lista, o tempo estimado de entrega, algumas fotos dos artigos e um botão «Adicionar ao carrinho» com o total estimado. Isso é suficiente para avaliar a lista num relance, sem sair do chat. Um botão «Ver lista» abre a visualização em página inteira, que apresenta a lista completa e tudo o que é necessário para a analisar em pormenor. Ambas as visualizações foram concebidas para serem compreendidas imediatamente e para que se possa agir diretamente a partir delas.

Um pormenor mostra até que ponto estas perspetivas divergem. Quando o agente escolhe um produto para um item da lista, mantém os outros produtos que corresponderam à mesma pesquisa, e o consumidor pode alternar entre eles com um toque. Mantém dez candidatos por item, e 99,7% dos itens têm correspondências suficientes para preencher esse número, pelo que quase todas as linhas na perspetiva do consumidor têm uma seleção e nove alternativas por trás dela. A visualização do consumidor apresenta todas essas alternativas. A visualização do agente não apresenta nenhuma delas, porque a escolha entre elas é da responsabilidade do consumidor (a menos que seja explicitamente pedido ao assistente para o fazer).

Figura 2: Uma lista, três perspetivas. O consumidor vê preços, fotografias e uma opção de troca por trás de cada linha. O agente vê apenas a loja e o que a lista contém. O artefacto contém tudo isso, incluindo nove alternativas só para as folhas de lasanha.

Manter os pés no chão

Com um carrinho que contém iogurte de framboesa, ao clicar em «Recomendar combinações para o carrinho» são apresentadas duas sugestões: granola, «porque combina com o seu iogurte», e mirtilos, «para adicionar fruta ao seu iogurte» (ver Figura 3). O caso de contraste já existe no nosso próprio produto, no mesmo ecrã: a página do carrinho apresenta um carrossel de artigos complementares que sugere artigos que o consumidor possa querer adicionar, sem qualquer justificação. O nosso agente do carrinho poderia ter apresentado exatamente isso: uma lista de itens plausíveis. Os itens poderiam muito bem ter sido os mesmos em qualquer dos casos. É a justificação que indica ao consumidor que a sugestão foi fundamentada e não apenas plausível e, uma vez que cada widget é também um local para agir, essa distinção tem um impacto real.

É isso que a integração com a realidade oferece: a diferença entre uma experiência de compras cativante e uma mera novidade. Se o resultado apresentado pelo assistente não for tangível, os consumidores têm poucos motivos para abandonar a rica experiência que a aplicação DoorDash já proporciona. O texto continua a desempenhar o seu papel, mas de forma secundária. Colocámos deliberadamente a lógica do assistente dentro dos widgets e à sua volta, em vez de mostrar as células dos itens exatamente como aparecem noutras partes da aplicação.

A integração também tem de ser assegurada ao nível dos dados, e aí o trabalho é dividido. Um agente escolhe um tipo de conteúdo suportado e fornece os dados comerciais correspondentes; o cliente iOS é responsável pela apresentação e interação, mapeando esse conteúdo para componentes nativos do sistema de design da DoorDash. Um pedido de mercearia gera uma lista de compras editável com quantidades, substituições e um subtotal. Um pedido de restaurante pode gerar fichas de loja, fichas de artigos ou sugestões para o carrinho.

É essa separação que fundamenta os próprios dados. Os valores comerciais num widget não provêm do modelo. Os preços, o inventário, o horário de funcionamento da loja e o conteúdo do carrinho são lidos a partir dos mesmos sistemas de registo que o resto da aplicação utiliza, pelo que um preço apresentado no Ask corresponde ao preço na página da loja naquele momento. O conteúdo tipado também proporciona ao backend e ao cliente um contrato estável. A implementação de um novo widget requer mais do que uma simples alteração no prompt. O agente tem de saber quando o utilizar e o que nele colocar, e o cliente precisa de um esquema nomeado, além do código para o descodificar e apresentar. Para além disso, um novo widget chega ao consumidor através do mesmo mecanismo de conversação e transmissão que qualquer outro.

Figura 3: Dois tipos de sugestões relativas ao mesmo carrinho. Apenas uma delas explica o motivo.

Widgets como canais de E/S

Cada novo widget que integramos contribuiu para tornar o assistente mais funcional. A razão para isso tem tanto a ver com a entrada de dados como com a saída de resultados. Existe um limite que rege todos eles: uma edição determinística permanece no cliente e aplica-se diretamente ao artefacto, enquanto uma alteração que exija uma avaliação dá início a um ciclo do agente. Os exemplos abaixo estão organizados em função de onde essa linha se situa.

A versão do hackathon perguntava qual a loja que o consumidor pretendia e, em seguida, aguardava que este a escrevesse. Não tinha forma de escolher por si própria; hoje em dia, essa escolha é automática. Muitas outras perguntas ainda dependem do consumidor, e a introdução direta de texto pode ser uma forma pouco eficaz de recolher as respostas. A introdução de texto é uma limitação de fluxo único: o consumidor pode saber todas as respostas, mas só as consegue fornecer à velocidade a que consegue escrever ou falar.

É aqui que os widgets ganham o seu lugar. Um consumidor pode ter dez operações para aplicar a uma lista de compras, sendo cada uma delas simples. Individualmente, são triviais; quando descritas em prosa, tornam-se uma tarefa complexa. É a diferença entre olhar por cima do ombro de alguém e dizer-lhe quais os botões que deve premir, e premir os botões por si próprio.

As perguntas esclarecedoras estruturadas são o exemplo mais claro, e o padrão é inspirado nos agentes de codificação: a ferramenta AskUserQuestion da Claude Code desempenha a mesma função para os programadores. Disponibilizamos um widget que interrompe o consumidor com um pequeno conjunto de perguntas (de escolha múltipla e seleção múltipla), permitindo-lhe orientar a conversa em momentos genuinamente abertos. Tornou-se um pilar fundamental do modelo de interação no agente de mercearia e está agora a ser adotado no agente de restaurante para simplificar o mesmo tipo de interação. Integramos esta funcionalidade com a nossa plataforma de memória do consumidor, o que reduz significativamente as opções, mas continuam a existir lacunas de conhecimento que exigem a intervenção do consumidor. Fazer perguntas é inevitável. Mas podemos fazê-lo de uma forma que seja fácil e eficiente para o consumidor responder.

A visualização da lista em página inteira é onde a colaboração de entrada/saída se concretiza. Um consumidor pode alterar a quantidade de um artigo, eliminar um artigo, trocar um artigo por uma das alternativas que o assistente encontrou ao lado dele e adicionar a lista finalizada ao seu carrinho. Cada uma dessas ações manipula o artefacto diretamente. Nenhuma delas requer que o assistente atue em nome do consumidor, e nenhuma implica uma ida e volta ao LLM. O caso da troca aproveita melhor os conjuntos de candidatos da versão desenvolvida no hackathon. As alternativas entre as quais o consumidor escolhe são os outros candidatos que o assistente recuperou quando selecionou o artigo. A lista de todas as opções disponíveis para o consumidor preenchia anteriormente um carrossel. Agora, encontram-se a um toque de distância de uma decisão, em vez de se apresentarem diante do consumidor como uma questão em aberto.

A mudança de loja é a exceção, e a exceção é a parte interessante. Não se trata de uma alteração da lista existente. Transforma-se num pedido ao assistente que reconstrói a lista na loja alternativa. Esta interação também é rara: foi a primeira ação em 0,1% das sessões ativas, o que corresponde aproximadamente ao que esperaríamos se o limite fosse definido no ponto certo. Se essa linha for traçada no local errado, o consumidor ou espera que o assistente faça algo que poderia ter feito com um simples toque, ou tem de percorrer várias etapas com toques que poderiam ter beneficiado do discernimento do assistente.

O artefacto torna a divisão segura, e os dois lados escrevem nele de forma diferente. Uma alteração na quantidade, uma remoção ou uma troca segue o caminho mais curto: o cliente atualiza a lista no local e a alteração aparece imediatamente. Uma alteração de armazenamento, por outro lado, dá início a um ciclo do agente, porque é necessário recriar a correspondência de toda a lista com um catálogo diferente. Uma revisão do agente não sobrescreve o que lá estava; produz uma nova lista derivada da anterior.

O resultado é que uma edição direta tem carácter vinculativo. Antes de uma intervenção alterar a lista, o agente consulta a versão atual em vez de se basear na transcrição; assim, se o consumidor retirar o leite de aveia, a intervenção seguinte começa com uma lista que já não inclui o leite de aveia.

O comportamento observado durante o mesmo período mostra onde se situa essa linha. Imediatamente após o primeiro pedido, quase três quartos das primeiras ações seguintes ocorreram através de um componente. A partir da segunda mensagem, a situação inverte-se, e as respostas digitadas passam a constituir a maioria em todos os níveis de profundidade que medimos. Os controlos absorvem os ajustes imediatos e estruturados; a linguagem assume o controlo quando a alteração é mais significativa ou mais difícil de expressar com um toque.

Figura 4: A lista ao atravessar o limite de uma volta. O consumidor retira as maçãs diretamente na visualização da lista, sem qualquer ida e volta pelo modelo. Quando a mudança de loja dá início a uma nova volta, o agente lê o artefacto em vez da transcrição, pelo que a lista que reconstrói na nova loja continua sem essas maçãs.

Todas as revisões do assistente permanecem ativas

Quando o assistente revê uma lista de compras, a versão que substitui permanece no ecrã e continua a poder ser utilizada.

Essa não foi a nossa primeira implementação. A primeira versão ocultava as listas substituídas: assim que uma revisão era publicada, a lista subjacente deixava de poder ser visualizada ou editada. Uma lista atual, sem confusão. Parecia um comportamento mais organizado. No entanto, o que isso fez foi tornar a revisão algo dispendioso. Se solicitar uma alteração pudesse apagar uma lista com a qual se estava satisfeito, a atitude mais segura seria deixar de solicitar alterações, o que compromete todo o sentido de um fluxo colaborativo.

Assim, cada revisão auxiliar produz agora um novo artefacto derivado do anterior, e cada um permanece no local onde foi criado na conversa. Se recuar na página, as versões anteriores continuam todas lá, ainda ativas: um consumidor pode abrir uma lista anterior, editá-la ou adicioná-la ao seu carrinho em vez da versão mais recente. Pedir uma alteração não custa nada, porque o que tinham há um momento está à distância de um simples deslocamento para trás.

Nem todas as listas criadas pelo assistente se tornam uma versão que o consumidor vê. Quando o assistente elabora uma lista de sugestões e conclui que a loja não dispõe do que foi solicitado, essa lista nunca é apresentada. O consumidor é informado, por meio de texto, de que faltavam artigos na loja e que uma nova lista está a caminho. É um dos poucos casos em que a prosa desempenha o papel de forma direta e que ilustra a razão subjacente a tudo o resto neste artigo: a interação é utilizada para simplificar e o texto é utilizado para justificar.

Quando uma lista se transforma num carrinho

Um assistente que edita diretamente o carrinho pode remover um artigo que o consumidor pretendia comprar ou adicionar um que este nunca confirmou, sem que lhe seja pedido. Basta um único erro para perder a confiança do consumidor, porque a falha ocorre de forma silenciosa e afeta precisamente o que este está prestes a pagar.

Por isso, apresentamos, em vez disso, uma lista de compras como proposta. Esta pode conter dezenas de artigos e passar por várias rondas de revisão, quer isso signifique remover um produto da despensa que o consumidor já tenha, alterar uma quantidade, trocar um produto ou reformular parte de uma receita, e nada disso afeta o carrinho. Para confirmar a compra, é necessário clicar explicitamente em «Adicionar ao carrinho», que é a estrutura mais simples que encontrámos e que dá ao consumidor controlo real sem o obrigar a supervisionar cada passo.

Os dois elementos ainda têm de ser conciliados, e a escolha interessante é quem o faz. O assistente analisa o carrinho enquanto elabora a lista, mas não a ajusta automaticamente para que corresponda: se uma receita precisar de duas bananas, a lista pede duas, independentemente de já haver ou não quatro no carrinho. Elaborar a lista com exatamente o que foi solicitado e conciliá-la com o carrinho numa etapa separada permite manter cada decisão num único local.

Essa etapa surge no momento da confirmação. Quando a lista e o carrinho coincidem, são apresentadas ao consumidor as duplicatas e este decide se pretende substituir essas quantidades ou aumentá-las. É um momento breve, mas são momentos breves como este que determinam se se ganha ou se perde a confiança.

Transmitir o contexto em toda a plataforma DoorDash

Não basta que o assistente esteja disponível num único local; tem de ser acessível a partir de qualquer ponto da aplicação. Abrir o assistente já é um forte sinal de intenção, mas um sinal ambíguo. Um consumidor, nesse momento, pode estar a fazer uma encomenda num restaurante favorito, a comprar mantimentos para a semana, a procurar uns auscultadores novos ou a procurar apoio relativamente a uma encomenda anterior. Um consumidor que tenha acedido a uma determinada mercearia está a enviar um sinal muito mais claro: é provável que pretenda encher o carrinho nessa loja. Transmitir esse contexto ao assistente é o que lhe permite concentrar-se na intenção provável, em vez de ter de perguntar.

O sistema de âmbito que concebemos para este projeto abrange o cliente e o Gateway. O cliente associa elementos-chave do contexto de entrada a cada pedido: o tópico sob o qual o consumidor entrou (mercearia, restaurante), a loja que está a consultar e alguns identificadores relacionados. O Gateway utiliza o tópico para decidir a que agente encaminhar o pedido e os restantes elementos para fornecer às ferramentas os identificadores de que necessitam.

O Scope é, deliberadamente, um conjunto simples de pares chave-valor, em vez de um esquema tipado, e é o cliente que decide o que nele é incluído. As chaves não reconhecidas são transmitidas em vez de rejeitadas, pelo que uma nova superfície pode começar a enviar contexto sem ter de aguardar uma alteração no Gateway. A exceção é o próprio tópico: adicionar um novo implica indicar ao Gateway para que agente deve encaminhá-lo. Assim, embora uma nova superfície seja de baixo custo, um novo domínio não o é.

O tema é também a parte que se aplica apenas à primeira mensagem de um contexto. Isso dá ao assistente uma base sólida a partir da qual trabalhar, sem ser excessivamente prescritivo, e é o que permite aos utilizadores sair de um âmbito quando optam explicitamente por fazê-lo. Um utilizador que utilize o assistente dentro de um restaurante pode sair completamente do âmbito do restaurante, pedindo-lhe para «encontrar uma receita para este prato e preparar-me uma lista de compras, para que eu o possa fazer em casa». Esse pedido não é gratuito, mas o custo é um pequeno desvio no percurso, em vez de um beco sem saída: o agente do restaurante tem de reconhecer o pedido como estando fora do seu domínio e devolvê-lo antes que outro agente o receba.

Em certos casos, os âmbitos também nos permitem ignorar completamente o modelo. Tomemos como exemplo o ponto de entrada «Reordenar o meu último carrinho». Poderia simplesmente enviar essa frase ao assistente como uma mensagem e, embora isso funcionasse, anexar um âmbito permite-nos ser mais específicos. O caso «reordenar» é, na prática, determinístico, pelo que podemos contornar o LLM e devolver uma lista de compras quase imediatamente. O que é devolvido é um widget comum de lista de compras: o consumidor pode alterar quantidades, trocar produtos ou pedir ao assistente para a rever no chat, exatamente como faria com qualquer outra lista. Note-se que esta omissão só se aplica se a loja ainda tiver todos os artigos do carrinho anterior; se um artigo não estiver disponível, o pedido é encaminhado para o agente de mercearia, que reconstrói a lista da mesma forma que faria a partir de um pedido digitado.

O escopo é também o que torna possível uma conversa única e contínua ao longo de uma sessão da aplicação, mas só funciona porque o escopo, a associação de agentes e o estado da sessão são mantidos separados. Tratamos o âmbito como um contexto por turno. A fixação, descrita anteriormente nesta série de publicações do blogue, mantém os turnos de acompanhamento com o agente que resolveu o turno anterior. Tanto a fixação como a transcrição (a conversa propriamente dita) são associadas ao chat e não ao âmbito; assim, um consumidor que se desloca de uma loja para outra redireciona a fixação para um agente de um novo domínio sem descartar o que foi dito. Vários agentes especializam-se internamente, e o sistema continua a comportar-se como um único assistente.

Figura 5: Uma conversa, iniciada a partir de dois locais. O âmbito acompanha cada pedido, pelo que fazer um pedido dentro do Safeway faz com que a lista seja criada no Safeway.

Conclusão

A integração de agentes em produtos de consumo ainda está numa fase inicial. No entanto, as bases estão a tornar-se claras. Os widgets são onde os consumidores realizam o trabalho e a interação entre o consumidor e o agente é o que os orienta. Existem atualmente três «leitores» do nosso artefacto de lista de compras, cada um dos quais necessita de uma perspetiva diferente do mesmo. Utilizamos a parte voltada para o utilizador para ancorar o consumidor em produtos reais e para tornar as modificações comuns ações com um único toque. À medida que os agentes assumem mais tarefas, esperamos que o que um consumidor precisa de ver e o que um agente precisa de analisar continuem a mudar, e que a linha divisória entre uma interface de aplicação e uma interface de chat se torne mais difícil de traçar.

A plataforma de experimentação da DoorDash gere mais de 60 000 «feature flags» em cerca de 623 repositórios. Identificámos mais de mil «feature flags» obsoletas; por outras palavras, a funcionalidade que outrora controlavam já foi totalmente implementada, mas a «flag» e a sua lógica de ramificação continuam na base de código como peso morto. Limpar apenas uma manualmente demora a um engenheiro entre uma a duas horas. Com cerca de 2 300 novas «flags» a serem criadas todos os meses, o atraso só aumenta.

Assim, criámos um sistema LLM multiagente que elimina as marcações obsoletas de forma integral, desde um ticket do Jira até um pedido de integração (PR) pronto para fusão, sem qualquer intervenção humana, exceto por um engenheiro que confirma o valor alvo e a implementação do PR. Das 50 marcações obsoletas mais recentes que processou, o sistema produziu PR utilizáveis para 45 delas, com um custo médio de 4,79 dólares e 13,8 minutos por marcação, poupando inúmeras horas de trabalho de engenharia. O sistema que criámos não só tinha de ser eficaz, como o seu limite de fiabilidade tinha de ser a exaustividade, e não a correção; se o agente falhasse, tinha de o fazer de forma segura, sem introduzir quaisquer alterações no código que causassem falhas.

Este artigo aborda as razões pelas quais as ferramentas prontas a usar não conseguiram alcançar este objetivo na nossa base de código, a forma como concebemos o sistema e o que aprendemos durante a sua implementação. Nota: Este trabalho foi submetido a revisão por pares e aceite para a secção dedicada à indústria da ICSME 2026.

Por que vale a pena automatizar a remoção de «feature flags» obsoletas

Os «feature flags» são um pilar fundamental da entrega moderna de software. Permitem-nos implementar funcionalidades de forma gradual, realizar experiências A/B e ativar mecanismos de desativação imediata quando algo corre mal. No entanto, cada «flag» tem um ciclo de vida e, assim que uma funcionalidade é totalmente implementada, o respetivo «flag» torna-se obsoleto. Os «feature flags» obsoletos são frequentemente deixados como dívida técnica, uma vez que o tempo de um engenheiro tem mais valor na criação de novas funcionalidades do que na sua limpeza. 

A sua lógica condicional já não tem qualquer utilidade, mas não fica simplesmente por aí sem causar danos:

  • Os «flags» obsoletos podem permanecer no código-fonte durante anos. Estudos anteriores revelaram que cerca de 25 % dos «feature flags» persistem durante mais de oito anos em projetos de código aberto; os profissionais referem frequentemente que a limpeza é um processo moroso e que é repetidamente adiada.
  • Um sinalizador obsoleto é uma dívida técnica. Cada sinalizador obsoleto acrescenta um ramo, um caso de exceção e um pouco mais para ler e analisar, o que pode ser especialmente complicado durante um incidente.
  • Os indicadores obsoletos podem constituir um risco operacional. Um indicador obsoleto mantém ativo um caminho de código inativo que pode ser reativado acidentalmente. Num caso bem documentado, uma empresa de negociação reutilizou um indicador obsoleto durante uma implementação, o que provocou transações não intencionais no valor de 460 milhões de dólares em apenas 45 minutos.

Se multiplicarmos dezenas de milhares de sinalizadores por uma taxa de criação mensal de quatro dígitos, torna-se evidente que a limpeza manual simplesmente não consegue acompanhar o ritmo. Eliminar manualmente o nosso acúmulo de tarefas em atraso custaria milhares de horas de engenharia que seriam mais bem empregues no desenvolvimento.

Valores dinâmicos

Os «feature flags» na DoorDash são designados por «valores dinâmicos» (DVs). São geridos pela nossa plataforma de experimentação. Ao longo deste artigo, o termo «DV» é sinónimo de «feature flag».

O ciclo de vida de um DV segue o padrão criação → experimentação → implementação → obsoleto → remoção. Classificamos um DV como obsoleto quando este cumpre todos os seguintes critérios:

  1. Não sofreu alterações nos últimos 90 dias.
  2. Ainda é referenciado no código.
  3. Ainda não se encontra em estado de fim de vida útil (arquivado ou retirado de serviço).
  4. Não consta de nenhuma lista de exclusão.

Uma tarefa cron diária cria um ticket STALEDV no Jira para cada DV obsoleto identificado e atribui-o ao criador do DV. Isto marca o início da fila a partir da qual o nosso sistema de limpeza opera.

Fluxo de trabalho baseado em agentes vs. ferramentas de limpeza baseadas em AST

A abordagem automatizada mais conhecida para a limpeza de flags é o Piranha e o seu sucessor poliglota, que simplificam as condições condicionadas por flags através da correspondência de padrões na árvore de sintaxe abstrata (AST). Funciona bem quando uma flag é lida através de uma chamada direta à API que uma regra de reescrita consiga corresponder a um padrão.

Mas não é assim que se acede aos DVs na DoorDash. Os nossos serviços utilizam um padrão de wrapper de três camadas com injeção de dependências:

// Layer 1: RuntimeKeys.kt – the DV name as a string constant
object RuntimeKeys {
  const val ENABLE_X = “enable_feature_x”
}

// Layer 2: FeatureFlags.kt – a DI wrapper that calls the DV client
@Singleton
class FeatureFlags @Inject constructor(
    private val dvClient: DynamicValuesClient
) {
  fun shouldEnableX(userId: String): Boolean =
    dvClient.getBoolean(ENABLE_X, withContext(“user_id” to userId), false)
}

// Layer 3: business logic – uses the flag via dependency injection
class MyService @Inject constructor(
    private val featureFlags: FeatureFlags
) {
  fun process(userId: String) {
    if (featureFlags.shouldEnableX(userId)) handleNewPath()
    else handleOldPath()
  }
}

Trata-se de uma separação clara de responsabilidades, mas isso significa que o nome DV, a chamada à API e a lógica condicional se encontram, cada um, num ficheiro diferente, ligados apenas através de chamadas a métodos e injeção de dependências. Trata-se de relações semânticas, não sintáticas; os comparadores de padrões AST não conseguem segui-las. 

Determinação do valor-alvo

Existe um problema adicional que uma ferramenta que trabalha apenas com código-fonte não consegue resolver: a determinação do valor-alvo e a consulta ao estado da implementação em tempo real. Uma ferramenta que apenas lê o código-fonte poderia, sem perceber, codificar o valor errado e alterar silenciosamente o comportamento. Garantir que a ferramenta efetue a limpeza correta do código requer conhecer o estado da implementação em tempo real do sinalizador, que se encontra na plataforma de experimentação, e não no repositório. Por exemplo, a plataforma de experimentação da DoorDash suporta a utilização de flags de funcionalidade do tipo inteiro, cadeia de caracteres e JSON. Uma leitura em tempo real do valor-alvo garante que a ferramenta está a modificar o código com o valor correto da flag de funcionalidade, que representa o estado atual do sistema. Da mesma forma, as informações sobre a implementação também são uma parte importante da equação. Uma experiência pode ter sido implementada em 60 % e, posteriormente, abandonada. A ferramenta teria de ter a inteligência para determinar que se trata de uma implementação parcial e solicitar a confirmação do utilizador antes de efetuar qualquer limpeza. Isto pode levar o utilizador a concluir a implementação/reversão antes de utilizar a ferramenta para efetuar a limpeza, ou levá-lo a ignorar a limpeza por enquanto.

Dimensão e complexidade

Por fim, mesmo um DV booleano simples pode afetar entre cinco a 20 ficheiros, depois de ter em conta a constante, o wrapper, todos os locais de chamada e a atualização ou eliminação de testes relevantes. Esta é uma tarefa que requer compreensão do código, não apenas a correspondência da sintaxe. Foi exatamente por isso que optámos por utilizar agentes LLM. Mas a tarefa não se resumiu a escrever um prompt e pedir ao agente para realizar a limpeza; isso não permitiria uma limpeza eficiente em termos de custos e tempo, com mecanismos de proteção em grande escala.

Um fluxo de trabalho em duas fases, com intervenção humana

O sistema foi desenvolvido com base no Agent Development Kit (ADK) da Google e funciona em duas fases, com um único ponto de verificação humano entre elas, conforme ilustrado na Figura 1.

Figura 1: Arquitetura do sistema. Um agente orquestrador executa a análise da Fase 1, extrai DVs desatualizados do Jira, consulta a plataforma de experimentação sobre o estado da implementação através do Protocolo de Contexto do Modelo (MCP) e pesquisa a base de código; um engenheiro verifica o relatório. A Fase 2, por sua vez, gera agentes de limpeza paralelos em árvores de trabalho Git isoladas, que editam, testam, verificam a cobertura e executam a verificação de conformidade antes de abrir um PR.

Fase 1: Análise e relatório

Um agente orquestrador, neste caso Claude Sonnet, processa os pedidos de DV desatualizados. Para cada DV, ele:

  1. Recupera os tickets DV do Jira desatualizados através da ferramenta de linha de comandos da Atlassian.
  2. Consulta a plataforma de experimentação da DoorDash através do Protocolo de Contexto do Modelo (MCP) para obter os metadados do DV — o seu UUID, a percentagem de implementação e o valor-alvo.
  3. Identifica o repositório local e procura todas as referências de código ao DV.
  4. Gera um relatório estruturado que propõe um valor-alvo e enumera os ficheiros afetados para cada DV.

Essa integração com o MCP é o herói discreto do projeto. Ao ler o estado atual da implementação em produção, o agente determina o valor-alvo correto, em vez de ter de adivinhar com base no código. Por exemplo, um DV que foi introduzido para uma funcionalidade que acabou por ser abandonada apresenta uma implementação de 0% na plataforma; assim, o agente sabe que deve removê-lo utilizando o valor de referência, em vez de partir do princípio de que a funcionalidade está ativa.

Ponto de controlo humano

Antes de qualquer alteração no código, um engenheiro analisa o relatório e confirma o valor-alvo de cada DV. Trata-se de uma medida de segurança deliberada para casos ambíguos, tais como implementações parciais ou experiências abandonadas, em que a resposta correta requer o julgamento humano. Por exemplo, uma experiência pode ter sido implementada em 60 % e, posteriormente, abandonada. O controlo humano permite que o utilizador intervenha, decidindo, por exemplo, se deve concluir a implementação ou reverter a experiência antes de se prosseguir com a limpeza.

Fase 2: Limpeza paralela

Por cada DV confirmado, o orquestrador cria um agente de remoção dedicado — o Claude Opus —, sendo que cada um é executado na sua própria árvore de trabalho Git isolada. Podem ser executados até quatro agentes em simultâneo por repositório, sendo este número configurável. Cada um deles realiza uma limpeza completa e abre um pedido de integração atribuído ao proprietário do DV.

No interior de um agente de remoção

Cada agente de remoção executa um fluxo de trabalho iterativo da seguinte forma:

  1. Procure todas as referências ao DV, incluindo a constante, a função de envolventes e todos os locais de chamada.
  2. Defina uma estratégia de limpeza com base no tipo da variável dinâmica (booleana, inteira ou cadeia de caracteres) e na sua utilização.
  3. Aplique as alterações; substitua as chamadas ao wrapper pelo valor pretendido e simplifique as condições que agora são constantes.
  4. Remova a função de invólucro, a definição e a constante.
  5. Atualizar ou remover os testes afetados, como, por exemplo, eliminar ramos de teste «marcados como desativados».
  6. Confirme se a compilação foi bem-sucedida.
  7. Confirme se os testes foram bem-sucedidos.
  8. Verifique se a cobertura do patch é de, pelo menos, 95% nas linhas alteradas.
  9. Execute o linter Detekt.
  10. Se alguma validação falhar, identifique o problema, corrija-o e tente novamente.

A autonomia sobre um conjunto de código só funciona se as medidas de segurança forem efetivas. Existem quatro mecanismos que garantem a segurança dos agentes:

  • Isolamento da árvore de trabalho do Git: Cada agente trabalha numa árvore de trabalho dedicada, pelo que os agentes em execução simultânea nunca interferem uns com os outros, e uma limpeza mal sucedida é descartada simplesmente removendo a árvore de trabalho.
  • Um tempo limite fixo de uma hora por agente: isto garante que uma sessão bloqueada não se prolongue indefinidamente.
  • Validação da cobertura de patches do JaCoCo: isto garante uma cobertura de testes de, pelo menos, 95% nas linhas alteradas pelo agente.
  • Análise estática com o Detekt: Esta ferramenta garante o cumprimento das normas de estilo e deteta problemas comuns.

Também executamos o Gradle com a opção –no-daemon para eliminar a contaminação do estado entre árvores de trabalho durante as execuções paralelas. É fundamental referir que um agente não pode abrir um PR enquanto os testes e a análise estática não forem aprovados localmente.

Resultados

Criar um sistema é uma coisa, mas quando este funciona à escala da DoorDash, só há uma questão que importa: até que ponto funciona bem? Neste caso, funciona mesmo muito bem.  Das 50 sinalizações de código obsoleto mais recentes que o sistema processou, gerou um PR pronto para fusão em 45 delas, com um custo médio de 4,79 dólares e 13,8 minutos por limpeza, em vez das uma a duas horas que uma limpeza manual teria demorado. O sistema não introduziu quaisquer erros nem regressões ao longo do processo.

Como o avaliámos

Avaliámos o sistema com base nos 50 DVs obsoletos mais recentes que este processou em vários repositórios Kotlin. Classificámos cada um deles de acordo com a sua complexidade: 

  • Simples — Uma única verificação booleana num ou dois ficheiros; n=6
  • Médio — Várias utilizações em três a cinco ficheiros, com algumas alterações de teste; n=18
  • Complexo — condicionais aninhadas, dependências entre ficheiros, tipos não booleanos ou atualizações significativas nos testes; n=26 

Por tipo, 41 eram booleanos, seis eram cadeias de caracteres e três eram inteiros/longos. Cada PR foi avaliado com base em três critérios: aprovação no CI — incluindo o limite de 95 % de cobertura do patch —, correção do código e revisão por parte dos programadores. 

Resultados por nível de complexidade

Figura 2: Resultados da limpeza por nível de complexidade. As DVs simples são aceites a 100 % à primeira tentativa; as DVs de complexidade média atingem uma taxa de limpeza de 94 %; as DVs complexas apresentam mais revisões e falhas, mas ainda assim atingem 85 %.

Conforme ilustrado na Figura 2, 31 das 50 limpezas foram concluídas à primeira tentativa, 14 exigiram uma pequena revisão e cinco exigiram a intervenção de um engenheiro. A análise da complexidade reflete o limite de fiabilidade do sistema:

  • DVs simples: 100% limpos numa única passagem.
  • DVs médias: 94% (17/18) — 14 concluídas numa única passagem, três após uma revisão e uma que exigiu a intervenção de um engenheiro.
  • DVs complexas: 85% (22/26), mesmo com a remoção em cascata de parâmetros ao longo de mais de cinco camadas de métodos, condições aninhadas e uma refatoração profunda dos testes.

As 14 revisões foram menores e autocorretivas; seis apresentavam uma cobertura insuficiente do patch, exigindo mais uma iteração para adicionar testes, e oito consistiam numa remoção incompleta de código morto, com uma variável ou referência remanescente numa cadeia de chamadas profunda. No entanto, todas foram corrigidas numa única nova solicitação ao LLM.

A conclusão mais importante prendeu-se com o tipo de problema que surgiu. Em todas as 50 PRs geradas, não observámos quaisquer erros ou regressões introduzidas pelo código alterado. Cada um dos cinco casos de intervenção resumiu-se à profundidade da cadeia de chamadas com encadeamento de parâmetros entre interfaces; o agente removeu corretamente a maior parte do código morto, mas deixou escapar um ou dois elos numa longa cadeia que envolvia vários ficheiros. Por outras palavras, o limite de fiabilidade do sistema é a exaustividade, e não a correção, o que atenua as preocupações de que o sistema pudesse criar problemas maiores quando não fosse bem-sucedido.

Custo e tempo

Os custos e os prazos variam em função da complexidade, mas mantêm-se firmemente no âmbito da «execução em grande escala», tal como se pode ver na Tabela 1 e na Figura 3. 

A Tabela 1 apresenta uma análise detalhada das métricas médias e medianas de desempenho — nomeadamente, tempo e custo — para os 50 «feature flags» analisados, classificados de acordo com a sua complexidade. Estes dados revelam que, embora os «feature flags» mais complexos exijam, naturalmente, mais tempo e orçamento, o sistema continua a ser altamente eficiente, mesmo nas tarefas de limpeza mais difíceis.

ComplexidadenTempo médioTempo medianoCusto médioCusto mediano
Simples67,5 min8,2 min$2.69$2.50
Médio1810,4 min9,9 min$3.46$3.42
Complexo2617,7 min14,4 min$6.20$4.50

Tabela 1: Métricas de desempenho por nível de complexidade nas 50 «feature flags» avaliadas.

Figura 3: Custo da API em função do tempo real para cada DV, classificado por complexidade. Os DVs simples e médios agrupam-se na região de baixo custo e baixo tempo. Os DVs complexos estão mais dispersos, com alguns valores atípicos que se aproximam dos 40 minutos e dos 19 dólares. Os DVs com falha (×) tendem a apresentar tempos de execução mais longos.

Conforme ilustrado na Figura 3, os DVs simples e médios agrupam-se estreitamente no canto «barato e rápido». Os DVs complexos estão mais dispersos, com alguns valores atípicos a atingirem cerca de 40 minutos e cerca de 19 dólares. Mesmo no limite superior desse intervalo, o agente representa uma redução drástica no esforço de engenharia e nos custos, mesmo quando comparado com uma estimativa conservadora de uma hora do que seria necessário para remover manualmente um único DV.

O que aprendemos

  • A especialização dos modelos por função compensa. Utilizamos o Claude Sonnet para a orquestração, incluindo o contexto geral, a recolha de metadados simplificada e o planeamento, e o Claude Opus para os agentes de remoção, incluindo o raciocínio aprofundado sobre a semântica do código, as cadeias de chamadas e as dependências de teste. Reservar o modelo mais dispendioso para a fase de edição, que exige maior esforço cognitivo, reduziu o nosso custo global da API sem comprometer a qualidade da limpeza.
  • O isolamento da árvore de trabalho é imprescindível para os agentes paralelos. As nossas primeiras experiências sem isolamento da árvore de trabalho geraram condições de corrida, nas quais agentes simultâneos editavam os mesmos ficheiros e geravam comparações corrompidas. Uma árvore de trabalho dedicada por agente, juntamente com o Gradle na opção –no-daemon, tornou a limpeza paralela segura e permitiu que as falhas fossem descartadas.
  • A integração da experimentação em tempo real foi a decisão com maior impacto. Sem o estado atual de implementação, qualquer abordagem automatizada — baseada em regras ou em LLM — corre o risco de codificar de forma rígida o valor errado e de, inadvertidamente, perpetuar o comportamento incorreto. A leitura através do MCP acrescentou uma latência insignificante e eliminou toda uma classe de erros relacionados com valores-alvo.

Qualquer equipa que esteja a ponderar uma automatização semelhante deve ter em conta que os nossos resultados apontam para três pré-requisitos práticos: 

  • Uma fonte fiável do Estado de bandeira em que o navio se encontra
  • Isolamento da árvore de trabalho para edições em paralelo, e 
  • Os critérios de validação determinísticos são aplicados antes mesmo de se abrir um PR.

O que se segue

Estamos a expandir o sistema em duas vertentes:

  1. Um índice de confiança da fase 1 para aprovar automaticamente as correções de baixo risco. Por exemplo, uma variável de dependência (DV) booleana com uma taxa de implementação de 100%, cujo código por predefinição já corresponde ao da produção, o que reserva a verificação humana para casos verdadeiramente ambíguos.
  2. Uma verificação da qualidade do código após a limpeza. Isto permitiria detetar problemas semânticos, tais como nomes de variáveis que já não refletem a sua finalidade após a remoção de um sinalizador.

A limpeza de feature flags é o tipo de trabalho que, individualmente, é pequeno, mas, em conjunto, é enorme — especialmente à escala da DoorDash — e que é constantemente adiado. Ao combinar um orquestrador, agentes de remoção paralelos em árvores de trabalho isoladas, consultas à plataforma de experimentação em tempo real e portas de validação rigorosas, o nosso sistema de limpeza de feature flags transforma um atraso de milhares de horas num processo em segundo plano económico e fiável que produz PRs prontas para fusão para 90% das flags que trata, a um custo de cerca de 4,79 dólares e 14 minutos cada, sem regressões. O único obstáculo que ainda resta é a exaustividade nas cadeias de chamadas mais profundas, e é precisamente nisso que nos vamos concentrar a seguir.

Está interessado em desenvolver sistemas como este? A equipa de engenharia da DoorDash está a recrutar – venha ajudar-nos a desenvolver em grande escala.

O Flux é a plataforma de agentes baseada na nuvem da DoorDash destinada a engenheiros. Num único mês de 2026, utilizámos o Flux para automatizar 130 000 tarefas de engenharia. Em rápida expansão após a sua estreia no primeiro trimestre de 2026, o Flux já alimenta fluxos de trabalho em segundo plano de grande volume em toda a DoorDash, incluindo mais de 25 000 revisões de código automatizadas por semana, bem como mais de 300 guias de procedimentos únicos e mais de 10 000 chamadas utilizadas todas as semanas. Estes fluxos de trabalho podem ser executados de forma autónoma, em paralelo e 24 horas por dia.

Nesta publicação do blogue, vamos abordar as limitações que nos levaram a ir além das cargas de trabalho de agentes locais, executadas em computadores portáteis, as razões pelas quais optámos por desenvolver o Flux internamente, em vez de depender exclusivamente de agentes de codificação alojados, e os elementos básicos da plataforma, tais como as sandboxes de agentes, o gateway MCP, os playbooks e as superfícies de invocação, para tornar a delegação de agentes repetível e segura.

Casos de utilização do fluxo de trabalho de fundo do Flux

Tabela 1: Um resumo da utilização do Flux na DoorDash ao longo de um mês, abrangendo revisões automatizadas de código, execuções de playbooks e conclusões de tarefas em segundo plano

Onde começámos

Ao longo do último ano, os utilizadores que executam cargas de trabalho baseadas em agentes nos seus portáteis depararam-se rapidamente com algumas limitações:

  • Recursos e disponibilidade. Um portátil tem um número fixo de núcleos de CPU, memória limitada e uma bateria, todos partilhados com todas as aplicações instaladas. Os fluxos de trabalho do Agentic precisam frequentemente de executar tarefas que exigem grande capacidade de computação, tais como compilações, testes e pesquisas de grande dimensão em paralelo, o que faz com que os portáteis esgotem rapidamente a sua capacidade. Os fluxos de trabalho também dependem de o dispositivo estar ligado, conectado e disponível; o trabalho é interrompido quando um engenheiro fecha o portátil, perde a ligação ou se afasta.
  • Controlos de segurança. Os computadores portáteis têm, normalmente, um acesso alargado a credenciais e sistemas sensíveis, incluindo chaves SSH, sessões VPN e ferramentas autenticadas. Conceder a um agente autónomo esse mesmo nível de acesso cria um risco desnecessário e um raio de impacto potencialmente vasto. Os ambientes locais também tornam mais difícil definir com rigor o âmbito do acesso de um agente e a duração desse acesso.
  • Visibilidade e auditabilidade. Quando as cargas de trabalho são executadas em computadores portáteis individuais, a execução fica fragmentada e é difícil de monitorizar. Torna-se mais difícil perceber o que está a ser executado, onde está a ser executado, em nome de quem e quais os sistemas ou ficheiros que foram afetados.

A nossa abordagem para resolver estas questões é simples: 

Delegar tarefas a agentes de programação seguros e autónomos, para que os engenheiros possam dedicar mais energia à inovação, ao pensamento crítico e à resolução de problemas complexos.

Por que desenvolvemos o Flux internamente

Os agentes de programação alojados são úteis, mas impõem um compromisso difícil: ou enviar código sensível e o contexto de execução a um terceiro, ou abrir uma via de acesso desse terceiro de volta aos sistemas internos. Para a DoorDash, o problema mais complexo não era apenas conseguir que um agente escrevesse código; isso já está praticamente resolvido. Era proporcionar a esse agente o ambiente, as ferramentas, as permissões, as integrações e as restrições adequadas.

A nossa estratégia consiste em controlar os elementos básicos em torno do agente, incluindo orquestração, ambientes de teste, fluxos de trabalho, permissões, integrações e os agentes de contexto específicos da DoorDash necessários para um funcionamento eficaz. Também concebemos esses elementos básicos de forma modular, o que nos dá a flexibilidade de utilizar a melhor ferramenta de terceiros para cada tarefa ou de desenvolver soluções internamente quando é importante garantir um maior nível de segurança, integração, desempenho ou controlo sobre a experiência do utilizador. 

Estas primitivas democratizam a criação de fluxos de trabalho e tornam os sistemas mais adaptáveis a futuros casos de utilização. Como podem ser combinadas de diferentes formas, as equipas podem criar novos fluxos de trabalho para os agentes sem terem de reformular a infraestrutura subjacente nem impor a forma como cada engenheiro deve estruturar o seu fluxo de trabalho. Por exemplo, executamos as avaliações da nossa revisão de código na infraestrutura do Flux.

Elementos primitivos, não fluxos de trabalho

Conforme ilustrado na Figura 1, o Flux assenta em quatro elementos fundamentais da plataforma: sandboxes, o gateway do protocolo de contexto do modelo (MCP), playbooks e superfícies de invocação. Em conjunto, tornam a delegação de tarefas aos agentes repetível. Um playbook define o trabalho. Uma sandbox na nuvem proporciona ao agente um ambiente real para o realizar. Um gateway de agente controla os sistemas aos quais o agente pode aceder. E as superfícies de invocação permitem que os engenheiros iniciem e recebam trabalho a partir dos ambientes que já utilizam.

Figura 1: As quatro primitivas da plataforma que compõem o Flux — sandboxes, o gateway MCP, os playbooks e as superfícies de invocação — e a forma como se interligam para transformar uma tarefa num trabalho que um agente possa executar com segurança

As sandboxes proporcionam o ambiente de execução

Os agentes locais funcionam bem para o desenvolvimento interativo, mas não são adequados para fluxos de trabalho não supervisionados. Dependem dos portáteis de cada engenheiro, competem pelos recursos locais, são difíceis de auditar e não se adaptam de forma eficiente a tarefas paralelas.

O Flux transfere a execução para ambientes isolados na nuvem, suportados por microvirtuais (microVMs) Firecracker, que garantem o isolamento ao nível do hardware. Cada ambiente é provisionado com os repositórios, as ferramentas de desenvolvimento, os segredos e as dependências de tempo de execução necessárias para a tarefa, proporcionando aos agentes um espaço de trabalho de engenharia completo e, ao mesmo tempo, oferecendo à DoorDash um modelo consistente de execução, segurança e observabilidade.

O controlo desta camada permite-nos dar suporte a fluxos de trabalho de engenharia reais, incluindo alterações em vários repositórios e vários pedidos de integração a partir de uma única sessão. O Flux tem um objetivo de nível de serviço no 95.º percentil inferior a cinco segundos para toda a configuração de ponta a ponta — desde o arranque da microVM até à clonagem dos repositórios necessários, passando pela instalação das ferramentas de compilação e pela configuração dos conjuntos de testes do agente de codificação suportados.

O gateway MCP proporciona acesso controlado

Os agentes precisam de ter acesso aos sistemas que os engenheiros utilizam diariamente, incluindo integração contínua (CI), plataformas de observabilidade, sistemas de acompanhamento de problemas, ferramentas de implementação, pesquisa de código, documentação e metadados de serviços. No entanto, conceder acesso amplo e sem restrições não deve ser a opção predefinida.

O Flux liga os agentes aos sistemas internos através de um gateway MCP interno denominado «Agent Gateway». Cada playbook declara as ferramentas de que necessita, e o Flux concede apenas as permissões específicas necessárias para essa tarefa. Todas as ações são registadas, criando um registo de auditoria claro.

Esta arquitetura de gateway proporciona-nos um ponto de controlo centralizado para a autenticação, autorização, observabilidade, acompanhamento da utilização e aplicação de políticas, o que torna o acesso dos agentes mais seguro e mais fácil de gerir em grande escala.

Os manuais definem o trabalho

Um «playbook» é uma unidade reutilizável de trabalho autônomo — o equivalente a um contentor Docker para competências e tarefas executadas por agentes na plataforma Flux. Definido num único ficheiro YAML de marcação, agrupa a tarefa, os dados de entrada, o contexto, as competências, as ferramentas, as permissões, a validação, os resultados esperados e os limites de segurança necessários para executar o trabalho de forma consistente.

Os playbooks podem combinar etapas orientadas por agentes, que proporcionam flexibilidade e capacidade de decisão, com etapas determinísticas, que oferecem previsibilidade, custos mais baixos e uma validação mais fácil. Isto permite que as equipas transfiram a lógica entre a execução orientada por agentes e o código convencional à medida que os requisitos evoluem, sem necessidade de redesenhar o fluxo de trabalho.

As interfaces de invocação vão ao encontro dos programadores onde quer que estes se encontrem

O mesmo manual de procedimentos pode ser acionado a partir do Slack, do GitHub, do cron, da CLI ou de uma funcionalidade conversacional. Isso significa que as equipas podem definir um fluxo de trabalho uma única vez e invocá-lo a partir da plataforma que melhor se adequar ao momento:

  • O Slack para a delegação colaborativa
  • GitHub para a automatização de PR e CI
  • Cron para manutenção recorrente
  • CLI para controlo direto por parte do programador ou invocada através de uma skill

É isso que torna o Flux fácil de adotar.

Lições aprendidas

A criação do Flux ensinou-nos tanto sobre a adoção de produtos como sobre infraestruturas, incluindo:

  • Comece por um âmbito restrito para ganhar confiança. Começámos pela revisão automatizada de código, em vez de tentarmos automatizar todo o ciclo de vida do desenvolvimento de software. A revisão de código era frequente, mensurável e fácil de avaliar pelos engenheiros. Isso proporcionou-nos um fluxo de trabalho de produção em que pudemos ajustar a qualidade, a latência, o custo e o comportamento antes de expandirmos para a triagem de CI, tarefas de plantão, manuais de manutenção e desenvolvimento orientado por tickets.
  • Tornar o trabalho visível. A nossa primeira integração com o Slack criou canais privados para cada execução de um agente. Isso tornou o Flux útil para os indivíduos, mas não criou hábitos de equipa. Transferir o trabalho para tópicos públicos alterou o padrão de adoção. Os engenheiros podiam ver o que os outros delegavam, acompanhar o progresso no Flux, analisar os resultados e construir confiança em conjunto.
  • Os manuais operacionais precisam de apoio. Os fluxos de trabalho reutilizáveis não surgem simplesmente porque a plataforma existe. Os workshops e os hackathons ajudaram as equipas a transformar tarefas operacionais repetitivas em manuais operacionais. Os elementos básicos tornaram a automatização possível; o apoio ajudou as equipas a reconhecer quais os fluxos de trabalho que valia a pena codificar.

O que se segue

Em publicações futuras, iremos aprofundar os conceitos básicos da plataforma que permitem o funcionamento do Flux, bem como a experiência do programador na criação de novos fluxos de trabalho. Iremos também abordar as aplicações que desenvolvemos com base nela, incluindo o Flux Responder, o nosso agente interno do Slack.

Agradecimentos

Agradecemos a Adam Rogal, Adam Yarger, Andy Fang, Ashwin Kachhara, Fan Xia, Ivan Rudovol, Jason Prasad, Jialu Deng, Justin Block, Justin Deocampo, Justin Fan, Keith Lyall, Praneet Singh, Sean Chen, Tyler Berrett e Volanda Zhu pelas suas contribuições para a plataforma e para este artigo.

Mantenha-se informado com as actualizações semanais

Subscreva o nosso blogue de Engenharia para receber actualizações regulares sobre todos os projectos mais interessantes em que a nossa equipa está a trabalhar

Os agentes de IA tornam-se úteis quando conseguem agir em sistemas reais. Na DoorDash, isso significa aceder a APIs internas, sistemas de engenharia, plataformas de observabilidade, sistemas de gestão de tickets, bases de conhecimento e produtos SaaS de terceiros. O Protocolo de Contexto do Modelo (MCP) facilitou a exposição dessas ferramentas, proporcionando aos agentes e servidores uma forma comum de descrever, descobrir e invocar funcionalidades.

À medida que os agentes passaram das experiências para os fluxos de trabalho reais, deparámo-nos com um problema diferente. Embora o MCP tivesse padronizado o formato de uma chamada de ferramenta, não respondia a questões-chave relacionadas com a produção em torno dessa chamada:

  • Que agente está autorizado a utilizar esta ferramenta?
  • Em nome de que utilizador, equipa ou serviço está a agir?
  • Que credencial deve ser utilizada?
  • Que subconjunto de ferramentas é que o agente deveria sequer ver?
  • Como é que revogamos o acesso?
  • Como é que sabemos o que aconteceu depois da chamada?

Estas necessidades aumentam rapidamente. Um agente de programação pode precisar do GitHub, do Jira, da pesquisa de código, da integração contínua (CI), da observabilidade e da documentação. Um servidor MCP de terceiros pode disponibilizar centenas de ferramentas, quando um fluxo de trabalho precisa apenas de cinco. Um agente que lida diretamente com os utilizadores pode precisar da autorização OAuth de um utilizador, enquanto a automação da equipa deve utilizar uma entidade de serviço não pessoal. Se cada equipa resolver estas questões de forma independente, cada par agente-ferramenta acaba por ter o seu próprio código de autenticação, fluxo OAuth, gestão de segredos, catálogo de ferramentas, limites de taxa e registos.

Foi por isso que criámos um Agent Gateway, para tornar o acesso às ferramentas dos agentes uma funcionalidade da plataforma. Trata-se de um único ponto de entrada regulamentado, através do qual os agentes descobrem e acedem às ferramentas. O gateway autentica o utilizador, verifica a autorização, expõe apenas as ferramentas aprovadas, introduz as credenciais corretas, encaminha para o servidor MCP a jusante e regista um evento de utilização estruturado para cada chamada.

O gateway não é apenas um proxy. É o plano de controlo do ecossistema de agentes. Determina quem pode aceder às ferramentas, seleciona as ferramentas que os agentes podem ver, agrupa as ferramentas em interfaces orientadas para tarefas e proporciona à DoorDash um único local para monitorizar, limitar o número de acessos, revogar e melhorar o acesso dos agentes às ferramentas.

Problema: O acesso às ferramentas tem três partes

Embora o MCP ajude os agentes a aceder às ferramentas, o problema mais complexo em ambiente de produção tem três dimensões:

  1. O primeiro é o acesso. A plataforma precisa de saber quem está a ligar, se essa pessoa está autorizada e qual o modelo de credenciais aplicável: identidade interna, token mantido pelo gateway, OAuth por utilizador ou acesso por entidade de serviço.
  2. O segundo aspeto é a seleção das superfícies das ferramentas. Os agentes não devem receber um conjunto bruto de todas as ferramentas expostas pelos servidores MCP a jusante. Catálogos mais pequenos e relevantes para a tarefa melhoram a segurança, reduzem a confusão dos modelos e facilitam a operação dos agentes.
  3. O terceiro aspeto é o das operações. As chamadas às ferramentas requerem limites de taxa, rastreios, métricas, eventos de utilização, atribuição de custos, metadados de propriedade e visibilidade da produção.

O nosso Agent Gateway existe porque o acesso, a curadoria e as operações devem estar reunidos numa única plataforma partilhada, e não duplicados em cada agente e em cada servidor MCP.

Arquitetura de gateway

O gateway tem duas componentes principais: um proxy e um registo, conforme ilustrado na Figura 1 abaixo. O proxy constitui o plano de dados; recebe cada pedido MCP, autentica o solicitante, autoriza a ação, aplica limites de taxa, insere credenciais, reencaminha o pedido e emite dados de observabilidade. O registo é a fonte de verdade do plano de controlo; armazena agentes, servidores MCP, proprietários, configurações de transporte, modos de autenticação, políticas, catálogos de ferramentas detetadas e configurações da superfície das ferramentas.

Figura 1: Arquitetura de alto nível do Agent Gateway

Esta divisão confere ao gateway algumas características que são difíceis de obter em integrações ponto a ponto:

  • Os agentes utilizam um padrão único e consistente de pontos finais MCP, em vez de terem de aprender o modelo de autenticação e encaminhamento de cada servidor a jusante.
  • Os proprietários das ferramentas registam as capacidades uma única vez, associam a propriedade e a política e visualizam a utilização em produção.
  • As equipas de segurança dispõem de um único local para controlar o acesso, revogar autorizações e auditar chamadas.
  • As equipas da plataforma podem melhorar o percurso partilhado uma única vez e fazer com que todos os agentes beneficiem dessa melhoria.

Também mantemos separados os limites de confiança internos e externos. Os fluxos de trabalho internos da DoorDash e os casos de utilização dos agentes voltados para o exterior são executados através de planos de proxy distintos, com bibliotecas partilhadas e conceitos de registo. Isso limita o alcance de um eventual incidente voltado para a Internet e permite que cada modelo de autenticação evolua de forma independente.

Identidade, autorização e segredos centralizados

Cada pedido de gateway está associado a um remetente: um utilizador, um serviço ou um agente que atua com um contexto de utilizador delegado. Essa identidade é mantida ao longo do processo de autorização, injeção de credenciais, encaminhamento e observabilidade, para que cada ação a jusante possa ser atribuída.

O gateway verifica a autorização de forma centralizada. As questões relacionadas com a política não se limitam a determinar se este utilizador pode aceder a este servidor. Podem também ser:

  • Este agente pode aceder a este servidor?
  • Este utilizador pode aceder a esta ferramenta através deste agente?
  • Esta ferramenta pode ser exposta neste ambiente?
  • Este utilizador pode utilizar uma variante com capacidade de gravação ou apenas uma de leitura?
  • Este fluxo de trabalho pode utilizar uma entidade de serviço da equipa ou requer OAuth por utilizador?

Como a política está definida no gateway, a DoorDash dispõe de um único local para alterar e revogar o acesso. Os responsáveis pelas ferramentas evitam ter de reconfigurar a autorização para cada servidor, e os criadores de agentes evitam incorporar decisões de segurança nos prompts ou no código da aplicação.

O tratamento das credenciais segue o mesmo padrão, conforme ilustrado na Tabela 1:

Modo de autenticaçãoQuem é o titular da credencialO que o gateway faz
Identidade de serviço internaInfraestrutura da DoorDashEncaminha o contexto do chamador verificado para os serviços internos
Token detido pela GatewayArmazenamento seguro de chaves de gatewayInjeta um token de fornecedor ou de serviço sem o expor ao agente
OAuth por utilizadorArmazenamento de autorizações encriptado por utilizadorInserir e atualizar o token do utilizador para ações no âmbito do utilizador
Serviço principalDiretor da equipa gerida pela GatewayAs entidades emissoras ou os intermediários emitem credenciais não pessoais de curta duração

Os agentes não devem deter credenciais em bruto, tais como chaves de API de fornecedores, tokens de atualização OAuth ou autorizações humanas emprestadas para automatizações da equipa. O gateway mantém esses limites explícitos e auditáveis.

OAuth por utilizador sem interromper a vez do agente

As ferramentas de terceiros com âmbito de utilizador requerem a autorização do utilizador. Ler os documentos de um utilizador, criar um ticket em nome desse utilizador ou atualizar dados de SaaS em seu nome não pode ser feito de forma segura utilizando uma chave partilhada. Antes de implementarmos o gateway, cada equipa tendia a criar o seu próprio fluxo OAuth, armazenamento de tokens e experiência do tipo «ligar-se primeiro».

O gateway centraliza a concessão de autorização OAuth. A unidade de acesso está limitada ao agente, ao utilizador e ao servidor. Na primeira chamada que exija autorização, o gateway inicia o fluxo OAuth do fornecedor, armazena os tokens de acesso e de atualização resultantes, encriptados, e insere o token do utilizador em chamadas futuras. Os agentes nunca têm acesso ao token em bruto.

Para clientes que suportam a autenticação MCP, o gateway pode suspender a chamada da ferramenta, solicitar ao cliente que apresente um aviso de ligação e retomar a chamada original após a autorização do utilizador. Para clientes sem suporte à autenticação, o gateway devolve uma resposta estruturada indicando que é necessária autorização, acompanhada de um URL de ligação, conforme ilustrado na Figura 2. Isto transforma a ligação, que seria uma etapa falhada, numa parte recuperável da chamada da ferramenta.

Figura 2: Processo de estabelecimento de contacto para a recolha de informações

Superfícies de ferramentas selecionadas: Pacotes e filtragem

Os agentes não pensam naturalmente em servidores MCP. Pensam em tarefas. Um agente de programação não quer o GitHub, o Jira, a observabilidade e a documentação como etapas de configuração separadas; quer o conjunto de ferramentas necessário para investigar um problema, modificar código, abrir um pedido de integração, inspecionar a integração contínua e compreender o comportamento em produção.

Ao mesmo tempo, a maioria dos servidores MCP a jusante disponibiliza muito mais ferramentas do que qualquer agente deveria utilizar. Os servidores de terceiros podem publicar centenas de operações, incluindo ações administrativas, ações destrutivas, APIs de faturação e funcionalidades específicas de fornecedores de nicho. A maioria dos fluxos de trabalho da DoorDash necessita apenas de um pequeno subconjunto aprovado dessas funcionalidades.

O gateway resolve ambos os problemas através de interfaces de ferramentas selecionadas, conforme ilustrado na Figura 3. Os pacotes combinam ferramentas de vários servidores MCP num único ponto de acesso lógico do MCP. Os filtros determinam quais as ferramentas de cada servidor que são disponibilizadas para um determinado pacote, agente, grupo de utilizadores, ambiente ou público-alvo.

Por exemplo, um pacote de ferramentas de desenvolvimento pode incluir:

  • ferramentas selecionadas do GitHub para fluxos de trabalho de repositórios e pedidos de integração;
  • ferramentas selecionadas do Jira para pesquisa e atualização de problemas;
  • ferramentas de observabilidade selecionadas para registos, métricas e rastreios;
  • ferramentas selecionadas de pesquisa de código e de documentação; e
  • ferramentas selecionadas de implementação ou de sinalizadores de funcionalidades.

Figura 3: Experiência do utilizador com o pacote MCP incluído

O agente liga-se a um URL do gateway, como, por exemplo, um ponto final das ferramentas de desenvolvimento. Por trás desse URL, o gateway distribui o conteúdo de `tools/list` pelos servidores do conjunto, aplica filtros de autorização e de ferramentas, atribui namespaces ou aliases aos nomes das ferramentas quando necessário e devolve um catálogo coerente. Quando o agente invoca `tools/call`, o gateway volta a aplicar a política, encaminha a chamada para o servidor a jusante correto e aplica o modelo de credenciais desse servidor.

Isto proporciona aos agentes uma interface de qualidade, em vez de uma lista bruta de funcionalidades a jusante, e inclui elementos como ferramentas aprovadas, nomes estáveis, descrições mais claras, metadados de propriedade e pacotes específicos para cada público-alvo. As equipas de engenharia, análise de dados, operações de suporte e pacotes externos podem todas utilizar as mesmas primitivas do gateway, ao mesmo tempo que expõem interfaces de ferramentas diferentes.

As vantagens são práticas:

  • A configuração do agente é mais simples: um único ponto de acesso, em vez de vários pontos de acesso de servidor.
  • A deteção de ferramentas é mais segura: os agentes só visualizam as ferramentas que se encontram dentro do limite aprovado.
  • O comportamento dos modelos melhora: catálogos mais reduzidos diminuem as opções irrelevantes e a confusão em relação às ferramentas.
  • A autorização continua a ser centralizada: a descoberta e a invocação aplicam a mesma política.

É aqui que o gateway se torna mais do que um proxy de acesso. Ele determina o que os agentes podem descobrir, o que podem chamar e a quantidade de contexto irrelevante que transportam. Uma seleção cuidada de ferramentas pode fazer a diferença entre um agente que escolhe a ferramenta certa e outro que vagueia por um catálogo de APIs excessivamente extenso.

Observabilidade, atribuição de custos e proteção a jusante

Como todas as chamadas passam pelo gateway, cada pedido pode emitir um evento estruturado com:

  • o servidor, a ferramenta, o pacote e a equipa responsável;
  • o utilizador, o agente, o serviço e a plataforma envolvidos na chamada;
  • resultado da autorização, código de estado, origem do erro e análise da latência;
  • tamanho do pedido e da resposta; e
  • metadados de custos comunicados a jusante, quando disponíveis.

O gateway também fornece métricas relativas ao volume de pedidos, à latência por ferramenta, às decisões de autorização, aos resultados da atualização do OAuth, às decisões de limitação de taxa, às ligações de streaming e às falhas a montante. A propagação de rastreios permite que as equipas acompanhem uma chamada desde o agente, passando pelo gateway, até ao servidor a jusante.

Isto tem um valor operacional direto; a equipa de segurança pode auditar os acessos, as equipas da plataforma podem identificar agentes problemáticos, os responsáveis pelas ferramentas podem analisar a adoção e os erros, e as equipas de infraestrutura podem atribuir os custos.

Este mesmo mecanismo protege os sistemas a jusante. Os limites de taxa podem ser definidos por servidor, ferramenta, entidade de origem, utilizador, pacote ou tipo de entidade de origem. Os novos limites podem ser testados em modo de simulação antes de serem aplicados, mostrando o que teria sido rejeitado sem afetar o tráfego de produção.

O gateway transforma a governação em dados, em vez de depender de cada equipa para registar os campos corretos e aplicar os limites adequados.

Integração em regime de autoatendimento

Um gateway só funciona se as equipas preferirem utilizá-lo em vez de o contornarem. O registo, a deteção, a filtragem e a gestão de pacotes têm de ser todos em regime de autoatendimento.

Através da interface de utilizador e da API do plano de controlo, as equipas podem registar servidores e agentes MCP, configurar a autenticação, detetar ferramentas, atribuir propriedade, definir filtros, adicionar ferramentas a pacotes e analisar a utilização em produção.

O ciclo de integração do gateway segue os seguintes passos:

  1. Registe o servidor MCP.
  2. Descubra o catálogo de ferramentas do Raw através de tools/list.
  3. Selecione e aprove as ferramentas que a DoorDash pretende disponibilizar.
  4. Definir o modo de autenticação, a titularidade e a política.
  5. Adicione as ferramentas aprovadas a um ou mais pacotes.
  6. Acompanhe o tráfego, a latência, os erros, as decisões de autorização e os custos.

Uma governança que exija a utilização de tickets não é escalável. O caminho mais fácil tem de ser mais simples do que copiar um segredo para um agente e estabelecer ligação diretamente a um servidor.

O que mudou

O portal oferece a cada grupo um benefício diferente:

  • Os criadores de agentes têm à disposição uma integração, um catálogo selecionado e não precisam de se preocupar com a autenticação a jusante, OAuth, gestão de segredos ou encaminhamento por ferramenta.
  • Os proprietários das ferramentas dispõem de um canal de distribuição gerido, com controlo de acesso, exposição aprovada das ferramentas e dados sobre a utilização em produção.
  • As equipas de segurança dispõem de políticas centralizadas, informações confidenciais, autorizações OAuth, revogação e registos de auditoria.
  • As equipas da plataforma ganham vantagem; a identidade, a limitação de taxas, a observabilidade, a qualidade das ferramentas, a atribuição de custos e a experiência do criador melhoram, tudo num único local.
  • Os agentes têm acesso a catálogos mais reduzidos, nomes de ferramentas mais claros, pacotes orientados para tarefas, menos opções irrelevantes e fluxos de ligação recuperáveis.

Adoção

A adoção é o verdadeiro teste de uma plataforma: as equipas só a utilizam se for mais fácil do que o acesso direto. Nesse sentido, o Agent Gateway tornou-se o caminho predefinido para o acesso dos agentes às ferramentas em toda a equipa de engenharia da DoorDash:

  • Estão registados mais de 200 servidores MCP atrás do gateway, expondo, no seu conjunto, milhares de ferramentas organizadas em subconjuntos aprovados e orientados para tarefas específicas, em vez de catálogos em bruto.
  • Mais de 30 agentes e serviços, utilizados por milhares de colaboradores, acedem a essas ferramentas através do gateway e nenhum deles lida com credenciais em bruto. 
  • Todas as semanas, milhões de chamadas de ferramentas são encaminhadas através do Agent Gateway, sendo cada uma delas autenticada, autorizada e registada como um evento de utilização estruturado.
  • A integração é autónoma e rápida. O registo de um novo servidor MCP e das suas ferramentas demora apenas alguns minutos, e associar um agente a uma ferramenta já registada é ainda mais rápido.

Lições aprendidas

A criação e a expansão do gateway redefiniram a forma como encaramos o acesso dos agentes às ferramentas. Há algumas lições que se destacam, não apenas na DoorDash:

  • O MCP resolve a questão da invocação, mas não a da governação. A identidade, as políticas, os segredos, a curadoria, a observabilidade e a revogação tornam-se os aspetos mais complexos.
  • O catálogo de ferramentas descoberto é uma interface, o que significa que os nomes, as descrições, a filtragem, o agrupamento e o público-alvo são importantes.
  • Os pacotes são a unidade ideal para os fluxos de trabalho. Os agentes precisam de conjuntos de ferramentas orientados para tarefas, e não de listas de servidores.
  • A filtragem de ferramentas melhora tanto a segurança como a qualidade dos agentes, ao apresentar um conjunto mais reduzido e claro de ações.
  • As credenciais devem ser armazenadas no gateway, onde podem ser atualizadas, auditadas e revogadas de forma centralizada.
  • A ausência de autorizações OAuth constitui um estado normal, e não uma exceção, no âmbito do protocolo.
  • O canal regulamentado tem de ser de autoatendimento; caso contrário, as equipas recorrerão diretamente a outras vias.

O que se segue

O próximo grande investimento incidirá no reforço da identidade dos agentes e na delegação de poderes aos utilizadores. O modelo-alvo atribui a cada agente uma identidade criptográfica e permite que o gateway emita credenciais delegadas de curta duração, limitadas ao utilizador, ao agente, à tarefa e à ferramenta de destino. Isto confere à pista de auditoria dois titulares reais: o utilizador e o agente.

Estamos também a investir em ferramentas de desenvolvimento, incluindo relatórios de qualidade e segurança, verificações de descrições de ferramentas de risco, deteção de segredos ou informações de identificação pessoal em erros, criação escalonada de servidores, registo automático, deteção dinâmica de ferramentas e fluxos de eventos de chamadas de ferramentas censurados para fins de análise e conformidade.

A descoberta dinâmica dá continuidade ao mesmo tema. Em vez de fornecer a um agente todas as ferramentas num pacote, o gateway pode utilizar o contexto da tarefa, a política e os sinais de utilização para apresentar apenas as ferramentas que provavelmente serão úteis para a tarefa em curso.

Conclusão

O Agent Gateway transforma o acesso às ferramentas dos agentes, que antes exigia um trabalho repetitivo de integração, numa funcionalidade da plataforma partilhada. O MCP facilitou a descrição e a invocação de ferramentas; o gateway torna esse acesso regulamentado, supervisionado, monitorizável e escalável.

Agradecimentos

Introdução

Criámos o Ask DoorDash numa plataforma comum que permite às equipas de cada domínio desenvolver e aperfeiçoar os seus agentes sem terem de reconstruir os sistemas subjacentes. Avaliámos a plataforma com base em dois resultados práticos: a rapidez com que as equipas conseguiam adicionar funcionalidades e domínios e a rapidez com que conseguiam avaliar e implementar melhorias em termos de custos, qualidade e latência.

Lançámos o Ask DoorDash com suporte para restaurantes e mercearias em cerca de dois meses e, desde então, já processou mais de dois milhões de conversas. A adição do Reservations, o nosso terceiro agente de domínio, demorou uma semana, o que é cerca de 10 vezes mais rápido do que a criação dos agentes de domínio iniciais.

O nosso conjunto de testes de avaliação partilhado e os nossos controlos de implementação fornecem às equipas indicadores claros de qualidade à medida que avançam com as alterações para produção. No prazo de uma semana após o lançamento de um novo LLM, avaliámo-lo e implementámo-lo, reduzindo a latência p50 em 35 % sem qualquer diminuição nos índices de qualidade. Uma atualização subsequente do modelo reduziu a latência p50 em mais 40 %.

Este artigo explica como escolhemos o que deveria fazer parte da plataforma, como os seus componentes se articulam entre si e as escolhas que estiveram na base dessas decisões. Segue-se à nossa visão geral de engenharia, à nossa análise aprofundada sobre inteligência e à nossa análise aprofundada sobre avaliação. Seguir-se-á uma análise aprofundada sobre a experiência do utilizador.

Como escolhemos o que padronizar

Só centralizávamos uma funcionalidade quando vários domínios precisavam dela e se implementações separadas pudessem causar problemas de fiabilidade ou operacionais. A orquestração, a memória, o acesso aos modelos, o rastreio, a infraestrutura de avaliação e os controlos de implementação cumpriam esse critério. As equipas de domínio mantiveram a responsabilidade pelas instruções, competências, ferramentas, critérios de avaliação e escolhas de modelos que definem os seus agentes.

Sempre que existia uma norma da indústria adequada, adotámo-la. O Agent2Agent (A2A) definiu a forma como os agentes comunicam, enquanto o Google Agent Development Kit (ADK) forneceu a estrutura para os criar e executar. Estas normas limitaram, por vezes, as nossas opções de conceção, mas proporcionaram às equipas contratos comuns e pouparam-nos de ter de desenvolver equivalentes proprietários.

No caso de problemas recorrentes para os quais não existia uma norma adequada, criámos nós próprios a capacidade necessária. Uma regressão no código partilhado poderia afetar vários agentes, pelo que os controlos de avaliação e implementação eram obrigatórios. Todas as alterações partilhadas tinham de passar por verificações de qualidade comuns e por medidas de segurança de lançamento.

Consultar a arquitetura da DoorDash

A decisão arquitetónica central consistiu em determinar o que cada agente deveria partilhar e o que cada domínio deveria controlar. Criámos um percurso de execução partilhado em torno de agentes especializados, controlados por cada domínio. Um único agente de uso geral tornar-se-ia cada vez mais difícil de compreender à medida que assumisse mais responsabilidades, enquanto pilhas de agentes totalmente independentes duplicariam a infraestrutura e gerariam experiências inconsistentes.

Como mostra a Figura 1, cada pedido entra através do Gateway. O Gateway autentica o utilizador, reúne o contexto do ponto de entrada e faz a tradução entre as interfaces HTTP e de streaming do cliente e o protocolo A2A da plataforma. Em seguida, encaminha o pedido para o Orchestrator, que seleciona o agente de domínio para cada turno, preservando a continuidade à medida que a conversa transita entre domínios. O agente selecionado carrega as competências adequadas e utiliza ferramentas do Model Context Protocol (MCP) para interagir com os serviços existentes da DoorDash.

Para além desse caminho de solicitação, a plataforma disponibiliza o estado da sessão, memória, artefactos, acesso a modelos, rastreio, infraestrutura de avaliação e controlos de implementação. Os agentes de domínio utilizam estes serviços comuns, mantendo ao mesmo tempo o controlo sobre as suas instruções, competências, ferramentas e critérios de avaliação.

Figura 1: O Ask DoorDash separa o comportamento dos agentes específico de cada domínio das capacidades partilhadas de execução e produção utilizadas em todo o sistema.

Uma porta de entrada para experiências responsivas e multimodais

Os gateways dos clientes da DoorDash foram concebidos para APIs que devolvem uma resposta completa rapidamente. Os agentes funcionam de forma diferente. O primeiro texto pode estar pronto enquanto o agente ainda está a aceder a ferramentas, e a resposta final pode combinar texto descritivo com cartões interativos de lojas ou artigos. Precisávamos de processar esse trabalho em tempo real sem ter de explicar a cada cliente como os agentes comunicam.

O Gateway encarrega-se desta conversão. Autentica o utilizador, acrescenta contexto sobre onde a conversa teve início e converte os pedidos HTTP dos clientes em pedidos A2A. No caminho de retorno, utiliza o SDK de IA da Vercel para enviar atualizações de texto e conteúdos dos widgets aos clientes através de Server-Sent Events (SSE). Os clientes apresentam as atualizações à medida que estas chegam, para que os utilizadores possam acompanhar o progresso enquanto o agente conclui a sua vez.

A criação e a operação do Gateway exigiram algum trabalho, mas permitiram concentrar tarefas que, de outra forma, seriam duplicadas em todos os clientes da DoorDash. Os agentes podem ser alterados no âmbito de um único contrato de cliente estável, sem necessidade de lançamentos coordenados por parte dos clientes. Um novo agente de domínio reutiliza o percurso de autenticação e transmissão já existente, em vez de se integrar separadamente com cada aplicação.

Um assistente, agentes especializados na área

Uma conversa pode passar de um domínio para outro sem aviso prévio. Um utilizador pode começar por dizer «Quero que me entreguem uma tarte de frango em menos de 30 minutos» e, em seguida, decidir: «Na verdade, quero fazê-la em casa». O primeiro pedido pertence ao domínio «Restaurantes» e o segundo ao domínio «Mercearia», mas a experiência tem de parecer uma única conversa.

Experimentámos uma arquitetura com um único agente, mas os domínios «Restaurante», «Mercearia» e «Reservas» dependem de ferramentas, políticas e critérios de avaliação diferentes. A sua combinação tornaria o agente mais difícil de testar e obrigaria todos os domínios a seguirem o mesmo ciclo de lançamento. Por isso, cada domínio dispõe de um agente especializado. O Orchestrator analisa a conversa e encaminha cada resposta para o agente adequado através do A2A.

Esse encaminhamento aumenta a latência e os tokens de entrada, mesmo quando a conversa permanece no mesmo domínio. Para reduzir este custo, o Orchestrator atribui as respostas subsequentes ao agente do domínio selecionado. Esta atribuição permite que esse agente trate diretamente os pedidos subsequentes, sem necessidade de mais uma etapa de encaminhamento. Se a conversa mudar de direção, o agente do domínio reconhece a mensagem fora do âmbito e devolve o controlo ao Orchestrator. O Orchestrator reencaminha a solicitação dentro da mesma vez, de forma invisível para o utilizador.

Figura 2: O «pinning» evita uma chamada ao Orchestrator nos turnos seguintes, permitindo, ainda assim, que a conversa transite entre domínios.

As competências mantêm o contexto e os custos dentro dos limites

Os agentes especializados impediram que os domínios «Restaurante», «Mercearia» e «Reservas» partilhassem uma única janela de contexto enorme. No entanto, à medida que cada agente ganhava novas capacidades, o mesmo problema de contexto surgiu dentro de cada domínio. As novas funcionalidades adicionavam instruções e ferramentas a cada turno, mesmo quando esse turno nunca as utilizava. Isso aumentou o custo dos tokens de entrada, e as instruções sobrepostas ou contraditórias confundiam o agente.

Adicionámos suporte a competências ao nosso sistema para modularizar instruções e ferramentas. Em cada turno, o agente carrega apenas o que é relevante. Um utilizador pode começar por dizer: «Encontra-me um restaurante tailandês com boas avaliações que faça entregas em menos de 30 minutos», e depois dizer: «Mostra-me o menu do primeiro e adiciona pad see ew ao meu carrinho.» Ambos os pedidos ficam a cargo do agente «Restaurante», mas o primeiro carrega a competência de pesquisa e descoberta. O segundo carrega a competência de encomenda pelo carrinho, que trata da navegação pelo menu e das ações no carrinho.

O carregamento dinâmico acrescenta um problema de seleção. O seletor tem de reconhecer quando uma capacidade é necessária sem carregar contexto não relevante com demasiada frequência; por isso, avaliamos a seleção de competências como parte do comportamento do agente. A complexidade adicional valeu a pena, pois as equipas puderam adicionar capacidades sem ter de expandir o contexto de cada turno.

Para avaliar o efeito, contámos os tokens presentes nas instruções básicas e nas instruções carregadas da competência do agente. Excluímos o histórico de conversas, as mensagens dos consumidores, os esquemas das ferramentas e os resultados das ferramentas. A mediana das respostas no âmbito da competência utilizou menos de metade dos tokens de instrução em comparação com o prompt do sistema monolítico.

AgenteInstruções básicas e sobre as habilidades, com todas as habilidades carregadasMédia de instruções com âmbito de competências por turnoRedução
Restaurante~42 000 fichas

~20 000 fichas50%+
Mercearia~25 000 fichas~10 000 fichas60%

Acesso seguro e reutilizável aos serviços através do MCP

O Ask DoorDash necessita de acesso aos serviços do DoorDash para pesquisar lojas e artigos, consultar ementas, gerir carrinhos de compras e agir em nome do utilizador. As APIs subjacentes a estas operações pressupõem código de aplicação determinístico. Um LLM que seleciona operações em tempo de execução necessita de uma interface mais restrita. Expor as APIs diretamente obrigaria o modelo a interpretar interfaces de baixo nível. Codificar permissões e regras de negócio apenas no prompt acrescentaria contexto sem garantir a sua aplicação.

Criámos uma camada partilhada do Protocolo de Contexto do Modelo (MCP) entre os agentes e as APIs da DoorDash. Cada ferramenta MCP expõe uma operação específica com as entradas e saídas de que o modelo necessita. O modelo escolhe qual a ferramenta a chamar. Um código determinístico valida cada pedido e aplica as permissões e regras de negócio antes de a chamada chegar ao serviço subjacente.

As instruções ajudam o modelo a escolher a operação correta, mas essa orientação é meramente consultiva. A validação e a aplicação das regras são executadas no código da ferramenta em cada chamada, criando um limite de segurança estável à medida que as instruções e os modelos mudam.

A conceção de ferramentas requer equilíbrio. Uma ferramenta demasiado abrangente pode apresentar demasiadas opções ao modelo, enquanto uma ferramenta demasiado restrita pode transformar uma tarefa numa longa cadeia de chamadas. O nosso servidor MCP partilhado disponibiliza agora mais de 60 ferramentas em fluxos de trabalho públicos e internos de agentes. Um novo agente seleciona as ferramentas de que necessita a partir dessa biblioteca, e as melhorias na validação, telemetria ou integração de serviços beneficiam todos os agentes que as utilizam.

Figura 3: As instruções influenciam o que o modelo solicita; o código da ferramenta MCP determina o que pode ser executado.

Pronto para produção por predefinição

A ADK forneceu-nos os elementos básicos para a criação de um agente, incluindo instruções, ferramentas, callbacks, sessões e integração de modelos. Os agentes da DoorDash também necessitavam de rastreio distribuído, acesso a modelos, estado duradouro e controlos de implementação. Sem uma camada partilhada, cada equipa de domínio teria de tomar essas decisões e gerir a infraestrutura resultante de forma independente.

Criámos módulos reutilizáveis com base no ADK para funcionalidades que devem funcionar da mesma forma em todos os agentes. As equipas de domínio continuam a escolher as suas instruções, ferramentas e configuração do modelo. A plataforma liga essas escolhas aos sistemas necessários para executar os agentes de forma fiável em produção.

O rastreio é um exemplo. Uma equipa ativa essa funcionalidade através da configuração, e o SDK partilhado propaga um ID de rastreio através de chamadas A2A, ferramentas MCP e serviços DoorDash a jusante. Os engenheiros podem acompanhar uma solicitação ao longo do Orchestrator, dos agentes de domínio e das chamadas às ferramentas, em vez de terem de reunir registos de sistemas separados. Os mesmos dados de rastreio servem de apoio à depuração e à avaliação. A disponibilização do rastreio através da plataforma poupa cerca de um mês de trabalho de observabilidade por cada lançamento de um novo agente.

O acesso aos modelos segue o mesmo princípio. As equipas de domínio escolhem quais os modelos que os seus agentes utilizam, enquanto a plataforma padroniza a forma como esses modelos são invocados, rastreados e protegidos por comportamentos de fallback. As equipas podem avaliar e adotar novos modelos sem terem de reescrever integrações específicas de cada fornecedor. Esse caminho comum permitiu as rápidas atualizações de modelos e as melhorias na latência descritas anteriormente.

Estado partilhado para conversas fiáveis

As primeiras tentativas de desenvolver produtos com agentes da DoorDash, em 2025, demonstraram a rapidez com que a experiência se deteriora quando o estado do sistema não é fiável. Um agente podia responder bem a um pedido, mas depois esquecer ou utilizar incorretamente informações de uma troca de mensagens anterior. Resolver esse problema exigiu mais do que apenas adicionar o histórico da conversa ao prompt.

O Ask DoorDash utiliza três tipos de estado. O estado de sessão acompanha a conversa ativa e o trabalho já concluído no âmbito dessa conversa. A memória conserva informações que podem ser úteis em conversas posteriores, tais como as preferências do utilizador. Os artefactos contêm resultados estruturados que os agentes criam e atualizam, incluindo listas de compras e cartões interativos. Cada um tem um período de validade e um padrão de acesso diferentes.

Os projetos anteriores de agentes do DoorDash implementavam estas funcionalidades de forma independente. Isso duplicava o trabalho de persistência e fazia com que a fiabilidade dependesse das escolhas de cada equipa. Centralizámos essas funcionalidades nos Serviços de Agentes Geridos, que fornecem APIs compatíveis com o ADK para sessões, memória e artefactos. Os agentes de domínio utilizam as mesmas interfaces sem terem de gerir os seus próprios sistemas com estado.

A centralização do estado continua a exigir regras de armazenamento e de ciclo de vida distintas para os dados de sessão, a memória de longo prazo e os artefactos. O Managed Agent Services mantém esses limites num único local. Cada domínio continua a decidir quais as informações que a sua experiência deve guardar e recuperar.

Os Serviços de Agentes Geridos e a arquitetura de memória são abordados com mais pormenor na Parte II.

Mantenha-se informado com as actualizações semanais

Subscreva o nosso blogue de Engenharia para receber actualizações regulares sobre todos os projectos mais interessantes em que a nossa equipa está a trabalhar

O que a plataforma alterou

O módulo «Reservas» constituiu um teste concreto da plataforma. A equipa reutilizou o fluxo de produção já em funcionamento para os módulos «Restaurante» e «Mercearia» e lançou o suporte para «Reservas» numa semana, cerca de 10 vezes mais rápido do que se tivesse de criar os agentes de domínio iniciais.

As equipas de domínio mantêm a responsabilidade pelo comportamento dos agentes e pelos critérios de qualidade. A plataforma fornece o conjunto de ferramentas de avaliação, as ferramentas MCP, o rastreio, o acesso aos modelos e os controlos de implementação, para que as melhorias nesses componentes cheguem a todos os agentes que os utilizam.

A infraestrutura partilhada aumenta o alcance dos erros. Uma falha pode afetar vários agentes, e uma abstração prematura pode obrigar produtos diferentes a assumirem o mesmo formato. Só padronizamos uma funcionalidade depois de vários domínios a necessitarem dela e de implementações separadas poderem criar problemas de fiabilidade ou operacionais.

Junte-se a nós

Se a criação de plataformas de agentes e de IA orientada para o utilizador em grande escala lhe parece interessante, consulte as nossas vagas abertas na área de engenharia em careersatdoordash.com.