
Quatro modos de falha ao executar um LLM local em um loop agentivo multi-etapas
A maioria dos benchmarks de LLM local mede a qualidade de chat de turno único. Fluxos de trabalho agenticos são uma besta diferente: o modelo tem que ler o estado, chamar uma ferramenta, inspecionar o resultado da ferramenta, decidir se está concluído e — se não — chamar outra ferramenta. Um modelo que pontua 95% em benchmarks de chat pode falhar catastroficamente nesse loop de maneiras características e reproduzíveis.
Eu passei três semanas tentando fazer com que LLMs locais executassem de forma confiável os fluxos de trabalho agenticos em uma extensão do VS Code que mantenho. Para ser transparente: eu sou o criador do SPECLAN, uma extensão que gerencia especificações de produtos como arquivos Markdown com frontmatter YAML — nativa do Git, um arquivo por requisito, organizado em uma árvore. Um recurso central, Infer Specs, percorre uma base de código e propõe uma árvore de Objetivo → Recurso → Requisito chamando ferramentas MCP (create_feature, update_requirement, read_file, etc.) em um loop até decidir que a árvore está completa. Este é um fluxo de trabalho agentico pesado: múltiplos turnos, pesado em ferramentas, e o modelo precisa saber quando parar.
O conceito funciona sem a ferramenta. Markdown mais YAML mais Git como formato de especificação é mais antigo que o SPECLAN e é o padrão generalizável que este artigo assume. Os modos de falha abaixo afetarão qualquer fluxo de trabalho agentico que utilize chamadas de ferramentas MCP mais saída estruturada — o SPECLAN é apenas onde eu os observei em sete modelos diferentes em dois servidores locais.
Aqui estão os quatro modos de falha, na ordem em que você provavelmente os encontrará.
1. O loop de chamada de ferramenta
Configuração: um modelo ajustado por instruções, tamanho razoável, ferramenta MCP conectada, semear um requisito e pedir ao agente para preenchê-lo.
O que você verá no rastreio:
18:56:25 update_requirement → R-0049
18:56:25 update_requirement → R-0049
18:56:26 update_requirement → R-0049
18:56:26 update_requirement → R-0049
... (12 vezes mais, mesmos argumentos)
Mesma ferramenta, mesmo alvo, mesmos argumentos, repetidos até que o agente fique sem turnos. No disco: lixo. A descrição do requisito ficou presa no campo YAML title:, o corpo ainda é o espaço reservado do modelo inalterado, e a seção "Critérios de Aceitação" acaba no lugar errado.
Isso não é um bug no seu código. A própria documentação do Gemma 4 do Google reconhece isso: o Gemma pode emitir várias chamadas de ferramentas por turno e não tem terminação de loop embutida. O modelo vê a resposta de sucesso da ferramenta, mas não reconhece "Eu terminei." Variantes elásticas do MoE e MatFormer atingem isso com mais força.
Mitigação (camada de aplicação): rastrear impressões digitais de chamadas de ferramentas no executor do agente. Se você ver o mesmo (tool_name, stable_arg_hash) três vezes seguidas, interrompa o loop com um resultado de ferramenta sintético que diz "esta ferramenta já produziu o efeito esperado; prossiga para o próximo passo ou termine." Isso funciona porque o loop geralmente é impulsionado pelo modelo não confiando no primeiro sucesso.
const callHistory: string[] = [];
for await (const step of agent.stream()) {
if (step.type === 'tool_call') {
const fp = `step.name}:stableStringify(step.args)}`;
if (callHistory.slice(-3).every(x => x === fp)) {
yield { role: 'tool', content: 'Já aplicado. Continue ou finalize.' };
continue;
}
callHistory.push(fp);
}
yield step;
}
Não é bonito, mas sobrevive a todas as variantes do MoE que eu joguei contra ele.
2. O sucesso alucinado
A segunda falha é pior, porque passa na validação superficial.
Rastreio:
17:22:01 update_requirement → R-8881 [chamada de ferramenta ocorreu]
17:22:03 assistente: "Eu li o estado atual de R-8881 e atualizei sua
descrição com uma especificação completa: [resumo longo e convincente
das mudanças]"
Arquivo no disco: inalterado.
A chamada da ferramenta foi acionada. Seus logs mostram isso. A resposta final do agente diz que a tarefa foi bem-sucedida. Mas os argumentos da chamada da ferramenta estavam malformados de uma maneira que seu servidor MCP ignorou silenciosamente — ou o modelo narrou sua intenção como uma conclusão sem nunca executá-la.
Este é o modo de "sucesso alucinado". É pior que o loop porque:
- Testes que afirmam "o agente chamou
update_requirementpelo menos uma vez" passam. - Testes que afirmam que o arquivo mudou falham — mas apenas se você realmente afirmar isso.
- A revisão manual vê uma mensagem confiante e detalhada "Eu fiz isso" e acredita.
Mitigação (camada de observabilidade): cada servidor MCP de chamada de ferramenta deve retornar um resumo de diff como parte de sua resposta, não apenas {"success": true}. Algo como { changed: true, hash_before: '...', hash_after: '...', fields_modified: ['description', 'acceptance_criteria'] }. Então seu executor de agente pode verificar se a afirmação final do modelo é consistente com o histórico real de diffs. Se o modelo disser "Eu atualizei a descrição", mas o resumo de diff mostrar changed: false, marque a sessão como inconsistente.
Eu também mantenho um campo diff_since_seed que o agente pode ler a qualquer momento — para que o modelo possa literalmente olhar o que mudou e o que não mudou, em vez de confiar em sua própria memória da conversa.
3. Editar como substituir
Fluxo de trabalho diferente: o usuário executa /add Acceptance Criteria em um existente de 5 seções.
As falhas em fluxos de trabalho agentivos podem impactar a eficiência de empresas que utilizam LLMs locais. Compreender esses modos de falha é crucial para otimizar processos e garantir resultados confiáveis em aplicações de IA. A implementação de soluções de mitigação pode aumentar a confiança em sistemas automatizados.

