paint-brush
Esta prática torna os LLMs mais fáceis de construir, testar e dimensionarpor@andrewproton
3,006 leituras
3,006 leituras

Esta prática torna os LLMs mais fáceis de construir, testar e dimensionar

por Andrew Prosikhin7m2025/04/07
Read on Terminal Reader

Muito longo; Para ler

A modularização do prompt LLM permite que você introduza mudanças com segurança no seu sistema ao longo do tempo. Como e quando fazer isso é descrito abaixo.
featured image - Esta prática torna os LLMs mais fáceis de construir, testar e dimensionar
Andrew Prosikhin HackerNoon profile picture

Isto faz parte de uma série contínua: veja o primeiro e o segundo posts.

Princípio III: Modularize os Prompts

Uma monstruosidade hedionda. Todo engenheiro experiente já viu uma: código tão vasto, de alto risco e difícil de entender que ninguém ousa tocá-lo. Não há testes unitários, cada mudança é motivo para um pequeno ataque cardíaco. Os únicos que se aventuram perto dele são os veteranos - aqueles que estavam por perto quando o monstro foi construído e só chegam perto quando não há alternativa. É obsoleto, não modularizado e as dependências estão desatualizadas. O componente é perigoso demais para ser alterado seriamente.


Lembro-me da primeira monstruosidade que encontrei. Uma função de 5.000 linhas que era central para as operações de um negócio que valia centenas de milhões de dólares; quase ninguém tinha confiança para tocá-la. Quando ela quebrou, equipes inteiras foram acordadas no meio da noite. Todo o desenvolvimento na empresa foi desacelerado por causa de uma dependência desse componente-chave. Milhões de dólares foram gastos tentando gerenciar o monstro.


O que tudo isso tem a ver com os prompts do LLM? Eles também podem se tornar monstruosidades! Tão assustadores de mudar, que ninguém os toca. Ou, inversamente, as equipes tentam consertá-los e causam uma avalanche de incidentes.


O que os clientes precisam

Os clientes não querem pagar por software que funciona corretamente apenas às terças e quintas-feiras; eles exigem confiabilidade constante e um fluxo de novos recursos. Ao construir sistemas de alta confiabilidade de longo prazo, é essencial permitir que o aplicativo evolua, mantendo as luzes constantemente acesas. Isso se aplica a aplicativos alimentados por Gen AI tanto quanto a softwares tradicionais.


Então, como você obtém um aplicativo saudável alimentado por IA e não uma monstruosidade? Há mais de uma dúzia de abordagens, todas abordadas nesta série. Todas elas começam com um princípio: em vez de um prompt gigantesco, você quer vários prompts menores focados, cada um com o objetivo de resolver um único problema.


O que é modularização

Modularização é a prática de dividir um sistema complexo em componentes menores, autocontidos e reutilizáveis. Na engenharia de software tradicional, isso significa escrever funções, classes e serviços que lidam com uma tarefa específica. No contexto da engenharia de prompts para LLMs, modularização significa dividir um prompt grande e monolítico em prompts menores e focados — cada um projetado para executar uma tarefa única e bem definida.


Benefícios da modularização

A modularização permite que você introduza mudanças com segurança no seu sistema ao longo do tempo. Sua importância cresce quando:

  • O período de tempo em que o aplicativo será mantido aumenta.
  • O número e a complexidade dos recursos que devem ser adicionados aumentam.
  • Os requisitos de confiabilidade do sistema ficam mais rigorosos.

Todas essas dimensões precisam ser entendidas ao planejar o sistema.


Mas como especificamente a modularização ajuda a manter o sistema? Os principais benefícios são descritos abaixo.

Redução de Risco

O desempenho do prompt LLM é inerentemente instável. Sua natureza é tal que qualquer mudança pode afetar a saída de maneiras imprevisíveis. Você pode gerenciar esse risco dividindo grandes prompts em componentes, onde uma mudança pode afetar apenas o desempenho de uma parte do sistema. Mesmo se um prompt estiver quebrado, o resto do sistema operará como antes da mudança.


Mas e se os prompts operarem como uma cadeia? Quebrar um componente ainda não quebraria a cadeia? Sim, quebraria, mas o dano ainda é reduzido neste cenário. Uma saída errônea em uma cadeia de prompts pode fornecer aos prompts downstream entradas defeituosas, mas cada componente ainda operaria como antes da mudança no conjunto de entradas válidas. Compare isso com a alteração de um prompt gigante - a mudança pode (e vai!) afetar cada bit de lógica codificado naquele prompt. Você não quebrou um aspecto do sistema - você potencialmente quebrou cada parte dele.


(Operar cadeias de prompts com segurança é um capítulo futuro da série. Você precisa planejar vários tipos de falhas e ter planos de contingência. Mas isso está além do escopo aqui)

Testabilidade melhorada

Qualquer um que tenha escrito testes unitários sabe que uma função simples que faz uma única coisa é BEM mais fácil de testar do que uma função complexa que tenta fazer muitas coisas diferentes. O mesmo se aplica a prompts - um prompt pequeno e focado pode ser testado muito mais completamente, tanto manualmente quanto de forma totalmente automatizada.

Melhor desempenho

Um amplo conjunto de evidências mostra que prompts mais curtos tendem a ter melhor desempenho do que os mais longos: 1 , 2 , 3 .


Pesquisas sobre os efeitos da multitarefa no desempenho do prompt são mais mistas: 4 , 5 . Um prompt perfeitamente otimizado pode, sob as circunstâncias certas, realizar multitarefas. Na prática, porém, é muito mais fácil otimizar prompts focados, onde você pode rastrear o desempenho ao longo de uma única dimensão principal. Você deve almejar prompts mais focados sempre que possível.

Facilidade de compartilhamento de conhecimento

Explicar as complexidades de um super prompt com 3 mil palavras para um novo membro da equipe é uma jornada. E não importa o quanto você explique, os únicos que têm uma noção dessa fera serão os autores contribuintes.


Um sistema de prompts, com cada parte relativamente simples, pode ser integrado muito mais rápido; os engenheiros começarão a ser produtivos mais cedo.

Otimização de Custos

Ao usar diferentes modelos em diferentes partes do sistema, você pode obter economias significativas de custo e latência sem afetar a qualidade da resposta.


Por exemplo, um prompt que determina o idioma de entrada não precisa ser particularmente inteligente - ele não requer seu modelo mais recente e caro. Por outro lado, o prompt que gera a resposta com base na documentação pode se beneficiar de uma cadeia de raciocínio de pensamento incorporada em modelos de ponta.


Quando NÃO modularizar

A maioria dos aplicativos baseados em software exige a adição segura de recursos por longos períodos de tempo. Há, no entanto, uma exceção. Os aplicativos de protótipo não devem ser mantidos por muito tempo; eles não receberão novos recursos e não são feitos para alta confiabilidade. Portanto, não perca tempo com modularização ao construir protótipos. Na verdade, a maioria dos padrões desta série não se aplica a aplicativos de protótipo. Ao construir um protótipo - vá rápido, verifique as incógnitas críticas e então jogue o código fora.


Outra consideração é saber quando parar de modularizar. Há sobrecarga para gerenciar prompts extras e se os benefícios de uma modularização adicional forem baixos, você deve parar de dividir o sistema ainda mais.


Infraestrutura para modularização

Se modularizar prompts fosse trivial - todo mundo estaria fazendo isso. Para gerenciar muitos prompts em um sistema, você precisa investir em infraestrutura - sem ela, você terá caos. Aqui estão os requisitos mínimos para a infraestrutura de prompt do LLM:

  • Capacidade de adicionar prompts rapidamente e sem dor de forma padronizada. Particularmente importante quando os prompts são carregados de fora da base de código. Veja Princípio II: Carregue Prompts com Segurança (Se Você Realmente Precisar) .

  • Capacidade de implantar prompts de forma automatizada.

  • Capacidade de registrar e monitorar entradas/saídas de prompts individuais.

  • Capacidade de adicionar testes automatizados que abrangem prompts.

  • Uma maneira de rastrear facilmente os gastos de token/$ em vários prompts.


Estudo de caso

Vamos ver como a construção de um sistema alimentado por Gen AI funciona na prática com e sem modularização.

Sem modularização

Você está construindo um aplicativo de suporte técnico e está determinado a implementá-lo com um único prompt. Na versão mais simples, você pode imaginar um prompt monolítico que gera respostas enquanto carrega documentação relevante por meio do RAG .

Sistema não modularizado

Parece legal e fácil, certo? Mas conforme você adiciona recursos, surgem problemas com essa arquitetura:

  • Você quer responder a mensagens em uma lista fixa de idiomas, mas não lidar com outros. Para conseguir isso, você adiciona instruções de prompt para responder somente em certos idiomas e fazer com que o LLM retorne o campo “idioma” para fins de relatórios.

  • Você quer que todas as conversas sejam classificadas. Adicione um campo “label” à saída do prompt.

  • Quando o usuário estiver insatisfeito - encaminhe o caso para o suporte humano. Adicione a variável de saída “escalate_to_human” junto com as instruções no prompt.

  • Precisa de uma tradução de todas as mensagens enviadas para auditoria interna. Retorne o campo “translated” com uma mensagem em inglês.

  • Precisa de proteção para garantir que o aplicativo nunca pergunte aos usuários sobre sua localização e em quem eles votaram na última eleição. Adicione instruções rápidas e teste manualmente.

  • Precisa de um resumo para cada conversa? Adicione o campo “summary” a cada saída.


Talvez você esteja começando a ver o problema - este prompt agora tem seis saídas. Testá-lo será um pesadelo. Você adiciona suporte para outro idioma e, de repente, seu aplicativo começa a retornar o resumo em espanhol em vez de inglês. Por quê? Quem sabe, as saídas do LLM são instáveis, então alterar o prompt tem resultados imprevisíveis.


Parabéns - você criou um monstro! Com o tempo, ele crescerá e causará ainda mais dor.

Com modularização

Sistema modularizado

Tanto o Prompt Chain quanto um prompt de classificação totalmente separado são usados. O prompt grande original é modularizado tanto quanto possível.

Um prompt detecta o idioma, um fornece a tradução, um determina se o usuário está chateado e escala para humanos, o prompt de resposta gera a resposta, o guardrail verifica a conformidade da resposta. As saídas de um prompt são encadeadas para serem entradas do próximo; o código tradicional pode operar entre esses prompts para, por exemplo, verificar a elegibilidade do idioma, sem envolver LLMs.


Uma alteração ainda pode interromper um determinado prompt, mas os riscos são bastante reduzidos porque:

  • Uma alteração em uma parte não corre o risco de quebrar todas as partes da lógica do aplicativo.
  • Testar é muito mais fácil e as chances de detectar falhas precocemente são altas.
  • Cada prompt é relativamente simples, por isso é mais fácil de entender e há menos probabilidade de causar danos com uma alteração.
  • As mudanças são mais fáceis de revisar.

Você obtém todos os benefícios da Gen AI, mas os riscos são muito reduzidos. Além disso, você pode usar modelos mais baratos para alguns componentes para economizar dinheiro.


Conclusão

A modularização permite isolar erros, melhorar a manutenibilidade e construir um sistema mais confiável. Mesmo aplicativos de tamanho moderado terão dezenas, se não centenas, de prompts de componentes. Divida os prompts até que cada um execute uma única tarefa e até que os benefícios da modularização adicional sejam superados pela complexidade operacional adicional. A modularização de seus prompts é uma necessidade se seus aplicativos orientados por IA devem permanecer confiáveis e continuar a adicionar recursos a longo prazo. Já existem muitos sistemas "monstros" por aí - tome cuidado para não criar novos!


Se você gostou desta série, inscreva-se para receber mais postagens.