はじめに
以前、Continue CLIとOllamaの組み合わせで記事を書きました。
今回はClaude CodeとOllamaを組み合わせてみます。
Windows 11環境で試しています。
手順
Claude Codeのインストール
PowerShellを使っています。
irm https://claude.ai/install.ps1 | iex
開始
Ollamaから開始
ollama launch claude
モデル選択画面が出てきます。
Claudeから開始
環境変数の設定
以下の設定は一時的な設定です。
$env:ANTHROPIC_AUTH_TOKEN="ollama" $env:ANTHROPIC_BASE_URL="http://localhost:11434"
永続的に設定する場合にはこのようにすれば良いと思います。
[System.Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "ollama", "User")
[System.Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", "http://localhost:11434", "User")
PowerShellの設定ファイル$profileに以下を記入しておけば設定は楽になります。
function claude-local {
$env:ANTHROPIC_AUTH_TOKEN = "ollama"
$env:ANTHROPIC_BASE_URL = "http://localhost:11434"
Write-Host "claude-local environment variables set."
}
function claude-cloud {
Remove-Item Env:ANTHROPIC_AUTH_TOKEN -ErrorAction SilentlyContinue
Remove-Item Env:ANTHROPIC_BASE_URL -ErrorAction SilentlyContinue
Write-Host "claude-cloud environment variables cleared."
}
開始
gpt-ossのnum_ctxを65536に設定しています。
設定方法はこちら。
claude --model gpt-oss:long
しっかり認識できています。

これでVibe Coding可能になっています。
Claude Codeを終了してもモデルが読み込まれたままでVRAMが解放されません。
その場合は以下を実行する必要があります。
ollama stop gpt-oss:long
次にAgent Skillsが使えるかどうか試してみました。
シンプルなAgent Skillsの例
--- name: greeting description: シンプルな挨拶を日本語で行うスキル。ユーザーが挨拶や自己紹介を求めた時に使用します。 --- # 挨拶スキル このスキルは、ユーザーに対してフレンドリーな日本語の挨拶を提供します。 ## いつ使うか - ユーザーが「こんにちは」「はじめまして」などの挨拶をした時 - ユーザーが自己紹介や挨拶を求めた時 ## 挨拶の方法 以下の形式で挨拶してください: 1. 時間帯に応じた挨拶(朝・昼・夜) 2. 簡単な自己紹介 3. お手伝いできることの説明 ## 例 ``` おはようございます!🌅 私はClaude、あなたのAIアシスタントです。 プログラミング、文章作成、データ分析など、 様々なタスクでお手伝いできます。 何かお困りのことはありますか? ``` ## 注意事項 - 常に丁寧な言葉遣いを使う - フレンドリーで親しみやすい雰囲気を保つ - 絵文字は1つまで使用可能
このような中身のSKILL.mdを用意して.claude/skills/greetingフォルダ内に保存する。
skillsを使って下さいと明示しないとなかなか使ってくれませんでした。

Pythonの実行を伴うAgent Skillsの例
PDFを1ページずつ画像に変換するコードを書きました。
LLMに実行させるのに工夫を要しました。
あらかじめuvで仮想環境.venvを作っておく必要があります。
CLAUD.mdにこのような記載をしました。
## Bash execution rules - Bashコマンドを提案する際は、テキストとして表示するだけでなく、必ず `Bash` ツールを使用して実行の許可を求めてください。 - `skill.md` に記載されている手順を実行する場合、各ステップを個別のBash実行として提案してください。 - ユーザーが「〜して」と依頼した際、それがファイルの操作や環境確認であれば、解説する前にまずコマンドを実行してください。
SKILL.mdはこのように記載しました。
--- name: pdf description: Convert PDF to PNG. --- # PDF Conversion Skill ## Instruction PDF変換の依頼を受けたら、以下の「1行のbashコード」を bash mode で実行して下さい。 **必ず `[PATH]` の部分を、ユーザーが指定した実際のファイルパスに書き換えてください。** 余計なJSONや説明文は一切含めないでください。 ```bash uv run .claude/skills/pdf/scripts/convert_pdf_to_images.py "[PATH]" ```
Pythonコードはこちらです。
import sys import io import logging from pathlib import Path import fitz # PyMuPDF from PIL import Image # Setup logging log_file = Path(__file__).parent.parent / "conversion.log" logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s", handlers=[ logging.FileHandler(log_file), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) # Converts each page of a PDF to a PNG image. def convert(pdf_path, output_dir, max_dim=1000): # Create output directory if it doesn't exist output_path = Path(output_dir) output_path.mkdir(parents=True, exist_ok=True) # Open PDF document pdf_document = fitz.open(pdf_path) total_pages = len(pdf_document) for i in range(total_pages): # Render page to an image (pixmap) page = pdf_document[i] # Use 200 DPI equivalent (2.67 zoom factor) pix = page.get_pixmap(matrix=fitz.Matrix(2.67, 2.67)) # Convert pixmap to PIL Image for resizing img = Image.open(io.BytesIO(pix.tobytes(output="png"))) # Scale image if needed to keep width/height under `max_dim` width, height = img.size if width > max_dim or height > max_dim: scale_factor = min(max_dim / width, max_dim / height) new_width = int(width * scale_factor) new_height = int(height * scale_factor) img = img.resize((new_width, new_height)) image_path = output_path / f"page_{i+1}.png" img.save(image_path) print(f"Saved page {i+1} as {image_path} (size: {img.size})") pdf_document.close() print(f"Converted {total_pages} pages to PNG images") if __name__ == "__main__": logger.info(f"Script started with args: {sys.argv}") if len(sys.argv) < 2: msg = "Usage: convert_pdf_to_images.py [input pdf] [output directory (optional, default: output)]" print(msg) logger.error(msg) sys.exit(1) pdf_path = sys.argv[1] output_directory = sys.argv[2] if len(sys.argv) > 2 else "output" logger.info(f"PDF path: {pdf_path}") logger.info(f"Output directory: {output_directory}") # Validate PDF file exists pdf_file = Path(pdf_path) if not pdf_file.exists(): msg = f"Error: PDF file not found: {pdf_file}" print(msg) logger.error(msg) sys.exit(1) if not pdf_file.suffix.lower() == ".pdf": msg = f"Error: File is not a PDF: {pdf_file}" print(msg) logger.error(msg) sys.exit(1) try: logger.info("Starting PDF conversion...") convert(str(pdf_file), output_directory) logger.info("PDF conversion completed successfully") except Exception as e: msg = f"Error: {e}" print(msg) logger.error(msg) sys.exit(1)
ここでやったことはcustom commandでもできそうです。
1行ですみます。
!uv run .claude/skills/pdf/scripts/convert_pdf_to_images.py $1