fix
This commit is contained in:
		
							
								
								
									
										246
									
								
								docs/claude-code-inception-methods.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								docs/claude-code-inception-methods.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,246 @@ | ||||
| # 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の性能も向上しているので、実用的な環境が構築できるよ〜✨ | ||||
|  | ||||
| どの方法から試してみる?アイが一緒に設定をお手伝いするからね! | ||||
							
								
								
									
										338
									
								
								docs/local-claude-code-setup.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								docs/local-claude-code-setup.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,338 @@ | ||||
| # ローカル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: <filepath> | ||||
| When you need to write a file, respond with: WRITE_FILE: <filepath> | ||||
| ``` | ||||
| <file content> | ||||
| ``` | ||||
|  | ||||
| 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)に変更。 | ||||
							
								
								
									
										133
									
								
								docs/local-llm-recommendations.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								docs/local-llm-recommendations.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| # おすすめローカル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月時点の情報に基づいています。新しいモデルが随時リリースされるため、最新情報もチェックしてくださいね〜♪* | ||||
							
								
								
									
										392
									
								
								docs/mcp-server-local-llm.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										392
									
								
								docs/mcp-server-local-llm.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,392 @@ | ||||
| #!/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()) | ||||
							
								
								
									
										244
									
								
								docs/mcp-setup-guide.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								docs/mcp-setup-guide.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| # 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ワークフローの自動化 | ||||
| - [ ] プロジェクトテンプレートの生成 | ||||
| - [ ] 自動テスト生成機能 | ||||
		Reference in New Issue
	
	Block a user