84091ed7b0
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
8.2 KiB
8.2 KiB
Límites de Tokens Mensuales por Usuario
Visión General
OpenCCB ahora soporta límites de tokens de IA mensuales configurables por usuario, permitiendo controlar el consumo de IA y prevenir usos excesivos.
Características
Configuración por Usuario
Cada usuario puede tener:
- Límite mensual personalizado: Número máximo de tokens que puede consumir por mes
- Día de reset: Día del mes cuando se reinicia el contador (1-28)
- Ilimitado: Configurando límite en 0
Valores por Defecto
- Límite: 100,000 tokens/mes
- Día de reset: 1 (primero del mes)
- Unlimited:
monthly_token_limit = 0
Esquema de Base de Datos
Tabla users (Nuevas Columnas)
monthly_token_limit INTEGER DEFAULT 100000
-- Límite mensual de tokens (0 = ilimitado)
token_limit_reset_day INTEGER DEFAULT 1
-- Día del mes para resetear (1-28)
Vista ai_usage_monthly
Muestra el uso actual del mes por usuario:
SELECT * FROM ai_usage_monthly
WHERE user_id = '{user-uuid}';
Columnas:
user_id: UUID del usuarioorganization_id: UUID de la organizaciónusage_month: Mes de usototal_tokens: Total de tokens consumidosinput_tokens: Tokens de entrada (prompts)output_tokens: Tokens de salida (respuestas)total_requests: Número de peticiones a IAtotal_cost_usd: Costo estimado en USD
Funciones SQL
check_token_limit(user_id, additional_tokens)
Verifica si un usuario tiene tokens disponibles.
SELECT * FROM check_token_limit(
'user-uuid'::UUID,
1000 -- Tokens adicionales a verificar
);
Retorna:
has_available_tokens: BOOLEAN - ¿Tiene tokens disponibles?monthly_limit: INTEGER - Límite mensual configuradoused_tokens: BIGINT - Tokens ya usados este mesremaining_tokens: BIGINT - Tokens restantesreset_date: TIMESTAMPTZ - Fecha del próximo reset
get_user_usage_stats(user_id, months)
Obtiene estadísticas históricas de uso.
SELECT * FROM get_user_usage_stats(
'user-uuid'::UUID,
3 -- Últimos 3 meses
);
Retorna:
month_start: DATE - Inicio del mestotal_tokens: BIGINT - Tokens totalesinput_tokens: BIGINT - Tokens de entradaoutput_tokens: BIGINT - Tokens de salidatotal_requests: BIGINT - Número de peticionestotal_cost_usd: NUMERIC - Costo estimadomonthly_limit: INTEGER - Límite del mespercentage_used: NUMERIC - Porcentaje usado
API Endpoints
1. Establecer Límite Mensual
PUT /api/admin/users/{user_id}/token-limit
Authorization: Bearer {admin_token}
Content-Type: application/json
{
"monthly_token_limit": 50000,
"token_limit_reset_day": 15
}
Parámetros:
monthly_token_limit(integer): Límite mensual (0 = ilimitado)token_limit_reset_day(integer, opcional): Día de reset (1-28, default: 1)
Respuesta: 200 OK
2. Ver Uso de Tokens de Usuario
GET /api/admin/users/{user_id}/token-usage
Authorization: Bearer {admin_token}
Respuesta:
{
"user_id": "uuid",
"email": "user@example.com",
"full_name": "Nombre Usuario",
"monthly_token_limit": 100000,
"token_limit_reset_day": 1,
"used_tokens": 45678,
"total_requests": 234,
"total_cost_usd": 0.05,
"last_used": "2026-03-23T10:30:00Z"
}
3. Verificar Límite Disponible
GET /api/admin/users/{user_id}/token-limit/check
Authorization: Bearer {admin_token}
Respuesta:
{
"has_available_tokens": true,
"monthly_limit": 100000,
"used_tokens": 45678,
"remaining_tokens": 54322,
"reset_date": "2026-04-01T00:00:00Z"
}
Ejemplos de Uso
Ejemplo 1: Establecer Límite de 50K Tokens
curl -X PUT "http://localhost:3001/api/admin/users/{user-id}/token-limit" \
-H "Authorization: Bearer {admin-token}" \
-H "Content-Type: application/json" \
-d '{
"monthly_token_limit": 50000,
"token_limit_reset_day": 1
}'
Ejemplo 2: Verificar Tokens Disponibles
curl "http://localhost:3001/api/admin/users/{user-id}/token-limit/check" \
-H "Authorization: Bearer {admin-token}"
Ejemplo 3: Obtener Uso del Mes
curl "http://localhost:3001/api/admin/users/{user-id}/token-usage" \
-H "Authorization: Bearer {admin-token}"
Ejemplo 4: SQL Directo
-- Ver uso actual de todos los usuarios
SELECT
u.email,
u.full_name,
u.monthly_token_limit,
COALESCE(SUM(au.tokens_used), 0) as used_tokens,
u.monthly_token_limit - COALESCE(SUM(au.tokens_used), 0) as remaining_tokens,
CASE
WHEN u.monthly_token_limit = 0 THEN 'Unlimited'
ELSE ROUND((COALESCE(SUM(au.tokens_used), 0)::NUMERIC / u.monthly_token_limit * 100)::NUMERIC, 2) || '%'
END as usage_percentage
FROM users u
LEFT JOIN ai_usage_logs au ON u.id = au.user_id
AND au.created_at >= DATE_TRUNC('month', NOW())
GROUP BY u.id, u.email, u.full_name, u.monthly_token_limit
ORDER BY used_tokens DESC;
Estrategias de Límites
Por Rol de Usuario
-- Estudiantes: 50K tokens/mes
UPDATE users SET monthly_token_limit = 50000 WHERE role = 'student';
-- Instructores: 200K tokens/mes
UPDATE users SET monthly_token_limit = 200000 WHERE role = 'instructor';
-- Admins: Ilimitado
UPDATE users SET monthly_token_limit = 0 WHERE role = 'admin';
Por Tipo de Plan
-- Plan Básico: 25K tokens
UPDATE users SET monthly_token_limit = 25000 WHERE plan = 'basic';
-- Plan Pro: 100K tokens
UPDATE users SET monthly_token_limit = 100000 WHERE plan = 'pro';
-- Plan Enterprise: Ilimitado
UPDATE users SET monthly_token_limit = 0 WHERE plan = 'enterprise';
Reset en Días Diferentes
-- Reset el día 15 (mitad de mes)
UPDATE users SET token_limit_reset_day = 15 WHERE organization_id = 'org-uuid';
Implementación de Enforce
Para hacer cumplir los límites a nivel de API, verifica antes de cada solicitud de IA:
// Ejemplo en handler de IA
pub async fn chat_with_tutor(...) -> Result<...> {
// 1. Verificar límite de tokens
let limit_check: TokenLimitCheck = sqlx::query_as(
"SELECT * FROM check_token_limit($1, 1000)" // 1000 tokens estimados
)
.bind(claims.sub)
.fetch_one(&pool)
.await?;
if !limit_check.has_available_tokens {
return Err((
StatusCode::TOO_MANY_REQUESTS,
format!(
"Monthly token limit exceeded. Reset date: {}",
limit_check.reset_date
)
));
}
// 2. Proceder con solicitud de IA
// ...
// 3. Loguear uso (ya implementado)
sqlx::query("SELECT log_ai_usage(...)").execute(&pool).await?;
Ok(response)
}
Monitoreo y Alertas
Dashboard de Uso
-- Usuarios que han usado > 80% de su límite
SELECT
u.email,
u.full_name,
u.monthly_token_limit,
SUM(au.tokens_used) as used_tokens,
ROUND((SUM(au.tokens_used)::NUMERIC / NULLIF(u.monthly_token_limit, 0) * 100)::NUMERIC, 2) as percentage_used
FROM users u
JOIN ai_usage_logs au ON u.id = au.user_id
WHERE au.created_at >= DATE_TRUNC('month', NOW())
AND u.monthly_token_limit > 0
GROUP BY u.id, u.email, u.full_name, u.monthly_token_limit
HAVING SUM(au.tokens_used)::NUMERIC / NULLIF(u.monthly_token_limit, 0) > 0.8
ORDER BY percentage_used DESC;
Notificación de Límite Alcanzado
Configura webhooks o emails cuando un usuario alcance el 80%, 90% y 100% de su límite.
Troubleshooting
Usuario Reporta que No Puede Usar IA
-- Verificar límite y uso
SELECT * FROM check_token_limit('user-uuid'::UUID, 0);
-- Ver historial de uso
SELECT * FROM get_user_usage_stats('user-uuid'::UUID, 1);
-- Ver logs de errores
SELECT * FROM ai_usage_logs
WHERE user_id = 'user-uuid'
ORDER BY created_at DESC
LIMIT 10;
Resetear Contador de Usuario
-- Establecer límite ilimitado temporalmente
UPDATE users SET monthly_token_limit = 0 WHERE id = 'user-uuid';
-- O aumentar límite
UPDATE users SET monthly_token_limit = 200000 WHERE id = 'user-uuid';
Referencias
- Migración:
services/cms-service/migrations/20260323000000_monthly_token_limits.sql - Handlers:
services/cms-service/src/handlers_admin.rs - Endpoints:
services/cms-service/src/main.rs
Fecha: 2026-03-23
Versión: OpenCCB 0.2.1