AIDive

वीडियो पैक

Ollama पर Claude Code: claude-alt alias और स्विच का नियम

6 मिनट पढ़ें

TL;DR और निष्कर्ष

जब टास्क के बीच आपके Claude प्लान की लिमिट लगे, तो आप वही Claude Code Ollama के ज़रिए अपने लैपटॉप के मॉडल पर चला सकते हैं। हमने यह 16 GB वाले M1 Pro पर qwen3.5:9b के साथ किया और उसे एक छोटे Python पैकेज में दो असली टास्क दिए।

  • टास्क A, एक-फ़ाइल वाला --prefix विकल्प: --bare के बिना लगभग पंद्रह मिनट तक कुछ नहीं हुआ। --bare के साथ यह 93 s में पास हुआ।
  • टास्क B, कई फ़ाइलों में rename: लोकल मॉडल ने टेस्ट हरे बताए, और दोनों रन में (4k और 64k context) एक import टूटा था। प्लान पर Claude ने इसे 38 s में किया और import चलते रहे।
  • Ollama हमारी जैसी मशीन को डिफ़ॉल्ट रूप से 4k context देता है। OLLAMA_CONTEXT_LENGTH=65536 उसे बढ़ाता है।

निष्कर्ष: alias उन एक-फ़ाइल वाले कामों के लिए सेट करने लायक है जिन्हें आप एक नज़र में जाँच सकें। कई फ़ाइलों वाला कुछ भी प्लान का इंतज़ार करे, और diff आप हमेशा पढ़ें। पैक में alias ब्लॉक और एक पन्ने का नियम कार्ड है।

स्रोतों के साथ सार

सेटअप तीन environment variable और एक मॉडल का नाम है। Ollama की गाइड Claude Code को ANTHROPIC_AUTH_TOKEN=ollama के साथ http://localhost:11434 की ओर मोड़ती है s1। Claude Code के डॉक्स कहते हैं कि ANTHROPIC_BASE_URL API endpoint को ओवरराइड करता है s17। क्योंकि variable alias की लाइन में हैं, सादा claude आपका प्लान ही इस्तेमाल करता रहता है।

सेट की हुई API key आपके सब्सक्रिप्शन को बदल देती है। Claude Code के डॉक्स कहते हैं कि सेट की हुई ANTHROPIC_API_KEY सब्सक्रिप्शन की जगह इस्तेमाल होती है, भले ही आप लॉग इन हों s17। इसीलिए variable alias में होने चाहिए, आपके शेल प्रोफ़ाइल में नहीं।

मॉडल को मेमोरी में समाना होगा। qwen3.5:9b 6.6 GB से 7.6 GB का सूचीबद्ध है, 256K context और tool सपोर्ट के साथ s18। हमारी मशीन पर ollama ps ने डिफ़ॉल्ट context पर 7.6 GB और 65536 पर 7.7 GB दिखाया।

context का डिफ़ॉल्ट पहला जाल है। Ollama 24 GiB VRAM से कम पर 4k context इस्तेमाल करता है, और कहता है कि कोडिंग टूल कम से कम 64000 पर सेट होने चाहिए s3। आप सर्वर शुरू करते समय OLLAMA_CONTEXT_LENGTH से इसे बढ़ाते हैं, और ollama ps दिखाता है कि यह लागू हुआ या नहीं s3। Ollama की गाइड भी 64k या उससे बड़ी window माँगती है s1।

--bare दूसरा है। एक लेख ने डिफ़ॉल्ट पहला अनुरोध 14.0k टोकन और --bare पर 0.75k मापा s8। हमने टोकन नहीं गिने। हमने यह देखा: उसी 4k context पर वही टास्क 900 s में कुछ नहीं से 93 s में पास हो गया। --bare hooks, plugins, मेमोरी और CLAUDE.md भी छोड़ देता है, इसलिए लोकल मॉडल आपके प्रोजेक्ट के नियम कभी नहीं देखता। हमारे Claude Code 2.1.294 में, उसकी help कहती है कि authentication सख़्ती से ANTHROPIC_API_KEY या apiKeyHelper है, इसलिए alias ANTHROPIC_API_KEY=ollama सेट करता है। हमने --bare में ख़ाली key आज़माई नहीं।

alias में एक header सेटिंग है, पर हमने उसे मापा नहीं। Unsloth के डॉक्स कहते हैं कि attribution header लोकल cache को अमान्य कर देता है और CLAUDE_CODE_ATTRIBUTION_HEADER=0 इसे ठीक करता है s5, और एक Claude Code issue वही cache miss खोजता है s9। --bare पहले से attribution छोड़ देता है, इसलिए हम नहीं कह सकते कि अतिरिक्त variable ने हमारे रन पर क्या किया।

छोटे लोकल मॉडल अक्सर कोड पर नहीं, tool के अनुबंध पर फ़ेल होते हैं। एक benchmark में मॉडल Write की जगह write_file कॉल करते मिले s7। Ollama के issue tracker में कटे हुए और छूटे हुए tool कॉल की एक रिपोर्ट है s10। हमें tool-नाम की कोई त्रुटि नहीं दिखी। हमारी विफलता ज़्यादा चुप थी: एक rename जिसने import तोड़ा छोड़ दिया।

पहले टर्न धीमे हो सकते हैं। 32 GB लैपटॉप पर 64k context के साथ qwen3.5:9b की एक फ़ील्ड रिपोर्ट में पहला अनुरोध 10 मिनट से ज़्यादा और बाद के टर्न 1 से 3 मिनट के थे s6। हमारे समय नीचे की टेबल में हैं।

endpoint क्या नहीं कर सकता। Ollama का Anthropic compatibility पेज prompt caching और forced tool choice को असमर्थित बताता है s2। Anthropic के डॉक्स कहते हैं कि वह किसी भी gateway से Claude Code को non-Claude मॉडलों तक रूट करने को सपोर्ट नहीं करता s4। एक आलोचनात्मक समीक्षा हमारी जैसी ही जगह पहुँचती है: लोकल सिर्फ़ रोज़मर्रा के काम के लिए s11।

सादा alias उस router से बेहतर है जो आपके सब्सक्रिप्शन का टोकन दोबारा इस्तेमाल करता है। एक सेटअप गाइड बताती है कि ऐसे router 401 के साथ फ़ेल होते हैं s13।

कोड

  • claude-alt.zsh

# 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
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'

claude-alt.zsh on GitHub

: alias ब्लॉक, जिसके ऊपर स्विच का नियम तीन कमेंट के रूप में है। इसे `~/.zshrc` में चिपकाइए, फिर `source ~/.zshrc` चलाइए। -

switch-rule.md

# The switch rule

Keep this next to the claude-alt alias. Decide before your limit hits, not while you wait.

## Goes to claude-alt (local model)

- A job in one file that you can check at a glance
- Adding an option, explaining a function, testing one function
- Work where a wrong result is visible in one short diff

## Waits for the plan

- Anything that crosses files, such as a rename with callers in other modules
- Anything you cannot check by reading the diff
- Work that depends on your hooks or your project rules (the alias runs with --bare, which skips both)
- Long sessions

## Always

- Read the diff before you commit, whichever model wrote it
- After a rename, import the old names by hand. A green test run only covers what the tests cover

## Why this rule

Two tasks on a 16 GB M1 Pro with qwen3.5:9b:

- One file (add a --prefix option): passed in 93 s with --bare.
- Across files (rename a function, keep the old name as an alias): the model said the tests were green, and an import was broken in both runs.
- On the plan, Claude did the rename in 38 s with both the old and the new imports working.

Two tasks on one small package is a starting point. Widen the rule with your own runs.

switch-rule.md on GitHub

: एक पन्ने का नियम कार्ड कि कौन से काम लोकल जाएँ, कौन से प्लान का इंतज़ार करें, और वह जाँच जो आप हमेशा चलाते हैं। -

run-task.sh

#!/bin/zsh
# Usage: run-task.sh <name> <A|B> <plan|alt|alt-nobare> [timeout_s]
# Runs one task on a fresh copy of slugkit and records time, output, diff and the check.
set -u
NAME=$1; TASK=$2; MODE=$3; TO=${4:-1800}
SRC=${SLUGKIT:?set SLUGKIT to the slugkit repo}
OUT=${RUNS:?set RUNS to the output dir}/$NAME
rm -rf $OUT; mkdir -p $OUT; cp -R $SRC $OUT/repo; cd $OUT/repo
A='In slugkit/cli.py add a --prefix option: when given, the slug starts with the prefix and the separator (python3 -m slugkit --prefix blog Hello World prints blog-hello-world). Then run that command to check it.'
B='Rename the function smart_truncate to truncate_words everywhere in this repo (definition, imports, calls, tests, __all__). Keep smart_truncate as an alias of truncate_words in slugkit/truncate.py so old imports still work. Then run python3 -m unittest discover tests and make sure every test passes.'
[[ $TASK == A ]] && P=$A || P=$B
TOOLS=(--allowedTools "Read" "Edit" "Write" "Glob" "Grep" "Bash(python3:*)" "Bash(grep:*)" "Bash(ls:*)")
start=$(date +%s)
case $MODE in
  plan) perl -e 'alarm shift; exec @ARGV' $TO claude -p "$P" --output-format json $TOOLS > $OUT/out.json 2> $OUT/err.log ;;
  alt) CLAUDE_CODE_ATTRIBUTION_HEADER=0 ANTHROPIC_AUTH_TOKEN=ollama ANTHROPIC_API_KEY=ollama ANTHROPIC_BASE_URL=http://localhost:11434 \
       perl -e 'alarm shift; exec @ARGV' $TO claude --bare --model qwen3.5:9b -p "$P" --output-format json $TOOLS > $OUT/out.json 2> $OUT/err.log ;;
  alt-nobare) CLAUDE_CODE_ATTRIBUTION_HEADER=0 ANTHROPIC_AUTH_TOKEN=ollama ANTHROPIC_API_KEY="" ANTHROPIC_BASE_URL=http://localhost:11434 \
       perl -e 'alarm shift; exec @ARGV' $TO claude --model qwen3.5:9b -p "$P" --output-format json $TOOLS > $OUT/out.json 2> $OUT/err.log ;;
esac
rc=$?; end=$(date +%s)
git diff --stat > $OUT/diff.stat; git diff > $OUT/diff.patch
if [[ $TASK == A ]]; then python3 -m slugkit --prefix blog Hello World > $OUT/check.txt 2>&1; else python3 -m unittest discover tests > $OUT/check.txt 2>&1; grep -rn smart_truncate slugkit tests >> $OUT/check.txt; fi
echo "{\"name\":\"$NAME\",\"task\":\"$TASK\",\"mode\":\"$MODE\",\"rc\":$rc,\"seconds\":$((end-start))}" > $OUT/meta.json
cat $OUT/meta.json; tail -3 $OUT/check.txt

run-task.sh on GitHub

: वह स्क्रिप्ट जिससे हमने प्लान या alias पर टास्क A या टास्क B का समय लिया, और diff और जाँच सहेजी। पहले `SLUGKIT` को अपने टेस्ट रेपो पर और `RUNS` को एक आउटपुट फ़ोल्डर पर सेट कीजिए।

Monday को यह कीजिए

  • ollama --version और claude --version चलाइए। हमने Ollama 0.40.13 s19 और Claude Code 2.1.294 इस्तेमाल किए।
  • ऐसा मॉडल pull कीजिए जो आपकी मेमोरी में आए। 16 GB के लिए हमने qwen3.5:9b लिया, जो 7.6 GB का है।
  • OLLAMA_CONTEXT_LENGTH=65536 ollama serve से Ollama शुरू कीजिए, फिर ollama ps चलाकर CONTEXT कॉलम पढ़िए।
  • claude-alt.zsh का ब्लॉक ~/.zshrc में चिपकाइए और source ~/.zshrc चलाइए। जाँचिए कि सादा claude अब भी आपका प्लान इस्तेमाल करता है।
  • किसी रेपो की एक throwaway कॉपी में एक-फ़ाइल वाला टास्क चुनिए और उसे claude-alt से चलाइए।
  • diff पढ़िए और जाँच ख़ुद चलाइए। मॉडल की अपनी रिपोर्ट पर भरोसा मत कीजिए।
  • उसी कॉपी में कई फ़ाइलों में एक rename आज़माइए। बाद में पुराने नाम हाथ से import कीजिए।
  • switch-rule.md को alias के पास रखिए और अपने रन जो दिखाएँ उससे उसे एडिट कीजिए।

मापन

मशीन: MacBook Pro M1 Pro, 16 GB, Claude Code 2.1.294, Ollama 0.40.13, qwen3.5:9b (7.6 GB)। रेपो 12 unittest टेस्ट वाला एक छोटा 4-मॉड्यूल Python पैकेज था, जो इस टेस्ट के लिए लिखा गया। मशीन पूरे समय मेमोरी के दबाव में थी, इसलिए लोकल समय ऊपरी सीमा हैं।

टास्क रूट समय नतीजा
A, --prefix जोड़ना (एक फ़ाइल) प्लान, Claude 21 s पास, blog-hello-world
A, --prefix जोड़ना (एक फ़ाइल) Alias, 4k, --bare के बिना 900 s 15 मिनट की सीमा पर रोका गया, कोई एडिट नहीं, कोई जवाब नहीं
A, --prefix जोड़ना (एक फ़ाइल) Alias, 4k, --bare 93 s पास, blog-hello-world
A, --prefix जोड़ना (एक फ़ाइल) Alias, 64k, --bare 35 s पास, blog-hello-world
A, --prefix जोड़ना (एक फ़ाइल) Alias, 64k, --bare के बिना पूरा नहीं हुआ कम मेमोरी के कारण सिस्टम ने मार दिया, कोई नतीजा नहीं
B, कई फ़ाइलों में rename प्लान, Claude 38 s पास, 12 टेस्ट OK, पुराने और नए import चलते हैं, टेस्ट का नाम बदला
B, कई फ़ाइलों में rename Alias, 4k, --bare 464 s टूटा: "All 12 unit tests pass", पर from slugkit import truncate_words से ImportError आया
B, कई फ़ाइलों में rename Alias, 64k, --bare 142 s टूटा: 12 टेस्ट OK और पूरा होने की रिपोर्ट दी, पर alias __init__.py में चला गया, इसलिए from slugkit.truncate import smart_truncate से ImportError आया

टास्क B में smart_truncate को slugkit/truncate.py में alias के रूप में रखने को कहा गया था। Claude Code ने यह भी चेतावनी दी कि वह मॉडल को नहीं जानता और 200k-टोकन की window मानता है। हमारे सेशन उससे बहुत नीचे रहे, और हमने लंबा सेशन नहीं आज़माया।

आगे के लिए

जो हमने छोड़ा, और अगर आप उसे चाहें तो कहाँ देखें।

  • होस्टेड रूट। DeepSeek, Z.AI या OpenRouter जैसे प्रोवाइडर वही alias दूसरे base URL के साथ इस्तेमाल करते हैं। वे प्रति टोकन बिल करते हैं और हमारे पास key नहीं थी, इसलिए हमने इन्हें नहीं चलाया।
  • फ़्री-टियर router। जो router फ़्री टियर को जोड़ते हैं वे Claude Code मुफ़्त देने का वादा करते हैं। हमने इन्हें नहीं आज़माया। आज़माने से पहले उनकी शर्तें देखिए और यह भी कि आपके prompt कहाँ जाते हैं।
  • Ollama क्लाउड मॉडल। अब कोई फ़्री टियर नहीं है, इसलिए वे pay-as-you-go हैं।
  • बड़े लोकल मॉडल। हमने 26b से 35b की रेंज के मॉडल नहीं आज़माए, जो 64k context के साथ 16 GB में नहीं समाते। अगर आपके पास 32 GB या ज़्यादा है, तो एक फ़ील्ड रिपोर्ट ने 35b मॉडल को छह ग्रेडेड टास्क पर चलाया और छह में से छह पाए, क्लाउड मॉडलों से लगभग 8 गुना समय पर s12।
  • हाइब्रिड routing। सब-एजेंट के लिए लोकल और मुख्य लूप के लिए प्लान, यह सेटअप हमने नहीं आज़माया।
  • दूसरे छोटे मॉडल। gemma4:e4b एक फ़ॉलबैक है जिसे कुछ गाइड इस्तेमाल करती हैं। हमने इसे नहीं चलाया।
  • असली benchmark। एक पैकेज पर दो टास्क एक पैटर्न दिखाते हैं, रैंकिंग नहीं। नियम बढ़ाने के लिए run-task.sh से अपने टास्क चलाइए और ऊपर जैसी टेबल रखिए।

अक्सर पूछे जाने वाले सवाल

alias जोड़ने पर क्या सादा claude बदल जाता है? नहीं। variable alias की लाइन में हैं, इसलिए सिर्फ़ claude-alt Ollama से बात करता है।

alias ख़ाली key की जगह ANTHROPIC_API_KEY=ollama क्यों सेट करता है? --bare में Claude Code अपनी key सिर्फ़ ANTHROPIC_API_KEY या apiKeyHelper से पढ़ता है। ollama को key बनाकर हमारा alias चला। हमने --bare में ख़ाली key को अंत तक नहीं आज़माया।

क्या Anthropic इसे सपोर्ट करता है? नहीं। Anthropic के डॉक्स कहते हैं कि वह किसी भी gateway से Claude Code को non-Claude मॉडलों तक रूट करने को सपोर्ट नहीं करता s4।

क्या मैं लोकल मॉडल के हरे टेस्ट रन पर भरोसा कर सकता हूँ? सिर्फ़ उतने पर जितना टेस्ट कवर करते हैं। टास्क B में टेस्ट पास हुए जबकि एक import टूटा था, क्योंकि पुराने import पाथ का कोई टेस्ट नहीं था। diff पढ़िए और पुराने नाम हाथ से import कीजिए।

क्या यह प्लान जितना तेज़ होगा? हमारे रन में नहीं। टास्क B प्लान पर 38 s और alias पर 142 s से 464 s में हुआ, और फिर भी टूटा।

फ़ाइलें