Lançamento · 22 de outubro de 2026
Nosso segundo modelo lê até 128 mil tokens de uma vez, chama ferramentas no formato da API da OpenAI e responde no idioma de quem pergunta. Tem 1,1 bilhão de parâmetros, foi treinado do zero em duas máquinas de mesa, e já está no ar no playground e na API.
Visão geral
O mochat-1 provou que dava para treinar do zero, em casa, um modelo que conversa bem em português. Ele também mostrou o que faltava: uma janela de 2.048 tokens, que não comporta um contrato, e nenhuma capacidade de acionar ferramentas. O mochat-2 foi desenhado em torno dessas duas lacunas.
A arquitetura foi refeita para contexto longo, o pré-treino é cinco vezes maior, e o ajuste fino passou a ensinar o modelo a declarar quando precisa de uma ferramenta, em vez de depender do servidor para isso. O português continua ocupando 42% do texto de pré-treino desde o primeiro passo.
Acha um fato escondido em qualquer ponto de um texto de 128 mil tokens. Na primeira tentativa de 128k, a janela aceitava o texto, mas o modelo só lia os últimos ~16 mil tokens.
Recebe a lista de ferramentas no campo tools, decide sozinho se chama e devolve
tool_calls no formato OpenAI. Parâmetros ainda erram em cerca de 1 a cada 5 chamadas.
Responde em português a quem escreve em português e em inglês a quem escreve em inglês, e obedece a pedidos explícitos de troca de idioma.
Avaliações
Os dois modelos foram medidos com os mesmos scripts e as mesmas configurações. Os testes de contexto longo e de ferramentas não se aplicam ao mochat-1, que tem janela de 2.048 tokens e não chama ferramentas.
| teste | mochat-2 | mochat-1 | amostra |
|---|---|---|---|
| Conhecimento e raciocínio | |||
| ENEMquestões oficiais, múltipla escolha | 32,8% | 27,6% | 500 · ±2,1 pp |
| ARC-Easy | 54,2% | 48,0% | conjunto de teste |
| ARC-Challenge | 41,4% | 40,4% | conjunto de teste |
| MMLU | 36,2% | 34,0% | conjunto de teste |
| Contexto longo | |||
| Agulha no palheiro em conversa32k / 64k / 128k tokens | 100 / 100 / 95% | — | 20 por comprimento |
| Perguntas sobre documentos longosacerto com F1 ≥ 0,5 sobre a resposta de referência | 36,2% | — | 116 documentos |
| Ferramentas | |||
| Chamada corretafunção e todos os argumentos iguais ao gabarito | 81,5%meta 85% | — | 173 casos |
| Função certaargumentos à parte | 94,2% | — | 173 casos |
| Recusa corretanão chama quando nenhuma ferramenta serve | 82,5%meta 80% | — | 63 casos |
| Chamadas com JSON inválido | 0 | — | 173 casos |
| Comportamento | |||
| Responde no idioma certo | 98%meta 90% | — | 50 perguntas |
ENEM, ARC e MMLU por verossimilhança normalizada pelo comprimento da resposta. O único erro de idioma do mochat-2 foi a resposta "Leonardo da Vinci" a uma pergunta em inglês, que o detector classificou como português. Todos os testes de ferramentas e de documentos longos usam dados separados dos de treino; nenhuma pergunta de teste aparece no treino.
Contexto longo
Nossa primeira versão de 128k aceitava textos desse tamanho e respondia, mas a agulha no palheiro mostrou o problema: o modelo achava o fato escondido em 95% dos casos a 32 mil tokens, em 30% a 64 mil e em 20% a 128 mil. Olhando por profundidade, ele só acertava quando o fato estava a menos de 16 a 25 mil tokens da pergunta. A janela era de 128k; o contexto útil, de 32k.
Mais dados longos não resolveram. Uma segunda extensão, com 3,5 bilhões de tokens de livros, código e web longa, deixou a agulha praticamente no mesmo lugar. O diagnóstico veio de testar mudanças só na inferência, sem treinar nada: aumentar a base do RoPE de 1 milhão para 2 milhões e escalar as consultas das camadas de atenção global pelo logaritmo da posição levou o modelo de 25% para 60% a 128k. O gargalo era posicional, a atenção se diluindo em sequências longas, e não falta de capacidade.
Incorporamos as duas mudanças ao modelo e fizemos o ajuste fino com perguntas sobre documentos de até 128 mil tokens, metade em português, em que a resposta aparece em qualquer ponto do texto. O resultado está abaixo.
A agulha é o teste fácil: um fato isolado, procurado com as mesmas palavras. O teste difícil são perguntas sobre documentos reais, em que a resposta precisa ser localizada e reformulada. Nele o mochat-2 acerta pouco mais de um terço das vezes, e cai conforme o documento cresce:
| tamanho do documento | acerto | F1 médio | casos |
|---|---|---|---|
| até 32 mil tokens | 42,9% | 0,47 | 49 |
| 32 a 64 mil | 33,3% | 0,40 | 27 |
| 64 a 128 mil | 30,0% | 0,39 | 40 |
| em português / em inglês | 32,8% / 40,4% | 0,40 / 0,46 | 64 / 52 |
Na primeira versão de 128k, o mesmo teste dava 23,3% no total, com 20% acima de 64 mil tokens. Com 116 casos, diferenças de até ~9 pontos entre versões estão dentro do ruído.
Ferramentas
No mochat-1, a busca na web era acionada pelo servidor: o modelo nunca pedia
nada por conta própria. O mochat-2 aprendeu um protocolo próprio, com tokens dedicados para a
declaração de ferramentas, para cada chamada e para o resultado. A API traduz esse protocolo para o
formato da OpenAI: você envia tools, recebe tool_calls, responde com uma
mensagem de papel tool, e o modelo usa o resultado na resposta final. Várias chamadas
no mesmo turno são suportadas.
O servidor não corrige nem completa o que o modelo escreve. Se ele errar o nome de um argumento, a chamada sai errada, e é isso que medimos.
| medida | inglês | português | total |
|---|---|---|---|
| Chamada correta (função e argumentos) | 82,8% | 80,2% | 81,5% |
| Função certa | 93,1% | 95,3% | 94,2% |
| Recusa correta | 80,0% | 87,0% | 82,5% |
| JSON inválido | 0 | 0 | 0 |
Estabelecemos 85% de chamadas corretas como critério antes de treinar, e o mochat-2 fica em 81,5%. Quase todos os erros estão nos argumentos, e não na escolha da função: um parâmetro opcional a mais, uma data no formato errado, "week" onde o gabarito pede "last week".
Revisamos à mão os 36 erros de uma versão anterior. Cerca de dez eram do gabarito, e não do modelo: valores que não aparecem na conversa, traduções inconsistentes entre a fala e o rótulo. Sem eles, o teto prático deste teste fica perto de 84%. Mantemos o número oficial com o gabarito como está, e corrigimos só um erro do avaliador, que tratava 101 e 101,0 como valores diferentes.
Usamos um modelo aberto maior para refazer 30 mil chamadas de treino, guardando só as que ele reproduzia exatamente, e para gerar exemplos novos com valores copiados literalmente do pedido. Em português, essa regra ensinou o modelo a enviar "comédia" onde a API espera "comedy". O inglês ficou igual, o português despencou, e a versão foi descartada.
O modelo gerava 8 respostas por pedido e era recompensado por acertar função, argumentos e valores. A recompensa nos próprios dados de treino caiu de 0,93 para 0,54 em 150 passos, e a chamada correta foi de 80% para 69%. O passo de otimização era grande demais para lotes tão pequenos e ruidosos, e como quase todas as recusas já davam certo, o sinal empurrava só para "chamar mais".
Com taxa de aprendizado seis vezes menor, o dobro de exemplos por passo e mais casos de recusa, a recompensa ficou estável e a chamada correta subiu de 80,3% para 81,5%, sem perda em nenhum outro teste. É a versão publicada. O ganho equivale a dois casos em 173, dentro do ruído.
O próximo passo é um conjunto de treino maior, focado em parâmetros opcionais e formatos de data, com valores no formato que a API espera.
Como usar
O identificador é mochat-2. A API é compatível com a da OpenAI,
incluindo streaming. Este é o exemplo do clima, com a resposta real do modelo publicado:
from openai import OpenAI
client = OpenAI(base_url="https://chat-api.mozyke.com/v1", api_key="SUA_CHAVE")
tools = [{"type": "function", "function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {"type": "object",
"properties": {"city": {"type": "string"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}},
"required": ["city"]}}}]
r = client.chat.completions.create(
model="mochat-2", tools=tools, temperature=0,
messages=[{"role": "user", "content": "Como está o tempo em Curitiba agora, em celsius?"}])
print(r.choices[0].message.tool_calls[0].function)
saídaname='get_weather' arguments='{"city": "Curitiba", "unit": "celsius"}'
Devolva o resultado como uma mensagem {"role": "tool",
"tool_call_id": ..., "content": ...} e chame de novo: o modelo escreve a resposta final com
base nele. Sem tools, o mochat-2 funciona como um modelo de conversa comum. Respostas
curtas saem a cerca de 42 tokens por segundo; um documento de 104 mil tokens leva uns 23 segundos
para ser lido antes da primeira palavra.
No playground, o botão Busca na web declara uma ferramenta web_search
e diz ao modelo, em uma frase, que ele guarda poucos fatos de memória. Ele decide quando pesquisar e
escreve a consulta; o servidor só executa a busca e devolve os resultados. Pela API, o mesmo vale
com "web_search": true no corpo da requisição.
Como foi construído
Tudo rodou em dois NVIDIA DGX Spark ligados por cabo direto. Nenhum peso veio de outro modelo.
27,8 bilhões de tokens em dois estágios: o primeiro com 45% de inglês, 42% de português, 8% de código e 5% de matemática; o segundo, mais curto, com metade em português e mais matemática. O CORE, uma média de benchmarks em inglês, chegou a 0,281, contra 0,204 do mochat-1 e 0,257 do GPT-2 de 1,6 bilhão de parâmetros.
De 4 mil para 32 mil tokens e depois para 128 mil, com documentos longos do próprio corpus, livros e código. Atenção local de 1.024 tokens em três de cada quatro camadas e atenção global na quarta mantêm o custo de 128k viável numa única máquina.
RoPE com base de 2 milhões e escala logarítmica nas camadas globais, escolhidas por um diagnóstico que mediu nove combinações só na inferência antes de treinar qualquer coisa.
Conversa, código, SQL e ferramentas em 4 mil tokens; depois perguntas sobre documentos de até 128 mil tokens, metade em português; por fim um estágio curto de escolha de idioma, que levou a resposta no idioma certo de 88% para 98–100%.
REINFORCE com recompensa calculada por programa contra o gabarito: função, conjunto de argumentos e valores, e recompensa por não chamar quando nenhuma ferramenta serve.
Dados
O pré-treino usa corpora abertos: em português, GigaVerbo-v2, FineWeb-2, FineWeb2-HQ e a Wikipédia; em inglês, FineWeb-Edu e Cosmopedia; além de código e de matemática abertos, como o FineMath.
Os dados de ferramentas partiram de conjuntos públicos em inglês (Glaive, ToolACE, Hermes). A tradução para o português, as perguntas sobre documentos longos e os exemplos de escolha de idioma foram gerados pelo Qwen3-30B-A3B-Instruct, um modelo aberto sob licença Apache 2.0, rodando nas nossas próprias máquinas.
Não usamos respostas do Claude, do GPT ou do Gemini para treinar o mochat-2: os termos desses serviços proíbem treinar modelos concorrentes, e isso importa para quem vai usar o modelo numa empresa. Pelo mesmo motivo retiramos do corpus um conjunto popular de instruções em português gerado pelo GPT-4, mesmo custando 5 pontos da mistura planejada.
Limitações
Ficha técnica
mochat-2 · compatível com OpenAI · tools e streamingmochat2v2_rl2, passo 80Disponibilidade
O mochat-2 é o modelo padrão do playground a partir de hoje e está disponível na
API como mochat-2. O mochat-1 continua disponível, assim como sua versão supervisionada
e o modelo de pré-treino.