本記事は、Difyでカスタムノードを作成し、外部API(特にHolySheep AI)とシームレスに統合する方法を解説する。導入部分を購入検討者向けの比較表で構成し、その後、具体的な実装コードとトラブルシューティングを示す。

結論:HolySheep AIが最適な理由

第三方AI APIの選択肢として、HolySheep AIは以下の理由で最もコスト効率に優れている:

主要AI API Provider比較表

ProviderGPT-4.1 ($/MTok)Claude Sonnet 4.5 ($/MTok)Gemini 2.5 Flash ($/MTok)DeepSeek V3.2 ($/MTok)レイテンシ決済手段最低料金適任チーム
HolySheep AI$8.00$15.00$2.50$0.42<50msWeChat Pay, Alipay, USDT$1〜コスト重視・グローバル展開
OpenAI公式$15.00-$15.00$2.50非対応80-200msカードのみ$5〜エンタープライズ向け
Anthropic公式$15.00$18.00$2.50非対応100-300msカードのみ$20〜、長文処理多用
Google AI$8.00$15.00$1.25非対応60-150msカードのみ$10〜GCP既存ユーザー
DeepSeek公式$8.00$15.00$2.50$0.50100-250msカード・Alipay$5〜中国語圏ユーザー

Difyカスタムノードとは

Difyのカスタムノードは、標準で提供されない処理ロジックをワークフローに組み込める拡張機能である。カスタムノードを使用することで、HolySheep AIのAPI呼び出しを最適化したり、複数のAI Providerを組み合わせたフォールバック機構を構築できる。

プロジェクト構成

my-dify-plugins/
├── holy_sheep_node/
│   ├── __init__.py
│   ├── manifest.json
│   ├── holy_sheep_assistant.py
│   └── requirements.txt
└── examples/
    ├── basic_chat.py
    └── streaming_chat.py

STEP 1: manifest.jsonの作成

{
  "name": "holy_sheep-assistant",
  "version": "1.0.0",
  "description": "HolySheep AI API integration for Dify workflows",
  "provider": "holysheep",
  "input_types": ["string", "number", "select"],
  "output_types": ["string", "json"],
  "category": "ai",
  "icon": "https://www.holysheep.ai/icon.png",
  "credentials": {
    "api_key": {
      "type": "secret",
      "required": true,
      "label": {
        "en_US": "API Key",
        "ja_JP": "APIキー"
      }
    }
  },
  "parameters": [
    {
      "name": "model",
      "type": "select",
      "required": true,
      "options": [
        {"label": "GPT-4.1", "value": "gpt-4.1"},
        {"label": "Claude Sonnet 4.5", "value": "claude-sonnet-4.5"},
        {"label": "Gemini 2.5 Flash", "value": "gemini-2.5-flash"},
        {"label": "DeepSeek V3.2", "value": "deepseek-v3.2"}
      ],
      "default": "gpt-4.1",
      "label": {"ja_JP": "モデル選択"}
    },
    {
      "name": "temperature",
      "type": "number",
      "required": false,
      "default": 0.7,
      "min": 0.0,
      "max": 2.0,
      "label": {"ja_JP": "temperature(創造性)"}
    },
    {
      "name": "max_tokens",
      "type": "number",
      "required": false,
      "default": 2048,
      "min": 1,
      "max": 128000,
      "label": {"ja_JP": "最大トークン数"}
    }
  ]
}

STEP 2: カスタムノード本体(holy_sheep_assistant.py)

"""
HolySheep AI Custom Node for Dify
HolySheep API Document: https://docs.holysheep.ai
"""
import json
import time
from typing import Any, Generator, Optional
from dify_plugin import Tool
from dify_plugin.file import MAX_CHARACTER_SIZE

HolySheep AI公式エンドポイント(絶対にapi.openai.com不使用)

HOLYSHEEP_BASE_URL = "https://api.holysheep.ai/v1"

実際のAPIキーはDifyの資格情報管理から取得

API_KEY_PLACEHOLDER = "YOUR_HOLYSHEEP_API_KEY" class HolySheepAssistant(Tool): """ Difyカスタムノード:HolySheep AI API統合 対応モデル: GPT-4.1, Claude Sonnet 4.5, Gemini 2.5 Flash, DeepSeek V3.2 特徴: <50msレイテンシ、¥1=$1の最優位レート """ def _invoke(self, tool_parameters: dict) -> str: """ ノード実行時のメインロジック Difyワークフローから呼び出される """ # パラメータ取得 user_message = tool_parameters.get("text", "") model = tool_parameters.get("model", "gpt-4.1") temperature = float(tool_parameters.get("temperature", 0.7)) max_tokens = int(tool_parameters.get("max_tokens", 2048)) # APIキー取得(Dify資格情報から) api_key = self.runtime.credentials.get("api_key") if not api_key or api_key == API_KEY_PLACEHOLDER: raise ValueError( "HolySheep APIキーが設定されていません。" "Difyの資格情報管理でAPIキーを登録してください。" ) # HolySheep AI API呼び出し start_time = time.time() response = self._call_holysheep_api( api_key=api_key, model=model, messages=[{"role": "user", "content": user_message}], temperature=temperature, max_tokens=max_tokens ) elapsed_ms = (time.time() - start_time) * 1000 # 結果整形 result = { "response": response, "model": model, "latency_ms": round(elapsed_ms, 2), "tokens_used": self._estimate_tokens(response) } return json.dumps(result, ensure_ascii=False) def _call_holysheep_api( self, api_key: str, model: str, messages: list, temperature: float, max_tokens: int ) -> str: """ HolySheep AI APIへのリクエスト実行 base_urlは api.holysheep.ai/v1 を使用 """ import urllib.request import urllib.error url = f"{HOLYSHEEP_BASE_URL}/chat/completions" payload = { "model": model, "messages": messages, "temperature": temperature, "max_tokens": max_tokens, "stream": False } data = json.dumps(payload).encode("utf-8") request = urllib.request.Request( url, data=data, headers={ "Content-Type": "application/json", "Authorization": f"Bearer {api_key}", "User-Agent": "Dify-Plugin/1.0 (HolySheep-Integration)" }, method="POST" ) try: with urllib.request.urlopen(request, timeout=30) as response: result = json.loads(response.read().decode("utf-8")) return result["choices"][0]["message"]["content"] except urllib.error.HTTPError as e: error_body = e.read().decode("utf-8") if e.fp else "{}" raise RuntimeError( f"HolySheep APIエラー (HTTP {e.code}): {error_body}" ) except urllib.error.URLError as e: raise RuntimeError( f"HolySheep API接続エラー: {e.reason}" ) def _estimate_tokens(self, text: str) -> int: """トークン数の概算(日本語は1文字≈1.5トークン)""" return int(len(text) * 1.5) def invoke_stream(self, tool_parameters: dict) -> Generator[str, None, None]: """ ストリーミング対応版(長文生成時に使用) レイテンシ<50msのHolySheep回線を活用 """ import urllib.request import urllib.error api_key = self.runtime.credentials.get("api_key") user_message = tool_parameters.get("text", "") model = tool_parameters.get("model", "gpt-4.1") url = f"{HOLYSHEEP_BASE_URL}/chat/completions" payload = { "model": model, "messages": [{"role": "user", "content": user_message}], "temperature": 0.7, "max_tokens": 4096, "stream": True } data = json.dumps(payload).encode("utf-8") request = urllib.request.Request( url, data=data, headers={ "Content-Type": "application/json", "Authorization": f"Bearer {api_key}", }, method="POST" ) with urllib.request.urlopen(request, timeout=60) as response: for line in response: line = line.decode("utf-8").strip() if line.startswith("data: "): if line == "data: [DONE]": break data = json.loads(line[6:]) delta = data["choices"][0]["delta"].get("content", "") if delta: yield delta

STEP 3: Difyワークフローへの組み込み

Difyの管理画面から「スタジオ」→「カスタムノード」で上記プラグインを読み込む。ワークフローエディタでHolySheepノードを配置し、モデル・パラメータ・資格情報を設定する。

# ワークフロー例: 多段AI処理パイプライン
workflow = {
    "nodes": [
        {
            "type": "user_input",
            "params": {"question": "入力テキスト"}
        },
        {
            "type": "holy_sheep-assistant",
            "params": {
                "model": "deepseek-v3.2",  # コスト効率重視
                "temperature": 0.3,
                "text": "{{user_input}}"
            }
        },
        {
            "type": "holy_sheep-assistant",
            "params": {
                "model": "gpt-4.1",  # 高品質処理
                "temperature": 0.7,
                "text": "以下の文章を校正してください:\n{{holy_sheep_assistant_1.response}}"
            }
        },
        {
            "type": "template",
            "params": {
                "output": "Latency: {{holy_sheep_assistant_2.latency_ms}}ms\n"
                          "Tokens: {{holy_sheep_assistant_2.tokens_used}}\n"
                          "Result: {{holy_sheep_assistant_2.response}}"
            }
        }
    ]
}

HolySheep APIのフォールバック機構実装

"""
複数のAI Providerをフォールバック機構で統合
HolySheep→OpenAI→Anthropicの優先順で可用性を確保
"""
import json
import time
from typing import Optional

class MultiProviderFallback:
    """
    マルチProviderフォールバック機構
    HolySheep AIを最優先で使用し、失敗時に次_providerへ切り替え
    """
    
    PROVIDERS = {
        "holysheep": {
            "base_url": "https://api.holysheep.ai/v1",
            "priority": 1,
            "models": ["gpt-4.1", "claude-sonnet-4.5", "gemini-2.5-flash", "deepseek-v3.2"]
        },
        "openai": {
            "base_url": "https://api.openai.com/v1",
            "priority": 2,
            "models": ["gpt-4", "gpt-4-turbo"]
        },
        "anthropic": {
            "base_url": "https://api.anthropic.com/v1",
            "priority": 3,
            "models": ["claude-3-sonnet-20240229"]
        }
    }
    
    def __init__(self, api_keys: dict):
        self.api_keys = api_keys
        self.current_provider = "holysheep"
        self.last_success_provider = None
        self.metrics = {"latency": {}, "success_rate": {}}
    
    def chat(self, message: str, model: str = "deepseek-v3.2") -> dict:
        """
        フォールバック機能付きチャット実行
        HolySheep優先で全Providerを試行
        """
        start_time = time.time()
        errors = []
        
        # HolySheepを試行(最優先・最安値)
        try:
            result = self._call_provider(
                "holysheep",
                model if model in self.PROVIDERS["holysheep"]["models"] else "deepseek-v3.2",
                message
            )
            self.last_success_provider = "holysheep"
            elapsed = (time.time() - start_time) * 1000
            self._record_metrics("holysheep", elapsed, True)
            return {"provider": "holysheep", "latency_ms": elapsed, **result}
            
        except Exception as e:
            errors.append(f"holysheep: {str(e)}")
            self._record_metrics("holysheep", 0, False)
        
        # OpenAIにフォールバック
        try:
            result = self._call_provider(
                "openai",
                "gpt-4-turbo",
                message
            )
            self.last_success_provider = "openai"
            elapsed = (time.time() - start_time) * 1000
            self._record_metrics("openai", elapsed, True)
            return {"provider": "openai", "latency_ms": elapsed, **result}
            
        except Exception as e:
            errors.append(f"openai: {str(e)}")
            self._record_metrics("openai", 0, False)
        
        # Anthropicに最終フォールバック
        try:
            result = self._call_provider(
                "anthropic",
                "claude-3-sonnet-20240229",
                message
            )
            self.last_success_provider = "anthropic"
            elapsed = (time.time() - start_time) * 1000
            self._record_metrics("anthropic", elapsed, True)
            return {"provider": "anthropic", "latency_ms": elapsed, **result}
            
        except Exception as e:
            errors.append(f"anthropic: {str(e)}")
            self._record_metrics("anthropic", 0, False)
        
        raise RuntimeError(
            f"全Provider接続失敗: {'; '.join(errors)}"
        )
    
    def _call_provider(self, provider: str, model: str, message: str) -> dict:
        """各ProviderのAPIを呼び出す内部メソッド"""
        import urllib.request
        import urllib.error
        
        config = self.PROVIDERS[provider]
        url = f"{config['base_url']}/chat/completions"
        
        payload = {
            "model": model,
            "messages": [{"role": "user", "content": message}]
        }
        
        headers = {
            "Content-Type": "application/json"
        }
        
        # Provider別の認証方式
        if provider == "holysheep":
            headers["Authorization"] = f"Bearer {self.api_keys['holysheep']}"
        elif provider == "openai":
            headers["Authorization"] = f"Bearer {self.api_keys['openai']}"
        elif provider == "anthropic":
            headers["x-api-key"] = self.api_keys['anthropic']
            headers["anthropic-version"] = "2023-06-01"
        
        data = json.dumps(payload).encode("utf-8")
        request = urllib.request.Request(
            url, data=data, headers=headers, method="POST"
        )
        
        with urllib.request.urlopen(request, timeout=30) as response:
            result = json.loads(response.read().decode("utf-8"))
            return {"response": result["choices"][0]["message"]["content"]}
    
    def _record_metrics(self, provider: str, latency: float, success: bool):
        """メトリクス記録"""
        if provider not in self.metrics["latency"]:
            self.metrics["latency"][provider] = []
            self.metrics["success_rate"][provider] = {"success": 0, "total": 0}
        
        if latency > 0:
            self.metrics["latency"][provider].append(latency)
        
        self.metrics["success_rate"][provider]["total"] += 1
        if success:
            self.metrics["success_rate"][provider]["success"] += 1
    
    def get_optimal_provider(self) -> str:
        """成功率と平均レイテンシから最適Providerを返す"""
        scores = {}
        for provider in self.PROVIDERS:
            if provider not in self.metrics["success_rate"]:
                scores[provider] = 0
                continue
            
            sr = self.metrics["success_rate"][provider]
            success_rate = sr["success"] / sr["total"] if sr["total"] > 0 else 0
            
            latencies = self.metrics["latency"].get(provider, [999999])
            avg_latency = sum(latencies) / len(latencies) if latencies else 999999
            
            # スコア計算(成功率70%、レイテンシ30%)
            scores[provider] = (success_rate * 0.7) + ((1000 / avg_latency) * 0.3)
        
        return max(scores, key=scores.get)


使用例

if __name__ == "__main__": client = MultiProviderFallback({ "holysheep": "YOUR_HOLYSHEEP_API_KEY", "openai": "sk-your-openai-key", "anthropic": "sk-ant-your-anthropic-key" }) result = client.chat("日本の四季について教えてください") print(f"Provider: {result['provider']}") print(f"Latency: {result['latency_ms']}ms") print(f"Response: {result['response'][:100]}...")

料金計算シミュレーター

"""
HolySheep AI料金計算ツール
公式¥7.3=$1 vs HolySheep ¥1=$1の節約額を算出
"""
from typing import Dict, List

class HolySheepPricingCalculator:
    """
    HolySheep AI料金計算
    2026年最新価格表に基づく
    """
    
    # HolySheep AI公式価格($/MTok入力・出力)
    HOLYSHEEP_PRICES = {
        "gpt-4.1": {"input": 8.00, "output": 8.00},
        "claude-sonnet-4.5": {"input": 15.00, "output": 15.00},
        "gemini-2.5-flash": {"input": 2.50, "output": 2.50},
        "deepseek-v3.2": {"input": 0.42, "output": 0.42}
    }
    
    # OpenAI公式価格(比較用)
    OPENAI_PRICES = {
        "gpt-4": {"input": 30.00, "output": 60.00},
        "gpt-4-turbo": {"input": 10.00, "output": 30.00}
    }
    
    # Anthropic公式価格(比較用)
    ANTHROPIC_PRICES = {
        "claude-3-sonnet-20240229": {"input": 3.00, "output": 15.00}
    }
    
    USD_TO_JPY = 7.3  # 公式レート
    HOLYSHEEP_USD_RATE = 1.0  # HolySheep ¥1 = $1
    
    def calculate_holysheep_cost(
        self,
        model: str,
        input_tokens: int,
        output_tokens: int
    ) -> Dict[str, float]:
        """
        HolySheep AI,成本計算
        input_tokens: 入力トークン数
        output_tokens: 出力トークン数
        """
        if model not in self.HOLYSHEEP_PRICES:
            raise ValueError(f"未対応のモデル: {model}")
        
        prices = self.HOLYSHEEP_PRICES[model]
        
        # MTok単位に変換
        input_mtok = input_tokens / 1_000_000
        output_mtok = output_tokens / 1_000_000
        
        # USD計算
        input_usd = input_mtok * prices["input"]
        output_usd = output_mtok * prices["output"]
        total_usd = input_usd + output_usd
        
        # 円換算(HolySheepレートの場合)
        total_jpy_holysheep = total_usd * self.HOLYSHEEP_USD_RATE
        
        # 公式レートとの比較
        total_jpy_official = total_usd * self.USD_TO_JPY
        
        return {
            "model": model,
            "input_tokens": input_tokens,
            "output_tokens": output_tokens,
            "input_cost_usd": round(input_usd, 4),
            "output_cost_usd": round(output_usd, 4),
            "total_cost_usd": round(total_usd, 4),
            "total_cost_jpy_holysheep": round(total_jpy_holysheep, 2),
            "total_cost_jpy_official": round(total_jpy_official, 2),
            "savings_jpy": round(total_jpy_official - total_jpy_holysheep, 2),
            "savings_percent": round(
                (total_jpy_official - total_jpy_holysheep) / total_jpy_official * 100, 1
            )
        }
    
    def compare_providers(
        self,
        input_tokens: int,
        output_tokens: int
    ) -> List[Dict]:
        """
        全Providerの料金比較
        """
        results = []
        
        for model, prices in self.HOLYSHEEP_PRICES.items():
            result = self.calculate_holysheep_cost(model, input_tokens, output_tokens)
            result["provider"] = "HolySheep AI"
            result["rate_advantage"] = "85% cheaper than official"
            results.append(result)
        
        # OpenAI比較
        for model, prices in self.OPENAI_PRICES.items():
            input_mtok = input_tokens / 1_000_000
            output_mtok = output_tokens / 1_000_000
            total_jpy = (input_mtok * prices["input"] + output_mtok * prices["output"]) * self.USD_TO_JPY
            results.append({
                "provider": "OpenAI公式",
                "model": model,
                "total_cost_jpy_official": round(total_jpy, 2),
                "savings_percent": 0
            })
        
        return sorted(results, key=lambda x: x.get("total_cost_jpy_holysheep", x.get("total_cost_jpy_official", 999999)))
    
    def estimate_monthly_budget(
        self,
        daily_requests: int,
        avg_input_tokens: int,
        avg_output_tokens: int,
        model: str = "deepseek-v3.2"
    ) -> Dict:
        """月間予算見積もり(DeepSeek V3.2使用時)"""
        daily_cost = self.calculate_holysheep_cost(
            model, avg_input_tokens, avg_output_tokens
        )
        
        monthly_tokens_input = daily_requests * avg_input_tokens * 30
        monthly_tokens_output = daily_requests * avg_output_tokens * 30
        
        monthly = self.calculate_holysheep_cost(
            model, monthly_tokens_input, monthly_tokens_output
        )
        
        return {
            "daily_requests": daily_requests,
            "monthly_requests": daily_requests * 30,
            "model": model,
            "monthly_cost_jpy": monthly["total_cost_jpy_holysheep"],
            "monthly_cost_usd": monthly["total_cost_usd"],
            "equivalent_credits": f"${monthly['total_cost_usd']:.2f}相当"
        }


if __name__ == "__main__":
    calc = HolySheepPricingCalculator()
    
    # 例:1,000トークン入力、2,000トークン出力の処理
    result = calc.calculate_holysheep_cost("deepseek-v3.2", 1000, 2000)
    print(f"モデル: {result['model']}")
    print(f"入力コスト: ${result['input_cost_usd']}")
    print(f"出力コスト: ${result['output_cost_usd']}")
    print(f"合計コスト: ${result['total_cost_usd']} (¥{result['total_cost_jpy_holysheep']})")
    print(f"公式比較: ¥{result['total_cost_jpy_official']}")
    print(f"節約額: ¥{result['savings_jpy']} ({result['savings_percent']}% OFF)")
    
    print("\n--- Provider比較 ---")
    comparison = calc.compare_providers(5000, 3000)
    for r in comparison[:4]:
        print(f"{r['provider']} {r['model']}: ¥{r.get('total_cost_jpy_holysheep', r.get('total_cost_jpy_official', 'N/A'))}")
    
    print("\n--- 月間予算見積もり ---")
    budget = calc.estimate_monthly_budget(
        daily_requests=100,
        avg_input_tokens=500,
        avg_output_tokens=1000,
        model="deepseek-v3.2"
    )
    print(f"月間コスト: ¥{budget['monthly_cost_jpy']} ({budget['monthly_cost_usd']})")

よくあるエラーと対処法

エラー1: APIキー認証失敗(401 Unauthorized)

# 問題: API呼び出し時に401エラーが発生

原因: APIキーが正しく設定されていない・有効期限切れ

解決策: Dify資格情報管理で正しいキーを設定

1. Dify管理画面 → 設定 → 資格情報

2. 「新しい資格情報を追加」をクリック

3. プロバイダー: "holysheep"、キー名: "api_key"

4. 実際のAPIキーをペースト

キーの有効性確認コード

import urllib.request import json def verify_api_key(api_key: str) -> dict: """HolySheep APIキーの有効性をチェック""" url = "https://api.holysheep.ai/v1/models" request = urllib.request.Request( url, headers={ "Authorization": f"Bearer {api_key}", "Content-Type": "application/json" }, method="GET" ) try: with urllib.request.urlopen(request, timeout=10) as response: return {"status": "valid", "models": json.loads(response.read())} except urllib.error.HTTPError as e: if e.code == 401: return {"status": "invalid", "error": "APIキーが無効です。新規取得してください。"} return {"status": "error", "error": f"HTTP {e.code}"}

使用

result = verify_api_key("YOUR_HOLYSHEEP_API_KEY") print(result)

エラー2: レートリミットExceeded(429 Too Many Requests)

# 問題: リクエスト过快で429エラー

原因: 短时间内太多リクエスト

解決策: リトライ機構+エクスポネンシャルバックオフ実装

import time import random from functools import wraps def retry_with_backoff(max_retries=3, base_delay=1.0, max_delay=60.0): """エクスポネンシャルバックオフ付きリトライデコレータ""" def decorator(func): @wraps(func) def wrapper(*args, **kwargs): for attempt in range(max_retries): try: return func(*args, **kwargs) except Exception as e: if "429" in str(e) and attempt < max_retries - 1: # バックオフ時間計算(ジッター付き) delay = min(base_delay * (2 ** attempt), max_delay) jitter = random.uniform(0, delay * 0.1) print(f"レートリミット到達。{delay + jitter:.1f}秒後にリトライ...") time.sleep(delay + jitter) else: raise return func(*args, **kwargs) return wrapper return decorator @retry_with_backoff(max_retries=5, base_delay=2.0) def call_holysheep_with_retry(api_key: str, model: str, message: str) -> str: """リトライ機能付きHolySheep API呼び出し""" import urllib.request import json url = "https://api.holysheep.ai/v1/chat/completions" payload = { "model": model, "messages": [{"role": "user", "content": message}] } data = json.dumps(payload).encode("utf-8") request = urllib.request.Request( url, data=data, headers={ "Content-Type": "application/json", "Authorization": f"Bearer {api_key}" }, method="POST" ) with urllib.request.urlopen(request, timeout=30) as response: result = json.loads(response.read().decode("utf-8")) return result["choices"][0]["message"]["content"]

使用

result = call_holysheep_with_retry( "YOUR_HOLYSHEEP_API_KEY", "deepseek-v3.2", "Hello!" ) print(result)

エラー3: タイムアウト・接続エラー(Connection Timeout)

# 問題: API呼び出しがタイムアウトする

原因: ネットワーク問題・HolySheepサーバーダウン

解決策: タイムアウト設定+代替エンドポイント対応

import socket import urllib.error from typing import Optional class HolySheepConnectionManager: """ HolySheep AI接続管理 タイムアウト・代替エンドポイント対応 """ # メインエンドポイント ENDPOINTS = [ "https://api.holysheep.ai/v1", "https://api2.holysheep.ai/v1", # 代替 ] DEFAULT_TIMEOUT = 30 # 秒 def __init__(self, api_key: str): self.api_key = api_key self.current_endpoint_index = 0 def get_base_url(self) -> str: """現在のエンドポイントURLを取得""" return self.ENDPOINTS[self.current_endpoint_index] def switch_endpoint(self): """代替エンドポイントに切り替え""" self.current_endpoint_index = (self.current_endpoint_index + 1) % len(self.ENDPOINTS) print(f"エンドポイント切替: {self.get_base_url()}") def call_api( self, model: str, messages: list, timeout: Optional[int] = None ) -> dict: """ タイムアウト付きAPI呼び出し 失敗時に代替エンドポイントを試行 """ import urllib.request import json timeout = timeout or self.DEFAULT_TIMEOUT # 全エンドポイントを試行 for endpoint in self.ENDPOINTS: try: url = f"{endpoint}/chat/completions" payload = { "model": model, "messages": messages, "timeout": timeout } data = json.dumps(payload).encode("utf-8") request = urllib.request.Request( url, data=data, headers={ "Content-Type": "application/json", "Authorization": f"Bearer {self.api_key}" }, method="POST" ) # カスタムタイムアウト設定 response = urllib.request.urlopen(request, timeout=timeout) result = json.loads(response.read().decode("utf-8")) return { "success": True, "endpoint": endpoint, "response": result } except socket.timeout: print(f"タイムアウト: {endpoint}") continue except urllib.error.URLError as e: print(f"接続エラー ({endpoint}): {e.reason}") continue # 全エンドポイント失敗 return { "success": False, "error": "全エンドポイントへの接続に失敗しました" } def health_check(self) -> dict: """接続テスト(各エンドポイント)""" import urllib.request results = {} for endpoint in self.ENDPOINTS: try: url = f"{endpoint}/models" request = urllib.request.Request( url, headers={ "Authorization": f"Bearer {self.api_key}" }, method="GET" ) start = time.time() urllib.request.urlopen(request, timeout=5) latency = (time.time() - start) * 1000 results[endpoint] = { "status": "healthy", "latency_ms": round(latency, 2) } except Exception as e