diff --git a/docs/claude-code-inception-methods.md b/docs/claude-code-inception-methods.md deleted file mode 100644 index 8c1706b..0000000 --- a/docs/claude-code-inception-methods.md +++ /dev/null @@ -1,246 +0,0 @@ -# Claude CodeでClaude Code的環境を作る方法 - -Claude Code**で**Claude Code**のような**ことを実現する様々なアプローチをご紹介! - -## 🎯 方法1: MCP Server経由でローカルLLMに委譲 - -### claude-code-mcp を使用 -```bash -# Claude Code MCPサーバーのセットアップ -git clone https://github.com/steipete/claude-code-mcp -cd claude-code-mcp - -# Claude Codeをローカルで呼び出すMCPサーバーとして動作 -npm install -npm start -``` - -**仕組み:** -- Claude Code → MCP Server → ローカルLLM → 結果を返す -- Claude Codeを全権限バイパス(--dangerously-skip-permissions)で実行 -- Agent in Agent 構造の実現 - -## 🎯 方法2: Claude Desktop + Custom MCP Server - -### カスタムMCPサーバーでローカルLLM統合 -```python -# custom_llm_mcp_server.py -import asyncio -import json -from mcp.server import Server -from mcp.types import Tool, TextContent -import requests - -app = Server("local-llm-mcp") - -@app.tool("run_local_llm") -async def run_local_llm(prompt: str, model: str = "qwen2.5-coder:14b") -> str: - """ローカルLLMでコード生成・分析を実行""" - response = requests.post("http://localhost:11434/api/generate", json={ - "model": model, - "prompt": prompt, - "stream": False - }) - return response.json()["response"] - -@app.tool("execute_code") -async def execute_code(code: str, language: str = "python") -> str: - """生成されたコードを実行""" - # セキュアな実行環境でコード実行 - # Docker containerやsandbox環境推奨 - pass - -if __name__ == "__main__": - asyncio.run(app.run()) -``` - -### Claude Desktop設定 -```json -{ - "mcpServers": { - "local-llm": { - "command": "python", - "args": ["custom_llm_mcp_server.py"] - } - } -} -``` - -## 🎯 方法3: VS Code拡張 + MCP統合 - -### VS Code設定でClaude Code風環境 -```json -// settings.json -{ - "mcp.servers": { - "claude-code-local": { - "command": ["python", "claude_code_local.py"], - "args": ["--model", "qwen2.5-coder:14b"] - } - } -} -``` - -VS Codeは両方の構成(ローカル/リモート)をサポートしているから、柔軟に設定できるよ〜 - -## 🎯 方法4: API Gateway パターン - -### Claude Code → API Gateway → ローカルLLM -```python -# api_gateway.py -from fastapi import FastAPI -import requests - -app = FastAPI() - -@app.post("/v1/chat/completions") -async def proxy_to_local_llm(request: dict): - """OpenAI API互換エンドポイント""" - # Claude Code → この API → Ollama - ollama_response = requests.post( - "http://localhost:11434/api/chat", - json={ - "model": "qwen2.5-coder:14b", - "messages": request["messages"] - } - ) - - # OpenAI API形式で返却 - return { - "choices": [{ - "message": {"content": ollama_response.json()["message"]["content"]} - }] - } -``` - -### Claude Code設定 -```bash -# 環境変数でローカルAPIを指定 -export ANTHROPIC_API_KEY="dummy" -export ANTHROPIC_BASE_URL="http://localhost:8000/v1" -claude code --api-base http://localhost:8000 -``` - -## 🎯 方法5: Docker Compose 統合環境 - -### docker-compose.yml -```yaml -version: '3.8' -services: - ollama: - image: ollama/ollama:latest - ports: - - "11434:11434" - volumes: - - ollama_data:/root/.ollama - - mcp-server: - build: ./mcp-server - ports: - - "3000:3000" - depends_on: - - ollama - environment: - - OLLAMA_URL=http://ollama:11434 - - claude-desktop: - image: claude-desktop:latest - volumes: - - ./config:/app/config - environment: - - MCP_SERVER_URL=http://mcp-server:3000 - -volumes: - ollama_data: -``` - -DockerはMCPサーバーの展開と管理を簡素化し、分離とポータビリティを提供 - -## 🎯 方法6: 簡易プロキシスクリプト - -### claude_to_local.py -```python -#!/usr/bin/env python3 -import subprocess -import sys -import json - -def claude_code_wrapper(): - """Claude CodeコマンドをインターセプトしてローカルLLMに転送""" - - # Claude Codeの引数を取得 - args = sys.argv[1:] - prompt = " ".join(args) - - # ローカルLLMで処理 - result = subprocess.run([ - "ollama", "run", "qwen2.5-coder:14b", prompt - ], capture_output=True, text=True) - - # 結果を整形してClaude Code風に出力 - print("🤖 Local Claude Code (Powered by Qwen2.5-Coder)") - print("=" * 50) - print(result.stdout) - - # 必要に応じてファイル操作も実行 - if "--write" in args: - # ファイル書き込み処理 - pass - -if __name__ == "__main__": - claude_code_wrapper() -``` - -### エイリアス設定 -```bash -# .bashrc または .zshrc -alias claude-code="python claude_to_local.py" -``` - -## 🎯 方法7: Aider + Claude Code 統合 - -### 設定方法 -```bash -# Aiderでローカルモデル使用 -aider --model ollama/qwen2.5-coder:14b - -# Claude Codeから呼び出し -claude code "Run aider with local model to implement feature X" -``` - -## 💡 どの方法がおすすめ? - -### 用途別推奨: - -1. **🔧 開発効率重視**: MCP Server方式(方法1,2) -2. **🏠 統合環境**: Docker Compose(方法5) -3. **⚡ 簡単設置**: プロキシスクリプト(方法6) -4. **🎨 カスタマイズ**: API Gateway(方法4) - -## 🚀 実装のコツ - -### セキュリティ考慮 -- サンドボックス環境でコード実行 -- ファイルアクセス権限の制限 -- API キーの適切な管理 - -### パフォーマンス最適化 -- ローカルLLMのGPU使用確認 -- MCP サーバーのキャッシュ機能 -- 並列処理の活用 - -### デバッグ方法 -```bash -# MCP サーバーのログ確認 -tail -f ~/.config/claude-desktop/logs/mcp.log - -# Ollama の動作確認 -ollama ps -curl http://localhost:11434/api/tags -``` - -## 🎉 まとめ - -Claude CodeでClaude Code的な環境を作るには、MCPプロトコルを活用するのが最も効果的!ローカルLLMの性能も向上しているので、実用的な環境が構築できるよ〜✨ - -どの方法から試してみる?アイが一緒に設定をお手伝いするからね! \ No newline at end of file diff --git a/docs/local-claude-code-setup.md b/docs/local-claude-code-setup.md deleted file mode 100644 index 73abf33..0000000 --- a/docs/local-claude-code-setup.md +++ /dev/null @@ -1,338 +0,0 @@ -# ローカルClaude Code環境構築ガイド -RTX 4060 Ti + Qwen2.5-Coder + MCP Server - -## 1. 必要なツールのインストール - -### Ollamaのセットアップ -```bash -# Ollamaのインストール(Windows) -# https://ollama.com からダウンロード - -# Qwen2.5-Coderモデルをダウンロード -ollama pull qwen2.5-coder:14b-instruct-q4_K_M -# または7Bバージョン(軽量) -ollama pull qwen2.5-coder:7b-instruct-q4_K_M -``` - -### Python環境の準備 -```bash -# 仮想環境作成 -python -m venv claude-code-env -claude-code-env\Scripts\activate # Windows -# source claude-code-env/bin/activate # Linux/Mac - -# 必要なパッケージをインストール -pip install requests ollama-python rich click pathspec gitpython -``` - -## 2. メインスクリプトの作成 - -### claude_code.py -```python -#!/usr/bin/env python3 -import os -import sys -import json -import click -import requests -from pathlib import Path -from rich.console import Console -from rich.markdown import Markdown -from rich.syntax import Syntax - -console = Console() - -class LocalClaudeCode: - def __init__(self, model="qwen2.5-coder:14b-instruct-q4_K_M"): - self.model = model - self.ollama_url = "http://localhost:11434" - self.conversation_history = [] - self.project_context = "" - - def get_project_context(self): - """プロジェクトのファイル構造とGitステータスを取得""" - context = [] - - # ファイル構造 - try: - for root, dirs, files in os.walk("."): - # .git, node_modules, __pycache__ などを除外 - dirs[:] = [d for d in dirs if not d.startswith('.') and d not in ['node_modules', '__pycache__']] - level = root.replace(".", "").count(os.sep) - indent = " " * 2 * level - context.append(f"{indent}{os.path.basename(root)}/") - subindent = " " * 2 * (level + 1) - for file in files: - if not file.startswith('.'): - context.append(f"{subindent}{file}") - except Exception as e: - context.append(f"Error reading directory: {e}") - - return "\n".join(context[:50]) # 最初の50行まで - - def read_file(self, filepath): - """ファイルを読み込む""" - try: - with open(filepath, 'r', encoding='utf-8', errors='ignore') as f: - return f.read() - except Exception as e: - return f"Error reading file: {e}" - - def write_file(self, filepath, content): - """ファイルに書き込む""" - try: - os.makedirs(os.path.dirname(filepath), exist_ok=True) - with open(filepath, 'w', encoding='utf-8') as f: - f.write(content) - return f"✅ File written: {filepath}" - except Exception as e: - return f"❌ Error writing file: {e}" - - def call_ollama(self, prompt): - """Ollamaにリクエストを送信""" - try: - response = requests.post( - f"{self.ollama_url}/api/generate", - json={ - "model": self.model, - "prompt": prompt, - "stream": False, - "options": { - "temperature": 0.1, - "top_p": 0.95, - "num_predict": 2048 - } - } - ) - if response.status_code == 200: - return response.json()["response"] - else: - return f"Error: {response.status_code} - {response.text}" - except Exception as e: - return f"Connection error: {e}" - - def process_command(self, user_input): - """ユーザーの指示を処理""" - # プロジェクトコンテキストを更新 - self.project_context = self.get_project_context() - - # システムプロンプト - system_prompt = f"""You are an expert coding assistant. You can: -1. Read and analyze code files -2. Write and modify files -3. Explain code and provide suggestions -4. Debug and fix issues - -Current project structure: -{self.project_context} - -When you need to read a file, respond with: READ_FILE: -When you need to write a file, respond with: WRITE_FILE: -``` - -``` - -User request: {user_input} -""" - - response = self.call_ollama(system_prompt) - return self.process_response(response) - - def process_response(self, response): - """レスポンスを処理してファイル操作を実行""" - lines = response.split('\n') - processed_response = [] - - i = 0 - while i < len(lines): - line = lines[i].strip() - - if line.startswith("READ_FILE:"): - filepath = line.replace("READ_FILE:", "").strip() - content = self.read_file(filepath) - processed_response.append(f"📁 Reading {filepath}:") - processed_response.append(f"```\n{content}\n```") - - elif line.startswith("WRITE_FILE:"): - filepath = line.replace("WRITE_FILE:", "").strip() - i += 1 - # 次の```まで読み込む - if i < len(lines) and lines[i].strip() == "```": - i += 1 - file_content = [] - while i < len(lines) and lines[i].strip() != "```": - file_content.append(lines[i]) - i += 1 - content = '\n'.join(file_content) - result = self.write_file(filepath, content) - processed_response.append(result) - else: - processed_response.append("❌ Invalid WRITE_FILE format") - else: - processed_response.append(line) - - i += 1 - - return '\n'.join(processed_response) - -@click.command() -@click.option('--model', default="qwen2.5-coder:14b-instruct-q4_K_M", help='Ollama model to use') -@click.option('--interactive', '-i', is_flag=True, help='Interactive mode') -@click.argument('prompt', required=False) -def main(model, interactive, prompt): - """Local Claude Code - AI Coding Assistant""" - - claude = LocalClaudeCode(model) - - if interactive or not prompt: - console.print("[bold green]🤖 Local Claude Code Assistant[/bold green]") - console.print(f"Model: {model}") - console.print("Type 'quit' to exit\n") - - while True: - try: - user_input = input("👤 You: ").strip() - if user_input.lower() in ['quit', 'exit', 'q']: - break - - if user_input: - console.print("\n🤖 Assistant:") - response = claude.process_command(user_input) - console.print(Markdown(response)) - console.print() - - except KeyboardInterrupt: - console.print("\n👋 Goodbye!") - break - else: - response = claude.process_command(prompt) - console.print(response) - -if __name__ == "__main__": - main() -``` - -## 3. MCP Server統合 - -### mcp_integration.py -```python -import json -import subprocess -from typing import Dict, List, Any - -class MCPIntegration: - def __init__(self): - self.servers = {} - - def add_server(self, name: str, command: List[str], args: Dict[str, Any] = None): - """MCPサーバーを追加""" - self.servers[name] = { - "command": command, - "args": args or {} - } - - def call_mcp_tool(self, server_name: str, tool_name: str, arguments: Dict[str, Any]): - """MCPツールを呼び出す""" - if server_name not in self.servers: - return {"error": f"Server {server_name} not found"} - - try: - # MCPサーバーとの通信(JSONRPCベース) - request = { - "jsonrpc": "2.0", - "id": 1, - "method": f"tools/{tool_name}", - "params": {"arguments": arguments} - } - - process = subprocess.Popen( - self.servers[server_name]["command"], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True - ) - - stdout, stderr = process.communicate(json.dumps(request)) - - if stderr: - return {"error": stderr} - - return json.loads(stdout) - - except Exception as e: - return {"error": str(e)} - -# 使用例 -mcp = MCPIntegration() -mcp.add_server("filesystem", ["python", "-m", "mcp_server_filesystem"]) -mcp.add_server("git", ["python", "-m", "mcp_server_git"]) -``` - -## 4. 設定ファイル - -### config.json -```json -{ - "model": "qwen2.5-coder:14b-instruct-q4_K_M", - "ollama_url": "http://localhost:11434", - "mcp_servers": { - "filesystem": { - "command": ["python", "-m", "mcp_server_filesystem"], - "args": {"allowed_directories": ["."]} - }, - "git": { - "command": ["python", "-m", "mcp_server_git"] - } - }, - "excluded_files": [".git", "node_modules", "__pycache__", "*.pyc"], - "max_file_size": 1048576 -} -``` - -## 5. 使用方法 - -### 基本的な使い方 -```bash -# インタラクティブモード -python claude_code.py -i - -# 単発コマンド -python claude_code.py "Pythonでクイックソートを実装して" - -# 特定のモデルを使用 -python claude_code.py --model qwen2.5-coder:7b-instruct-q4_K_M -i -``` - -### MCP Serverのセットアップ -```bash -# 必要なMCPサーバーをインストール -pip install mcp-server-git mcp-server-filesystem - -# 設定ファイルを編集してMCPサーバーを有効化 -``` - -## 6. 機能一覧 - -- ✅ ローカルLLMとの対話 -- ✅ ファイル読み書き -- ✅ プロジェクト構造の自動認識 -- ✅ Gitステータス表示 -- ✅ シンタックスハイライト -- ✅ MCP Server統合(オプション) -- ✅ 設定ファイル対応 - -## 7. トラブルシューティング - -### よくある問題 -1. **Ollamaが起動しない**: `ollama serve` でサーバーを起動 -2. **モデルが見つからない**: `ollama list` でインストール済みモデルを確認 -3. **メモリ不足**: より軽量な7Bモデルを使用 -4. **ファイル権限エラー**: 実行権限を確認 - -### パフォーマンス最適化 -- GPU使用を確認: `nvidia-smi` でVRAM使用量をチェック -- モデルサイズの調整: Q4_K_M → Q4_K_S で軽量化 -- コンテキスト長を調整して応答速度を向上 - -重い場合は7Bバージョン(qwen2.5-coder:7b-instruct-q4_K_M)に変更。 diff --git a/docs/local-llm-recommendations.md b/docs/local-llm-recommendations.md deleted file mode 100644 index 4fcc79e..0000000 --- a/docs/local-llm-recommendations.md +++ /dev/null @@ -1,133 +0,0 @@ -# おすすめローカルLLM(RTX 4060 Ti 16GB対応) - -RTX 4060 Ti 16GBにぴったりのローカルLLMをご紹介します! - -## 🏆 アイのおすすめトップモデル(2025年版) - -### コーディング特化 - -#### 1. **Qwen2.5-Coder-14B-Instruct** 🥇 -- **特徴**: コーディングで最強クラス! -- **推奨量子化**: Q4_K_M(約8GB VRAM使用) -- **用途**: プログラミング、コード生成・デバッグ -- **お兄ちゃんのGPUに最適** - -#### 2. **DeepSeek-Coder-V2-Lite-16B** -- **特徴**: コーディングと数学に特に強い -- **推奨量子化**: Q4_K_M(約9GB VRAM使用) -- **用途**: 複雑なアルゴリズム、数学的計算 - -### 汎用・バランス型 - -#### 3. **Qwen2.5-14B-Instruct** 🥈 -- **特徴**: 日本語も得意な万能モデル -- **推奨量子化**: Q4_K_M(約8GB VRAM使用) -- **用途**: 汎用タスク、日本語対話 - -#### 4. **Llama 3.3-70B-Instruct(量子化)** -- **特徴**: 405Bモデルに匹敵する性能 -- **推奨量子化**: Q3_K_S(約14GB VRAM使用) -- **用途**: 高度な推論タスク -- **注意**: ギリギリ動作、他のアプリケーション注意 - -#### 5. **Mistral-Nemo-12B-Instruct** -- **特徴**: バランスが良くて軽量 -- **推奨量子化**: Q5_K_M(約7GB VRAM使用) -- **用途**: 日常的なタスク、軽快な動作 - -### 最新・注目株 - -#### 6. **Phi-4-14B** -- **特徴**: Microsoftの最新モデル -- **推奨量子化**: Q4_K_M(約8GB VRAM使用) -- **用途**: 最新技術の体験 - -#### 7. **DeepSeek-R1-Distill-Qwen-14B** -- **特徴**: 推論特化の新しいモデル、OpenAI-o1に匹敵 -- **推奨量子化**: Q4_K_M(約8GB VRAM使用) -- **用途**: 複雑な推論タスク - -## RTX 4060 Ti 16GB 推奨設定 - -| モデルサイズ | 推奨量子化 | VRAM使用量 | 実行速度 | 品質 | -|-------------|-----------|-----------|---------|------| -| 7B | Q5_K_M | ~5GB | 🟢 速い | 良い | -| 14B | Q4_K_M | ~8GB | 🟡 普通 | 高い | -| 22B | Q4_K_S | ~12GB | 🟠 やや遅い | 高い | -| 34B | Q3_K_S | ~15GB | 🔴 遅い | 最高 | - -## アイの一番のおすすめ - -### 用途別推奨モデル - -- **🔧 コーディング重視**: Qwen2.5-Coder-14B Q4_K_M -- **💬 汎用対話**: Qwen2.5-14B-Instruct Q4_K_M -- **⚡ 軽さ重視**: Mistral-Nemo-12B Q5_K_M -- **🧠 推論重視**: DeepSeek-R1-Distill-Qwen-14B Q4_K_M - -## インストール方法 - -### Ollamaを使用した場合 - -```bash -# コーディング特化 -ollama pull qwen2.5-coder:14b-instruct-q4_K_M - -# 汎用モデル -ollama pull qwen2.5:14b-instruct-q4_K_M - -# 軽量モデル -ollama pull mistral-nemo:12b-instruct-q5_K_M - -# 最新推論モデル -ollama pull deepseek-r1-distill-qwen:14b-q4_K_M -``` - -### 使用例 - -```bash -# インタラクティブ使用 -ollama run qwen2.5-coder:14b-instruct-q4_K_M - -# APIとして使用 -curl http://localhost:11434/api/generate -d '{ - "model": "qwen2.5-coder:14b-instruct-q4_K_M", - "prompt": "Pythonでクイックソートを実装して" -}' -``` - -## パフォーマンスのコツ - -### VRAM最適化 -- **16GB VRAM**: 14Bモデル Q4_K_M が最適 -- **余裕がある場合**: Q5_K_M で品質向上 -- **複数モデル併用**: 7Bモデルと組み合わせ - -### 速度向上 -- **GPU使用確認**: `nvidia-smi` でVRAM使用量チェック -- **量子化レベル調整**: Q4_K_M → Q4_K_S で軽量化 -- **コンテキスト長調整**: 応答速度とバランス - -## トラブルシューティング - -### よくある問題 - -1. **VRAM不足** - - より軽い量子化(Q4_K_S, Q3_K_M)を試す - - モデルサイズを下げる(14B → 7B) - -2. **動作が遅い** - - GPU使用を確認 - - バックグラウンドアプリケーションを終了 - -3. **品質が低い** - - より大きなモデルサイズを試す - - 高品質量子化(Q5_K_M, Q8_0)を使用 - -## 結論 - -RTX 4060 Ti 16GBなら、高品質量子化(Q5_K_M, Q8_0)でも快適に動作します。用途に応じてモデルを選択し、最適な設定で楽しいローカルLLM体験をお楽しみください! - ---- - -*このガイドは2025年5月時点の情報に基づいています。新しいモデルが随時リリースされるため、最新情報もチェックしてくださいね〜♪* \ No newline at end of file diff --git a/docs/mcp-server-local-llm.py b/docs/mcp-server-local-llm.py deleted file mode 100644 index 296a50f..0000000 --- a/docs/mcp-server-local-llm.py +++ /dev/null @@ -1,392 +0,0 @@ -#!/usr/bin/env python3 -""" -Local LLM MCP Server for Claude Code Integration -Claude Code → MCP Server → Local LLM (Qwen2.5-Coder) -""" - -import asyncio -import json -import logging -import requests -import subprocess -import os -from pathlib import Path -from typing import Dict, List, Any, Optional -from mcp.server import Server -from mcp.types import ( - Tool, - TextContent, - Resource, - PromptMessage, - GetPromptResult -) - -# ログ設定 -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger("local-llm-mcp") - -class LocalLLMServer: - def __init__(self, model: str = "qwen2.5-coder:14b-instruct-q4_K_M"): - self.model = model - self.ollama_url = "http://localhost:11434" - self.conversation_history = [] - - def call_ollama(self, prompt: str, system_prompt: str = "") -> str: - """Ollamaにリクエストを送信""" - try: - full_prompt = f"{system_prompt}\n\nUser: {prompt}\nAssistant:" - - response = requests.post( - f"{self.ollama_url}/api/generate", - json={ - "model": self.model, - "prompt": full_prompt, - "stream": False, - "options": { - "temperature": 0.1, - "top_p": 0.95, - "num_predict": 2048, - "stop": ["User:", "Human:"] - } - }, - timeout=60 - ) - - if response.status_code == 200: - return response.json()["response"].strip() - else: - return f"Error: {response.status_code} - {response.text}" - - except Exception as e: - logger.error(f"Ollama call failed: {e}") - return f"Connection error: {e}" - - def get_project_context(self) -> str: - """現在のプロジェクトの情報を取得""" - context = [] - - # 現在のディレクトリ - cwd = os.getcwd() - context.append(f"Current directory: {cwd}") - - # Git情報 - try: - git_status = subprocess.run( - ["git", "status", "--porcelain"], - capture_output=True, text=True, cwd=cwd - ) - if git_status.returncode == 0: - context.append(f"Git status: {git_status.stdout.strip() or 'Clean'}") - except: - context.append("Git: Not a git repository") - - # ファイル構造(簡略版) - try: - files = [] - for item in Path(cwd).iterdir(): - if not item.name.startswith('.') and item.name not in ['node_modules', '__pycache__']: - if item.is_file(): - files.append(f"📄 {item.name}") - elif item.is_dir(): - files.append(f"📁 {item.name}/") - - if files: - context.append("Project files:") - context.extend(files[:10]) # 最初の10個まで - - except Exception as e: - context.append(f"File listing error: {e}") - - return "\n".join(context) - -# MCPサーバーのセットアップ -app = Server("local-llm-mcp") -llm = LocalLLMServer() - -@app.tool("code_with_local_llm") -async def code_with_local_llm( - task: str, - include_context: bool = True, - model_override: str = "" -) -> str: - """ - ローカルLLMでコーディングタスクを実行 - - Args: - task: 実行したいコーディングタスク - include_context: プロジェクトコンテキストを含めるか - model_override: 使用するモデルを一時的に変更 - """ - logger.info(f"Executing coding task: {task}") - - # モデルの一時変更 - original_model = llm.model - if model_override: - llm.model = model_override - - try: - # システムプロンプト構築 - system_prompt = """You are an expert coding assistant. You can: -1. Write, analyze, and debug code -2. Explain programming concepts -3. Suggest optimizations and best practices -4. Generate complete, working solutions - -Always provide: -- Clear, commented code -- Explanations of your approach -- Any assumptions you've made -- Suggestions for improvements - -Format your response clearly with code blocks and explanations.""" - - # プロジェクトコンテキストを追加 - if include_context: - context = llm.get_project_context() - system_prompt += f"\n\nCurrent project context:\n{context}" - - # LLMに送信 - response = llm.call_ollama(task, system_prompt) - - return response - - except Exception as e: - logger.error(f"Code generation failed: {e}") - return f"❌ Error in code generation: {e}" - finally: - # モデルを元に戻す - llm.model = original_model - -@app.tool("read_file_with_analysis") -async def read_file_with_analysis( - filepath: str, - analysis_type: str = "general" -) -> str: - """ - ファイルを読み込んでLLMで分析 - - Args: - filepath: 分析するファイルのパス - analysis_type: 分析タイプ (general, bugs, optimization, documentation) - """ - logger.info(f"Analyzing file: {filepath}") - - try: - # ファイル読み込み - with open(filepath, 'r', encoding='utf-8', errors='ignore') as f: - content = f.read() - - # 分析タイプに応じたプロンプト - analysis_prompts = { - "general": "Analyze this code and provide a general overview, including its purpose, structure, and key components.", - "bugs": "Review this code for potential bugs, errors, or issues. Suggest fixes if found.", - "optimization": "Analyze this code for performance optimizations and suggest improvements.", - "documentation": "Generate comprehensive documentation for this code, including docstrings and comments." - } - - prompt = f"{analysis_prompts.get(analysis_type, analysis_prompts['general'])}\n\nFile: {filepath}\n\nCode:\n```\n{content}\n```" - - system_prompt = "You are a code review expert. Provide detailed, constructive analysis." - - response = llm.call_ollama(prompt, system_prompt) - - return f"📋 Analysis of {filepath}:\n\n{response}" - - except FileNotFoundError: - return f"❌ File not found: {filepath}" - except Exception as e: - logger.error(f"File analysis failed: {e}") - return f"❌ Error analyzing file: {e}" - -@app.tool("write_code_to_file") -async def write_code_to_file( - filepath: str, - task_description: str, - overwrite: bool = False -) -> str: - """ - LLMでコードを生成してファイルに書き込み - - Args: - filepath: 書き込み先のファイルパス - task_description: コード生成のタスク説明 - overwrite: 既存ファイルを上書きするか - """ - logger.info(f"Generating code for file: {filepath}") - - try: - # 既存ファイルのチェック - if os.path.exists(filepath) and not overwrite: - return f"❌ File already exists: {filepath}. Use overwrite=true to replace." - - # ファイル拡張子から言語を推定 - ext = Path(filepath).suffix.lower() - language_map = { - '.py': 'Python', - '.js': 'JavaScript', - '.ts': 'TypeScript', - '.java': 'Java', - '.cpp': 'C++', - '.c': 'C', - '.rs': 'Rust', - '.go': 'Go' - } - language = language_map.get(ext, 'appropriate language') - - # コード生成プロンプト - prompt = f"""Generate {language} code for the following task and save it to {filepath}: - -Task: {task_description} - -Requirements: -- Write complete, working code -- Include appropriate comments -- Follow best practices for {language} -- Make the code production-ready - -Return ONLY the code that should be saved to the file, without any additional explanation or markdown formatting.""" - - system_prompt = f"You are an expert {language} developer. Generate clean, efficient, well-documented code." - - # コード生成 - generated_code = llm.call_ollama(prompt, system_prompt) - - # ファイルに書き込み - os.makedirs(os.path.dirname(filepath), exist_ok=True) - with open(filepath, 'w', encoding='utf-8') as f: - f.write(generated_code) - - return f"✅ Code generated and saved to {filepath}\n\nGenerated code:\n```{language.lower()}\n{generated_code}\n```" - - except Exception as e: - logger.error(f"Code generation and file writing failed: {e}") - return f"❌ Error: {e}" - -@app.tool("debug_with_llm") -async def debug_with_llm( - error_message: str, - code_context: str = "", - filepath: str = "" -) -> str: - """ - エラーメッセージとコードコンテキストでデバッグ支援 - - Args: - error_message: エラーメッセージ - code_context: エラーが発生したコードの部分 - filepath: エラーが発生したファイル(オプション) - """ - logger.info("Debugging with LLM") - - try: - # ファイルが指定されていれば読み込み - if filepath and os.path.exists(filepath): - with open(filepath, 'r', encoding='utf-8', errors='ignore') as f: - file_content = f.read() - code_context = f"Full file content:\n{file_content}" - - prompt = f"""Help debug this error: - -Error message: {error_message} - -Code context: -{code_context} - -Please: -1. Explain what's causing the error -2. Provide a specific solution -3. Show the corrected code if applicable -4. Suggest ways to prevent similar errors""" - - system_prompt = "You are an expert debugger. Provide clear, actionable solutions to programming errors." - - response = llm.call_ollama(prompt, system_prompt) - - return f"🔧 Debug Analysis:\n\n{response}" - - except Exception as e: - logger.error(f"Debugging failed: {e}") - return f"❌ Debug error: {e}" - -@app.tool("explain_code") -async def explain_code( - code: str, - detail_level: str = "medium" -) -> str: - """ - コードの説明を生成 - - Args: - code: 説明するコード - detail_level: 説明の詳細レベル (basic, medium, detailed) - """ - logger.info("Explaining code with LLM") - - try: - detail_prompts = { - "basic": "Provide a brief, high-level explanation of what this code does.", - "medium": "Explain this code in detail, including its purpose, how it works, and key components.", - "detailed": "Provide a comprehensive explanation including line-by-line analysis, design patterns used, and potential improvements." - } - - prompt = f"{detail_prompts.get(detail_level, detail_prompts['medium'])}\n\nCode:\n```\n{code}\n```" - - system_prompt = "You are a programming instructor. Explain code clearly and educationally." - - response = llm.call_ollama(prompt, system_prompt) - - return f"📚 Code Explanation:\n\n{response}" - - except Exception as e: - logger.error(f"Code explanation failed: {e}") - return f"❌ Explanation error: {e}" - -@app.tool("switch_model") -async def switch_model(model_name: str) -> str: - """ - 使用するローカルLLMモデルを切り替え - - Args: - model_name: 切り替え先のモデル名 - """ - logger.info(f"Switching model to: {model_name}") - - try: - # モデルの存在確認 - response = requests.get(f"{llm.ollama_url}/api/tags") - if response.status_code == 200: - models = response.json().get("models", []) - available_models = [model["name"] for model in models] - - if model_name in available_models: - llm.model = model_name - return f"✅ Model switched to: {model_name}" - else: - return f"❌ Model not found. Available models: {', '.join(available_models)}" - else: - return "❌ Cannot check available models" - - except Exception as e: - logger.error(f"Model switching failed: {e}") - return f"❌ Error switching model: {e}" - -async def main(): - """MCPサーバーを起動""" - logger.info("Starting Local LLM MCP Server...") - logger.info(f"Using model: {llm.model}") - - # Ollamaの接続確認 - try: - response = requests.get(f"{llm.ollama_url}/api/tags", timeout=5) - if response.status_code == 200: - logger.info("✅ Ollama connection successful") - else: - logger.warning("⚠️ Ollama connection issue") - except Exception as e: - logger.error(f"❌ Cannot connect to Ollama: {e}") - - # サーバー起動 - await app.run() - -if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file diff --git a/docs/mcp-setup-guide.md b/docs/mcp-setup-guide.md deleted file mode 100644 index 2491d42..0000000 --- a/docs/mcp-setup-guide.md +++ /dev/null @@ -1,244 +0,0 @@ -# MCP Server セットアップガイド -Claude Code + ローカルLLM統合環境 - -## 🚀 セットアップ手順 - -### 1. 依存関係のインストール - -```bash -# 仮想環境作成 -python -m venv mcp-env -mcp-env\Scripts\activate # Windows -# source mcp-env/bin/activate # Linux/Mac - -# 必要なパッケージをインストール -pip install mcp requests pathlib asyncio -``` - -### 2. Ollamaのセットアップ - -```bash -# Ollamaのインストール(https://ollama.com) -# Windows: インストーラーをダウンロード -# Linux: curl -fsSL https://ollama.com/install.sh | sh - -# Qwen2.5-Coderモデルをダウンロード -ollama pull qwen2.5-coder:14b-instruct-q4_K_M - -# Ollamaサーバー起動確認 -ollama serve -``` - -### 3. Claude Desktop設定 - -#### claude_desktop_config.json の作成 -**Windows**: `%APPDATA%\Claude\claude_desktop_config.json` -**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` -**Linux**: `~/.config/claude/claude_desktop_config.json` - -```json -{ - "mcpServers": { - "local-llm": { - "command": "python", - "args": ["/path/to/your/local_llm_mcp_server.py"], - "env": { - "OLLAMA_URL": "http://localhost:11434", - "DEFAULT_MODEL": "qwen2.5-coder:14b-instruct-q4_K_M" - } - } - } -} -``` - -### 4. Claude Code設定 - -```bash -# Claude Codeをインストール(既にインストール済みの場合はスキップ) -# 公式サイトからダウンロード - -# MCP サーバーを追加 -claude mcp add local-llm - -# または手動で設定ファイルを編集 -# ~/.config/claude-code/config.json -``` - -## 🎯 使用方法 - -### Claude Codeから使用 - -```bash -# Claude Codeを起動 -claude code - -# プロンプト例: -# "Use local LLM to implement a Python quicksort function" -# "Analyze main.py with local model for potential bugs" -# "Generate a REST API using the local coding model" -``` - -### 利用可能なツール - -1. **code_with_local_llm** - - タスク: `"Implement a binary search tree in Python"` - - プロジェクトコンテキスト含む: `true` - -2. **read_file_with_analysis** - - ファイルパス: `"src/main.py"` - - 分析タイプ: `"bugs"` | `"optimization"` | `"documentation"` - -3. **write_code_to_file** - - ファイルパス: `"utils/helpers.py"` - - タスク説明: `"Create utility functions for data processing"` - -4. **debug_with_llm** - - エラーメッセージ: `"IndexError: list index out of range"` - - コードコンテキスト: 該当するコード部分 - -5. **explain_code** - - コード: 解説したいコード - - 詳細レベル: `"basic"` | `"medium"` | `"detailed"` - -6. **switch_model** - - モデル名: `"qwen2.5-coder:7b-instruct"` - -## 🔧 カスタマイズ - -### モデル設定の変更 - -```python -# デフォルトモデルの変更 -llm = LocalLLMServer("deepseek-coder:6.7b-instruct-q4_K_M") - -# 複数モデル対応 -models = { - "coding": "qwen2.5-coder:14b-instruct-q4_K_M", - "general": "qwen2.5:14b-instruct-q4_K_M", - "light": "mistral-nemo:12b-instruct-q5_K_M" -} -``` - -### プロンプトのカスタマイズ - -```python -# システムプロンプトの調整 -system_prompt = """You are an expert coding assistant specialized in: -- Clean, efficient code generation -- Best practices and design patterns -- Security-conscious development -- Performance optimization - -Always provide: -- Working, tested code -- Comprehensive comments -- Error handling -- Performance considerations""" -``` - -## 🛠️ トラブルシューティング - -### よくある問題 - -1. **MCPサーバーが起動しない** -```bash -# ログ確認 -tail -f ~/.config/claude-desktop/logs/mcp.log - -# Pythonパスの確認 -which python -``` - -2. **Ollamaに接続できない** -```bash -# Ollamaの状態確認 -ollama ps -curl http://localhost:11434/api/tags - -# サービス再起動 -ollama serve -``` - -3. **モデルが見つからない** -```bash -# インストール済みモデル確認 -ollama list - -# モデルの再ダウンロード -ollama pull qwen2.5-coder:14b-instruct-q4_K_M -``` - -### パフォーマンス最適化 - -```python -# Ollamaの設定調整 -{ - "temperature": 0.1, # 一貫性重視 - "top_p": 0.95, # 品質バランス - "num_predict": 2048, # 応答長制限 - "num_ctx": 4096 # コンテキスト長 -} -``` - -### セキュリティ設定 - -```python -# ファイルアクセス制限 -ALLOWED_DIRECTORIES = [ - os.getcwd(), - os.path.expanduser("~/projects") -] - -# 実行可能コマンドの制限 -ALLOWED_COMMANDS = ["git", "python", "node", "npm"] -``` - -## 🎉 使用例 - -### 1. 新機能の実装 -``` -Claude Code Prompt: -"Use local LLM to create a user authentication system with JWT tokens in Python Flask" - -→ MCPサーバーがローカルLLMでコード生成 -→ ファイルに自動保存 -→ Claude Codeが結果を表示 -``` - -### 2. バグ修正 -``` -Claude Code Prompt: -"Analyze app.py for bugs and fix them using the local model" - -→ ファイル読み込み + LLM分析 -→ 修正版コードを生成 -→ バックアップ作成後に上書き -``` - -### 3. コードレビュー -``` -Claude Code Prompt: -"Review the entire codebase with local LLM and provide optimization suggestions" - -→ プロジェクト全体をスキャン -→ 各ファイルをLLMで分析 -→ 改善提案をレポート形式で生成 -``` - -## 📊 パフォーマンス比較 - -| 機能 | Claude Code (公式) | ローカルLLM + MCP | -|------|-------------------|-------------------| -| 応答速度 | ⚡ 高速 | 🟡 中程度 | -| プライバシー | 🟡 クラウド | 🟢 完全ローカル | -| カスタマイズ | 🟡 限定的 | 🟢 完全自由 | -| コスト | 💰 従量課金 | 🟢 無料 | -| 専門性 | 🟢 汎用的 | 🟢 カスタマイズ可能 | - -## 🔄 今後の拡張 - -- [ ] 複数LLMモデルの同時利用 -- [ ] コード実行環境の統合 -- [ ] Gitワークフローの自動化 -- [ ] プロジェクトテンプレートの生成 -- [ ] 自動テスト生成機能 \ No newline at end of file