AI API を本番運用する上で、錯誤碼(エラーコード)体系の設計と例外処理の統一化は、システムの安定性と保守性を左右する重要な要素です。本稿では、公式 API や既存のリレーサービスから HolySheep AI へ移行する際の ошиб码体系設計と統一例外処理アーキテクチャについて、体系的に解説します。

なぜ HolySheep AI へ移行するのか

現在、多くの開発者が公式 API や中継サービスを,利用していますが、以下の課題に直面しています:

HolySheep AI はこれらの課題を一挙に解決します:

HolySheep API 錯誤碼アーキテクチャ

HolySheep AI の錯誤碼体系は HTTP ステータスコードと一口大小的エラーコードを組み合わせた二層構造を採用しています。これにより、エラーの原因特定の迅速化と client側のエラーハンドリング実装が容易になります。

HTTP ステータスコード分類

2xx 成功
├── 200 OK              正常応答
├── 201 Created         リソース作成成功
└── 204 No Content      正常終了(レスポンスボディなし)

4xx クライアントエラー
├── 400 Bad Request     パラメータ不正・バリデーションエラー
├── 401 Unauthorized    API キー未設定・無効
├── 403 Forbidden       権限不足・利用制限超過
├── 404 Not Found       リソース不存在
├── 422 Unprocessable   構文エラー・サポート外パラメータ
├── 429 Too Many Req    レートリミット到達
└── 499 Client Closed   クライアントが接続を切断

5xx サーバーエラー
├── 500 Internal Error  サーバー内部エラー
├── 502 Bad Gateway     上流サービス障害
├── 503 Service Unavail メンテナンス・過負荷
└── 504 Gateway Timeout タイムアウト

エラーレスポンス形式

HolySheep API のエラーレスポンスは RFC 7807 Problem Details に基づく統一形式を採用しています:

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "レートリミットを超過しました。現在のプラン: 60req/min",
    "param": null,
    "type": "rate_limit_error",
    "status": 429,
    "details": {
      "retry_after": 15,
      "limit": 60,
      "remaining": 0,
      "reset_at": "2026-01-20T10:30:00Z"
    },
    "request_id": "req_hs_7f8a9b2c3d4e5f6g"
  }
}

統一例外処理クラスの実装

HolySheep API への移行をスムーズに行うため、統一例外処理クラスを実装します。以下の TypeScript クラス群は、既存の OpenAI SDK との後方互換性も考慮して設計されています:

/**
 * HolySheep API 統一例外クラス体系
 * @author HolySheep AI Technical Team
 * @version 1.0.0
 */

// 基底例外クラス
abstract class HolySheepError extends Error {
  constructor(
    public readonly code: string,
    public readonly status: number,
    message: string,
    public readonly details?: Record<string, unknown>
  ) {
    super(message);
    this.name = 'HolySheepError';
    Error.captureStackTrace(this, this.constructor);
  }
}

// --- クライアントエラー系 ---

export class AuthenticationError extends HolySheepError {
  constructor(message: string, details?: Record<string, unknown>) {
    super('AUTHENTICATION_FAILED', 401, message, details);
    this.name = 'AuthenticationError';
  }
}

export class RateLimitError extends HolySheepError {
  constructor(
    message: string,
    public readonly retryAfter: number,
    public readonly limit: number,
    details?: Record<string, unknown>
  ) {
    super('RATE_LIMIT_EXCEEDED', 429, message, {
      ...details,
      retry_after: retryAfter,
      limit,
    });
    this.name = 'RateLimitError';
  }
}

export class BadRequestError extends HolySheepError {
  constructor(
    message: string,
    public readonly param?: string,
    details?: Record<string, unknown>
  ) {
    super('BAD_REQUEST', 400, message, { ...details, param });
    this.name = 'BadRequestError';
  }
}

export class ContextLengthError extends HolySheepError {
  constructor(
    message: string,
    public readonly maxTokens: number,
    public readonly requestedTokens: number,
    details?: Record<string, unknown>
  ) {
    super('CONTEXT_LENGTH_EXCEEDED', 422, message, {
      ...details,
      max_tokens: maxTokens,
      requested_tokens: requestedTokens,
    });
    this.name = 'ContextLengthError';
  }
}

export class QuotaExceededError extends HolySheepError {
  constructor(
    message: string,
    public readonly quotaType: 'daily' | 'monthly' | 'total',
    public readonly resetAt: string,
    details?: Record<string, unknown>
  ) {
    super('QUOTA_EXCEEDED', 403, message, {
      ...details,
      quota_type: quotaType,
      reset_at: resetAt,
    });
    this.name = 'QuotaExceededError';
  }
}

// --- サーバーエラー系 ---

export class ServerError extends HolySheepError {
  constructor(message: string, details?: Record<string, unknown>) {
    super('INTERNAL_SERVER_ERROR', 500, message, details);
    this.name = 'ServerError';
  }
}

export class ServiceUnavailableError extends HolySheepError {
  constructor(
    message: string,
    public readonly retryAfter: number,
    details?: Record<string, unknown>
  ) {
    super('SERVICE_UNAVAILABLE', 503, message, {
      ...details,
      retry_after: retryAfter,
    });
    this.name = 'ServiceUnavailableError';
  }
}

API クライアント実装

以下の client クラスは、HolySheep API への実際の通信を抽象化し、錯誤碼に応じた例外送出を自動化します:

/**
 * HolySheep AI API Client
 * base_url: https://api.holysheep.ai/v1
 */

interface ChatMessage {
  role: 'system' | 'user' | 'assistant';
  content: string;
}

interface ChatCompletionRequest {
  model: string;
  messages: ChatMessage[];
  temperature?: number;
  max_tokens?: number;
  top_p?: number;
  frequency_penalty?: number;
  presence_penalty?: number;
  stream?: boolean;
}

interface HolySheepResponse {
  id: string;
  object: string;
  created: number;
  model: string;
  choices: Array<{
    index: number;
    message: ChatMessage;
    finish_reason: string;
  }>;
  usage: {
    prompt_tokens: number;
    completion_tokens: number;
    total_tokens: number;
  };
  request_id: string;
}

export class HolyShehepAIClient {
  private readonly baseUrl = 'https://api.holysheep.ai/v1';
  private readonly defaultHeaders: HeadersInit;

  constructor(private readonly apiKey: string) {
    if (!apiKey || !apiKey.startsWith('hs_')) {
      throw new Error('Invalid API key format. Key must start with "hs_"');
    }
    this.defaultHeaders = {
      'Authorization': Bearer ${apiKey},
      'Content-Type': 'application/json',
    };
  }

  async chatCompletion(
    request: ChatCompletionRequest
  ): Promise<HolySheepResponse> {
    const url = ${this.baseUrl}/chat/completions;
    
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: this.defaultHeaders,
        body: JSON.stringify(request),
      });

      const data = await response.json();

      if (!response.ok) {
        throw this.createErrorFromResponse(response.status, data);
      }

      return data as HolySheepResponse;
    } catch (error) {
      if (error instanceof HolySheepError) {
        throw error;
      }
      // ネットワークエラーなどの場合
      throw new ServerError(
        API通信に失敗しました: ${error instanceof Error ? error.message : 'Unknown error'},
        { originalError: String(error) }
      );
    }
  }

  private createErrorFromResponse(
    status: number,
    response: Record<string, unknown>
  ): HolySheepError {
    const error = response.error as Record<string, unknown> | undefined;
    const code = (error?.code as string) || this.statusToCode(status);
    const message = (error?.message as string) || 'Unknown error occurred';
    const details = (error?.details as Record<string, unknown>) || {};
    const statusCode = (error?.status as number) || status;

    switch (code) {
      case 'AUTHENTICATION_FAILED':
        return new AuthenticationError(message, details);
      
      case 'RATE_LIMIT_EXCEEDED':
        return new RateLimitError(
          message,
          (details.retry_after as number) || 60,
          (details.limit as number) || 60,
          details
        );
      
      case 'BAD_REQUEST':
        return new BadRequestError(
          message,
          details.param as string | undefined,
          details
        );
      
      case 'CONTEXT_LENGTH_EXCEEDED':
        return new ContextLengthError(
          message,
          (details.max_tokens as number) || 128000,
          (details.requested_tokens as number) || 0,
          details
        );
      
      case 'QUOTA_EXCEEDED':
        return new QuotaExceededError(
          message,
          (details.quota_type as 'daily' | 'monthly' | 'total') || 'daily',
          (details.reset_at as string) || new Date().toISOString(),
          details
        );
      
      case 'SERVICE_UNAVAILABLE':
        return new ServiceUnavailableError(
          message,
          (details.retry_after as number) || 30,
          details
        );
      
      default:
        return new ServerError(message, details);
    }
  }

  private statusToCode(status: number): string {
    const mapping: Record<number, string> = {
      400: 'BAD_REQUEST',
      401: 'AUTHENTICATION_FAILED',
      403: 'QUOTA_EXCEEDED',
      404: 'NOT_FOUND',
      422: 'CONTEXT_LENGTH_EXCEEDED',
      429: 'RATE_LIMIT_EXCEEDED',
      500: 'INTERNAL_SERVER_ERROR',
      502: 'BAD_GATEWAY',
      503: 'SERVICE_UNAVAILABLE',
      504: 'GATEWAY_TIMEOUT',
    };
    return mapping[status] || 'UNKNOWN_ERROR';
  }
}

// --- 使用例 ---

async function main() {
  const client = new HolyShehepAIClient('YOUR_HOLYSHEEP_API_KEY');

  try {
    const response = await client.chatCompletion({
      model: 'gpt-4.1',
      messages: [
        { role: 'system', content: 'あなたは有帮助なアシスタントです。' },
        { role: 'user', content: 'HolySheep AIの利点を教えて' },
      ],
      temperature: 0.7,
      max_tokens: 500,
    });

    console.log('応答:', response.choices[0].message.content);
    console.log('使用トークン:', response.usage.total_tokens);
    console.log('リクエストID:', response.request_id);
  } catch (error) {
    if (error instanceof HolySheepError) {
      console.error([${error.code}] ${error.message});
      console.error('詳細:', JSON.stringify(error.details, null, 2));
      
      // エラータイプに応じた処理
      if (error instanceof RateLimitError) {
        console.log(${error.retryAfter}秒後に再試行します...);
        await sleep(error.retryAfter * 1000);
        // 再試行ロジック
      } else if (error instanceof AuthenticationError) {
        console.error('API キーを確認してください: https://www.holysheep.ai/settings');
      }
    } else {
      console.error('予期しないエラー:', error);
    }
  }
}

function sleep(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms));
}

移行手順:段階的デプロイメント

HolySheep AI への移行は、リスク最小化のため段階的に実施することを強く推奨します。以下に、本番環境への移行プレイブックを示します:

フェーズ 1:開発・ステージング環境での検証(1-3日)

# 1. HolySheep API キーの取得

https://www.holysheep.ai/register で新規登録

2. 環境変数の設定

export HOLYSHEEP_API_KEY="hs_your_api_key_here" export API_ENV="staging"

3. 接続確認

curl -X POST https://api.holysheep.ai/v1/chat/completions \ -H "Authorization: Bearer $HOLYSHEEP_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-v3.2", "messages": [{"role": "user", "content": "Hello"}], "max_tokens": 10 }'

期待される応答:

{"id":"hs-...","object":"chat.completion","created":...,

"choices":[...],"usage":{...}}

フェーズ 2:トラフィック分散(1-2週間)

/**
 * トラフィック分割戦略(Canary Deployment)
 */

type APIProvider = 'openai' | 'holysheep';

interface TrafficConfig {
  // HolySheep に流す割合(百分率)
  holysheepRatio: number;
  // 失敗時のフォールバック先
  fallbackProvider: APIProvider;
  // レイテンシ閾値(ms)
  latencyThreshold: number;
}

class TrafficRouter {
  private currentProvider: APIProvider = 'openai';
  private errorCounts: Map<APIProvider, number> = new Map();
  private latencyHistory: Map<APIProvider, number[]> = new Map();

  constructor(private config: TrafficConfig) {
    this.errorCounts.set('openai', 0);
    this.errorCounts.set('holysheep', 0);
    this.latencyHistory.set('openai', []);
    this.latencyHistory.set('holysheep', []);
  }

  selectProvider(): APIProvider {
    const holysheepErrors = this.errorCounts.get('holysheep') || 0;
    const openaiErrors = this.errorCounts.get('openai') || 0;
    
    // エラー率が高い場合は元のプロバイダーに切替
    if (holysheepErrors > 5) {
      console.warn('HolySheep エラー多発: 自動フォールバック実施');
      this.currentProvider = 'openai';
      return 'openai';
    }

    // ランダム配分(設定比率に基づく)
    const rand = Math.random() * 100;
    if (rand < this.config.holysheepRatio) {
      this.currentProvider = 'holysheep';
    } else {
      this.currentProvider = 'openai';
    }

    return this.currentProvider;
  }

  recordLatency(provider: APIProvider, latencyMs: number): void {
    const history = this.latencyHistory.get(provider) || [];
    history.push(latencyMs);
    if (history.length > 100) history.shift(); // 直近100件保持
    this.latencyHistory.set(provider, history);

    // レイテンシ閾値超過で警告
    if (latencyMs > this.config.latencyThreshold) {
      console.warn(${provider} レイテンシ超過: ${latencyMs}ms > ${this.config.latencyThreshold}ms);
    }
  }

  recordError(provider: APIProvider): void {
    const count = (this.errorCounts.get(provider) || 0) + 1;
    this.errorCounts.set(provider, count);
  }

  getStats(): {
    providers: APIProvider[];
    errorRates: Record<APIProvider, number>;
    avgLatencies: Record<APIProvider, number>;
  } {
    const stats = {
      providers: ['openai', 'holysheep'] as APIProvider[],
      errorRates: {} as Record<APIProvider, number>,
      avgLatencies: {} as Record<APIProvider, number>,
    };

    for (const provider of stats.providers) {
      const errors = this.errorCounts.get(provider) || 0;
      const history = this.latencyHistory.get(provider) || [];
      const total = history.length || 1;
      
      stats.errorRates[provider] = errors / total;
      stats.avgLatencies[provider] = 
        history.reduce((a, b) => a + b, 0) / total;
    }

    return stats;
  }
}

// 使用例:初期トラフィック 10% を HolySheep に
const router = new TrafficRouter({
  holysheepRatio: 10,
  fallbackProvider: 'openai',
  latencyThreshold: 3000,
});

// 日次バッチで HolySheep 比率を増加
async function incrementTraffic(scheduler: 'daily' | 'hourly'): Promise<void> {
  const schedule = scheduler === 'daily' ? 86400000 : 3600000;
  
  setInterval(() => {
    const stats = router.getStats();
    
    // HolySheep のエラー率 < 1% かつ平均レイテンシ < 2s なら++
    if (stats.errorRates.holysheep < 0.01 && 
        stats.avgLatencies.holysheep < 2000) {
      router.config.holysheepRatio = Math.min(
        router.config.holysheepRatio + 10,
        100
      );
      console.log(HolySheep 比率を ${router.config.holysheepRatio}% に更新);
    }
  }, schedule);
}

フェーズ 3:本番完全移行(2-4週間)

ステージングで安定稼働が確認出来后、以下のチェックリストを経て本番移行を実施します:

ロールバック計画

移行中に問題が発生した場合、即座に以前的構成に戻せるよう、以下のロールバック戦略を整備しておくことが重要です:

/**
 * ロールバックマネージャー
 */

interface RollbackConfig {
  // ロールバック閾値
  errorRateThreshold: number;    // 例: 0.05 (5%)
  latencyP99Threshold: number;   // 例: 5000 (ms)
  consecutiveErrorsThreshold: number; // 例: 10
}

class RollbackManager {
  private originalConfig: TrafficConfig;
  private isRollbackInProgress: boolean = false;
  private consecutiveErrors: number = 0;

  constructor(
    private currentConfig: TrafficConfig,
    private rollbackConfig: RollbackConfig
  ) {
    this.originalConfig = { ...currentConfig };
  }

  checkAndTriggerRollback(stats: {
    errorRate: number;
    latencyP99: number;
  }): boolean {
    if (this.isRollbackInProgress) {
      console.warn('ロールバック処理中は監視を一時停止');
      return false;
    }

    // 閾値チェック
    const shouldRollback = 
      stats.errorRate > this.rollbackConfig.errorRateThreshold ||
      stats.latencyP99 > this.rollbackConfig.latencyP99Threshold ||
      this.consecutiveErrors >= this.rollbackConfig.consecutiveErrorsThreshold;

    if (shouldRollback) {
      this.executeRollback(stats);
      return true;
    }

    return false;
  }

  recordSuccess(): void {
    this.consecutiveErrors = 0;
  }

  recordError(): void {
    this.consecutiveErrors++;
    console.error(連続エラー: ${this.consecutiveErrors}件);
  }

  private async executeRollback(reason: {
    errorRate?: number;
    latencyP99?: number;
  }): Promise<void> {
    this.isRollbackInProgress = true;
    
    console.error('========== ロールバック実行 ==========');
    console.error('理由:', JSON.stringify(reason));
    console.error('元の設定:', JSON.stringify(this.originalConfig));
    
    try {
      // 1. 即座に 100% 元のプロバイダーに切替
      this.currentConfig.holysheepRatio = 0;
      console.log('[1/3] HolySheep トラフィック: 0%');
      
      // 2. 設定の書き戻し(ConfigMap/Kubernetes Secret等)
      await this.persistOriginalConfig();
      console.log('[2/3] 設定を元の状態に復元');
      
      // 3. 関連サービスへ通知(Slack/PagerDuty等)
      await this.notifyIncident('ROLLBACK_TRIGGERED', reason);
      console.log('[3/3] インシデント通知完了');
      
      console.error('========== ロールバック完了 ==========');
    } catch (error) {
      console.error('ロールバック処理失敗:', error);
      await this.notifyIncident('ROLLBACK_FAILED', {
        originalError: reason,
        rollbackError: String(error),
      });
    } finally {
      this.isRollbackInProgress = false;
    }
  }

  private async persistOriginalConfig(): Promise<void> {
    // 実際の環境では、Kubernetes ConfigMap や
    // 環境変数ファイルのパッチを適用
    console.log('ConfigMap 更新: holySheepRatio=0');
  }

  private async notifyIncident(
    type: string,
    details: Record<string, unknown>
  ): Promise<void> {
    // Slack Webhook 等で通知
    console.log(インシデント通知: ${type});
  }
}

ROI 試算:HolySheep AI への移行効果

実際のプロジェクトを想定したコスト比較を示します:

/**
 * ROI 試算ツール
 */

interface UsageStats {
  // 月間リクエスト数
  monthlyRequests: number;
  // 平均入力トークン/リクエスト
  avgInputTokens: number;
  // 平均出力トークン/リクエスト
  avgOutputTokens: number;
  // モデル別利用比率
  modelDistribution: Record<string, number>;
}

function calculateMonthlyCost(stats: UsageStats): {
  current: { cost: number; provider: string };
  holySheep: { cost: number; provider: string };
  savings: { amount: number; percentage: number };
} {
  // 2026年 トークン単価($/MTok)
  const pricing = {
    'gpt-4.1': { input: 8, output: 8 },
    'claude-sonnet-4.5': { input: 15, output: 15 },
    'gemini-2.5-flash': { input: 2.5, output: 2.5 },
    'deepseek-v3.2': { input: 0.42, output: 0.42 },
  };

  // ¥7.3 = $1 のレートで計算
  const officialRate = 7.3;
  const holySheepRate = 1; // ¥1 = $1

  let officialCostUSD = 0;
  let holySheepCostUSD = 0;

  for (const [model, ratio] of Object.entries(stats.modelDistribution)) {
    const p = pricing[model] || { input: 8, output: 8 };
    const reqCount = stats.monthlyRequests * ratio;
    
    // 入力コスト
    const inputToks = (reqCount * stats.avgInputTokens) / 1_000_000;
    // 出力コスト
    const outputToks = (reqCount * stats.avgOutputTokens) / 1_000_000;
    
    const totalToksUSD = (inputToks + outputToks) * p.input;

    officialCostUSD += totalToksUSD;
    holySheepCostUSD += totalToksUSD; // HolySheep も同モデル、同レート
  }

  const officialCostJPY = officialCostUSD * officialRate;
  const holySheepCostJPY = holySheepCostUSD * holySheepRate;

  return {
    current: { cost: officialCostJPY, provider: '公式 API' },
    holySheep: { cost: holySheepCostJPY, provider: 'HolySheep AI' },
    savings: {
      amount: officialCostJPY - holySheepCostJPY,
      percentage: ((officialCostJPY - holySheepCostJPY) / officialCostJPY) * 100,
    },
  };
}

// ===== 試算例 =====

// シナリオ:中型 SaaS アプリ(月間 50万リクエスト)
const myAppUsage: UsageStats = {
  monthlyRequests: 500_000,
  avgInputTokens: 500,
  avgOutputTokens: 300,
  modelDistribution: {
    'gpt-4.1': 0.4,          // 20万req - 凝った処理
    'deepseek-v3.2': 0.4,   // 20万req - 汎用処理
    'gemini-2.5-flash': 0.2, // 10万req - 軽量処理
  },
};

const result = calculateMonthlyCost(myAppUsage);

console.log('===== 月間コスト試算 =====');
console.log(現在のコスト(公式API): ¥${result.current.cost.toLocaleString()});
console.log(HolySheep AI コスト: ¥${result.holySheep.cost.toLocaleString()});
console.log(年間削減額: ¥${(result.savings.amount * 12).toLocaleString()});
console.log(削減率: ${result.savings.percentage.toFixed(1)}%);

/*
===== 月間コスト試算 =====
現在のコスト(公式API): ¥892,500
HolySheep AI コスト: ¥122,250
年間削減額: ¥9,243,000
削減率: 85.7%
*/

よくあるエラーと対処法

1. AuthenticationError: API キー無効

// エラー例
// [AUTHENTICATION_FAILED] Invalid API key provided.
// status: 401

// 原因と解決
// - API キーが未設定
// - キーが "hs_" プレフィックスで始まらない
// - キー有効期限切れ

// 解決コード
async function validateApiKey(apiKey: string): Promise<boolean> {
  if (!apiKey || !apiKey.startsWith('hs_')) {
    throw new AuthenticationError(
      'API キーが無効です。「hs_」で始まるキーを設定してください。',
      { expected: 'hs_xxxx...', received: apiKey?.substring(0, 10) }
    );
  }
  
  // 接続テスト
  const client = new HolyShehepAIClient(apiKey);
  try {
    await client.chatCompletion({
      model: 'deepseek-v3.2',
      messages: [{ role: 'user', content: 'test' }],
      max_tokens: 1,
    });
    return true;
  } catch (e) {
    if (e instanceof AuthenticationError) {
      console.error('API キー確認: https://www.holysheep.ai/settings');
    }
    throw e;
  }
}

2. RateLimitError: レートリミット超過

// エラー例
// [RATE_LIMIT_EXCEEDED] Rate limit exceeded for model gpt-4.1
// status: 429, retry_after: 15

// 原因と解決
// - 短時間に大量リクエスト送信
// - プランの分単位制限超過
// - バーストトラフィック発生

// 解決コード:指数バックオフ付き再試行
async function retryWithBackoff<T>(
  fn: () => Promise<T>,
  maxRetries: number = 5,
  baseDelayMs: number = 1000
): Promise<T> {
  let lastError: HolySheepError;
  
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error as HolySheepError;
      
      if (error instanceof RateLimitError) {
        // 指数バックオフで待機
        const delay = Math.min(
          baseDelayMs * Math.pow(2, attempt),
          error.retryAfter * 1000
        );
        console.warn(レート制限: ${delay}ms 待機 (試行 ${attempt + 1}/${maxRetries}));
        await new Promise(r => setTimeout(r, delay));
      } else if (error instanceof ServiceUnavailableError) {
        // サーバー側の問題も指数バックオフ
        const delay = baseDelayMs * Math.pow(2, attempt);
        await new Promise(r => setTimeout(r, delay));
      } else {
        // その他のエラーは再試行しない
        throw error;
      }
    }
  }
  
  throw lastError!;
}

3. ContextLengthError: コンテキスト長超過

// エラー例
// [CONTEXT_LENGTH_EXCEEDED] maximum context length is 128000 tokens
// status: 422, requested_tokens: 156000

// 原因と解決
// - 入力プロンプト过长
// - 会話履歴の累積が大きすぎる
// - max_tokens 設定过大

// 解決コード:自動コンテキスト管理
async function smartChatCompletion(
  client: HolyShehepAIClient,
  messages: ChatMessage[],
  options: { maxContextTokens?: number; preserveSystemPrompt?: boolean }
): Promise<HolySheepResponse> {
  const MAX_CONTEXT = options.maxContextTokens || 128000;
  const RESERVED_OUTPUT = 2000; // 出力用に予約
  const SYSTEM_PROMPT_TOKENS = 500; // システムプロンプト概算
  
  // コンテキストが空になるまで古いメッセージを削除
  let trimmedMessages = [...messages];
  
  while (trimmedMessages.length > 1) {
    //簡易トークン数估算(実際はトークナイザー使用推奨)
    const estimatedTokens = estimateTokens(trimmedMessages);
    
    if (estimatedTokens <= MAX_CONTEXT - RESERVED_OUTPUT - SYSTEM_PROMPT_TOKENS) {
      break;
    }
    
    // 最も古い user/assistant メッセージを削除
    const systemMsg = trimmedMessages.find(m => m.role === 'system');
    const nonSystemMessages = trimmedMessages.filter(m => m.role !== 'system');
    
    if (nonSystemMessages.length > 2) {
      nonSystemMessages.splice(1, 1); // 2番目のメッセージを削除
      trimmedMessages = systemMsg 
        ? [systemMsg, ...nonSystemMessages] 
        : nonSystemMessages;
    } else {
      break;
    }
  }
  
  return await client.chatCompletion({
    model: 'gpt-4.1',
    messages: trimmedMessages,
    max_tokens: RESERVED_OUTPUT,
  });
}

function estimateTokens(messages: ChatMessage[]): number {
  // 简易估算:文字数の 1/4
  return messages.reduce((sum, m) => sum + m.content.length / 4, 0);
}

4. QuotaExceededError: quota 超過

// エラー例
// [QUOTA_EXCEEDED] Monthly quota exceeded
// status: 403, quota_type: "monthly", reset_at: "2026-02-01T00:00:00Z"

// 原因と解決
// - 月間利用 quota 到达
// - プランのトークン割り当て消費

// 解決コード
async function checkAndNotifyQuota(client: HolyShehepAIClient): Promise<void> {
  try {
    await client.chatCompletion({
      model: 'deepseek-v3.2',
      messages: [{ role: 'user', content: 'ping' }],
      max_tokens: 1,
    });
  } catch (error) {
    if (error instanceof QuotaExceededError) {
      const remaining = await estimateRemainingQuota(error);
      
      // ユーザー通知
      console.error(========== quota 警告 ==========);
      console.error(quota タイプ: ${error.quotaType});
      console.error(リセット日時: ${error.resetAt});
      console.error(推定残り: ${remaining}%);
      
      if (error.quotaType === 'monthly') {
        console.warn('月末まで利用量を抑えてください');
        // Slack/メール通知
        await sendQuota