Intro
Claude Code na modelu z laptopa przeszedł jedno z naszych dwóch prawdziwych zadań. Większość demo tej konfiguracji kończy się na „hello”. My daliśmy małemu lokalnemu modelowi dwie prace w pakiecie Pythona i opisujemy, co się stało, razem z aliasem i regułą, którą zachowaliśmy.
Konfiguracja jest prosta. Gdy w środku zadania uderzysz w limit planu, albo czekasz na reset, albo przekazujesz pracę temu samemu Claude Code, który działa na modelu na twoim własnym komputerze. Przy zadaniu obejmującym wiele plików model lokalny zgłosił, że wszystkie testy przechodzą, choć zmiana nazwy zepsuła import. Jedna flaga, --bare, zmieniła lokalny przebieg, który niczego nie zmienił, w czyste zaliczenie tego samego zadania.
Ten artykuł omawia alias, flagę, która go naprawia, pułapkę okna kontekstu, zadanie obejmujące wiele plików oraz regułę, które prace idą na model lokalny, a które czekają na twój plan.
Claude Code na twoim własnym modelu
Claude Code składa się z dwóch części. Harness to program w twoim terminalu, który czyta pliki, uruchamia polecenia i wprowadza zmiany. Model decyduje, co zrobić dalej, a domyślnie działa na serwerach Anthropic i liczy się do twojego planu.
Jedno ustawienie, base URL, mówi harnessowi, dokąd wysyłać pytania. Ollama to program, który pobiera otwarte modele i udostępnia je pod adresem na twoim komputerze. W Claude Code nic się nie zmienia poza adresem, z którym rozmawia, dlatego wystarczy jedna linia w powłoce. To trochę jak skierowanie aplikacji na lokalną bazę danych zamiast produkcyjnej.
Aby to skonfigurować, zainstaluj Ollamę przez Homebrew, a potem pobierz jeden model, który zmieści się w pamięci. Nasz to qwen3.5:9b, 7,6 GB, na MacBooku Pro M1 Pro z 16 GB. Większe wersje tego samego modelu w ogóle by się nie zmieściły. Porównaj rozmiar modelu ze swoją pamięcią, zanim cokolwiek pobierzesz, bo cały model musi w niej siedzieć obok wszystkiego innego, co masz otwarte.
Jedno zastrzeżenie z dokumentacji samego Anthropic: nie wspiera ona kierowania Claude Code do modeli, które nie są Claude. Jeśli w tej konfiguracji coś się zepsuje, zostajesz sam, a model, który uruchamiasz, jest dużo mniejszy niż ten, który daje ci plan.
Alias claude-alt
Alias to krótka nazwa, którą powłoka rozwija do dłuższego polecenia. Jeśli całe przełączenie zapiszesz w jednym aliasie, zwykłe claude nadal korzysta z twojego planu, bo ustawienia działają tylko wtedy, gdy wywołasz alias.
Ustawienia podaje własny przewodnik Ollamy: lokalny adres, zastępczy token i klucz API. Klucz zasługuje na uwagę. Dokumentacja Claude Code mówi, że ustawiony klucz jest używany zamiast subskrypcji, nawet gdy jesteś zalogowany, dlatego trzymamy go tylko w linii aliasu. Otwierasz plik powłoki, wklejasz alias z nazwą modelu na końcu i przeładowujesz plik.
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'
To wersja końcowa, z już dodanym --bare (następna sekcja wyjaśnia dlaczego). CLAUDE_CODE_ATTRIBUTION_HEADER=0 to ustawienie polecane w przewodnikach dla modeli lokalnych. Nigdy nie zmierzyliśmy, co robi, więc traktuj je jako opcjonalne.
Zaczęliśmy bez --bare. Pierwsze prawdziwe zadanie, w małym pakiecie Pythona napisanym na potrzeby testu, polegało na dodaniu jednej opcji w jednym pliku i uruchomieniu go. Claude Code wystartował, ostrzegł, że nie zna tego modelu, i pracował dalej, a zegar tykał. Po 15 minutach nie zmienił ani jednej linii, więc go zatrzymaliśmy, a opcja nie istniała.
Jeśli wypróbujesz alias w tej postaci, prawdopodobnie zobaczysz to samo: sesję, która ciągle pracuje, i plik, który nigdy się nie zmienia. Alias kieruje Claude Code na twój model, ale w przypadku małego modelu to za mało, żeby wykonać zadanie.
Flaga, która sprawia, że odpowiada: --bare
Każda sesja Claude Code zaczyna się od długiego zestawu instrukcji: twojego pliku pamięci i narzędzi. Dla Claude to w porządku, dla małego modelu na laptopie to ciężar. Flaga --bare to tryb minimalny Claude Code. Pomija hooki, pluginy, pamięć i plik projektu, więc model dostaje krótką kartkę zamiast podręcznika.
Dodajesz --bare na końcu aliasu i wpisujesz słowo ollama w ANTHROPIC_API_KEY, bo w trybie minimalnym Claude Code czyta swój klucz tylko stamtąd. Przy tym samym poleceniu, tym samym małym modelu i tym samym małym oknie kontekstu przebieg przeczytał plik, zmienił go i uruchomił polecenie. Skończył w 93 sekundy, ze zmienionym jednym plikiem, a polecenie wypisało slug z prefiksem z przodu, dokładnie tak, jak prosiliśmy: blog-hello-world.
Sprawdzasz to tak, jak sprawdziłbyś zmianę kolegi: czytasz jeden mały diff i sam uruchamiasz polecenie.
Koszt jest realny. Tryb minimalny pomija też twoje hooki i reguły projektu, więc model lokalny nigdy nie widzi konwencji, które spisałeś. Jeśli twój projekt polega na hooku blokującym coś niebezpiecznego, zostaw tę pracę na planie, gdzie twoje hooki faktycznie działają.
Pułapka 4k i poprawka 64k
Druga pułapka łatwo umyka, bo Ollama sama wybiera rozmiar pamięci modelu. Ta pamięć to okno kontekstu, czyli ile rozmowy model może utrzymać w polu widzenia naraz. Dokumentacja Ollamy mówi, że na takiej maszynie jak nasza domyślne okno jest małe, 4k tokenów poniżej 24 GiB VRAM, daleko od 64 000, które zalecają dla narzędzi do kodowania. Wszystkie nasze pierwsze przebiegi używały tej wartości domyślnej i nie dowiesz się o tym, dopóki nie sprawdzisz.
Aby to naprawić, zatrzymaj Ollamę i uruchom ją ponownie z długością kontekstu ustawioną na 64 000 (OLLAMA_CONTEXT_LENGTH=65536), potem uruchom ollama ps i odczytaj kolumnę CONTEXT. Ustawiasz to przy każdym starcie serwera, a ollama ps to jedyne miejsce, które pokazuje, że zadziałało. Kolumna zmieniła się z 4096 na 65536, a model zajął ledwie więcej pamięci: 7,6 GB przed, 7,7 GB po.
| Przebieg | Kontekst | --bare |
Wynik | Czas |
|---|---|---|---|---|
a-4k-nobare (alias bez --bare) |
4096 | nie | FAIL: przerwany przy limicie 15 min, zero zmian, brak odpowiedzi | 900 s |
| a-4k (alias) | 4096 | tak | PASS, blog-hello-world | 93 s |
| a-64k (alias) | 65536 | tak | PASS, blog-hello-world | 35 s |
Zadanie w jednym pliku przeszło w 35 sekund, dużo szybciej niż z małym oknem. Zadanie obejmujące wiele plików, omówione dalej, też skróciło się z kilku minut do paru. Mała wartość domyślna nie tylko ogranicza pamięć, ale spowalnia każdą turę, a ty obwiniałbyś model, gdy winne jest ustawienie.
Claude Code wypisuje też ostrzeżenie, że nie zna tego modelu i zakłada okno 200k tokenów dla auto-compact, dużo większe niż to, co serwuje Ollama. CLAUDE_CODE_MAX_CONTEXT_TOKENS ustawia prawdziwą wartość. Ta rozbieżność nie zaszkodziła przy naszych krótkich zadaniach i nie testowaliśmy jej w długiej sesji. Granicą jest pamięć, bo większe okno zajmuje jej więcej, a na laptopie z 16 GB to mniej więcej tyle, ile da się wycisnąć.
Zadanie na wielu plikach: zielone testy, zepsuty kod
Skoro model lokalny odpowiada szybko, kusi, żeby dać mu prawdziwą pracę. Daliśmy mu więc zadanie obejmujące wiele plików: zmienić smart_truncate na truncate_words w całym pakiecie i zachować smart_truncate jako alias w slugkit/truncate.py. Alias w kodzie to stara nazwa zachowana jako wskaźnik na nową funkcję, dzięki czemu kod nadal używający starej nazwy dalej działa.
Model lokalny pracował kilka minut, zmienił pliki, uruchomił testy i każdy test przeszedł. Potem zgłosił, że zadanie jest skończone.
| Przebieg | Kontekst | --bare |
Wynik | Czas |
|---|---|---|---|---|
| b-plan (plan, Claude) | n/a | nie | PASS: 12 testów OK, stary i nowy import działają, testy przemianowane | 38 s |
| b-4k (alias) | 4096 | tak | BROKE: „All 12 unit tests pass”, ale from slugkit import truncate_words daje ImportError; testy nadal wołają smart_truncate przez import truncate_words as smart_truncate |
464 s |
| b-64k (alias) | 65536 | tak | BROKE: 12 testów OK, zgłoszone jako zrobione, ale alias trafił do __init__.py, więc from slugkit.truncate import smart_truncate daje ImportError (instrukcja mówiła truncate.py) |
142 s |
Gdy zaimportowaliśmy starą nazwę tak, jak zrobiłby to stary kod, Python odmówił. Model umieścił alias w głównym pliku pakietu zamiast w module, o który prosiliśmy, więc stara ścieżka importu zniknęła. Przy małym oknie to samo zadanie zepsuło się inaczej: nowa nazwa nigdy nie została wyeksportowana, a testy nadal wołały starą.
Jak to możliwe, że wszystkie testy są zielone, a kod zepsuty? Testy sprawdzają tylko to, co sprawdzają, i nikt nie napisał testu na stary import. Zielony przebieg modelu lokalnego mówi, że nie zepsuło się nic z tego, co testy pokrywają, a nic nie mówi o tym, czego nie pokrywają.
Na planie Claude zrobił tę samą pracę w 38 sekund, przemianował też testy, a zarówno stary, jak i nowy import działały. Uczciwie mówiąc, praca z planu też zasługuje na sprawdzenie, ale tutaj model lokalny dwukrotnie źle wykonał zadanie obejmujące wiele plików. Po każdym lokalnym przebiegu przeczytaj diff sam i zaimportuj stare nazwy ręcznie, zanim zaufasz zielonym testom. Takie sprawdzenie trwa krócej niż przebieg i zatrzymuje zepsuty import przed trafieniem do głównej gałęzi.
Reguła przełączania
Gdy uderzysz w limit, masz kilka sekund, żeby zdecydować, czy praca idzie na model lokalny, czy czeka. Reguła przełączania to kilka linii trzymanych obok aliasu, żeby decyzja zapadła, zanim się spieszysz. Otwórz plik powłoki i wpisz trzy komentarze nad aliasem:
# 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
Model lokalny dostaje prace w jednym pliku, które możesz sprawdzić rzutem oka, jak dodanie opcji, wyjaśnienie funkcji czy przetestowanie jednej funkcji. Wszystko, co obejmuje wiele plików albo czego nie możesz sprawdzić, czytając diff, czeka na twój plan. Niezależnie od tego, który model napisał kod, czytasz diff przed commitem.
Reguła wynika wprost z naszego przebiegu: zadanie w jednym pliku przeszło dwa razy, a zmiana nazwy w wielu plikach zepsuła się dwa razy. Ten wzorzec ma sens, gdy raz zobaczysz, jak zawodzi, bo praca w jednym pliku trzyma wszystko, czego model potrzebuje, tuż przed jego oczami.
Ta konfiguracja ma też ograniczenia, które Ollama wymienia we własnej dokumentacji. Nie ma prompt cachingu, czyli serwera trzymającego w gotowości początek rozmowy, więc w długiej sesji każda tura czyta wszystko od nowa i cię spowalnia. Nie może wymusić na modelu użycia konkretnego narzędzia. A Anthropic nie wspiera Claude Code na modelach, które nie są Claude. Nasza reguła pochodzi z dwóch zadań na jednym małym pakiecie, więc traktuj ją jako punkt wyjścia i rozszerzaj własnymi przebiegami.
Werdykt
Gdy limit planu uderza w środku zadania, jeden alias uruchamia to samo Claude Code na modelu na twoim laptopie. W naszym teście zaliczył zadanie w jednym pliku i zepsuł to obejmujące wiele plików. Groźny jest ten zepsuty przebieg, bo zgłosił wszystkie testy na zielono, podczas gdy import nie działał.
Używaj go, gdy jesteś zablokowany, praca mieści się w jednym pliku i możesz przeczytać cały diff przed commitem. Nie używaj go do niczego, co obejmuje wiele plików, do długich sesji ani do pracy, której nie sprawdzisz, bo tam zawodzi po cichu.
Na planie każde zadanie zajęło poniżej 40 sekund (21 s i 38 s), więc gdy reset jest blisko, czekanie bywa szybszym wyborem. Alias nie zastępuje twojego planu. Pozwala pracować nad małymi zadaniami, gdy czekasz na jego powrót, a jeśli skonfigurujesz go dziś, będzie gotowy następnym razem, gdy uderzysz w limit.
Reguła do zapamiętania: model lokalny jest do prac, które możesz sprawdzić rzutem oka.
AIDive