レート制限とクォータ管理
ユーザー単位、組織単位、エンドポイント単位でクォータを設定し、1つのテナントがOpenAIの予算を使い果たさないようにします。
「レート制限とクォータ管理」はCoddyKit上の無料AI Agentsレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Agents学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Agentsコースには全4レッスンが含まれています。
このレッスンの一部はまだ翻訳されておらず、英語で表示されています。
なぜ制限が必要ですか
制限がないと、1人の悪意あるクライアントによって次のような事態が起こり得ます。
- OpenAIの予算を使い果たす
- ほかのユーザーを締め出す
- サービスにDDoS攻撃を仕掛ける
レート制限とクォータによって、コスト、レイテンシ、そして公平性を守れます。
レート制限とクォータの違い
- レート制限 — 1秒または1分あたりのリクエスト数(短期)
- クォータ — 1日または1か月あたりの総予算(長期)
どちらも必要です。
トークンバケットアルゴリズム
古典的なアルゴリズムでは、各ユーザーに一定の速度で補充される「バケット」を割り当てます。各リクエストがトークンを1つ消費します。トークンがなければ、サービスを提供しません。
Redis Token Bucket Example
def allow(user_id, rate=10, capacity=30):
key = f'rate:{user_id}'
now = time.time()
pipe = redis.pipeline()
pipe.hgetall(key)
state, _ = pipe.execute()
tokens = float(state.get('tokens', capacity))
last = float(state.get('last', now))
tokens = min(capacity, tokens + (now - last) * rate)
if tokens < 1:
return False
tokens -= 1
redis.hset(key, mapping={'tokens': tokens, 'last': now})
redis.expire(key, 60)
return TrueFastAPI Integration with slowapi
# pip install slowapi
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter
@app.post('/agents/qa')
@limiter.limit('10/minute')
def qa(req: AgentRequest):
...Different Limits Per Tier
class User:
def __init__(self, is_pro):
self.is_pro = is_pro
class State:
def __init__(self, is_pro):
self.user = User(is_pro)
class Req:
def __init__(self, is_pro):
self.state = State(is_pro)
def limit_for(req):
return '100/minute' if req.state.user.is_pro else '10/minute'
def qa(req):
limit = limit_for(req)
print(f'user is_pro={req.state.user.is_pro} -> rate limit {limit}')
return limit
qa(Req(is_pro=True))
qa(Req(is_pro=False))
コストベースのクォータ
リクエスト数だけでなく、金額も制限してください。
def check_budget(user_id, predicted_cost):
key = f'cost:{user_id}:{date.today()}'
spent = float(redis.get(key) or 0)
if spent + predicted_cost > daily_budget(user_id):
raise HTTPException(429, 'Daily budget exceeded')
# After the call:
redis.incrbyfloat(key, actual_cost)
redis.expireat(key, midnight_tomorrow_ts)同時実行数の上限
ユーザーごとの実行中リクエスト数も制限してください。
key = f'inflight:{user_id}'
redis.sadd(key, request_id)
if redis.scard(key) > 3:
raise HTTPException(429, 'Too many concurrent requests')
# Remove from set when the request finishes.グローバルレート制限
下流のLLM APIを、自分のサービスから保護してください。
global_key = 'rate:global:llm'
if redis.incr(global_key) > 60: # 60 calls per second
raise HTTPException(503, 'Service overloaded')
redis.expire(global_key, 1)Return Useful Errors
headers = {
'X-RateLimit-Limit': '60',
'X-RateLimit-Remaining': '0',
'X-RateLimit-Reset': str(reset_time),
'Retry-After': '30'
}
return JSONResponse({'error': 'rate-limited'}, status_code=429, headers=headers)分散レート制限
複数のAPIサーバーを実行する場合、レート制限を共有する必要があります。標準的なバックエンドはRedisです。CloudflareとKongにはマネージドの代替手段があります。
バーストの許容
実際の利用はバーストします。小さなバーストを許容してください(レートが毎秒10リクエストなら、同時に30リクエストまで許容するなど)。トークンバケットの実装では、より大きな`capacity`を設定することで自然に対応できます。
アラート
次の状況でアラートを発生させます。
- グローバルレート制限に達した回数が1分あたりX回を超えたとき
- 特定のユーザーが継続的に制限に達しているとき(アップグレードが必要、またはバグがある可能性があります)
- 1日の予算が80%に近づいたとき
2層の保護
レート制限とクォータの両方を用意するのはなぜですか。
まとめ
レート制限にはトークンバケット、クォータにはコストカウンター、ユーザーごとの同時実行数の上限、グローバルなサーキットブレーカー、Retry-Afterを含む役立つ429レスポンスを使用します。
よくある質問
「レート制限とクォータ管理」レッスンは無料ですか?
はい。「レート制限とクォータ管理」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Agentsコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Agentsコースには全4レッスンが含まれています。
「レート制限とクォータ管理」で何を学びますか?
ユーザー単位、組織単位、エンドポイント単位でクォータを設定し、1つのテナントがOpenAIの予算を使い果たさないようにします。 ブラウザで直接実行するハンズオンコードでAI Agentsを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AI Agentsを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAI Agentsは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「レート制限とクォータ管理」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAI Agentsレッスンでコードを書いて実行できますか?
はい。すべてのAI Agentsレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。