SSD Nodes Learn 🎉 VPS desde $5.50/mês
Guias Matt ConnorPor Matt Connor · Atualizado 2026-08-21

Como o esforço de raciocínio afeta um LLM local

Entenda como cada nível altera tokens, tempo no CPU ou GPU e uso da janela de contexto, sem mudar pesos ou quantizacao do modelo local.

O que o esforço de raciocínio altera num LLM local

O esforço de raciocínio é uma definição que indica ao modelo quanto tempo deve pensar antes de responder. Altera o comprimento do segmento de raciocínio e nada mais. Os pesos armazenados no disco são idênticos em todos os níveis, a quantização é idêntica e a resposta resulta da mesma passagem direta. O que muda é o número de tokens que o modelo gasta primeiro no seu bloco de notas interno.

Essa distinção é importante devido ao local onde esses tokens são contabilizados. Numa API alojada, os tokens de raciocínio aparecem na fatura. Num VPS que controla, são pagos em tempo de geração no seu próprio CPU ou GPU e em espaço dentro da janela de contexto. Um modelo deixado no nível máximo de esforço pode gastar a maior parte da saída em raciocínio antes de aparecer a primeira palavra da resposta. Em hardware alojado localmente, isso pode ser a diferença entre uma resposta em dois segundos e uma resposta em dois minutos.

Onde o nível fica definido: no modelo de chat, não nos pesos

Um modelo de raciocínio é treinado para emitir um segmento de raciocínio, normalmente delimitado pelas tags <think> e </think>, antes da resposta final. O nível de esforço é uma instrução que o modelo de chat escreve no prompt. Esse modelo é um ficheiro Jinja fornecido com o modelo. Ele lê uma variável como reasoning_effort e gera uma linha diferente ao nível do sistema para cada valor. O modelo foi treinado para encurtar ou prolongar o seu bloco de raciocínio em resposta a essa linha.

Há duas consequências. Os nomes dos níveis pertencem ao modelo, não ao seu ambiente de execução. Por isso, um nome indicado no cartão de um modelo pode não significar nada noutro. Além disso, se qualquer componente da cadeia substituir o modelo de chat por um modelo genérico, a variável nunca é gerada e a configuração não produz efeito, sem apresentar um erro.

Verificado em 2026-08-20, o cartão do modelo Qwen3.8-27B documenta três níveis de esforço: low, medium e xhigh, com xhigh como predefinição. Não existe high. O raciocínio é ativado com enable_thinking, que fica ativado por predefinição. O cartão também documenta preserve_thinking, igualmente ativado por predefinição, que mantém o raciocínio de turnos anteriores no histórico da conversa. O gpt-oss utiliza low, medium e high. Muitas outras famílias aceitam apenas um valor booleano. Consulte o cartão da versão exata que instalou, porque estes nomes não são um padrão. Como executar um modelo 27B numa VPS vem primeiro. Esta página explica o que deve configurar depois de o modelo responder.

Por que um esforço de raciocínio elevado custa mais numa VPS

Tokens de saída. Os tokens de raciocínio são tokens gerados. Passam pelo mesmo ciclo de descodificação que a resposta, à mesma velocidade de tokens por segundo que o seu hardware consegue atingir. Suponha que uma tarefa produz 200 tokens de resposta e 4,000 tokens de raciocínio. Foram gerados 4,200 tokens, mas o leitor viu apenas 200. A velocidade de descodificação é determinada pela largura de banda da memória e pela quantização escolhida, por isso o único fator que resta controlar é o número de tokens.

Tempo de relógio. Uma pessoa espera pelo primeiro token da resposta, porque tudo o que acontece antes aparece como um ecrã vazio ou um indicador de carregamento recolhido. O raciocínio é emitido primeiro, por isso a espera corresponde aproximadamente ao número de tokens de raciocínio dividido pela velocidade de descodificação, acrescido do processamento do prompt. Duplicar o comprimento do raciocínio duplica essa espera.

Contexto. Os tokens de raciocínio ocupam a janela de contexto como qualquer outro token. Com preserve_thinking ativo, o bloco de notas da primeira interação continua no prompt da quinta, por isso o processamento do prompt fica mais lento a cada interação, enquanto a janela é preenchida pelas duas extremidades. Aumentar num_ctx para o manter consome memória da cache KV, que numa VPS sem GPU corresponde a RAM do sistema que pode não estar disponível.

Quando aumentar o nível e quando o manter baixo

Aumente-o para tarefas em que um passo intermédio incorreto compromete o resultado: aritmética com vários passos e conversão de unidades, planeamento de uma edição em vários ficheiros, código que tem de compilar e problemas de restrições em que uma resposta tem de satisfazer várias condições ao mesmo tempo. Nestes casos, o rascunho está a fazer trabalho real, e um rascunho mais longo é uma forma barata de detetar um erro que, de outro modo, o modelo poderia cometer.

Mantenha-o baixo quando a resposta já está nos dados de entrada e a tarefa consiste em a transferir. Extração, classificação, etiquetagem, tradução, reescrita, resumo e formatação enquadram-se nesta categoria. O segmento de raciocínio limita-se, na maior parte, a repetir a tarefa e dá ao modelo margem para contrariar a sua primeira intuição correta.

Mantenha-o baixo também para tudo o que seja interativo. Numa caixa de chat ou num editor, está no circuito, por isso uma resposta rápida que pode corrigir é melhor do que uma resposta lenta pela qual tem de esperar. Essa é a verdadeira compensação de apontar um agente de programação para um modelo local: um agente faz muitas chamadas pequenas, e o custo do raciocínio é cobrado em cada uma delas.

Como definir o nível no llama.cpp

O llama.cpp escreve a variável diretamente no template. Isso faz dele o runtime em que pode confirmar que o nível foi recebido. Aponte -m para o ficheiro GGUF que já tem.

llama-server -m ./qwen3.8-27b-Q4_K_M.gguf \
  --jinja \
  --reasoning-effort medium \
  --reasoning-format deepseek \
  -c 32768 \
  --host 127.0.0.1 --port 8080

--jinja usa o próprio chat template do modelo e está ativado por predefinição nas compilações atuais. --reasoning-effort aceita default, minimal, low, medium, high, xhigh ou max, em que default significa manter a predefinição do próprio template. Esta lista pertence ao vocabulário do llama.cpp, não ao do modelo. Por isso, passe apenas um nome listado no card: um nível que o template não defina pode causar um erro do template no momento do pedido. --reasoning-format deepseek move o raciocínio de message.content para message.reasoning_content. Isso permite medir a separação na secção seguinte.

Para desativar o raciocínio, em vez de o encurtar, defina manualmente a variável do template:

llama-server -m ./qwen3.8-27b-Q4_K_M.gguf --jinja \
  --chat-template-kwargs '{"enable_thinking": false}'

--reasoning-budget é um mecanismo diferente. Limita o segmento de raciocínio em tokens. 0 termina-o imediatamente e -1 deixa-o sem limite, em vez de pedir ao modelo que faça um plano mais curto. Ambos os flags aplicam-se a todo o servidor. O llama-server não aceita reasoning_effort como campo por pedido. Para servir dois níveis de esforço ao mesmo tempo, são necessários dois processos em duas portas.

O vLLM expõe a mesma variável por pedido, no corpo compatível com OpenAI:

{"model": "Qwen/Qwen3.8-27B",
 "messages": [{"role": "user", "content": "Summarise this changelog in two lines."}],
 "chat_template_kwargs": {"reasoning_effort": "medium"}}

Como definir o nível no Ollama

Ollama tem o seu próprio campo, think, em /api/chat e /api/generate. Ele aceita true, false ou um de low, medium, high e max, sendo que max pede o nível mais alto disponibilizado pelo modelo. O raciocínio fica ativado por padrão nos modelos que o suportam.

ollama run qwen3.8:27b --think=low "Draft a one line commit message for a README typo fix"
{"model": "qwen3.8:27b",
 "messages": [{"role": "user", "content": "Which HTTP status code means the request body was too large?"}],
 "think": "low",
 "stream": false}

O raciocínio é devolvido em message.thinking e a resposta em message.content, já separados. Numa sessão interativa ollama run, /set think e /set nothink ativam ou desativam essa função sem reiniciar.

Agora observe a diferença. O vocabulário do Ollama é low, medium, high e max. O template do Qwen3.8 define low, medium e xhigh. É necessário mapear um conjunto para o outro. Além disso, um modelo do Ollama contém um template incluído na sua tag, em vez do ficheiro Jinja do repositório original. Por isso, o nível que definir só chega ao modelo de acordo com esse template incluído. Não assuma que funcionou. A medição demora cerca de um minuto.

Como medir se o nível foi realmente aplicado

Envie o mesmo prompt com mais de um nível e defina temperature como 0. Depois, compare as contagens de tokens. Aqui, jq constrói o corpo para que não tenha de fazer o escape das aspas manualmente.

for level in low medium max; do
  body=$(jq -n --arg lvl "$level" '{
    model: "qwen3.8:27b",
    messages: [{role: "user", content: "A pump fills a 4500 litre tank in 25 minutes. A second pump is 40 percent slower. How long do both together take? Answer in minutes."}],
    think: $lvl,
    stream: false,
    options: {temperature: 0, num_ctx: 8192}
  }')
  echo "== $level"
  curl -s http://localhost:11434/api/chat -d "$body" | jq '{
    thinking_chars: (.message.thinking // "" | length),
    answer_chars: (.message.content | length),
    eval_count: .eval_count,
    seconds: (.total_duration / 1e9),
    tok_per_sec: (.eval_count / (.eval_duration / 1e9))
  }'
done

eval_count corresponde a todos os tokens gerados, incluindo o raciocínio. Por isso, a diferença entre dois níveis é quase toda devida ao raciocínio. thinking_chars fornece diretamente a separação. Devem verificar-se duas condições: os números devem variar entre os níveis e a resposta deve continuar correta no nível inferior. Se eval_count permanecer dentro do ruído nas três execuções, o nível está a ser ignorado. Nesse caso, a correção é usar um runtime que o transmita, não escolher outro nome de nível.

O tempo total é apenas metade da análise. Meça também o intervalo até ao primeiro token da resposta, fazendo streaming e parando no primeiro bloco content não vazio. Para isso, são necessários jq e bc.

start=$(date +%s.%N)
curl -sN http://localhost:11434/api/chat -d '{
  "model": "qwen3.8:27b",
  "messages": [{"role": "user", "content": "Explain what a reverse proxy does, in three sentences."}],
  "think": "low",
  "stream": true
}' |
while IFS= read -r line; do
  if [ -n "$(printf '%s' "$line" | jq -r '.message.content // ""')" ]; then
    echo "first answer token after $(echo "$(date +%s.%N) - $start" | bc)s"
    break
  fi
done

Execute em low e depois em max. A diferença é o tempo de espera que está a adicionar. No llama.cpp, os mesmos números são devolvidos na resposta, sem necessidade de fazer cálculos no shell:

curl -s http://localhost:8080/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"model": "local", "temperature": 0,
       "messages": [{"role": "user", "content": "A pump fills a 4500 litre tank in 25 minutes. A second pump is 40 percent slower. How long do both together take?"}]}' | jq '{
  reasoning_chars: (.choices[0].message.reasoning_content // "" | length),
  answer_chars: (.choices[0].message.content | length),
  predicted_n: .timings.predicted_n,
  tok_per_sec: .timings.predicted_per_second
}'

Faça este teste no seu próprio servidor. Uma comparação de esforço publicada foi medida em hardware que não é o seu. A sua taxa de descodificação é o fator que converte uma contagem de tokens em segundos. Medir tokens por segundo no seu próprio servidor fornece esse fator: os tokens de raciocínio divididos pela sua taxa de descodificação correspondem ao tempo de espera que acabou de adicionar.

O que pode correr mal

A resposta é cortada ou content fica vazio enquanto thinking fica preenchido. O limite de geração foi consumido pelo raciocínio. O num_predict do Ollama limita toda a geração, incluindo o raciocínio, e o raciocínio ocorre primeiro. Por isso, um limite de 512 tokens com esforço elevado pode terminar a resposta antes de ela começar. O Ollama apresenta "done_reason": "length" nessa resposta. Aumente o limite ou reduza o esforço. Como num_predict conta tokens explica esta interação em detalhe.

O nível não altera nada. As contagens de tokens são idênticas em todos os níveis. Isso significa que o runtime não está a passar a variável ou que o template não a está a ler. Verifique o template que o runtime está realmente a usar, e não o template do repositório original. O llama.cpp, com --jinja e --chat-template-kwargs, escreve a variável manualmente. Por isso, é um bom controlo: se o nível funcionar aí e não noutro local, o modelo está correto e o outro runtime está a ignorá-lo.

O nome de um nível é rejeitado. Um erro do template no momento do pedido, ou uma falha na primeira mensagem com um servidor que funciona corretamente, normalmente significa que foi passado um nível que o template não define. Por exemplo, high pode ser passado a um modelo cujo cartão lista apenas low, medium e xhigh.

As conversas com várias mensagens ficam mais lentas a cada turno. O raciocínio anterior está a ser mantido no histórico. Defina preserve_thinking como false se o modelo suportar essa opção, ou remova o campo thinking das mensagens que envia novamente. Caso contrário, o processamento do prompt aumenta a cada turno, enquanto as respostas mantêm o mesmo comprimento.

A qualidade diminui com esforço baixo numa tarefa que parecia simples. Algumas tarefas de extração não são apenas extração. Se a entrada exigir uma conversão de unidades ou a aplicação ordenada de uma regra, trata-se de uma tarefa de raciocínio com uma saída curta. Aumente o nível apenas nesse pedido, em vez de o aumentar em todo o servidor.

Executar dois níveis ao mesmo tempo

O llama.cpp fixa o nível no arranque. Por isso, um servidor que disponibiliza um editor e uma tarefa batch noturna precisa de dois processos em duas portas, cada um com o seu próprio --reasoning-effort. Dois processos também significam duas cópias dos pesos na memória, a menos que os trabalhos sejam separados no tempo. Num VPS, a configuração mais económica costuma ser um servidor de baixo esforço para tudo aquilo por que uma pessoa está à espera, além de uma execução agendada com esforço mais elevado para tarefas que ninguém está a acompanhar. O que acontece quando vários utilizadores partilham um modelo local também se aplica aqui: os tokens de raciocínio são trabalho de decodificação. Por isso, aumentar o esforço reduz a sua simultaneidade efetiva aproximadamente pelo mesmo fator em que aumenta a contagem de tokens.

FAQ

Que nível de esforço de raciocínio devo usar por predefinição?

Comece pelo nível mais baixo disponibilizado pelo modelo e aumente-o apenas para tarefas que já observou falharem. Vários modelos de raciocínio são distribuídos com um nível predefinido elevado, e o Qwen3.8-27B usa xhigh, o seu nível máximo, por predefinição em agosto de 2026. Essa predefinição é escolhida para obter bons resultados nas tabelas de benchmark, mas uma tabela de benchmark não contabiliza o tempo. No seu próprio hardware, o custo é medido em segundos. Por isso, faça do nível mais elevado uma opção por tarefa, em vez de o usar como configuração herdada por todos os pedidos.

Os tokens de raciocínio contam para a janela de contexto?

Sim. São tokens comuns na saída e ocupam espaço na janela de contexto juntamente com todo o restante conteúdo. A sua permanência no turno seguinte depende do runtime e do modelo. A documentação do Qwen3.8 descreve preserve_thinking, ativado por predefinição. Essa opção mantém o raciocínio anterior no histórico, pelo que uma conversa longa transporta todos os scratchpads que o modelo produziu. Defina-a como false ou remova o campo thinking das mensagens que reproduz. Assim, o processamento dos prompts deixa de aumentar.

Por que motivo alterar o nível de raciocínio não muda a contagem de tokens?

A configuração não está a chegar ao chat template. O nível é uma variável do template. Só funciona se o runtime a transmitir e se o template empacotado a ler. Alguns runtimes distribuem o seu próprio template com o modelo, em vez do ficheiro Jinja do repositório original. Nesse caso, a variável é descartada sem que seja apresentada qualquer mensagem de erro. Confirme-o enviando o mesmo prompt com o nível mais baixo e com o mais elevado, mantendo temperature em 0, e compare eval_count. Se as contagens coincidirem dentro da margem de variação, o nível está a ser ignorado.

Um esforço de raciocínio mais baixo torna o modelo menos preciso?

Depende da tarefa. É melhor medir do que assumir. Quando a resposta já está presente na entrada, como acontece na extração ou na reescrita, um scratchpad mais curto normalmente não altera o resultado. Quando uma etapa intermédia tem de estar correta antes de a etapa final poder ser concluída, como em cálculos aritméticos com várias etapas ou em código que tem de compilar, a precisão diminui com um scratchpad mais curto. Crie um conjunto de vinte prompts a partir da sua carga de trabalho real, execute-os com dois níveis mantendo temperature em 0 e conte as respostas erradas. Esse número é específico da sua carga de trabalho. Nenhuma tabela publicada o pode fornecer.