Bee-350M PT — adapter agêntico (chamada de ferramenta)

Adapter LoRA sobre BrCamp/bee-350m-pt-base, treinado para selecionar uma ferramenta de um catálogo e emitir a chamada em JSON, em português. Três sementes publicadas (seed-42/, seed-43/, seed-44/) — ver §Ressalvas para saber por que as três importam.

Código, dados e o relatório completo: brcampidelli/llm-ptbr

Desempenho medido

Holdout de 536 casos, com ferramentas que o modelo nunca viu no treino (separação por raiz semântica: nem o nome nem quase-sinônimos), catálogo de 1 a 6 ferramentas, posição da correta sorteada.

s42 s43 s44 média
ferramenta correta 80,0% 84,1% 83,8% 82,6%
executou e cumpriu 70,1% 74,4% 74,6% 73,1%
over-calling (chamou quando não devia) 17,5% 16,0% 18,3% 17,3%

Desvio-padrão entre sementes: 2,53 pp — da mesma ordem do erro amostral esperado em n=536 (1,92 pp). Não há variância de treino anômala.

Com as duas restrições de decodificação ligadas (recomendado)

s42 s43 s44 média
ferramenta correta 82,3% 85,1% 84,9% 84,1% ± 1,6
executou e cumpriu 71,8% 75,0% 75,2% 74,0% ± 1,9
over-calling 17,2% 16,8% 17,5% 17,2% ± 0,4
ferramenta inexistente emitida 0 0 0 0

⚠️ Como o desempenho cai com o tamanho do catálogo

ferramentas no catálogo ferramenta correta
1–6 82,3%
5 77,2%
10 64,0%
15 51,7%

Este modelo não serve para catálogo grande. Escalar de 151M para 345M não conserta (queda relativa 45% × 39%). ⭐ O que conserta é filtrar o catálogo antes de perguntar: um recuperador lexical simples leva o acerto de 48,5% para 75,2% com top-3, sem treinar nada — ver §Uso.

🔴 Este adapter destrói as outras capacidades do modelo base

Medido em 2026-08-30 com 3 sementes, em ChatML (o formato em que ele foi treinado). Ele responde a um pedido de tradução com "não consigo traduzir com as ferramentas disponíveis":

modelo base este adapter piso trivial
resumo — cobertura 84,0% 12,4% ± 15,5
resumo — respondeu (de 150) 131 0 · 4 · 52
tradução en→pt (chrF2) 51,12 17,97 ± 0,78 21,54 (copiar a fonte)
tradução pt→en (chrF2) 43,30 12,99 ± 0,24 22,72
atendimento — JSON válido 0,0% 0,4% ± 0,7

⚠️ Nas duas direções a tradução fica ABAIXO do piso de copiar a fonte sem traduzir — ou seja, pior que não fazer nada.

A causa está no corpus: 91,1% dos 4.421 exemplos negativos são recusas, e o modelo generalizou "sem ferramenta → recuse" para qualquer tarefa.

Se você precisa que o modelo também converse, traduza ou resuma, use BrCamp/bee-350m-pt-assistente — mesmos prompts e mesma dose de negativos, com resposta útil no lugar da recusa. Ele custa 5,9 pp de execução e 1,65 pp de macro, e devolve tradução (27,5), resumo (72,8% de cobertura) e atendimento (30,9% de JSON), com 2,6 pp a menos de over-calling.

⚠️ Ressalvas — leia antes de usar o número

1. A folga sobre a versão anterior é +3,7 pp, e não a chamo de significativa — ela é medida contra um modelo de 2 sementes, e comparar média de 3 com média de 2 é assimétrico.

⚠️ E vale como aviso de método: com duas sementes este modelo dava 70,1% e 74,4%, e eu reportei que a folga (+2,9 pp) cabia dentro da própria amplitude. A terceira deu 74,6% — a s42 era a ponta baixa de três, não instabilidade. Duas sementes não estimam variância, só produzem uma diferença. É por isso que as três estão publicadas: para quem baixar verificar, em vez de acreditar numa média.

2. Catálogo acima de 6 ferramentas é extrapolação. O treino não contém catálogos maiores.

3. O holdout tem 0,5% de e-mail e por isso quase não mede cópia de cadeia densa em pedido natural. Esse eixo foi medido por sonda sintética, separadamente.

4. Argumentos de texto livre (assunto, corpo de mensagem, título) não entram no escore — não há critério exato para julgá-los. A cobertura da pontuação vai impressa no avaliador.

O que este adapter conserta em relação ao anterior

Diversificação de cadeias arbitrárias no treino: os endereços de e-mail do corpus tinham 724 ocorrências e apenas 22 valores distintos (boss@company.com em 47%). O modelo não aprendera a copiar — decorara. Trocando por 868 endereços inéditos, sem um exemplo novo:

cópia de e-mail inédito
antes (22 distintos) 41,7%
depois (868 distintos) 53,7% nas duas sementes

Pareado: +15/−2, McNemar p = 0,0024.

Uso

from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel

base = "BrCamp/bee-350m-pt-base"
tok = AutoTokenizer.from_pretrained(base)
modelo = AutoModelForCausalLM.from_pretrained(base, dtype="bfloat16")
# a semente 42 esta' na RAIZ do repo; 43 e 44 estao em seed-43/ e seed-44/
modelo = PeftModel.from_pretrained(modelo, "BrCamp/bee-350m-pt-agentico")

sistema = """Você é um assistente AGÊNTICO. Você tem acesso às ferramentas abaixo.

FERRAMENTAS DISPONÍVEIS:
- send_email: Envie um email para um destinatário.
    args: recipient (O endereço de e-mail do destinatário.), subject (O assunto.), content (O conteúdo.)
    obrigatorios: recipient, subject, content

Responda com UM objeto JSON: {"tool": "<nome>", "args": {...}}. Se nenhuma ferramenta servir, responda em texto normal."""

msgs = [{"role": "system", "content": sistema},
        {"role": "user", "content": "Envie um e-mail para ana@contoso.com com o assunto Reunião."}]
ent = tok(tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True),
          return_tensors="pt")
saida = modelo.generate(**ent, max_new_tokens=320, do_sample=False,
                        eos_token_id=tok.convert_tokens_to_ids("<|im_end|>"))
print(tok.decode(saida[0][ent["input_ids"].shape[1]:], skip_special_tokens=True))

🔴 subfolder= NÃO funciona no PEFT 0.19.1

A versão anterior deste card mandava usar subfolder="seed-42", e isso falha: o PEFT acha o adapter_config.json mas não propaga a subpasta para os pesos, dando Can't find weights ... adapter_model.safetensors. Corrigido em 2026-08-30 — a semente 42 está na raiz do repositório e carrega com o código acima.

Para a 43 ou a 44:

from huggingface_hub import snapshot_download
d = snapshot_download("BrCamp/bee-350m-pt-agentico", allow_patterns="seed-43/*")
modelo = PeftModel.from_pretrained(modelo, f"{d}/seed-43")

⚠️ Duas coisas que mudam muito o resultado

O token de parada tem de estar ligado. Sem eos_token_id apontando para <|im_end|>, a geração vai até o teto e o parser recebe várias chamadas concatenadas — o que se lê como 0% de acerto num modelo que acerta.

Ligue as duas restrições de decodificação. Ambas em comeia/eval/esquema.py:

  1. chave do argumento restrita ao esquema do prompt — o modelo às vezes escreve receptor onde o esquema diz recipient. +16,4 pp, +144 casos e −0.
  2. nome da ferramenta restrito ao catálogo — ele inventa nomes como executar_program e search_livros em 3% dos casos (catálogo 1–6) e 10% (catálogo 15). Restringir dá +2,3 pp (4 células, pareado 38×2, p = 1,5e-09) e, sobretudo, zera saída inexecutável: 0 ferramentas inválidas em 1.730 chamadas.

⭐ Nas duas, nenhum caso legítimo é bloqueado — chave e ferramenta da referência sempre vêm do catálogo.

Se o catálogo tiver mais de ~8 ferramentas, filtre antes de perguntar. Um recuperador lexical (sobreposição de palavras com peso IDF) leva o acerto de 48,5% para 75,2% com top-3, sem treinar nadacomeia/eval/recuperar_catalogo.py. ⚠️ Ele exige que a descrição da ferramenta esteja no idioma do usuário: com descrições em outro idioma o recall cai de 90,1% para 6,3%.

⚠️ Restringir o VALOR, não. Duas versões foram medidas e reprovadas (−9,0 pp e −15,8 pp): o modelo não deixa de copiar por escolha, e restrição de decodificação não conserta incapacidade — só troca a forma do erro. Ficam no código, desligadas, com os números no docstring.

Treino

base BrCamp/bee-350m-pt-base (345M, pré-treinado do zero em PT)
método LoRA r=16 α=32, 1 época, lr 1,2e-3, batch efetivo 16
dados 11.160 exemplos (6.739 com chamada · 4.421 negativos)
hardware RTX 5070 Laptop 8 GB · ~90 min por semente

O corpus vem do gigaverbo e derivados, com separação treino/teste por componente conexo de tudo que é compartilhado (pedido ou tupla de argumentos) e verificação posterior sobre os arquivos finais.

Licença

Apache-2.0, como o modelo base.

Downloads last month
26
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for BrCamp/bee-350m-pt-agentico

Adapter
(2)
this model