1 pontos por GN⁺ 2 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • Forge é uma camada de confiabilidade para chamadas de ferramentas em LLMs auto-hospedados, com foco em aumentar a estabilidade de modelos locais pequenos em fluxos de trabalho de agentes com múltiplas etapas
  • Os principais recursos incluem rescue parsing para recuperar chamadas de ferramentas incorretas, indução de novas tentativas, imposição de etapas obrigatórias, orçamento de tokens com consciência de VRAM e compressão hierárquica de contexto
  • Atualmente, a principal configuração auto-hospedada, Ministral-3 8B Instruct Q8 no llama-server, registra 86,5% em 26 cenários de avaliação e 76% no nível mais difícil
  • Há três formas de uso: delegar todo o loop do agente ao WorkflowRunner, inserir o middleware Guardrails no loop de orquestração existente ou aplicá-lo de forma transparente com um servidor proxy compatível com OpenAI
  • O WorkflowRunner gerencia prompt de sistema, execução de ferramentas, compressão de contexto e guardrails, enquanto o SlotWorker adiciona fila de prioridade e preempção automática a slots compartilhados de inferência em GPU
  • O servidor proxy é executado com python -m forge.proxy e aplica guardrails entre clientes compatíveis com OpenAI, como opencode, Continue e aider, e o servidor local de modelos
  • O proxy injeta automaticamente uma ferramenta sintética respond em requisições com ferramentas para fazer o modelo chamar respond(message="...") em vez de retornar texto simples; na resposta, isso é removido para que o cliente veja uma resposta de texto normal
  • Os backends compatíveis são Ollama, llama-server (llama.cpp), Llamafile e Anthropic; o llama-server oferece o melhor desempenho e controle, o Ollama facilita a configuração, o Llamafile permite execução em binário único, e o Anthropic serve como baseline de fronteira e para fluxos híbridos
  • A instalação pode ser feita com pip install forge-guardrails; o cliente Anthropic é adicionado com pip install "forge-guardrails[anthropic]"; os requisitos são Python 3.12+ e um backend de LLM em execução
  • O harness de avaliação mede a confiabilidade de chamadas de ferramentas em múltiplas etapas para combinações de modelo e backend em 26 cenários, divididos entre os níveis baseados em OG-18 e 8 níveis de advanced_reasoning
  • A configuração de testes inclui 865 testes unitários determinísticos que não exigem backend de LLM e um harness de avaliação para backends reais
  • O framework de guardrails Forge e o estudo de ablação foram publicados como Forge: A Reliability Layer for Self-Hosted LLM Tool-Calling; a licença é MIT

1 comentários

 
GN⁺ 2 시간 전
Opiniões do Hacker News
  • Gosto de trabalhar nessa área e isso ajuda, mas evito LLMs baseados em nuvem e uso principalmente modelos locais de 4B a 30A3B parâmetros
    Então, mesmo sem ter muita noção do desempenho ou da precisão dos LLMs mais recentes, acho que conheço bem o nível de expectativa e os gargalos em modelos locais
    Dei uma passada rápida no texto e li o resumo, e parece que há menção de que ajustes simples podem deixá-lo 10 vezes mais rápido ou mais lento, mas as métricas e os dados parecem focar quase só em precisão. Precisam falar de velocidade
    Especialmente em workflows de agente e com modelos locais, para mim a precisão de chamadas de função/ferramenta não tem sido um grande problema desde a época do QwenCoder3, ao longo dos últimos 6 a 12 meses; o essencial é gerenciamento de contexto e impacto no tempo. Se o agente muda o prompt com frequência, otimizações de tempo como cache de prompt deixam de funcionar
    Parece que ainda estão adicionando camadas e wrappers como guardrails e retries, e isso, em modelos locais, especialmente para uso como agente, pode ficar impraticável por causa da latência
    Desculpe se isso já foi tratado de frente, mas há tão pouca discussão sobre impacto no tempo que dá a impressão de estar escondendo ou inflando o ganho real. Queria ouvir a experiência de velocidade. Também me preocupa um pouco que mais ninguém tenha levantado isso; fico pensando se estou fazendo algo errado ou se ninguém realmente usa modelos locais

  • Venho dizendo há tempos que até modelos locais pequenos podem se sair surpreendentemente bem se houver um harness decente
    Se for um sistema que pode tentar de tudo, então, desde que você o impeça de produzir o resultado errado no meio do caminho, ele acaba acertando

    • O problema é que a qualidade fica parecida com dar tempo ilimitado a um júnior e mandar continuar tentando abordagens diferentes até chegar ao objetivo
      Se a tarefa for complexa o bastante, até os modelos de ponta mais recentes têm esse problema, e em modelos pequenos isso é ainda mais amplificado
    • Gostei desse enquadramento. Trabalhando nisso, os modelos pequenos me impressionaram bastante
      O raciocínio também é bem bom e, em muitos casos, é suficiente. Às vezes basta dar um empurrãozinho para colocá-los de volta nos trilhos e eles resolvem sozinhos
    • Se entendi direito, o motivo de o modelo conseguir acertar é que ele sabe quando está errado
  • Fico feliz de ver alguém ter construído muito melhor algo que eu queria arrumar tempo para fazer. Uma pergunta é se, por exemplo, há espaço para paralelização no loop de retry
    Modelos locais normalmente conseguem lidar razoavelmente bem com um número limitado de requisições simultâneas, algo na faixa de dezenas, mesmo em hardware de consumo, e isso pode elevar os tokens efetivos por segundo em mais de 10 vezes
    Faz um tempo que penso em workflows que aproveitem isso, e “corrija este erro”, mesmo não sendo perfeito, parece um possível caso de uso. Queria saber como você vê isso

  • Tenho algumas ideias nessa área e estou colocando no meu harness. Ele é bem especializado, então não sei o quanto dá para generalizar
    Eu quebro o problema em uma execução planejada e forneço um plano inicial que inclui objetivos explícitos, como quais ferramentas o agente executor deve chamar e quais são os critérios de uma execução bem-sucedida. O harness executa esse plano em ordem
    Em cada etapa que envolve chamada de ferramenta, eu quebro a chamada em componentes. O harness pergunta ao agente quais são os valores válidos para os argumentos atuais da ferramenta, e a definição da ferramenta tem validadores para cada argumento. Se a validação falha, o harness rebobina a conversa e injeta o motivo da falha na próxima tentativa
    Quando sai uma resposta válida para um argumento, ele passa ao seguinte e, quando todos os argumentos estão preenchidos, chama a ferramenta. Ele então passa a expectativa inicial do agente, o valor real e os erros ocorridos, e pergunta se o resultado o satisfaz
    Se não satisfizer, o agente apresenta o motivo, e o harness rebobina a conversa, insere a razão da nova tentativa e reinicia todo o processo de chamada da ferramenta desde o começo
    O agente pode pedir replanejamento se encontrar falhas no plano inicial, e o harness também tenta replanejar se houver falhas consecutivas demais
    Esse método é bem eficaz para reduzir falhas de chamada de ferramenta. Uma vantagem é que os subagentes recebem um histórico de conversa perfeito, sem erros. Ainda não medi em benchmark se isso melhora a taxa real de conclusão de tarefas

    • Também fiz experimentos com uma filosofia parecida em um harness de programação com agentes baseado em modelos pequenos, construído sobre o forge
      Em relação a rebobinar a conversa, implementei um folding de chamadas de ferramenta semelhante para o agente principal, ou seja, o agente que conversa com o usuário. Quando a tarefa terminava, eu recolhia o histórico de chamadas de ferramenta para manter o contexto limpo; era mais uma questão de higiene do que de tamanho
      A parte em que o harness interroga o modelo é um pouco diferente, e eu não tentei essa abordagem. O Forge depende da autocorreção do modelo para evitar modos de erro dedicados, mas parece viável se for possível abstrair e automatizar o processo de perguntas com base em algo como schema
      No geral, a ideia de um histórico de conversa limpo é boa, mas em ferramentas com muitos argumentos parece que isso pode gerar muito mais idas e vindas do que “deixar falhar primeiro e dar um empurrão depois”. Ainda assim, é uma ideia interessante para cenários ou tarefas mais difíceis
    • Estou usando Strix Halo e, como ele fica lento com contexto longo, pensei na mesma abordagem. Desse jeito, daria para manter um contexto abaixo de 10 mil tokens
      Se for possível passar de 50k tokens/segundo com um modelo pequeno, isso seria bem grande
      Mas, por enquanto, estou atolado com trabalho da empresa e outros projetos, então só testei algumas dezenas de prompts para ver se seria viável
    • Por curiosidade, estou fazendo algo parecido por conta própria com o gemma4, e estou surpreso com o quanto isso está indo mais longe do que eu esperava
  • Excelente. No momento não consigo usar inferência local por custo, mas me preocupava com chamadas de ferramenta ao usar modelos pequenos via OpenRouter
    Estou criando um framework de testes de argumentos com foco em pytest chamado Dokimasia (do-kee-ma-see-ah) e queria ouvir opiniões: https://github.com/deevus/dokimasia
    Talvez testes de argumentos não sejam algo de que o Forge precise, mas como você está construindo ferramentas de IA mais a fundo, imaginei que teria alguma opinião

    • Ideia interessante. Essencialmente, isso parece formalizar uma camada de abstração para testar vários tipos de integração existentes no ecossistema de IA, como MCP ou skills
      Parece estar um nível acima do Forge, mais voltado a testar o workflow real e os pontos de integração que aparecem nele, por exemplo qual ferramenta oferece acesso via MCP
      Não acho que seja um grande problema usar os dois juntos
      O que me deixa curioso é como você lida com a não determinismo desses modelos. Às vezes eles fazem a chamada de ferramenta direito, às vezes cospem JSON inválido. O conjunto de testes tenta várias vezes?
  • Essa ambiguidade em chamadas de ferramenta acontece até em modelos de fronteira. Uso Claude Code, Codex e Gemini CLI todos os dias em paralelo no desenvolvimento, e o modo de falha mais comum é quando grep/find termina com código de saída 1, isto é, sem correspondência
    O modelo interpreta isso não como “a busca foi executada e não encontrou nada”, mas como “a ferramenta falhou”, e em vez de desistir ou ampliar o escopo da busca, ele só muda um pouco a sintaxe e tenta de novo
    A camada de retry com nudges corresponde quase 1:1 ao que faço manualmente várias vezes por hora. Algo como “não, a ferramenta não falhou, é só que aquele padrão não está nesse arquivo. Tente X”
    Parece a direção certa codificar isso no nível de framework
    Fico curioso se vocês também viram esses guardrails reduzirem a diferença para modelos de ponta menores em tarefas longas. Meu palpite é que a diferença de 87→99 no Sonnet não se manteria igual depois de umas 50 etapas, porque a partir daí o drift de contexto passa a dominar mais do que a semântica de retry

    • Pelo menos em modelos grandes de ponta, eles claramente ainda ficam na frente nesse ponto. Só não formalizei esses resultados por falta de tempo
      Como pista útil, tecnicamente o forge se interessa pela execução da chamada de ferramenta, não pela qualidade do modelo em si. A resposta real é esta
      Em modelos pequenos na faixa de 14B, o fator limitante era a atenção efetiva. Mesmo cabendo confortavelmente dentro da janela de contexto de treinamento, depois de certo ponto começava a aparecer degradação. Não tenho números exatos, mas modelos como o Opus conseguem ir muito mais longe nesse ponto
      Também fiz um recurso de recolhimento do histórico de mensagens de chamadas de ferramenta, que talvez eu ainda use diretamente no forge. Essencialmente, ele organiza o histórico de mensagens de forma inteligente para que o modelo perca menos o fio da meada
      Mesmo assim, o conjunto de avaliações de programação do harness de codificação com agentes inclui tarefas de refatoração e adição de funcionalidades, todas executadas em repositórios sandbox reais. Até modelos pequenos conseguem levar isso adiante por 50 a 60 chamadas de ferramenta, e ainda assim concluir esse tipo de tarefa. Mas eu provavelmente não colocaria mais de uma tarefa dessas na mesma sessão
  • Um pouco fora do assunto, mas se alguém estiver na Texas Instruments, queria saber se seria possível descobrir qual foi o destino da propriedade intelectual da máquina Lisp TI Explorer
    Sei quem é o dono da propriedade intelectual do Genera, mas nunca consegui descobrir a do Lisp OS da TI

    • Quem é o dono da propriedade intelectual do Genera?
  • Para quem pensa a stack de “segurança de agentes” de forma mais ampla, essa direção parece complementar a coisas como Kontext, kontext-cli (github.com/kontext-dev/kontext-cli) e OneCLI (github.com/onecli/onecli)

  • Há uma parte que diz que “os mesmos pesos do Mistral-Nemo 12B tiveram 7% de precisão nas chamadas de função nativas do llama-server e 83% no modo prompt do Llamafile”
    Eu achava que o Llamafile era só empacotar o modelo e o llama.cpp em um único binário, então essa diferença é entre o Llamafile injetando um prompt de sistema padrão e chamar o endpoint bruto do llama-server sem harness algum?
    Isso parece comparar laranjas com torta de maçã, está faltando ingrediente no meio

    • Também me surpreendeu. No texto foi dado um exemplo extremo, mas real. Nesse caso, é provável que o template nativo de chamadas de função tenha funcionado
      Mas isso não explica a diferença de cerca de +4 pontos percentuais entre o prompt do Lamaserver e o llamafile, nem a diferença de cerca de +30 pontos percentuais do Ollama, que ficou quase no meio entre o llamaserver nativo e o llamafile
      O backend de serving afetou quase todas as famílias de modelos, e eu realmente quase nunca tinha visto esse ponto ser discutido
  • Isso é realmente uma direção excelente. Até em modelos bonsai de 1 bit os resultados são absurdamente bons, e também funciona bem com o lmstudio
    Agora ficou totalmente realista colocar uma 7900XTX em uma máquina sobrando no porão, jogar nela um objetivo absurdo e simplesmente esquecer do assunto