AI API をビジネスシステムに統合する際、プロバイダーの直接呼び出しではなく、自前で API ゲートウェイを構築する需求が急増しています。認証管理、レート制御、マルチプロバイダー集約、詳細なコスト分析など、本番環境必需的機能をどのように実装すべきか、私は複数のプロジェクトで実践的に検証を行いました。
本稿では、NestJS + Redis + PostgreSQL を基盤とした AI API ゲートウェイの構築方法を詳細に解説し、HolySheep AI を始めとする主要プロバイダーとの比較、そしてコスト最適化のベストプラクティスをお届けします。
アーキテクチャ設計:なぜ自建ゲートウェイが必要か
まず、自建ゲートウェイが必要な場面を整理します。直接 API を呼び出す場合、以下の課題に直面します:
- 認証の分散管理:複数のチーム・サービスが個別に API キーを管理し、漏洩リスクが高くなる
- レイテンシ制御の欠如:provider 側の障害時にフォールバックできず、可用性が低下する
- コスト可視化の困難:使用量に応じた請求額をリアルタイムに把握できず、予算超過のリスクがある
- マルチプロバイダー対応:GPT-4 Claude Gemini DeepSeek など複数プロバイダーを切り替える際、コード変更が必要
自建ゲートウェイは、これらの課題を統一的なレイヤーで解決します。以下のアーキテクチャを採用しました:
┌─────────────────────────────────────────────────────────────────┐
│ Client Layer │
│ (Web App / Mobile / Server-side Service) │
└──────────────────────────┬────────────────────────────────────────┘
│ HTTPS
▼
┌─────────────────────────────────────────────────────────────────┐
│ API Gateway (NestJS) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ Auth │ │ Rate │ │ Load │ │ Request/Response │ │
│ │ Middleware│ │ Limiter │ │ Balancer │ │ Transformer │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────────┘ │
└──────────────────────────┬────────────────────────────────────────┘
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ HolySheep AI │ │ OpenAI │ │ Anthropic │
│ ¥1=$1 │ │ Direct │ │ Direct │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
└──────────────────┼──────────────────┘
▼
┌─────────────────────────────────────────────────────────────────┐
│ Backend Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ Redis │ │ Postgres │ │ Metrics │ │ Billing │ │
│ │ Cache │ │ Usage DB │ │ Store │ │ Engine │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
コア機能の実装
1. 認証システム
JWT ベースの認証システムを導入し、API キーの発行・検証・ローテーションを自動化します。
import { Controller, Post, Body, UseGuards, Req } from '@nestjs/common';
import { AuthService } from './auth.service';
import { JwtAuthGuard } from './guards/jwt-auth.guard';
import { ApiKeyService } from './api-key.service';
@Controller('api/v1')
export class ApiGatewayController {
constructor(
private readonly authService: AuthService,
private readonly apiKeyService: ApiKeyService,
) {}
@Post('auth/create-api-key')
async createApiKey(
@Body() createKeyDto: { userId: string; name: string; scopes: string[] },
) {
const apiKey = await this.apiKeyService.createApiKey(
createKeyDto.userId,
createKeyDto.name,
createKeyDto.scopes,
);
return {
success: true,
data: {
api_key: apiKey.key,
key_id: apiKey.id,
created_at: apiKey.createdAt,
expires_at: apiKey.expiresAt,
},
};
}
@Post('ai/completions')
@UseGuards(JwtAuthGuard)
async completions(@Req() req: any, @Body() body: any) {
const userId = req.user.userId;
const apiKey = req.headers['x-api-key'];
// Verify API key and check quotas
await this.apiKeyService.verifyAndTrackUsage(apiKey, userId);
// Route to appropriate provider
const response = await this.routeToProvider({
model: body.model,
messages: body.messages,
temperature: body.temperature,
max_tokens: body.max_tokens,
});
return response;
}
private async routeToProvider(params: any) {
// HolySheep AI へのプロキシ
const response = await fetch('https://api.holysheep.ai/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': Bearer ${process.env.HOLYSHEEP_API_KEY},
},
body: JSON.stringify({
model: params.model,
messages: params.messages,
temperature: params.temperature ?? 0.7,
max_tokens: params.max_tokens ?? 2048,
}),
});
return response.json();
}
}
2. レート制限とコスト追跡
Redis を使用して滑动窗口アルゴリズムによるレート制限を実装し、各リクエストのコストをリアルタイムで計算します。
import Redis from 'ioredis';
import { Injectable } from '@nestjs/common';
interface RateLimitConfig {
windowMs: number;
maxRequests: number;
costPerRequest: number;
}
interface UsageRecord {
requests: number;
tokensUsed: number;
costUSD: number;
lastReset: number;
}
@Injectable()
export class RateLimitService {
private redis: Redis;
// コストテーブル (USD per 1M tokens - 2026年 prices)
private readonly COST_TABLE = {
'gpt-4.1': { input: 8, output: 8 },
'claude-sonnet-4.5': { input: 15, output: 15 },
'gemini-2.5-flash': { input: 2.50, output: 2.50 },
'deepseek-v3.2': { input: 0.42, output: 0.42 },
};
constructor() {
this.redis = new Redis(process.env.REDIS_URL);
}
async checkRateLimit(
userId: string,
tier: 'free