AIDive

Rodei o Claude Code no notebook: 1 de 2 tarefas passou

Por AIDive · Publicado em

Agentes de códigoModelos de IA

Introdução

O Claude Code rodando num modelo de notebook passou em uma das nossas duas tarefas reais. A maioria das demos desse setup para no "hello"; nós demos dois trabalhos a um modelo local pequeno, dentro de um pacote Python, e contamos o que aconteceu, junto com o alias e a regra que mantivemos.

O setup é simples. Quando o limite do seu plano estoura no meio de uma tarefa, você espera o reset ou passa o trabalho para o mesmo Claude Code rodando contra um modelo na sua própria máquina. No trabalho que atravessava arquivos, o modelo local disse que todos os testes passavam, enquanto a renomeação que ele fez tinha quebrado um import. Uma única flag, --bare, transformou uma execução local que não mudava nada em um sucesso limpo na mesma tarefa.

Este artigo cobre o alias, a flag que resolve o problema, a armadilha da janela de contexto, o trabalho que atravessa arquivos e a regra sobre quais trabalhos vão para o local e quais esperam o seu plano.

Claude Code no seu próprio modelo

O Claude Code tem duas partes. O harness é o programa no seu terminal que lê seus arquivos, executa seus comandos e faz as edições. O modelo decide o que fazer em seguida e, por padrão, vive nos servidores da Anthropic e conta contra o seu plano.

Uma única configuração, a URL base, diz ao harness para onde enviar as perguntas. O Ollama é um programa que baixa modelos abertos e os serve em um endereço na sua própria máquina. Nada no Claude Code muda, só o endereço com que ele conversa, e por isso uma linha no shell basta. É parecido com apontar seu app para um banco de dados local em vez do de produção.

Para configurar, instale o Ollama com o Homebrew e depois baixe um modelo que caiba na sua memória. O nosso foi o qwen3.5:9b, 7,6 GB, num MacBook Pro M1 Pro com 16 GB. As versões maiores do mesmo modelo simplesmente não cabiam. Compare o tamanho do modelo com a sua memória antes de baixar qualquer coisa, porque o modelo inteiro precisa caber nela junto com tudo o que você já tem aberto.

Um aviso da própria documentação da Anthropic: ela não oferece suporte a rotear o Claude Code para modelos que não sejam Claude. Se algo quebrar nesse setup, você está por conta própria, e o modelo que você roda é bem menor do que o que o seu plano oferece.

O alias claude-alt

Um alias é um nome curto que o seu shell expande para um comando mais longo. Ao colocar toda a troca em um alias, o seu claude do dia a dia continua usando o plano, porque as configurações só valem quando você chama o alias.

O guia do próprio Ollama fornece as configurações: o endereço local, um token de mentira e uma API key. A key merece atenção. A documentação do Claude Code diz que uma key definida é usada no lugar da sua assinatura, mesmo que você esteja logado, e é por isso que ela fica só na linha do alias. Você abre o arquivo do shell, cola o alias com o nome do modelo no final e recarrega o arquivo.

alias claude-alt='CLAUDE_CODE_ATTRIBUTION_HEADER=0 ANTHROPIC_AUTH_TOKEN=ollama ANTHROPIC_API_KEY=ollama ANTHROPIC_BASE_URL=http://localhost:11434 claude --bare --model qwen3.5:9b'

Esta é a versão final, já com o --bare (a próxima seção explica o porquê). CLAUDE_CODE_ATTRIBUTION_HEADER=0 é uma configuração que os guias para modelos locais recomendam. Nunca medimos o que ela faz, então trate-a como opcional.

Começamos sem o --bare. A primeira tarefa real, num pequeno pacote Python que escrevemos para este teste, era adicionar uma opção a um arquivo e executá-lo. O Claude Code iniciou, avisou que não conhecia esse modelo e continuou trabalhando enquanto o relógio corria. Depois de 15 minutos ele não tinha alterado uma única linha, então o interrompemos, e a opção não existia.

Se você testar o alias do jeito que está, provavelmente verá a mesma coisa: uma sessão que continua trabalhando e um arquivo que nunca muda. O alias aponta o Claude Code para o seu modelo, mas num modelo pequeno isso não basta para concluir a tarefa.

A flag que faz ele responder: --bare

Toda sessão do Claude Code abre com um longo conjunto de instruções: seu arquivo de memória e suas ferramentas. Isso é tranquilo para o Claude e pesado para um modelo pequeno num notebook. A flag --bare é o modo mínimo do Claude Code. Ela pula hooks, plugins, memória e o arquivo do projeto, de modo que o modelo recebe uma página curta em vez de um manual.

Você adiciona --bare no final do alias e coloca a palavra ollama em ANTHROPIC_API_KEY, porque no modo mínimo o Claude Code só lê a key a partir dali. Com o mesmo pedido, o mesmo modelo pequeno e a mesma janela de contexto curta, a execução leu o arquivo, editou e rodou o comando. Terminou em 93 segundos com um arquivo alterado, e o comando imprimiu o slug com o prefixo na frente, exatamente como pedido: blog-hello-world.

Você confere como conferiria a alteração de um colega: leia um diff pequeno e rode o comando você mesmo.

O custo é real. O modo mínimo também descarta seus hooks e as regras do projeto, então o modelo local nunca vê as convenções que você escreveu. Se o seu projeto depende de um hook para bloquear algo perigoso, mantenha esse trabalho no plano, onde os seus hooks realmente rodam.

A armadilha dos 4k e a correção para 64k

A segunda armadilha é fácil de não notar porque o Ollama escolhe por você o tamanho da memória do modelo. Essa memória é a janela de contexto, quanto da conversa o modelo consegue manter à vista de uma vez. A documentação do Ollama diz que numa máquina como a nossa a janela padrão é pequena, 4k tokens abaixo de 24 GiB de VRAM, muito longe dos 64.000 que eles recomendam para ferramentas de código. Todas as nossas primeiras execuções usaram esse padrão, e você não percebe até conferir.

Para corrigir, pare o Ollama e inicie de novo com o tamanho de contexto em 64.000 (OLLAMA_CONTEXT_LENGTH=65536), depois rode ollama ps e leia a coluna CONTEXT. Você precisa definir isso toda vez que iniciar o servidor, e ollama ps é o único lugar que mostra que pegou. A coluna passou de 4096 para 65536, e o modelo usou só um pouco mais de memória: 7,6 GB antes, 7,7 GB depois.

Execução Contexto --bare Resultado Tempo
a-4k-nobare (alias sem --bare) 4096 não FALHA: interrompida no limite de 15 min, zero edições, sem resposta 900 s
a-4k (alias) 4096 sim PASSOU, blog-hello-world 93 s
a-64k (alias) 65536 sim PASSOU, blog-hello-world 35 s

A tarefa de um arquivo passou em 35 segundos, bem mais rápido do que com a janela pequena. O trabalho entre arquivos, tratado a seguir, também caiu de vários minutos para uns dois. O padrão pequeno não limita só a memória, ele deixa cada turno mais lento, e você acaba culpando o modelo quando a causa é a configuração.

O Claude Code, por sua vez, assume uma janela de 200k tokens para o auto-compact, bem maior do que a que o Ollama serve. CLAUDE_CODE_MAX_CONTEXT_TOKENS define o valor real. A diferença não nos atrapalhou nas tarefas curtas, e não testamos numa sessão longa. O limite é a memória, porque uma janela maior ocupa mais dela, e num notebook de 16 GB isso é mais ou menos até onde dá para ir.

O trabalho em vários arquivos: testes verdes, código quebrado

Com o modelo local respondendo rápido, a tentação é entregar a ele trabalho de verdade. Então demos um trabalho que atravessa arquivos: renomear smart_truncate para truncate_words em todo o pacote e manter smart_truncate como alias em slugkit/truncate.py. Um alias no código é o nome antigo mantido como ponteiro para a nova função, de modo que qualquer código que ainda use o nome antigo continua funcionando.

O modelo local trabalhou por uns dois minutos, editou os arquivos, rodou os testes, e todos passaram. Depois ele informou que o trabalho estava feito.

Execução Contexto --bare Resultado Tempo
b-plan (plano, Claude) n/a não PASSOU: 12 testes OK, imports antigo e novo funcionam, testes renomeados 38 s
b-4k (alias) 4096 sim QUEBROU: "All 12 unit tests pass", mas from slugkit import truncate_words dá ImportError; os testes ainda chamam smart_truncate via import truncate_words as smart_truncate 464 s
b-64k (alias) 65536 sim QUEBROU: 12 testes OK, informou como concluído, mas o alias foi para o __init__.py, então from slugkit.truncate import smart_truncate dá ImportError (a instrução dizia truncate.py) 142 s

Quando importamos o nome antigo do jeito que o código antigo faria, o Python recusou. O modelo tinha colocado o alias no arquivo de entrada do pacote em vez do módulo que pedimos, então o caminho de import antigo desapareceu. Com a janela pequena, a mesma tarefa quebrou de outro jeito: o nome novo nunca foi exportado, e os testes continuavam chamando o antigo.

Como todos os testes podem estar verdes com o código quebrado? Os testes só verificam o que verificam, e ninguém tinha escrito um teste para o import antigo. Um resultado verde do modelo local não diz nada sobre o que os testes não cobrem, nem garante que o que eles cobrem não quebrou.

No plano, o Claude fez o mesmo trabalho em 38 segundos, renomeou os testes também, e os imports antigo e novo funcionaram. Para ser justo, o trabalho do plano também merece uma conferência, mas aqui o modelo local errou o trabalho entre arquivos nas duas vezes. Depois de cada execução local, leia o diff você mesmo e importe os nomes antigos à mão antes de confiar num teste verde. Essa checagem leva menos tempo do que a execução e impede que um import quebrado chegue à sua branch principal.

A regra de troca

Quando o limite estoura, você tem poucos segundos para decidir se um trabalho vai para o local ou espera. Uma regra de troca são algumas linhas que você mantém junto ao alias, para que a decisão seja tomada antes de você estar com pressa. Abra o arquivo do shell e escreva três comentários acima do alias:

# claude-alt: one-file jobs I can check in a glance
# plan: anything across files, or that I can't check by reading the diff
# always: read the diff before committing

O modelo local recebe trabalhos em um único arquivo que você consegue conferir num relance, como adicionar uma opção, explicar uma função ou testar uma função. Tudo o que atravessa arquivos, ou que você não consegue conferir lendo o diff, espera o seu plano. Seja qual for o modelo que escreveu o código, você lê o diff antes de fazer o commit.

A regra vem direto da nossa execução: a tarefa de um arquivo passou nas duas vezes, e a renomeação entre arquivos quebrou nas duas. O padrão faz sentido depois que você o vê falhar, porque um trabalho em um arquivo mantém tudo o que o modelo precisa diante dele.

Esse setup também tem limites que o Ollama lista na própria documentação. Ele não tem prompt caching, em que o servidor mantém o começo da conversa pronto, então numa sessão longa cada turno relê tudo e deixa você mais lento. Ele não consegue forçar o modelo a usar uma ferramenta específica. E a Anthropic não oferece suporte ao Claude Code em modelos que não sejam Claude. Nossa regra vem de duas tarefas num pacote pequeno, então trate-a como ponto de partida e amplie com as suas próprias execuções.

Veredito

Quando o limite do plano estoura no meio de uma tarefa, um alias roda o mesmo Claude Code num modelo no seu notebook. No nosso teste, ele passou na tarefa de um arquivo e quebrou a de vários. A execução quebrada é a perigosa, porque informou todos os testes verdes enquanto um import estava falhando.

Use quando você está travado, o trabalho cabe em um arquivo e você consegue ler o diff inteiro antes de fazer o commit. Não use para nada que atravesse arquivos, para sessões longas ou para trabalho que você não vai revisar, porque é aí que ele falha em silêncio.

No plano, cada tarefa levou menos de 40 segundos (21 s e 38 s), então, quando o seu reset está perto, esperar costuma ser a escolha mais rápida. O alias não substitui o seu plano. Ele mantém você andando em trabalhos pequenos enquanto espera o plano voltar, e se você configurar hoje, ele estará pronto na próxima vez que o limite estourar.

A regra para lembrar: o modelo local é para trabalhos que você consegue conferir num relance.

Recursos gratuitos

  • Pack de vídeo

    Claude Code no Ollama: o alias claude-alt e a regra de troca

    O bloco do alias claude-alt, uma regra de troca de uma página, o checklist de segunda-feira e nossa tabela de execuções do Claude Code num notebook de 16 GB com qwen3.5:9b.

    6 min de leitura · Rodei o Claude Code no notebook: 1 de 2 tarefas passou

Fontes

Perguntas frequentes

Dá para rodar o Claude Code com um modelo local do Ollama?
Sim. Defina a URL base para o endereço do seu Ollama, um token de mentira e uma API key, e passe o nome de um modelo. A Anthropic não oferece suporte a rotear o Claude Code para modelos que não sejam Claude, então, se quebrar, você está por conta própria.
O que a flag --bare faz no Claude Code?
`--bare` é o modo mínimo do Claude Code. Ela pula hooks, plugins, memória e o arquivo do projeto, de modo que um modelo pequeno recebe um prompt curto. Na nossa execução, ela transformou uma sessão de 15 minutos com zero edições em um sucesso de 93 segundos.
Por que meu modelo local está lento no Claude Code com Ollama?
O Ollama usa por padrão uma janela de contexto de 4k abaixo de 24 GiB de VRAM. Inicie o servidor com `OLLAMA_CONTEXT_LENGTH=65536` e confira a coluna `CONTEXT` em `ollama ps`. Nossa tarefa de um arquivo caiu para 35 segundos.
Um modelo local é bom o bastante para substituir o Claude Code no meu plano?
Não. No nosso teste ele passou numa tarefa de um arquivo, mas quebrou uma renomeação em vários arquivos informando os 12 testes verdes. Use para trabalhos que você confere em um único diff e deixe o trabalho entre arquivos para o seu plano.
O que devo conferir depois que um modelo local termina um trabalho?
Leia o diff e importe os nomes antigos à mão. Testes verdes só cobrem o que os testes verificam, e ninguém tinha testado o import antigo que a renomeação quebrou.
O que o endpoint Anthropic do Ollama não suporta?
A documentação do Ollama lista a ausência de prompt caching e de escolha forçada de ferramenta. Sem caching, cada turno de uma sessão longa relê a conversa inteira, o que deixa você mais lento.

Vídeos relacionados