TL;DR
- Claude Code の
ANTHROPIC_API_KEYを OpenRouter 経由に差し替えると:freeモデルが使える -
claude --modelフラグとCLAUDE_MODEL環境変数で無料モデルを固定できる - レート制限を踏まえた「重い作業はキュー、軽い作業は即時」の2段構えが鍵
- コスト0円で実用的なコーディング支援ループを回すための具体的設定を5つ紹介
背景: LLM コスト問題とOpenRouterの立ち位置
Claude Code は強力なコーディングエージェントだが、Anthropic 直接課金だと長いコンテキストやマルチターンのセッションでコストが積み上がりやすい。
OpenRouter は複数の LLM プロバイダを統一 API で束ねるルーターで、多数のモデルに :free サフィックスの無料ティアを提供している。
2026年時点の代表的な :free モデル例:
| モデル名 | 備考 |
|---|---|
qwen/qwen3-235b-a22b:free |
Qwen3 MoE・コード補完に強い |
google/gemini-2.0-flash-exp:free |
マルチモーダル対応 |
meta-llama/llama-3.3-70b-instruct:free |
バランス型 |
mistralai/mistral-7b-instruct:free |
軽量・高速 |
deepseek/deepseek-r1:free |
推論特化 |
:free モデルは 1分あたりのリクエスト数や1日のトークン上限が設けられている点に注意。しかしローカル開発・プロトタイプ・CI 補助の用途なら十分に実用になる。
設定1: OpenRouter エンドポイントへの差し替え
Claude Code は ANTHROPIC_BASE_URL 環境変数でベース URL を上書きできる。
OpenRouter は OpenAI 互換 API を提供しているため、以下のように設定する。
# ~/.bashrc or ~/.zshrc に追記
export ANTHROPIC_BASE_URL="https://openrouter.ai/api/v1"
export ANTHROPIC_API_KEY="sk-or-v1-xxxxxxxxxxxx" # OpenRouter のキー
注意: ここに書いた
ANTHROPIC_API_KEYは OpenRouter から発行されたキーを使う。実際のキー文字列は環境変数から読み込むか、シークレットマネージャに保管する。ソースコードや設定ファイルにハードコーディングしない。
設定2: モデルの固定
Claude Code はデフォルトで Anthropic の Claude モデルを呼ぼうとする。
CLAUDE_MODEL 環境変数(または --model フラグ)でモデルを明示的に指定する。
export CLAUDE_MODEL="qwen/qwen3-235b-a22b:free"
または単発実行時:
claude --model "qwen/qwen3-235b-a22b:free" "この関数のバグを直して"
CLAUDE_MODEL を設定しておくと、毎回フラグを書かなくてよい。
複数のモデルを使い分けたい場合は shell alias が便利:
alias cc-fast='claude --model "mistralai/mistral-7b-instruct:free"'
alias cc-smart='claude --model "qwen/qwen3-235b-a22b:free"'
alias cc-reason='claude --model "deepseek/deepseek-r1:free"'
-
cc-fast: 簡単なリファクタやコメント生成 -
cc-smart: 設計相談・複雑なバグ修正 -
cc-reason: アルゴリズム検討・数学的推論
設定3: レート制限対策の非同期キュー
:free モデルの制約として最も頻繁に当たるのが 429 Too Many Requests。
特にループ処理や複数ファイルの一括修正で連続リクエストを投げると即座にブロックされる。
シンプルな bash の wait + retry ラッパーを作るだけで体感がかなり変わる:
#!/usr/bin/env bash
# cc-retry.sh — レート制限を踏んだら指数バックオフでリトライ
set -euo pipefail
MAX_RETRIES=5
DELAY=10
run_claude() {
local attempt=1
until claude "$@"; do
if [[ $attempt -ge $MAX_RETRIES ]]; then
echo "❌ Max retries reached." >&2
return 1
fi
echo "⏳ Rate limited. Waiting ${DELAY}s (attempt ${attempt}/${MAX_RETRIES})..." >&2
sleep "$DELAY"
DELAY=$(( DELAY * 2 ))
attempt=$(( attempt + 1 ))
done
}
run_claude "$@"
使い方:
chmod +x cc-retry.sh
./cc-retry.sh --model "qwen/qwen3-235b-a22b:free" "この PR の差分をレビューして"
Python の tenacity ライブラリを使う場合はよりきめ細かく制御できる:
from tenacity import retry, wait_exponential, stop_after_attempt, retry_if_exception_type
import httpx
@retry(
wait=wait_exponential(multiplier=1, min=10, max=120),
stop=stop_after_attempt(6),
retry=retry_if_exception_type(httpx.HTTPStatusError),
)
def call_openrouter(prompt: str, model: str) -> str:
# openai SDK or requests で OpenRouter を呼ぶ処理
...
設定4: CLAUDE.md でプロジェクト固有のコンテキストを圧縮する
Claude Code はプロジェクトルートの CLAUDE.md を自動で読み込む。
無料モデルはコンテキストウィンドウが小さめのモデルも多いため、必要最小限の情報に絞ることがコスト節約と精度の両立につながる。
有効な CLAUDE.md の構成例:
# Project: my-app
## Stack
- Language: TypeScript 5.x
- Framework: Next.js 15 (App Router)
- DB: PostgreSQL via Prisma
- Test: Vitest + Playwright
## Conventions
- コンポーネントは `src/components/<domain>/` に配置
- API ルートは `src/app/api/` 配下、全て Edge Runtime
- エラーは `Result<T, E>` 型で返す (neverthrow 使用)
## Do NOT
- `any` 型を使わない
- `console.log` をコミットに含めない
- Prisma の `$queryRaw` は直接使わず `prisma-extension-kysely` を使う
## Frequently Asked
- マイグレーション: `pnpm prisma migrate dev`
- テスト実行: `pnpm test`
- ビルド: `pnpm build`
ポイントは「何をするプロジェクトか」「命名規則」「禁止事項」の3点に絞ること。
README の全文を貼り付けるとトークンを浪費し、無料モデルの上限に早く当たる。
設定5: モデルスイッチングの自動化 (fallback chain)
:free モデルが落ちているときや制限超過時に自動でフォールバックする簡易スクリプト:
#!/usr/bin/env python3
"""
model_fallback.py — OpenRouter :free モデルの fallback chain
"""
import os
import httpx
import json
OPENROUTER_BASE = "https://openrouter.ai/api/v1"
API_KEY = os.environ["OPENROUTER_API_KEY"] # 環境変数から読む
FREE_MODELS = [
"qwen/qwen3-235b-a22b:free",
"meta-llama/llama-3.3-70b-instruct:free",
"mistralai/mistral-7b-instruct:free",
]
def chat(prompt: str) -> str:
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
for model in FREE_MODELS:
try:
resp = httpx.post(
f"{OPENROUTER_BASE}/chat/completions",
headers=headers,
json={
"model": model,
"messages": [{"role": "user", "content": prompt}],
},
timeout=60,
)
resp.raise_for_status()
return resp.json()["choices"][0]["message"]["content"]
except httpx.HTTPStatusError as e:
if e.response.status_code in (429, 503):
print(f"⚠️ {model} unavailable, trying next...")
continue
raise
raise RuntimeError("All free models exhausted.")
if __name__ == "__main__":
import sys
print(chat(" ".join(sys.argv[1:])))
python model_fallback.py "この Python コードをリファクタして"
FREE_MODELS リストの順序が優先度になる。最も高品質なモデルを先頭に置き、負荷状況に応じて軽量モデルに自動降格する設計。
実際の使用感と注意点
良い点
- プロトタイプフェーズ: コスト気にせず試行錯誤できる
- CI での軽量チェック: PR のコメント生成や lint エラーの説明など
- 学習用スクリプト: 個人プロジェクトでの実験
限界
| 制約 | 内容 |
|---|---|
| レート制限 | モデルにより 10-20 req/min 程度 |
| コンテキスト長 | 一部モデルは 8K〜32K と短め |
| 可用性 |
:free ティアはキュー待ちが発生することがある |
| 機能差 | tool use / function calling が使えないモデルもある |
コードベース全体を食わせるような長大なプロンプトには向かない。
「1ファイル1タスク」の粒度に分解するのが無料モデルを最大限に活かすコツ。
セキュリティ上の注意
- API キーは必ず環境変数か
.env(.gitignore済) から読む -
CLAUDE.mdに内部ドメイン・IP・接続文字列を書かない -
--dangerously-skip-permissionsフラグは実験環境専用。本番サーバーでは絶対に使わない
まとめ
| # | 設定 | 効果 |
|---|---|---|
| 1 | OpenRouter エンドポイントへ差し替え | 無料モデルにアクセス可能に |
| 2 |
CLAUDE_MODEL でモデル固定 |
用途別に使い分けが簡単に |
| 3 | 指数バックオフ retry ラッパー | 429 エラーで詰まらない |
| 4 |
CLAUDE.md を最小化 |
トークン節約 + 精度向上 |
| 5 | fallback chain スクリプト | モデル障害時の自動切り替え |
月額ほぼ0円で回せるとはいえ、有償モデルと比べればクオリティや速度のトレードオフは存在する。**「プロトタイプ・学習・CI補助は free、本番クリティカルは有償」**という使い分けが現実的な運用ラインになる。
参考リンク
- OpenRouter 公式ドキュメント
- Claude Code 公式ドキュメント
- OpenRouter モデル一覧
- tenacity (Python retry ライブラリ)
- neverthrow (TypeScript Result 型)
✍️ 本記事の著者: 合同会社ジモラボ
ジモラボは、八王子を拠点に AI を活用した SaaS を多数開発しています。本記事の技術検証もそうした開発過程の副産物です。
- 🌐 公式サイト: https://locallab.jp
- 🔍 AI SEO 最適化 SaaS: lookupai.jp
- 📺 YouTube: @locallab_llc
- ✉️ お問い合わせ: info@locallab.jp
興味を持っていただけたら、ぜひ各 SNS のフォローもお願いします!