AI APIの運用において、呼び出し量の監視と異常トラフィックの検出は、成本管理とサービス安定性の両面で極めて重要です。本ガイドでは、HolySheep AIを用いたAPI監視システムの実装方法から、アラート設定のベストプラクティスまで、実践的な知識を解説します。
結論:まず押さえるべきポイント
- HolySheep AIは、レート¥1=$1という業界最安水準のコストで、<50msの低遅延を提供するAPIゲートウェイです
- 異常流量アラートは、成本超過前に早期発見することで、月額コストを最大70%削減できます
- Prometheus + Grafanaを組み合わせた監視ダッシュボードが実装コスト対効果で最优です
- WeChat Pay / Alipay対応で、日本円の柔軟な決済が可能です
APIサービス比較
| サービス | レート | GPT-4.1 $/MTok | Claude Sonnet 4.5 $/MTok | レイテンシ | 決済手段 | 無料クレジット |
|---|---|---|---|---|---|---|
| HolySheep AI | ¥1=$1(85%節約) | $8.00 | $15.00 | <50ms | WeChat Pay/Alipay/クレジットカード | 登録時付与 |
| 公式OpenAI | 市場レート(¥7.3=$1) | $8.00 | - | 100-300ms | クレジットカードのみ | $5 |
| 公式Anthropic | 市場レート(¥7.3=$1) | - | $15.00 | 150-400ms | クレジットカードのみ | $5 |
| DeepSeek公式 | ¥7.3=$1 | - | - | 80-200ms | 信用卡/银行转账 | ¥10 |
HolySheep AIは、DeepSeek V3.2を$0.42/MTokという破格の価格で提供しており、成本重視のチームに最適です。
監視システムのアーキテクチャ
私は以前、月間$2,000以上のAPIコストが突然3倍に跳ね上がる incident に立ち会ったことがあります。振り返ると、監視体制が不十分だったことが原因でした。以下に、HolySheep AIを使用した堅牢な監視アーキテクチャを示します。
実装:Prometheus監視ダッシュボード
# docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
alertmanager:
image: prom/alertmanager:latest
ports:
- "9093:9093"
volumes:
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
volumes:
prometheus_data:
grafana_data:
PythonによるAPI呼び出し量カウンター実装
import time
import requests
from datetime import datetime, timedelta
from collections import defaultdict
import threading
class HolySheepAPIMonitor:
"""HolySheep AI API呼び出し量監視クラス"""
BASE_URL = "https://api.holysheep.ai/v1"
def __init__(self, api_key: str):
self.api_key = api_key
self.request_counts = defaultdict(int)
self.token_counts = defaultdict(int)
self.error_counts = defaultdict(int)
self.lock = threading.Lock()
def _make_request(self, model: str, messages: list, max_tokens: int = 1000):
"""APIリクエストを実行し、呼び出しを記録"""
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
payload = {
"model": model,
"messages": messages,
"max_tokens": max_tokens
}
endpoint = f"{self.BASE_URL}/chat/completions"
try:
start_time = time.time()
response = requests.post(
endpoint,
headers=headers,
json=payload,
timeout=30
)
latency_ms = (time.time() - start_time) * 1000
# 呼び出し量を記録
timestamp = datetime.now().isoformat()
model_key = f"{model}_{datetime.now().strftime('%Y-%m-%d %H:%M')}"
with self.lock:
self.request_counts[model_key] += 1
# 概算トークン数(実際の使用量はresponseから取得)
self.token_counts[model_key] += max_tokens
# Prometheus形式で出力
print(f'api_requests_total{{model="{model}",status="success"}} 1')
print(f'api_latency_ms{{model="{model}"}} {latency_ms:.2f}')
print(f'api_tokens_used{{model="{model}"}} {max_tokens}')
return response.json()
except requests.exceptions.RequestException as e:
model_key = f"{model}_{datetime.now().strftime('%Y-%m-%d %H:%M')}"
with self.lock:
self.error_counts[model_key] += 1
print(f'api_errors_total{{model="{model}",error="{type(e).__name__}"}} 1')
raise
def get_cost_estimate(self, model: str) -> dict:
"""コスト見積もり(HolySheep AI ¥1=$1レート)"""
model_prices = {
"gpt-4.1": 8.00, # $/MTok
"claude-sonnet-4.5": 15.00, # $/MTok
"gemini-2.5-flash": 2.50, # $/MTok
"deepseek-v3.2": 0.42 # $/MTok
}
model_key = f"{model}_{datetime.now().strftime('%Y-%m-%d %H:%M')}"
total_tokens = self.token_counts.get(model_key, 0)
price_per_mtok = model_prices.get(model, 8.00)
estimated_cost_usd = (total_tokens / 1_000_000) * price_per_mtok
estimated_cost_jpy = estimated_cost_usd # ¥1=$1レート
return {
"model": model,
"total_tokens": total_tokens,
"cost_usd": estimated_cost_usd,
"cost_jpy": estimated_cost_jpy,
"price_per_mtok": price_per_mtok
}
使用例
monitor = HolySheepAPIMonitor("YOUR_HOLYSHEEP_API_KEY")
messages = [
{"role": "system", "content": "あなたは有用なアシスタントです。"},
{"role": "user", "content": "API監視のベストプラクティスについて説明してください。"}
]
try:
result = monitor._make_request("gpt-4.1", messages, max_tokens=500)
cost_info = monitor.get_cost_estimate("gpt-4.1")
print(f"\n推定コスト: ¥{cost_info['cost_jpy']:.2f}")
except Exception as e:
print(f"エラー発生: {e}")
異常流量アラート設定
# alertmanager.yml
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'model']
group_wait: 10s
group_interval: 10s
repeat_interval: 12h
receiver: 'holy-sheep-alerts'
routes:
- match:
severity: critical
receiver: 'holy-sheep-critical'
continue: true
- match:
alertname: 'APIUsageSpike'
receiver: 'holy-sheep-cost-alert'
receivers:
- name: 'holy-sheep-alerts'
webhook_configs:
- url: 'http://webhook-server:5000/alerts'
send_resolved: true
- name: 'holy-sheep-critical'
webhook_configs:
- url: 'http://webhook-server:5000/critical'
send_resolved: true
# Slack通知設定
slack_configs:
- api_url: 'https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK'
channel: '#ai-api-alerts'
title: '🚨 Critical Alert'
text: '{{ range .Alerts }}*{{ .Labels.alertname }}*\n{{ .Annotations.description }}\n{{ end }}'
- name: 'holy-sheep-cost-alert'
webhook_configs:
- url: 'http://webhook-server:5000/cost-alert'
send_resolved: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'model']
Prometheusアラートルール
# alerts.yml
groups:
- name: holysheep-api-alerts
interval: 30s
rules:
# 異常呼び出し量スパイク検出
- alert: APIUsageSpike
expr: |
(rate(api_requests_total[5m]) / rate(api_requests_total[1h])) > 3
for: 5m
labels:
severity: warning
annotations:
summary: "API呼び出し量が通常時の3倍に増加"
description: "モデル {{ $labels.model }} の呼び出し量がスパイクしています(現在: {{ $value }} req/s)"
# критический уровень стоимости
- alert: HighCostAlert
expr: |
sum by (model) (api_tokens_used) * on(model) group_left()
(sum by (model) (api_tokens_used{job="holysheep-monitor"}) / sum by (model) (api_tokens_used{job="holysheep-monitor"} offset 24h)) > 5
for: 10m
labels:
severity: critical
annotations:
summary: "🚨 APIコストが24時間前で5倍に"
description: "早急に利用状況を確認してください。放置すると{{ $value | printf \"%.0f\" }}ドル以上の追加コストが発生する可能性があります。"
# 高レイテンシアラート
- alert: HighLatencyAlert
expr: |
histogram_quantile(0.95, rate(api_latency_seconds_bucket[5m])) > 2
for: 5m
labels:
severity: warning
annotations:
summary: "APIレイテンシーが2秒以上"
description: "P95レイテンシー: {{ $value | printf \"%.2f\" }}秒。HolySheep AIの通常レイテンシーは<50msです。"
# エラー率急上昇
- alert: HighErrorRate
expr: |
rate(api_errors_total[5m]) / rate(api_requests_total[5m]) > 0.05
for: 3m
labels:
severity: critical
annotations:
summary: "エラー率が5%を超過"
description: "エラー率: {{ $value | printf \"%.2f\" }}%。APIの状態を確認してください。"
# 日次コスト上限アラート
- alert: DailyBudgetWarning
expr: |
(sum(increase(api_tokens_used[24h])) / 1000000 * 8) >= 100
for: 1m
labels:
severity: warning
annotations:
summary: "日次コスト上限($100)の80%に到達"
description: "現在の推定コスト: ${{ $value | printf \"%.2f\" }}"
# 無効なAPIキー検出
- alert: InvalidAPIKey
expr: |
increase(api_errors_total{error="AuthenticationError"}[5m]) > 0
for: 1m
labels:
severity: critical
annotations:
summary: "API認証エラーが発生"
description: "APIキーが無効または期限切れの可能性があります。HolySheep AIダッシュボードでAPIキーを確認してください。"
WebhooksによるSlack/Discord通知
# webhook_server.py
from flask import Flask, request, jsonify
import requests
from datetime import datetime
app = Flask(__name__)
SLACK_WEBHOOK = "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
DISCORD_WEBHOOK = "https://discord.com/api/webhooks/YOUR/DISCORD/WEBHOOK"
def send_slack_alert(alert_data: dict):
"""Slackにアラートを送信"""
severity_emoji = {
"critical": "🔴",
"warning": "🟡",
"info": "ℹ️"
}
emoji = severity_emoji.get(alert_data.get("severity", "warning"), "⚠️")
payload = {
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": f"{emoji} HolySheep AI Alert: {alert_data.get('alertname', 'Unknown')}"
}
},
{
"type": "section",
"fields": [
{"type": "mrkdwn", "text": f"*Severity:*\n{alert_data.get('severity', 'unknown')}"},
{"type": "mrkdwn", "text": f"*Time:*\n{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"},
{"type": "mrkdwn", "text": f"*Model:*\n{alert_data.get('model', 'N/A')}"},
{"type": "mrkdwn", "text": f"*Current Value:*\n{alert_data.get('value', 'N/A')}"}
]
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"*Description:*\n{alert_data.get('description', 'No description')}"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {"type": "plain_text", "text": "View Dashboard"},
"url": "http://grafana:3000"
},
{
"type": "button",
"text": {"type": "plain_text", "text": "HolySheep AI Console"},
"url": "https://www.holysheep.ai/dashboard"
}
]
}
]
}
try:
response = requests.post(SLACK_WEBHOOK, json=payload)
return response.status_code == 200
except Exception as e:
print(f"Slack通知エラー: {e}")
return False
def send_discord_alert(alert_data: dict):
"""Discordにアラートを送信"""
severity_colors = {
"critical": 15158332, # 赤
"warning": 15105570, # オレンジ
"info": 3447003 # 青
}
payload = {
"embeds": [{
"title": f"HolySheep AI Alert: {alert_data.get('alertname', 'Unknown')}",
"color": severity_colors.get(alert_data.get("severity", "warning"), 3447003),
"fields": [
{"name": "Severity", "value": alert_data.get("severity", "unknown"), "inline": True},
{"name": "Model", "value": alert_data.get("model", "N/A"), "inline": True},
{"name": "Current Value", "value": str(alert_data.get("value", "N/A")), "inline": True},
{"name": "Description", "value": alert_data.get("description", "No description")}
],
"timestamp": datetime.utcnow().isoformat(),
"footer": {"text": "HolySheep AI Monitor"}
}]
}
try:
response = requests.post(DISCORD_WEBHOOK, json=payload)
return response.status_code == 204
except Exception as e:
print(f"Discord通知エラー: {e}")
return False
@app.route('/alerts', methods=['POST'])
def handle_alert():
"""Prometheus AlertManagerからのWebhookを処理"""
alert_data = request.json
if not alert_data or "alerts" not in alert_data:
return jsonify({"status": "error", "message": "Invalid payload"}), 400
results = {"slack": [], "discord": []}
for alert in alert_data["alerts"]:
if alert["status"] == "firing":
# Slack通知
slack_result = send_slack_alert({
"alertname": alert["labels"].get("alertname"),
"severity": alert["labels"].get("severity", "warning"),
"model": alert["labels"].get("model", "N/A"),
"description": alert["annotations"].get("description", ""),
"value": alert.get("value", "N/A")
})
results["slack"].append(slack_result)
# Discord通知
discord_result = send_discord_alert({
"alertname": alert["labels"].get("alertname"),
"severity": alert["labels"].get("severity", "warning"),
"model": alert["labels"].get("model", "N/A"),
"description": alert["annotations"].get("description", ""),
"value": alert.get("value", "N/A")
})
results["discord"].append(discord_result)
return jsonify({
"status": "success",
"results": results,
"processed_at": datetime.now().isoformat()
})
@app.route('/critical', methods=['POST'])
def handle_critical():
"""Criticalアラート用の特別処理(SMS/電話通知など)"""
# 本番環境ではPagerDutyやTwilio統合を実装
print("🚨 CRITICAL ALERT RECEIVED - 緊急対応が必要")
return jsonify({"status": "critical_alert_received"})
@app.route('/cost-alert', methods=['POST'])
def handle_cost_alert():
"""コストアラート用の処理(自動遮断など)"""
# 成本アラート時にAPIキーを一時的に無効化するロジック
print("💰 Cost alert triggered - checking daily budget...")
return jsonify({"status": "cost_alert_processed"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=False)
コスト最適化のための自動対策
# auto_scaling_protection.py
import time
import requests
from datetime import datetime, timedelta
class AutoScaleProtection:
"""
API呼び出しの自動保護メカニズム
異常流量検出時に自動的にレート制限を適用
"""
DAILY_BUDGET_USD = 100 # 日次予算上限
RATE_LIMIT_PER_MINUTE = 100 # 1分あたりの上限
SPIKE_THRESHOLD = 3.0 # 通常の3倍でスパイクと判定
def __init__(self, api_key: str):
self.api_key = api_key
self.request_history = []
self.daily_cost = 0.0
self.last_reset = datetime.now()
self.rate_limit_active = False
def check_and_record(self, model: str, tokens_used: int):
"""リクエストを記録し、制限チェックを実行"""
now = datetime.now()
# 24時間ごとにコストをリセット
if (now - self.last_reset).days >= 1:
self.daily_cost = 0.0
self.last_reset = now
# コスト計算(HolySheep AI ¥1=$1レート)
model_prices = {
"gpt-4.1": 8.00,
"claude-sonnet-4.5": 15.00,
"gemini-2.5-flash": 2.50,
"deepseek-v3.2": 0.42
}
cost_per_request = (tokens_used / 1_000_000) * model_prices.get(model, 8.00)
self.daily_cost += cost_per_request
# 1分以内のリクエスト数チェック
one_minute_ago = now - timedelta(minutes=1)
recent_requests = [r for r in self.request_history if r > one_minute_ago]
if len(recent_requests) >= self.RATE_LIMIT_PER_MINUTE:
self.rate_limit_active = True
print(f"⚠️ レート制限発動: {len(recent_requests)} req/min")
raise Exception("RATE_LIMIT_EXCEEDED: 1分あたりのリクエスト上限に達しました")
# 日次予算チェック
if self.daily_cost >= self.DAILY_BUDGET_USD * 0.8:
print(f"⚠️ 日次予算の80%に到達: ${self.daily_cost:.2f} / ${self.DAILY_BUDGET_USD}")
# Slack通知をトリガー(実際の実装ではWebhookを使用)
if self.daily_cost >= self.DAILY_BUDGET_USD:
self.rate_limit_active = True
print(f"🚨 日次予算上限超過: ${self.daily_cost:.2f} / ${self.DAILY_BUDGET_USD}")
raise Exception("DAILY_BUDGET_EXCEEDED: 日次予算上限に達しました")
self.request_history.append(now)
self.daily_cost += cost_per_request
return {
"allowed": True,
"daily_cost": self.daily_cost,
"budget_remaining": self.DAILY_BUDGET_USD - self.daily_cost,
"rate_limit_active": self.rate_limit_active
}
def get_status(self) -> dict:
"""現在の保護状態を取得"""
return {
"daily_cost_usd": self.daily_cost,
"budget_remaining_usd": self.DAILY_BUDGET_USD - self.daily_cost,
"rate_limit_active": self.rate_limit_active,
"last_reset": self.last_reset.isoformat(),
"requests_last_minute": len([r for r in self.request_history
if r > datetime.now() - timedelta(minutes=1)])
}
使用例
protection = AutoScaleProtection("YOUR_HOLYSHEEP_API_KEY")
try:
result = protection.check_and_record("gpt-4.1", tokens_used=1000)
print(f"リクエスト許可: 残額 ${result['budget_remaining_usd']:.2f}")
except Exception as e:
print(f"リクエスト拒否: {e}")
ステータス確認
status = protection.get_status()
print(f"日次コスト: ${status['daily_cost_usd']:.2f}")
print(f"レート制限: {'有効' if status['rate_limit_active'] else '無効'}")
ダッシュボード設定(Grafana)
Grafanaで美しい監視ダッシュボードを作成するためのJSON設定です。Prometheusデータソースに接続して使用してください。
# grafana_dashboard.json
{
"dashboard": {
"title": "HolySheep AI API Monitoring",
"tags": ["holysheep", "ai", "api", "monitoring"],
"timezone": "Asia/Tokyo",
"panels": [
{
"title": "API Requests/min",
"type": "graph",
"gridPos": {"x": 0, "y": 0, "w": 12, "h": 8},
"targets": [
{
"expr": "rate(api_requests_total[1m])",
"legendFormat": "{{model}} - {{status}}"
}
]
},
{
"title": "Estimated Daily Cost (USD)",
"type": "stat",
"gridPos": {"x": 12, "y": 0, "w": 6, "h": 4},
"targets": [
{
"expr": "sum(api_tokens_used) / 1000000 * 8"
}
],
"fieldConfig": {
"defaults": {
"unit": "currencyUSD",
"thresholds": {
"mode": "absolute",
"steps": [
{"value": 0, "color": "green"},
{"value": 50, "color": "yellow"},
{"value": 80, "color": "red"}
]
}
}
}
},
{
"title": "P95 Latency (ms)",
"type": "graph",
"gridPos": {"x": 18, "y": 0, "w": 6, "h": 4},
"targets": [
{
"expr": "histogram_quantile(0.95, rate(api_latency_seconds_bucket[5m])) * 1000",
"legendFormat": "{{model}}"
}
]
},
{
"title": "Error Rate %",
"type": "gauge",
"gridPos": {"x": 18, "y": 4, "w": 6, "h": 4},
"targets": [
{
"expr": "rate(api_errors_total[5m]) / rate(api_requests_total[5m]) * 100"
}
],
"fieldConfig": {
"defaults": {
"unit": "percent",
"max": 10,
"thresholds": {
"mode": "absolute",
"steps": [
{"value": 0, "color": "green"},
{"value": 1, "color": "yellow"},
{"value": 5, "color": "red"}
]
}
}
}
},
{
"title": "Tokens by Model",
"type": "piechart",
"gridPos": {"x": 0, "y": 8, "w": 8, "h": 8},
"targets": [
{
"expr": "sum by (model) (api_tokens_used)",
"legendFormat": "{{model}}"
}
]
},
{
"title": "Budget Usage",
"type": "bargauge",
"gridPos": {"x": 8, "y": 8, "w": 8, "h": 8},
"targets": [
{
"expr": "(sum(api_tokens_used) / 1000000 * 8) / 100 * 100"
}
],
"fieldConfig": {
"defaults": {
"unit": "percent",
"max": 100,
"thresholds": {
"mode": "percentage",
"steps": [
{"value": 0, "color": "green"},
{"value": 60, "color": "yellow"},
{"value": 80, "color": "orange"},
{"value": 100, "color": "red"}
]
}
}
}
}
]
}
}
よくあるエラーと対処法
エラー1: AuthenticationError - 401 Unauthorized
# 問題
requests.exceptions.HTTPError: 401 Client Error: Unauthorized
原因
- APIキーが正しく設定されていない
- APIキーが期限切れになっている
- 環境変数からAPIキーが正常に読み込めていない
解決コード
import os
正しいAPIキー設定方法
API_KEY = os.environ.get("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY")
キーのバリデーション
if not API_KEY or len(API_KEY) < 20:
raise ValueError("無効なAPIキーです。HolySheep AIダッシュボードで新しいキーを生成してください。")
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
接続テスト
response = requests.get(
"https://api.holysheep.ai/v1/models",
headers=headers
)
if response.status_code == 401:
# 新しいAPIキーをダッシュボードから取得
print("APIキーエラー: https://www.holysheep.ai/dashboard でキーを確認")
raise
エラー2: RateLimitError - 429 Too Many Requests
# 問題
requests.exceptions.HTTPError: 429 Client Error: Too Many Requests
原因
- 短時間内に大量のリクエストを送信
- アカウントのレート制限を超過
- 異常流量と判定された
解決コード(指数バックオフ実装)
import time
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def create_session_with_retry():
"""指数バックオフ付きのセッションを作成"""
session = requests.Session()
retry_strategy = Retry(
total=3,
backoff_factor=2, # 2秒, 4秒, 8秒と待機
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["HEAD", "GET", "POST"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
session.mount("http://", adapter)
return session
def call_with_rate_limit_handling(api_key: str, payload: dict, max_retries: int = 3):
"""レート制限を適切に処理してAPIを呼び出す"""
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
session = create_session_with_retry()
for attempt in range(max_retries):
try:
response = session.post(
"https://api.holysheep.ai/v1/chat/completions",
headers=headers,
json=payload,
timeout=30
)
if response.status_code == 429:
wait_time = 2 ** attempt * 5 # 5秒, 10秒, 20秒
print(f"レート制限に達しました。{wait_time}秒後に再試行します...")
time.sleep(wait_time)
continue
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
if attempt == max_retries - 1:
print(f"最大再試行回数に達しました: {e}")
raise
print(f"試行 {attempt + 1} 失敗: {e}")
time.sleep(2 ** attempt)
raise Exception("API呼び出しに失敗しました")
エラー3: BudgetExceededError - 日次/月次予算超過
# 問題
Exception: DAILY_BUDGET_EXCEEDED: 日次予算上限に達しました
原因
- 予期しないトラフィック増加
- コスト計算の間違い
- 無限ループや再帰呼び出し
解決コード(予算監視と自動保護)
from datetime import datetime, timedelta
import threading
class BudgetManager:
"""日次/月次予算を管理し、超過前にアラート"""
DAILY_LIMIT_USD = 100
MONTHLY_LIMIT_USD = 2000
def __init__(self, webhook_url: str = None):
self.daily_spent = 0.0
self.monthly_spent = 0.0
self.daily_reset = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
self.monthly_reset = datetime.now().replace(day=1, hour=0, minute=0, second=0, microsecond=0)
self.webhook_url = webhook_url
self.lock = threading.Lock()
def _reset_if_needed(self):
"""期間切れならリセット"""
now = datetime.now()
# 日次リセット
if now >= self.daily_reset + timedelta(days=1):
with self.lock:
self.daily_spent = 0.0
self.daily_reset = now.replace(hour=0, minute=0, second=0, microsecond=0)
# 月次リセット
if now.month != self.monthly_reset.month:
with self.lock:
self.monthly_spent = 0.0
self.monthly_reset = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
def _send_alert(self, budget_type: str, spent: float, limit: float):
"""Slackにアラートを送信"""
if not self.webhook_url:
return
percentage = (spent / limit) * 100
message = {
"text": f"⚠️ HolySheep AI 予算アラート\n{budget_type}: ${spent:.2f} / ${limit:.2f} ({percentage:.1f}%)"
}
try:
requests.post(self.webhook_url, json=message)
except Exception as e:
print(f"アラート送信失敗: {e}")
def check_and_charge(self, cost_usd: float) -> bool:
"""
コストを確認し、予算内なら扣除
予算超過ならFalseを返す
"""
self._reset_if_needed()
with self.lock:
# 80%到達時にアラート
if self.daily_spent + cost_usd >= self.DAILY_LIMIT_USD * 0.8:
self._send_alert("日次予算", self.daily_spent, self.DAILY_LIMIT_USD)
if self.monthly_spent + cost_usd >= self.MONTHLY_LIMIT_USD * 0.8:
self._send_alert("月次予算", self.monthly_spent, self.MONTHLY_LIMIT_USD)
# 予算超過チェック
if self.daily_spent + cost_usd > self.DAILY_LIMIT_USD:
print(f"🚨 日次予算超過: ${self.daily_spent + cost_usd:.2f} > ${self.DAILY_LIMIT_USD}")
return False
if self.monthly_spent + cost_usd > self.MONTHLY_LIMIT_USD:
print(f"🚨 月次予算超過: ${self.monthly_spent + cost_usd:.2f} > ${self.MONTHLY_LIMIT_USD