1 pontos por GN⁺ 4 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • Agentes que lidam com tarefas complexas de forma confiável precisam não de cadeias de prompts mais sofisticadas, mas de um fluxo de controle determinístico codificado no software
  • Se você depende de expressões como MANDATORY ou DO NOT SKIP no prompt, isso significa que já chegou ao limite do prompting
  • Imagine uma linguagem de programação em que frases funcionam como sugestões e funções alucinam ao retornar “Success”; à medida que a complexidade cresce, torna-se impossível raciocinar sobre o sistema e a confiabilidade desmorona
  • O software escala por meio da composicionalidade recursiva formada por bibliotecas, módulos e funções, e isso permite raciocínio local porque oferece comportamento previsível
  • Cadeias de prompts são úteis para tarefas restritas, mas não têm as mesmas propriedades, pois são não determinísticas, fracamente especificadas e difíceis de verificar

Estrutura necessária para a confiabilidade de agentes

  • Para garantir confiabilidade, é preciso tirar a lógica das explicações em linguagem natural e levá-la para o runtime
  • A estrutura necessária é um scaffold determinístico que trata o LLM não como o sistema inteiro, mas como um componente
  • Esse scaffold deve incluir transições de estado explícitas e checkpoints de validação
  • Orquestração determinística por si só não basta; sistemas que podem falhar silenciosamente precisam de detecção agressiva de erros
  • Sem validação programática, as opções se reduzem a três
    • Babá (Babysitter)

      • Uma pessoa precisa continuar no loop para detectar erros antes que eles se propaguem
    • Auditor (Auditor)

      • É preciso verificar minuciosamente todo o resultado depois que a execução termina
    • Oração (Prayer)

      • Passa-se a depender de aceitar o resultado pelo feeling

1 comentários

 
GN⁺ 4 시간 전
Comentários do Hacker News
  • Concordo 1000%. Está cada vez mais difícil acreditar no tamborilar da Anthropic de “construa mirando no desempenho dos modelos do futuro, eles vão melhorar em breve”
    Criei um agente de QA que vasculhava 200 arquivos Markdown de requisitos em uma sessão de navegador, e era um bom sistema que aumentou bastante a eficiência da equipe. Mas quando deixei para o modelo um fluxo de controle de alto nível, tipo “olhe os arquivos de requisitos deste diretório e, para cada arquivo, crie itens de tarefa para verificar se o app atende àqueles requisitos”, tudo começava a desmoronar por volta de 30 arquivos
    Ele deixava arquivos de fora, ou testava alguns grupos de arquivos três vezes, fazendo uma tarefa de 3 minutos levar 10, ou ainda retestava sem motivo os 4 arquivos anteriores por causa de um erro em um único arquivo. No Opus 4.6 e no GPT 5.4, e também em testes rápidos com Opus 4.7 e GPT 5.5, a capacidade de orquestrar workflows era inconsistente
    No fim, criei um harness determinístico muito simples em volta do modelo, chamando o modelo para cada caso de teste, salvando os resultados em um array e depois gravando em arquivo, e a confiabilidade do sistema melhorou absurdamente. Mas plataformas de agentes gerenciados como Cursor Cloud Agents ou Anthropic parecem obcecadas demais com a ideia de que “o agente tem que executar tudo”, e não parecem enxergar o valor de inserir um pouco de determinismo nos pontos certos

    • Antes eu achava que eles empurravam as pessoas para workflows feitos só com prompt porque podiam cobrar pelo custo de tokens, mas não pelo scaffolding criado pelo usuário. Agora, acho mais que eles têm medo do fato de que alguém precisa projetar e implementar esse tipo de scaffolding
      Porque isso joga água fria na alegação de que essa tecnologia vai substituir pessoas inteiras, workflows inteiros ou projetos inteiros. Ainda acho que ela pode aumentar muito a produtividade e ter um efeito desastroso no mercado de contratação e nos salários de desenvolvedores, mas não parece que a versão atual dessa tecnologia vá chegar no nível que eles anunciam. Se tivessem posicionado isso como “uma ferramenta muito útil que reduz boa parte do trabalho chato de uma equipe humana de desenvolvimento”, os desenvolvedores iam querer, mas executivos iam querer menos, e os investidores provavelmente não deixariam passar
      Além disso, etapas minuciosas e fortemente controladas combinam muito melhor com modelos menores, mais baratos e especializados do que com modelos enormes capazes de escrever, num instante, 5 volumes de fanfic de CSI
    • Isso talvez venha do próprio jeito como benchmarks são usados para avaliar modelos
      Alguns benchmarks não deixam o modelo tentar várias vezes o mesmo problema e depois ignoram a taxa de falha, adotando só o resultado caso tenha acertado pelo menos uma vez?
    • Concordo. A única forma de tornar esse tipo de sistema confiável é quebrar o problema em partes pequenas. Até verificações internas de consistência só mostram que LLMs são muito menos consistentes do que se esperava
    • Tive um ganho enorme ao combinar apply_patch com check_compilation e run_unit_tests. O nome da ferramenta continua sendo apply_patch, mas agora, se o patch dá certo, ela também retorna informações adicionais sobre build e testes
      A taxa de sucesso do agente subiu de algo como 80% para um nível que, até agora, parece quase determinístico. Agora eu nem preciso explicar no prompt o processo de compilação e de testes unitários; basta que ele rode com certas dependências e devolva o resultado
      Também sinto que isso vai contra a moda do momento. Faz muito tempo que uso tokens pré-pagos e harnesses customizados, e simplesmente funciona bem. Dá para ignorar a maior parte das notícias. Em problemas explicitamente visados, ferramentas estilo Copilot já não servem para muita coisa e, em algumas codebases, mesmo usando o mesmo modelo base GPT 5.4, a diferença de desempenho é de outra ordem de grandeza
    • O segredo é “compilar” esse prompt de orquestração. Se você transforma o prompt em código, esse código pode então executar o agente, executar código ou ambos, o que resolve o problema de determinismo
      Todo mundo deixa esse padrão passar batido nas skills. Se você coloca código ao lado de SKILL.md, consegue garantir certos comportamentos, mas por algum motivo todo mundo está viciado em escrever prompts. Nem precisa criar uma CLI; um simples skill.py com a tarefa dentro já basta. Você ainda pode ter um helper chamando claude -p
  • Seria engraçado se, daqui a alguns anos, as pessoas ainda usassem LLMs, mas no fim só conseguissem usá-los por meio de um vocabulário e gramática controlados que precisassem aprender. Igual a 15 anos atrás, quando todo mundo migrou para NoSQL e logo em seguida recriou schemas dentro de JSON

  • Acho que parte do problema talvez seja que estamos aplicando LLMs da forma errada desde o começo. Como já apareceu em outros lugares, talvez o prompt do agente devesse ser: escreva código que execute a tarefa de uma maneira o mais repetível, verificável e determinística possível
    A validação da saída do agente também deveria estar incluída. O objetivo geral é tirar o LLM de tarefas que um programa consegue fazer com mais eficiência e muitas vezes com mais precisão

    • Concordo 100%. Você deve usar uma ferramenta não determinística que acerta 90% para construir uma ferramenta determinística que acerta 100%. Uma das frases-chave que sempre coloco no prompt é: “se encontrar um caso de borda ambíguo, me consulte”
      É ruim colocar IA em produção fazendo algo diretamente por chamada de API. Na minha visão, o único uso que a IA deve ter num app é para leitura, classificação e coisas assim. É como substituir o “R” de um app CRUD antigo
      Usar esse mesmo endpoint de “R” baseado em IA para preencher automaticamente formulários de “C”, “U” e “D” conforme o prompt é aceitável, mas ele não deve alterar nada para o cliente antes de revisão humana. Apps CRUD continuam sendo apps CRUD e continuarão sendo; o que surgiu foi só um endpoint de “R” muito inteligente que sugere ações ou faz autocomplete de formulários para clientes, ferramentas internas, pipelines do Jenkins etc. Ele pode sugerir ações, mas não executá-las diretamente
    • Na maioria das organizações, o fluxo parece ir de llm -> prompt -> result, depois llm -> prompt + prompt encoded as skill -> result, e depois llm -> prompt + deterministic code encoded as skill -> result
      Fazer o prompt gerar código logo no início pode encurtar o caminho até código determinístico, mas ainda assim você está colocando código determinístico dentro de um wrapper não determinístico. Para ter sucesso em tarefas de longo prazo, muitas vezes é preciso uma camada de determinismo que está faltando
      É preciso colocar código determinístico fora da fronteira não determinística, por meio de um loop de agente ou framework. Aí você fica com algo como fluxo de agente determinístico -> tomada de decisão não determinística -> ferramenta determinística, com o julgamento não determinístico espremido entre camadas determinísticas. Em experimentos, isso foi um padrão muito forte, e fica ainda mais forte quando o agente cria seu próprio determinismo com ferramentas como auto-researcher
    • Tivemos a mesma experiência. No começo, dávamos ao agente uma lista de ferramentas que podiam manipular estruturas de dados de uma maneira específica, e isso era bem frágil
      Agora usamos uma pequena linguagem específica de domínio e uma única ferramenta, e o agente fornece como entrada um script escrito nessa linguagem. Isso lida com casos de uso mais dinâmicos, e erros de sintaxe são facilmente pegos pelo parser e devolvidos ao agente
    • O problema é que programas frequentemente encontram casos de borda que exigem interpretação, e nesse momento você quer deixar o LLM lidar com o caso de borda, e então acaba querendo deixar também para ele o loop inteiro e as chamadas de ferramenta
    • No meu último projeto, fiz exatamente isso ao automatizar a geração de uma biblioteca de interface entre um servidor que controlava hardware e um app mobile
      A equipe de controle de hardware entregava a especificação em documentos e planilhas, e a equipe mobile olhava aquilo, codava a biblioteca de interface e depois validava com o servidor. Eu converti os documentos para TSV e enviei partes ao Claude para que ele escrevesse um parser TSV que preservasse nuances da especificação escrita por humanos
      Foram necessárias mais de 150 iterações para cobrir todos os casos de borda e gerar resultados intermediários em JSON. Depois, o Claude ajudou a escrever um gerador de código que adicionava código de cola customizado sobre o Apollo para gerar o código consumido pelo app mobile
      Todo esse pipeline roda como parte do Github Actions, e só chama o Claude quando o validador da biblioteca falha. Quando falha, há um arquivo md incluído na solicitação pedindo que ele descubra o que deu errado, proponha uma solução e crie um PR. Depois disso, uma pessoa revisa, ajusta e faz o merge. O custo total em créditos até aqui foi inferior a 350 dólares
  • Concordo com a intenção, mas acho que a conclusão precisa mudar. Quando você bate no limite dos prompts, em vez de tentar usar o LLM para executar a tarefa em tempo de execução, deveria usar o LLM para escrever o software que executará a tarefa
    Em tempo de execução, o papel do LLM tende a se reduzir a ajudar o usuário a escolher entradas que se encaixem em um sistema de software com regras de negócio rígidas já embutidas

    • Na empresa tivemos algumas semanas livres, então resolvemos experimentar colocar agentes em processos de trabalho como anotações, acompanhamento de tarefas e gestão de documentos, e isso bate exatamente com a minha experiência
      Na primeira semana, os prompts só cresciam e o desempenho só piorava. Na segunda, foquei em definir com precisão objetos como notas, tarefas, projetos e pessoas, e em definir métodos que executassem operações bem definidas sobre esses objetos. Como você apontou, a superfície do agente encolhe para uma camada de tradução que converte linguagem natural em comandos e argumentos que passam por validadores de entrada
    • Se fosse um system prompt que fecha o ciclo completo, seria algo como: “procure toda oportunidade de automação que possa tornar seu próprio trabalho desnecessário. Se receber uma pergunta que código pode responder, escreva e execute o código para obter o resultado e então responda”
      Um LLM assim talvez tivesse ido melhor no teste do strawberry
    • Já houve neste fórum a visão de que o futuro do software está em programas gerados e adaptados em tempo de execução com uso de IA generativa. Não sei quão longe estamos disso
    • Já vi casos em que o modelo ficava preso em uma forma específica de resolver o problema e precisava de um empurrão para mudar de abordagem. Por exemplo, em vez de ficar mexendo em um monte de configuração de serviço do sistema para tratar hotplug/unplug de stream de áudio, o que realmente precisava era escrever algumas dezenas de linhas de Python
      Fiz o Claude escrever por conta própria alguns scripts shell para lidar com casos comuns no meu workflow, como rodar testes. Agora, em vez de ficar rodando em círculos por 30 minutos, ele executa essas ferramentas e conclui a configuração
      Sempre que ele pede permissão para rodar um shell esquisito de uso único ou uma one-liner estranha em Python para fazer alguma coisa, eu me pergunto se não deveria fazer com que ele usasse uma ferramenta que pudesse ser aprovada automaticamente
  • É por isso que muitas vezes falo em “IA de próxima geração”. Não estou falando apenas de LLMs. LLMs são bem legais e, mesmo sem mais avanços fundamentais, ainda devem continuar gerando valor ao serem usados e otimizados de maneiras mais interessantes
    Mas certas partes parecem precisar, de alguma forma, de uma melhoria fundamental de próxima geração. O fato de um LLM tornar difuso um “nunca faça X” e, depois de muito contexto, acabar tratando isso como “por favor faça X” parece algo próximo do núcleo do modo como funciona. É fácil esquecer isso no entusiasmo inicial de descobrir o que ainda conseguimos fazer, mas LLMs não são tudo o que procuramos em IA
    Tem que existir uma estrutura que trate “nunca faça X” como um humano trataria. Também precisa existir uma estrutura com uma hierarquia de memória parecida com a humana, em vez de uma simples “janela de contexto”. Duas pessoas mantendo uma conversa longa o suficiente, mesmo que no começo estivessem falando com a mesma IA, acabariam tendo duas IAs realmente diferentes, e não só duas janelas de contexto diferentes
    Claro, ninguém sabe como isso vai parecer. Só não há motivo para achar que LLMs sejam a resposta final da IA

    • Na minha opinião, precisamos de memória real. A memória atual, em termos amplos, é mais parecida com um sistema de post-its que a IA escreve para si mesma e vai conferindo toda hora, e não um sistema integrado que permita aprendizado e seja ativado com mais flexibilidade
    • Há um exemplo interessante: https://www.youtube.com/watch?v=kYkIdXwW2AE&t=315s
  • Discordo, vindo de um ciclo completo de imposição por prompt → fluxo determinístico → imposição por prompt
    O motivo de “não pule” falhar é que o agente está com trabalho demais e outras coisas no contexto acabam desviando a atenção dessa instrução
    Mas ninguém disse que o agente encarregado de impor regras precisa ser o mesmo agente que constrói. Dá para codificar algum nível de lógica inteligente de decisão em um fluxo de controle determinístico, mas se você o tornar rígido demais ele não funciona bem, e se o tornar complexo demais, talvez usar agentes acabe saindo mais barato em custo de configuração e manutenção
    Basicamente, o que você precisa são três tipos de agentes: um supervisor que gerencia o loop e aciona o que for apropriado quando há problema, um orquestrador que delega ao agente certo e impõe guardrails onde necessário, e trabalhadores que executam as unidades de trabalho

    • Isso, é só adicionar mais agentes
  • Na minha visão, todos os harnesses estão errados nesse aspecto, e alguns estão muito errados
    Por exemplo, comandos slash são um recurso equivocado. Você não deveria precisar esperar o chatbot terminar um turno para conferir o estado da janela de contexto ou quanto dinheiro foi gasto nesta sessão. O controle deveria ser ortogonal ao loop de chat
    Coisas que não têm nada a ver com controlar entrada e saída do gerador de texto estão amarradas ao comportamento de chat só porque “é um chat, então vamos tocar isso como se fosse um bot de IRC”
    Hoje existem muitos agentes com LLM, mas quase nenhum separa de forma correta controle, loop do agente e camada de apresentação. Alguns pelo menos têm modo headless, e isso já é bom

    • Entendo o ponto, mas na prática é bem mais difícil construir a arquitetura que você propôs. Que tal fazer você mesmo e tentar uma vaga em alguma big tech?
    • No codex CLI, /status funciona bem até no meio de um turno
      Nos outros não
    • Eu uso o app desktop do Codex. Na GUI dá para ver o indicador de contexto e estatísticas de uso
      Também é mais prático para navegar entre conversas e ver atualizações. Às vezes uso Claude Code ou opencode no terminal, mas a experiência é muito pior comparada ao app desktop do Codex
  • A frase “imagine uma linguagem de programação em que sentenças são sugestões e funções alucinam e retornam ‘Success’. Fica impossível raciocinar, e a confiabilidade desmorona à medida que a complexidade cresce” é essencialmente mais próxima de programação declarativa
    A maior parte da programação tradicional é imperativa, familiar aos desenvolvedores. Você dá um conjunto exato de instruções e espera que sejam seguidas como foram escritas. Agentes estão muito mais próximos do declarativo do que do imperativo: você dá o resultado desejado e eles trabalham para alcançá-lo
    Claro, em sistemas declarativos como SQL, o resultado costuma ser bem consistente e bem definido, mas ainda assim você está confiando no engine interno para decidir como processar aquilo. Pensar em agentes como algo declarativo me ajudou muito mais do que tentar projetar um sistema de “controle” estilo Rube Goldberg. Se não bater, você valida, informa que está errado e tenta de novo ou escolhe outra abordagem
    Se você realmente precisa de algo imperativo, então escreva de forma imperativa. Ou mande o agente escrever assim. Isso parece mais uma tentativa de usar uma ferramenta inadequada para a tarefa

    • Parece um nível de abstração ainda acima do declarativo. Talvez possamos chamar de “programação narrativa”? Claro, ainda dá para discutir se a palavra “programação” continua adequada
      Pode parecer declarativo, mas isso só acontece dentro de uma ilusão. Na prática, não estamos descrevendo objetivos para a IA e deixando que ela os interprete; temos um documento de história em que um personagem substituto de humano conversa com um personagem-computador, e nós, no mundo real, esperamos que o LLM cole uma narrativa mais coesa por trás disso e daí extraia algo útil
      Não é uma distinção meramente acadêmica. Entender que existe uma história ajuda a criar modelos melhores para compreender a relação entre entrada e saída e montar estratégias. Por exemplo, ajuda a entender riscos como prompt injection e também dá orientação sobre que dados de treinamento incluir ou excluir
    • Pensei em declarativo também, mas mais em PROLOG do que em SQL. Algo com fluxo de controle e capacidade real de raciocínio
      Aí você esbarra em problemas parecidos com os dos LLMs: falhas silenciosas, repetição e contradições, a menos que tome muito cuidado. A essência pode ser o mesmo problema de suposição de mundo fechado. Nos LLMs, isso aparece como alucinação em vez de admitir que não sabe
    • Concordo. Mas você também pode falar com o agente de forma imperativa. Pode dizer “aqui estão os passos concretos, siga-os”, e ainda assim ele pode estragar tudo. O que se busca não é imperatividade, e sim determinismo
      E, como você disse, se instruir um LLM não determinístico de forma declarativa para “me leve a esse estado final”, a chance de ele sair dos trilhos é ainda maior
    • A natureza declarativa do SQL se baseia na matemática da álgebra relacional, então ele retorna o mesmo resultado toda vez. Se vai retornar no mesmo tempo a cada consulta depende de índices e do tamanho do banco de dados
      Mas a própria consulta não muda de uma execução para outra como acontece com um LLM
  • Tenho pensado bastante nesse problema. Isso também pode se conectar à discussão sobre especialização. Quanto mais especializado o modelo fica, mais parece perder capacidades de base, e talvez mirar em um pouquinho de abstração permita obter vantagens dos dois lados
    É um exemplo bem específico, mas dá o que pensar
    Resumo de 20 minutos do podcast: https://pub-6333550e348d4a5abe6f40ae47d2925c.r2.dev/EP008.ht...
    Artigo: https://arxiv.org/abs/2605.00225

  • Isso já era visível na época do Auto-GPT, em 2023. As pessoas deixavam o GPT “dirigir”, mas na maioria dos casos o que realmente precisavam eram dez linhas de Python e talvez algumas chamadas de função llm()
    A alternativa era executar essas dez linhas de Python da forma mais cara, lenta e menos confiável possível. Claro que isso foi popular
    Por exemplo, a maioria usava agentes para pesquisa na internet. Eles ficavam rodando por horas, se distraíam ou esqueciam o que estavam fazendo
    Enquanto isso, com import duckduckgo e import llm, você pode escrever dez linhas de código que fazem a mesma coisa em 20 segundos, de forma realmente determinística e custando 50 vezes menos
    Os modelos atuais são muito melhores, e hoje eles já melhoraram o suficiente para que algo como Auto-GPT pareça viável. Mas continuar executando um fluxo de controle mal especificado da maneira mais cara possível ainda é uma péssima ideia