12-Factor Agents: padrões confiáveis para aplicações com LLM
(github.com/humanlayer)- 12-Factor Agents é um guia público que organiza 12 princípios para criar software baseado em LLM confiável o suficiente para ser oferecido a clientes em produção
- A visão é que um bom agente se parece menos com “dar um prompt e um conjunto de ferramentas e repetir até atingir o objetivo” e mais com uma estrutura que insere etapas de LLM nos pontos necessários de um software majoritariamente determinístico
- Em um loop de agente típico, o LLM decide a próxima etapa por meio de uma chamada de ferramenta em JSON estruturado, o código determinístico executa essa etapa, adiciona o resultado à janela de contexto e repete até a conclusão
- Muitos criadores de SaaS começam rapidamente com frameworks e chegam a uma qualidade de 70–80%, mas isso não basta para funcionalidades voltadas ao cliente, levando-os a fazer engenharia reversa de framework, prompt e fluxo, ou a recomeçar do zero
- A forma mais rápida de entregar software de IA de alta qualidade aos clientes não é adotar um framework de agentes completo, mas integrar conceitos de construção de agentes pequenos e modulares ao produto existente
O problema que motiva o projeto
- 12-Factor Agents é um projeto público que busca aplicar o espírito do 12 Factor Apps aos princípios de construção de aplicações com LLM
- A pergunta central é: “quais princípios podem ser usados para construir software baseado em LLM realmente bom, confiável o suficiente para clientes em produção?”
- O projeto parte da experiência de testar vários frameworks de agentes e conversar com fundadores técnicos dentro e fora da YC
- Muitos fundadores estão construindo sua própria stack em vez de usar pesadamente frameworks em agentes voltados a clientes em produção
- Muitos produtos chamados de “AI Agent” são vistos menos como totalmente agentivos e mais como uma mistura apropriada de etapas com LLM dentro de código majoritariamente determinístico
Visão básica sobre agentes
- Um bom agente não é composto apenas pelo padrão “prompt, conjunto de ferramentas e repetição até atingir o objetivo”
- Software pode ser visto como um grafo dirigido (DG), e esse é um dos motivos pelos quais programas eram historicamente representados como fluxogramas
- Há cerca de 20 anos, orquestradores de DAG começaram a ser amplamente usados
- A promessa dos agentes é que, em vez de o engenheiro codificar todas as etapas e exceções, basta fornecer o objetivo e as transições, deixando o LLM decidir o caminho em tempo real
- A expectativa é escrever menos código, recuperar-se de erros e permitir que o LLM encontre novas soluções
- Mas a avaliação é que, na prática, essa abordagem não funciona tão bem quanto o esperado
Modelo de execução do loop de agente
- O loop básico de um agente consiste em julgamento do LLM → execução da ferramenta → adição do resultado ao contexto → repetição
- O fluxo é o seguinte
- O contexto inicial é um evento de partida, como uma mensagem do usuário, uma execução de cron ou um webhook
- O LLM decide a próxima etapa ou se o processo foi concluído
- A próxima etapa é emitida como uma chamada de ferramenta em JSON estruturado
- Um código determinístico executa a chamada de ferramenta
- O resultado da execução é adicionado à janela de contexto
- Se a próxima etapa for
done, a resposta final é retornada
- O exemplo no README mostra um loop em que a próxima etapa é decidida com
llm.determine_next_step(context), executada comexecute_step(next_step)e então o resultado é anexado ao contexto
Por que são necessários 12 princípios
- Ao criar a HumanLayer, os autores conversaram com pelo menos 100 criadores de SaaS, em geral fundadores técnicos tentando tornar seus produtos existentes mais agentivos
- A jornada típica é a seguinte
- Decidem criar um agente
- Definem o desenho do produto, o mapeamento de UX e o problema a resolver
- Escolhem um framework específico para se mover mais rápido
- Chegam a um nível de qualidade de 70–80%
- Percebem que 80% de qualidade não é suficiente para a maioria das funcionalidades voltadas ao cliente
- Para passar de 80%, precisam fazer engenharia reversa de framework, prompts e fluxos
- No fim, acabam recomeçando do zero
- A crítica não pretende atacar frameworks nem seus criadores; o texto afirma que frameworks aceleraram o ecossistema de IA
- MCP não é tratado, e os exemplos usam principalmente TypeScript, mas os princípios também se aplicam a Python e outras linguagens
Os 12 fatores
- A visão é que, mesmo com LLMs se tornando cada vez mais poderosos, as técnicas centrais de engenharia para tornar software baseado em LLM mais confiável, escalável e fácil de manter continuarão relevantes
- Os 12 fatores são os seguintes
- Factor 1: Natural Language to Tool Calls: linguagem natural para chamadas de ferramenta
- Factor 2: Own your prompts: assuma controle dos seus prompts
- Factor 3: Own your context window: assuma controle da sua janela de contexto
- Factor 4: Tools are just structured outputs: ferramentas são apenas saídas estruturadas
- Factor 5: Unify execution state and business state: unifique estado de execução e estado de negócio
- Factor 6: Launch/Pause/Resume with simple APIs: iniciar/pausar/retomar com APIs simples
- Factor 7: Contact humans with tool calls: contate pessoas com chamadas de ferramenta
- Factor 8: Own your control flow: assuma controle do seu fluxo de controle
- Factor 9: Compact Errors into Context Window: compacte erros na janela de contexto
- Factor 10: Small, Focused Agents: agentes pequenos e focados
- Factor 11: Trigger from anywhere, meet users where they are: dispare de qualquer lugar e encontre os usuários onde eles estão
- Factor 12: Make your agent a stateless reducer: transforme seu agente em um reducer sem estado
- Como conselho adicional, inclui-se Factor 13: Pre-fetch all the context you might need
Forma de aplicação e materiais relacionados
- A avaliação é que adotar um framework inteiro e acabar indo para uma reescrita praticamente greenfield pode ser contraproducente
- Embora a adoção de um framework possa oferecer muitos dos princípios que tornam um agente bom, o caminho mais rápido para entregar software de IA de alta qualidade aos clientes é integrar conceitos menores e modulares ao produto existente
- Esses conceitos modulares podem ser definidos e aplicados até por engenheiros de software experientes sem background em IA
- Como materiais relacionados, o texto aponta Building Effective Agents, da Anthropic, Prompts are Functions, Library patterns: Why frameworks are evil, The Wrong Abstraction
- O conteúdo e as imagens são disponibilizados sob licença CC BY-SA 4.0, e o código sob Apache 2.0
1 comentários
Opiniões no Hacker News
Os pontos deste texto são excelentes. Também há uma lista de aprendizados que compilei depois de experimentar isso na prática por alguns anos: https://mg.dev/lessons-learned-building-ai-agents/
Se eu fosse acrescentar algo hoje, o principal seria: seja dono do loop de planejamento no nível mais baixo. Planejamento dinâmico é OK, mas você precisa ter seu próprio loop observar-orientar-decidir-agir (OODA), com heurísticas (por exemplo, pontuação) para determinar se está convergindo para a resposta, ou condições de saída (por exemplo, número máximo de iterações)
Também vale considerar colocar um motor de workflow. Em vez de fazer o modelo manter e avançar implicitamente um workflow ao longo de vários turnos, é melhor fazer o modelo criar uma especificação de workflow a ser executada por esse motor e, em cada etapa, chamar o modelo de novo quando necessário
Fico curioso sobre como bibliotecas como DSPY se encaixam no factor-2: https://dspy.ai/, https://github.com/humanlayer/12-factor-agents/blob/main/con...
Ao ler, vi uma parte dizendo que prompts são gerados com BAML. Pessoalmente, não achei fácil escrever manualmente prompts para extrair informações estruturadas de dados não estruturados, e até agora tive uma experiência bem boa com DSPY
Se a ideia é usar o prompt bruto do BAML, fico curioso sobre como você vê a abordagem de usar o prompt bruto do DSPY: https://dspy.ai/tutorials/observability/#using-inspect_histo...
Não concordo totalmente com este texto, https://www.chrismdp.com/beyond-prompting/, mas a comparação cartões perfurados → assembly → C → linguagens de alto nível é bem útil aqui
Ainda não sei quando a abstração adequada vai aparecer, e não vejo LangChain ou DSPY como a “linguagem de programação C” da IA ainda. Talvez um dia sejam
Por enquanto, eu usaria uma bancada de trabalho de baixo nível, na qual posso inspecionar tokens, mudar a ordem de tokens especiais como system/user/JSON e me ajustar rapidamente às peculiaridades de novos modelos, sem ficar preso esperando suporte de bibliotecas
Um texto antigo e pouco conhecido sobre padrões de frameworks ressoou comigo ao longo de toda a minha carreira, e acho que também se aplica aqui: https://tomasp.net/blog/2015/library-frameworks/
Pelos motivos descritos no texto e outros mais, especialmente em um momento como o atual, em que tudo muda rapidamente, é melhor usar LLMs como bibliotecas do que como frameworks. Só que frameworks são mais sexy, mais fáceis de vender e levam a lock-in e serviços complementares, então são promovidos com mais força
Criei e acabei de abrir o código do nosso próprio “framework de agentes de IA”, o SecAI, baseado no modelo de atores, máquinas de estado e programação orientada a aspectos: https://github.com/pancsta/secai
Gosto especialmente do nº 5, “unifique estado de execução e estado de negócio”, e do nº 8, “seja dono do fluxo de controle”. O núcleo do SecAI é uma biblioteca de fluxo de controle em grafo; ele usa multigrafos em vez de DAGs, e as chamadas a LLM são embutidas nos nós do grafo
O fluxo é reforçado com negociação, cancelamento e relações com estado, funcionando de forma mais orgânica. Ele também inclui ferramentas de desenvolvimento dedicadas que frequentemente faltam em outros frameworks (dbg, repl, svg), programação assumindo falhas, inspeção detalhada de todas as etapas, exportação automática de dados (métricas, traces, logs, SQL) e integração simples (bash)
Também publiquei a primeira demo técnica, que mostra as ferramentas de desenvolvimento com uma implementação de referência de deepresearch portada do AtomicAgents: https://youtu.be/0VJzO1S-gV0
Os botões Send/Stop são basicamente o “Factor 6. iniciar/pausar/retomar com uma API simples”, e também há transparência de rede, então é escalável
Eu acrescentaria mais um ponto: é preciso planejar o custo quando houver escala
Esses sistemas não são baratos quando escalam, então, se alguma tarefa puder ser tratada por um componente determinístico, é melhor tentar esse caminho primeiro. Isso não só reduz alucinações e latência, como também pode fazer uma grande diferença no lucro final
Para facilitar o acompanhamento de cada princípio, seria bom haver uma narrativa consistente atravessando os vários factors. Acho que seria mais fácil entender se fosse usado continuamente um exemplo de sistema próximo da realidade
Quero continuar evoluindo isso publicamente junto com a comunidade
Excelente. Já aprendi 80% na marra, e os 20% restantes parecem valer a leitura
Pessoalmente, tive sucesso com a combinação LangGraph + esquema pydantic. Também fico curioso para saber quais ferramentas outras pessoas acharam úteis
Este texto saiu exatamente no momento em que eu precisava
Estou experimentando uma ideia de sandbox audiovisual. É algo como vvvv, mas muito mais simples e com apenas o mínimo de funcionalidades: https://kfs.mkj.lt/#audiovisllm, https://vvvv.org/
A ideia é inserir “nós” de LM ou redes neurais locais simples que assumem uma tarefa específica e têm uma saída bem limitada. Por isso, exemplos como “question -> answer: float” são muito atraentes. No meu caso, algumas das perguntas podem ser bem abstratas, mas pipelines em várias etapas também são interessantes
Não li em detalhes, mas quero usar o máximo possível de código determinístico e recorrer ao LLM o mínimo possível
Acho que isso resulta em saídas previsíveis, custos operacionais baixos e também sinaliza que não é tão fácil para outros copiarem rapidamente o mesmo app. Em vez de usar diretamente alguma cola cheia de buzzwords para conectar um LLM a outros sistemas, prefiro criar as próprias ferramentas
Se essas condições não forem atendidas ou não forem necessárias, acho que alguém poderia criar a mesma solução num piscar de olhos com vibe coding. É preciso manter o controle. Eu morreria nessa colina do controle. Isso não quer dizer que eu não me impressione com LLMs; muito pelo contrário