O que é um LLM e como ele realmente funciona
Token, contexto, temperatura e alucinação explicados com um modelo de linguagem minúsculo escrito em JavaScript, rodando e imprimindo de verdade.
LLM é a sigla de large language model, modelo de linguagem grande. Por baixo de toda a conversa que você tem com um assistente de IA existe uma máquina que faz uma única coisa: dado um texto, prever qual é o próximo pedaço de texto mais provável. Repete isso algumas centenas de vezes e sai um parágrafo.
Não há intenção, memória nem verificação nesse processo. Isso soa reducionista, e é — mas é o modelo mental correto, e é ele que explica todos os comportamentos estranhos que você já viu.
A melhor forma de entender é escrever um. O modelo abaixo é ridiculamente pequeno, roda em JavaScript puro e não tem rede neural nenhuma. Ainda assim, ele exibe três dos quatro comportamentos que importam: probabilidade, temperatura e alucinação. Se objeto, array e função ainda não são território conhecido, leia o código pelo comportamento e volte a ele depois — a ideia sobrevive sem a sintaxe.
Um autocomplete gigantesco, uma previsão por vez
Imagine o autocomplete do celular depois de ler uma biblioteca inteira. Você escreve um começo, ele compara aquele começo com padrões que aprendeu e aposta no próximo pedaço. Assim que escolhe, o texto ficou um pouco maior e ele faz uma nova aposta. Repetir esse ciclo muitas vezes produz uma resposta que parece ter sido planejada do começo ao fim.
Num LLM, cada pedaço é um token e cada aposta é uma distribuição de probabilidades calculada pelo modelo. A analogia não transforma o modelo num teclado: ela só isola o mecanismo central, a previsão do próximo token. Na microprática abaixo, dê o mesmo começo ao modelo pequeno mais de uma vez e compare os finais; a variação observada mostra a escolha probabilística em ação.
Um modelo de linguagem é treinado lendo texto e contando o que costuma vir depois do quê. Vamos treinar um com cinco frases de um atendimento de loja:
const corpus = `
o cliente pediu reembolso do pedido
o cliente pediu troca do produto
o cliente pediu segunda via do boleto
o cliente cancelou o pedido
o cliente elogiou o atendimento
`;
const palavras = corpus.trim().split(/\s+/);
const seguintes = {};
for (let i = 0; i < palavras.length - 1; i++) {
const atual = palavras[i];
seguintes[atual] ??= {};
seguintes[atual][palavras[i + 1]] = (seguintes[atual][palavras[i + 1]] ?? 0) + 1;
}
const depoisDeCliente = seguintes['cliente'];
const total = Object.values(depoisDeCliente).reduce((a, b) => a + b, 0);
for (const [palavra, vezes] of Object.entries(depoisDeCliente)) {
console.log(palavra.padEnd(10), (vezes / total).toFixed(2));
}Isso é um modelo de linguagem. Depois da palavra “cliente”, ele atribui 60% a “pediu” e 20% a cada uma das outras duas. Um LLM de verdade faz exatamente a mesma coisa, com três diferenças de escala: olha para milhares de palavras anteriores em vez de uma, distribui a probabilidade entre cem mil possibilidades em vez de três, e aprendeu essas probabilidades ajustando bilhões de parâmetros em vez de contando ocorrências.
A operação, porém, é essa: uma distribuição de probabilidade sobre o próximo pedaço. E o parágrafo inteiro sai de repetir esse passo, uma vez por token, realimentando o resultado na entrada:
Não existe uma etapa de “decidir o que dizer” antes dessa alça. O texto inteiro é o subproduto de repeti-la.
Token: o pedaço não é a palavra
O modelo não trabalha com palavras nem com letras, e sim com tokens — fragmentos de texto de tamanho variável, decididos por um algoritmo de compressão durante o treino.
Palavras comuns viram um token só. Palavras raras, nomes próprios e termos em
português são quebrados em pedaços: “inteligência” pode virar algo como
intel + ig + ência. Números costumam ser fatiados de formas
contraintuitivas, o que é parte da razão de os modelos errarem aritmética.
Duas consequências práticas:
- Preço e limite são contados em tokens, não em caracteres. Como regra de bolso para português, algo entre 3 e 4 caracteres por token. Textos em inglês rendem mais tokens por real gasto, porque os tokenizadores foram treinados majoritariamente em inglês.
- Pedir para “contar as letras de uma palavra” é pedir para o modelo enxergar algo que ele não recebe. Ele viu tokens, não letras.
Contexto: a janela, e a memória que não existe
A janela de contexto é o número máximo de tokens que entram numa chamada: instruções, histórico da conversa, documentos anexados e a resposta que está sendo gerada, tudo somado.
Fora dessa janela, não existe memória. Um chat parece lembrar do que você disse porque a aplicação reenvia o histórico inteiro a cada mensagem. Quando o histórico passa do limite, alguém precisa cortar — e é aí que o assistente “esquece” o que foi combinado no começo.
const historico = [
{ papel: 'sistema', texto: 'Você é o suporte da Club Store.' },
{ papel: 'usuario', texto: 'Meu pedido 1042 não chegou.' },
{ papel: 'assistente', texto: 'Vou verificar o rastreio do pedido 1042.' },
{ papel: 'usuario', texto: 'Consigo cancelar?' },
];
const estimarTokens = (texto) => Math.ceil(texto.length / 3.6);
const cabemNaJanela = (mensagens, limite) => {
const mantidas = [];
let usados = 0;
for (const m of [...mensagens].reverse()) {
const custo = estimarTokens(m.texto);
if (usados + custo > limite) break;
usados += custo;
mantidas.unshift(m);
}
return { mantidas, usados };
};
const { mantidas, usados } = cabemNaJanela(historico, 20);
console.log('tokens usados:', usados);
console.log('mensagens que sobreviveram:', mantidas.map((m) => m.papel));Repare no que se perdeu: a instrução de sistema. Uma janela apertada e uma estratégia ingênua de corte descartaram justamente a mensagem que definia o comportamento do assistente. É por isso que aplicações sérias fixam o prompt de sistema e cortam só o meio da conversa.
Temperatura: o quanto ele se permite arriscar
Tendo a distribuição de probabilidades, falta decidir como escolher. Temperatura é o parâmetro que achata ou afia essa distribuição antes do sorteio.
const contagens = { pediu: 3, cancelou: 1, elogiou: 1 };
function comTemperatura(contagens, temperatura) {
const nomes = Object.keys(contagens);
const logits = nomes.map((n) => Math.log(contagens[n]));
const escalados = logits.map((l) => l / temperatura);
const maior = Math.max(...escalados);
const exp = escalados.map((l) => Math.exp(l - maior));
const soma = exp.reduce((a, b) => a + b, 0);
return Object.fromEntries(nomes.map((n, i) => [n, exp[i] / soma]));
}
for (const t of [0.2, 1, 2]) {
const p = comTemperatura(contagens, t);
const linha = Object.entries(p).map(([n, v]) => `${n} ${v.toFixed(3)}`);
console.log(`T=${t}`.padEnd(7), linha.join(' '));
}Com temperatura 0,2 o favorito abocanha 99,2% da probabilidade: a saída fica quase determinística. Com temperatura 2 as três opções ficam próximas: o modelo passa a sortear alternativas improváveis com frequência.
Na prática: temperatura baixa para extrair dados, classificar e gerar código; temperatura alta para variação criativa. E note o que a tabela deixa claro — temperatura não mexe em qual token é o mais provável. Ela mexe só na chance de você receber outro.
Alucinação: fluência sem verificação
Aqui está a parte que mais confunde. Vamos treinar o mesmo modelo minúsculo com fatos de rastreio e deixá-lo gerar uma frase:
const corpus = `
o pedido 1042 foi entregue em Sorocaba
o pedido 1042 foi cancelado pelo cliente
o pedido 2318 foi entregue em Curitiba
o pedido 2318 foi extraviado pela transportadora
`;
const palavras = corpus.trim().split(/\s+/);
const seguintes = {};
for (let i = 0; i < palavras.length - 1; i++) {
(seguintes[palavras[i]] ??= []).push(palavras[i + 1]);
}
let semente = 7;
const aleatorio = () => ((semente = (semente * 1103515245 + 12345) % 2147483648) / 2147483648);
let atual = 'o';
const frase = [atual];
for (let i = 0; i < 7; i++) {
const opcoes = seguintes[atual];
if (!opcoes) break;
atual = opcoes[Math.floor(aleatorio() * opcoes.length)];
frase.push(atual);
}
console.log(frase.join(' '));Leia o corpus de novo. O pedido 1042 foi entregue ou cancelado. Quem foi extraviado foi o 2318. A frase que o modelo produziu é gramaticalmente perfeita, tem o formato exato de um fato de rastreio, e é falsa.
Ninguém mentiu. O modelo emendou trechos prováveis: depois de “1042 foi” cabe “extraviado”, porque “foi extraviado” apareceu no treino. A verificação de que a combinação corresponde a algo real simplesmente não faz parte da operação.
Alucinação não é um defeito que será consertado com um modelo maior. É o mesmo mecanismo que gera as respostas certas, aplicado onde os padrões prováveis não coincidem com os fatos. Modelos maiores erram menos porque viram mais; erram igual quando o dado não estava lá.
De onde vêm essas probabilidades
Contar ocorrências, como fizemos acima, só funciona em cinco frases. Com a internet inteira, o número de sequências possíveis é maior que o número de átomos disponíveis para guardá-las. Um LLM resolve isso comprimindo: em vez de uma tabela, uma função com bilhões de parâmetros ajustáveis — a diferença entre guardar todas as respostas e guardar uma regra capaz de produzi-las.
O treino acontece em três etapas, e vale conhecer os nomes porque eles explicam comportamentos diferentes.
Pré-treino. O modelo recebe quantidades enormes de texto com um pedaço escondido e tenta adivinhar o que vem a seguir. Errou, os parâmetros são corrigidos um pouquinho; repita bilhões de vezes. É aqui que ele absorve gramática, fatos, estilos e também os vieses do material. É a etapa cara — meses de máquina — e é por isso que o conhecimento tem data de corte.
Ajuste por instrução. Um modelo recém-pré-treinado não responde perguntas: ele completa texto. Perguntando “qual a capital da França?”, ele pode devolver mais perguntas, porque listas de perguntas são padrões prováveis. A segunda etapa treina em pares de pedido e resposta bem-feita, ensinando o formato de assistente.
Alinhamento com preferência humana. Pessoas comparam respostas duas a duas e dizem qual é melhor; essas comparações treinam o modelo a preferir respostas úteis, seguras e no tom certo. É daqui que vem boa parte da personalidade que você percebe — e também a tendência a concordar demais com quem pergunta.
A arquitetura por trás de tudo isso é o Transformer, apresentado em 2017. A ideia central, o mecanismo de atenção, é o que permite ao modelo pesar quais palavras anteriores importam para prever a próxima — em vez de tratar o texto como uma fila em que só o vizinho conta, como o nosso modelinho de bigrama faz.
O que o prompt realmente muda
Se o modelo é fixo depois do treino, o único ponto de controle que sobra é o texto que entra. Isso não é pouco: mudar o contexto muda a distribuição de probabilidade sobre a resposta inteira.
Três coisas mudam resultado de forma mensurável, e nenhuma delas é fórmula mágica:
- Contexto específico. Colar o dado real (o pedido, o log, o trecho de código) em vez de descrevê-lo. O modelo não pode consultar o que você não mandou.
- Formato pedido explicitamente. “Responda em JSON com as chaves
causaecorrecao” produz saída processável; “me explica o erro” produz um ensaio. - Exemplos. Duas ou três amostras de entrada e saída no formato desejado guiam melhor do que um parágrafo de instrução. É o que se chama de few-shot.
O que não muda muito: implorar, ameaçar, prometer gorjeta, ou repetir “importante” em maiúsculas. Se funcionou uma vez, foi ruído de amostragem — teste dez vezes antes de virar superstição.
Chamando um de verdade
A interface de todos os provedores é a mesma ideia: você manda a lista de mensagens e os parâmetros de amostragem, e recebe o texto gerado mais a contagem de tokens usados.
const resposta = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'content-type': 'application/json',
'x-api-key': process.env.ANTHROPIC_API_KEY,
'anthropic-version': '2023-06-01',
},
body: JSON.stringify({
model: 'claude-opus-5',
max_tokens: 2048,
output_config: { effort: 'low' },
system: 'Você é o suporte da Club Store. Responda em no máximo três frases.',
messages: [{ role: 'user', content: 'Meu pedido 1042 não chegou. O que faço?' }],
}),
});
const dados = await resposta.json();
const texto = dados.content.find((bloco) => bloco.type === 'text');
console.log(texto.text);
console.log(dados.usage);Os campos que decidem o resultado estão aí: system (as instruções fixas),
messages (o contexto) e o controle de esforço. O usage que volta é o que
você vai pagar — entrada e saída são cobradas em tokens, com preços diferentes.
Duas armadilhas nesse trecho, e as duas custam caro em produção:
contenté uma lista de blocos de tipos diferentes, não um texto. Nos modelos que raciocinam antes de responder, o primeiro item pode ser um bloco de raciocínio;content[0].textpega o bloco errado. Procure pelo bloco de tipotext, como no exemplo.max_tokensé o teto da resposta inteira, raciocínio incluído. Apertar esse número para economizar corta a resposta no meio, e você paga pelo pedaço truncado do mesmo jeito.
Onde os alunos se confundem
Depois de muita turma passando por este assunto, três confusões se repetem, e vale nomeá-las.
A primeira é achar que o modelo consulta a internet. Por padrão ele não consulta nada: responde a partir dos pesos, que foram congelados no fim do treino. Quando um produto de IA cita uma fonte, é porque alguém programou uma busca e colou o resultado no contexto antes de chamar o modelo. Isso é engenharia ao redor, não capacidade do modelo.
A segunda é confundir contexto com memória. Aluno pede ao assistente para “lembrar” de uma preferência e se frustra quando ele esquece. Não há onde guardar: se a informação não estiver no texto enviado nesta chamada, ela não existe. Persistência é um banco de dados que você escreve.
A terceira, e a mais cara, é tratar temperatura como controle de qualidade. Vejo gente baixando a temperatura para zero esperando eliminar erro factual. Não elimina — deixa o erro consistente. Se a resposta mais provável está errada, você passa a recebê-la todas as vezes, com firmeza.
O modelo mental que resolve as três: um LLM é um completador de texto muito bom, sem acesso ao mundo e sem estado. Tudo que ele sabe sobre a sua situação está no que você mandou nesta chamada. Todo produto de IA que funciona é, em grande parte, o trabalho de escolher bem o que colocar ali dentro.
Vale um aviso sobre usar LLM para aprender a programar, que é o uso mais comum entre quem está começando. Pedir explicação de um conceito funciona muito bem — o modelo é excelente em reformular. Pedir código pronto para um exercício funciona contra você: o código costuma rodar, e é exatamente por isso que engana. Quando ele erra, erra com a mesma segurança de quando acerta, e você ainda não tem repertório para diferenciar os dois casos. Um erro clássico dessa fase é receber um trecho que assume um dado sempre presente e cair no TypeError: Cannot read properties of undefined na primeira execução com dado real — a linha estava plausível, a suposição é que era falsa.
Perguntas frequentes
LLM é a mesma coisa que inteligência artificial?
O modelo aprende com as minhas conversas?
Por que o modelo erra conta simples?
Temperatura zero garante resposta correta?
Dúvidas e comentários
Travou em algum passo? Pergunte aqui — a equipe e outros alunos respondem.
Entrar para perguntarÉ o mesmo login gratuito dos cursos.
Nenhuma dúvida por aqui ainda — a primeira pode ser a sua.
Todo o código deste artigo foi executado em Node 24.16.0, e as saídas exibidas são as reais — como produzimos este conteúdo.


