以下の内容はhttps://touch-sp.hatenablog.com/entry/2026/01/19/142520より取得しました。


Claude Code と Ollama を使ってローカル環境で Vibe Coding

はじめに

以前、Continue CLIとOllamaの組み合わせで記事を書きました。

touch-sp.hatenablog.com

今回は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




以上の内容はhttps://touch-sp.hatenablog.com/entry/2026/01/19/142520より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14