Instructions to use BrCamp/bee-350m-pt-assistente with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use BrCamp/bee-350m-pt-assistente with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("BrCamp/bee-350m-pt-base") model = PeftModel.from_pretrained(base_model, "BrCamp/bee-350m-pt-assistente") - Notebooks
- Google Colab
- Kaggle
Bee-350M PT — adapter assistente (chama ferramenta e responde)
Adapter LoRA sobre BrCamp/bee-350m-pt-base.
Faz chamada de ferramenta em JSON e responde normalmente quando nenhuma ferramenta serve —
em vez de recusar.
⭐ Este modelo é o par de BrCamp/bee-350m-pt-agentico,
não o sucessor dele. Os dois foram treinados com os mesmos prompts e a mesma proporção de
exemplos negativos; muda só a forma da resposta quando não há ferramenta aplicável. A
medição com 3 sementes de cada lado mostra que isso é uma troca, não uma melhora geral.
Código, dados e relatório: brcampidelli/llm-ptbr
(docs/e19-forma-da-classe-negativa.md)
Qual dos dois usar
use bee-350m-pt-agentico se |
use este se |
|---|---|
| o modelo é só chamador de ferramenta | ele também conversa, traduz ou resume |
| errar a chamada é o erro mais caro | chamar à toa é o erro mais caro |
Desempenho — 3 sementes de cada lado, mesma régua
Holdout de 536 casos com ferramenta + 268 sem, com ferramentas que o modelo nunca viu no treino (separação por raiz semântica), catálogo de 1 a 6, posição da correta sorteada.
agentico (recusa) |
este (responde) | |
|---|---|---|
| ferramenta correta | 84,1% ± 1,6 | 77,7% ± 1,4 |
| executou e cumpriu | 74,0% ± 1,9 | 68,1% ± 1,3 |
| deixou de chamar quando devia | 9,0% ± 1,7 | 15,8% ± 0,8 |
| ⭐ chamou quando não devia | 17,2% ± 0,4 | 14,6% ± 0,4 |
| macro (executou + recusa correta)/2 | 78,4% ± 1,0 | 76,8% ± 0,8 |
A troca, com os dois lados medidos: o agentico executa 5,9 pp melhor (t = 4,4); este chama à
toa 2,6 pp menos (t = 8,7); no líquido a macro fica 1,65 pp abaixo (t = 2,4, p ≈ 0,08).
⭐ E o que este adapter recupera fora do eixo de ferramenta
agentico |
este | |
|---|---|---|
| resumo — cobertura | 12,4% ± 15,5 | 72,8% ± 7,0 |
| resumo — respondeu (de 150) | 0 · 4 · 52 | 117 · 117 · 94 |
| atendimento — JSON válido | 0,4% ± 0,7 | 30,9% ± 7,6 |
| tradução en→pt (chrF2) | 17,97 ± 0,78 | 27,47 ± 6,12 |
| tradução pt→en (chrF2) | 12,99 ± 0,24 | 19,10 ± 1,36 |
| seguimento de instrução (IFEval-PT) | 29,3% ± 0,9 | 29,2% ± 0,8 |
| sentimento (verossimilhança) | 71,0% ± 13,3 | 56,8% ± 2,1 |
O agentico responde a um pedido de tradução com "não consigo traduzir com as ferramentas
disponíveis". Este responde. O piso de copiar a fonte sem traduzir é 21,54 (en→pt) e
22,72 (pt→en): o agentico fica abaixo dele nas duas direções, este fica acima em en→pt.
⚠️ Ressalvas — leia antes de usar os números
1. A tradução oscila muito entre sementes. As três deram 21,79 · 26,67 · 33,96 (dp 6,12),
enquanto o agentico deu 18,75 · 17,97 · 17,19 (dp 0,78). Mesma régua nos dois, então a
oscilação é do modelo. As distribuições não se sobrepõem — o máximo do agentico fica
abaixo do mínimo deste — mas a folga sobre o piso de copiar não está estabelecida: a pior
semente fica 0,25 acima dele.
2. Catálogo acima de 6 ferramentas é extrapolação. O treino não contém catálogos maiores, e a seleção degrada com o tamanho do catálogo. Filtre antes de perguntar (ver §Uso).
3. atendimento emite JSON válido em 30,9% e é útil em 0,0%. O formato voltou; a resposta
ainda não serve. Um piso de regras faz 60,4%.
4. Código: 0% de pass@1 aqui e no agentico. Nenhuma intervenção deste eixo toca isso.
5. Sentimento é a única métrica em que o agentico ganha, e o dp dele é 13,3 pontos —
a vantagem é muito menos sólida do que a média sugere. Nenhum dos dois passa do piso léxico de
60 palavras (79,0%).
Como foi construído
O corpus tem 6.739 exemplos com chamada de ferramenta e 4.421 negativos — pedidos para os
quais nenhuma ferramenta do catálogo serve. No agentico, 91,1% desses negativos eram
recusas, sempre na mesma fórmula. O modelo generalizou "sem ferramenta → recuse" para
qualquer tarefa.
Aqui os mesmos 4.421 prompts foram reescritos por um modelo professor: atender o que é respondível por raciocínio (uma conta, uma conversão, uma explicação) e, quando o pedido exige ação no mundo, dizer isso sem fórmula e ser útil mesmo assim — nunca fingir que executou.
⚠️ O alvo não é "nunca recusar". Boa parte dos pedidos é ação real (criar fatura, verificar disponibilidade de e-mail). Ensinar o modelo a dizer que fez seria ensinar a mentir.
Duas guardas mecânicas rejeitaram gerações antes de entrarem no corpus: fórmula de recusa (validada contra as recusas originais — pega 79,9% delas) e afirmação de valor vivo ("hoje 1 USD vale 0,93 EUR"), que rejeitou 2,3%.
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-assistente")
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
Testado: PeftModel.from_pretrained(m, repo, subfolder="seed-43") acha o adapter_config.json
mas não propaga a subpasta para os pesos, e falha com
Can't find weights ... adapter_model.safetensors. Por isso a semente 42 está na raiz do
repositório e é a que carrega com o código acima.
Para usar a 43 ou a 44, baixe a pasta e carregue do caminho local:
from huggingface_hub import snapshot_download
d = snapshot_download("BrCamp/bee-350m-pt-assistente", allow_patterns="seed-43/*")
modelo = PeftModel.from_pretrained(modelo, f"{d}/seed-43")
⚠️ O que esperar na prática
Este é um modelo de 345M. Os números da tabela são relativos ao par e aos pisos triviais, não a um modelo utilizável em produção. Duas saídas reais da semente 42:
pedido : Envie um e-mail para ana@contoso.com com o assunto Reuniao e o corpo Confirmado.
saída : {"tool": "send_email", "args": {"recipient": "ana@contoso.com",
"subject": "Meeting", "content": "Meeting"}}
⚠️ chamada correta, mas traduziu o assunto para inglês — e repetiu a chamada,
porque não emitiu o token de parada nesta amostra.
pedido : Traduza para o português: The committee approved the new budget on Friday.
saída : "The committee has meeting today for the first time on Friday..."
⚠️ não traduziu. chrF2 27,5 é acima do piso de copiar (21,5) e muito abaixo
do modelo base em texto cru (51,1).
⭐ O ganho real deste adapter sobre o agentico é deixar de recusar — ele tenta a tarefa em
vez de responder "não consigo com as ferramentas disponíveis". A qualidade do que ele produz
continua a de um 345M.
⚠️ Três 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.
Use o chat template. Este adapter foi treinado em ChatML. Medido em texto cru, o modelo base vaza por baixo do adapter e o resultado não é o deste modelo.
Ligue as duas restrições de decodificação, ambas em
comeia/eval/esquema.py:
a chave do argumento restrita ao esquema do prompt (+16,4 pp — o modelo às vezes escreve
receptor onde o esquema diz recipient) e o nome da ferramenta restrito ao catálogo
(+2,3 pp, e zera saída inexecutável). Os números acima já as incluem.
⚠️ Restringir o VALOR, não. Duas versões foram medidas e reprovadas (−9,0 pp e −15,8 pp).
Se o catálogo tiver mais de ~8 ferramentas, filtre antes de perguntar. Um recuperador
lexical simples leva o acerto de 48,5% para 75,2% com top-3, sem treinar nada —
comeia/eval/recuperar_catalogo.py. ⚠️ Ele exige que a descrição da ferramenta esteja no
idioma do usuário.
Treino
| base | BrCamp/bee-350m-pt-base (345M, pré-treinado do zero em PT) |
| método | LoRA r=16 α=32, 698 passos (≈1 época), lr 1,2e-3, batch efetivo 16 |
| dados | 11.058 exemplos (6.739 com chamada · 4.319 negativos com resposta útil) |
| hardware | RTX 5070 Laptop 8 GB · ~1h45 por semente |
| sementes | 42, 43, 44 — todas publicadas |
Separação treino/teste por componente conexo de tudo que é compartilhado (pedido ou tupla de argumentos), com verificação posterior sobre os arquivos finais.
Licença
Apache-2.0, como o modelo base.
- Downloads last month
- -
Model tree for BrCamp/bee-350m-pt-assistente
Base model
BrCamp/bee-350m-pt-base