Xây dựng AI Gateway tập trung với LiteLLM và Docker: Quản lý API Key, Cân bằng tải và Kiểm soát chi phí

AI tutorial - IT technology blog
AI tutorial - IT technology blog

Thực tế lộn xộn khi triển khai nhiều LLM

Quý trước, hạ tầng của chúng tôi rơi vào cảnh hỗn loạn. Chúng tôi vận hành ba dịch vụ cốt lõi—một service phân tích tài liệu viết bằng FastAPI, một notification engine bằng Node.js và một Slack bot nội bộ—song song với sáu kỹ sư liên tục thử nghiệm các prompt pipeline. Mỗi hệ thống đều lưu trữ trực tiếp API key của OpenAI và Anthropic trong các file .env riêng biệt. Chẳng ai biết ai đang chi tiêu bao nhiêu tiền.

Rồi sự cố ập đến. Một kỹ sư chạy script đánh giá và gửi ồ ạt 3.200 request mỗi phút tới OpenAI. Con số này vượt xa rate limit 1.000 RPM của gói Tier-3, khiến lưu lượng production bị nghẽn hoàn toàn trong 20 phút. Ba tuần sau đó, một test script không được giám sát đã tiêu tốn tới 1.400 USD gọi Claude Opus chỉ trong hai ngày cuối tuần. Chi phí LLM hàng tháng của chúng tôi tăng vọt 45% mà không rõ nguyên nhân từ đâu.

Việc rải rác API key khắp nơi cùng sự thiếu hụt trong quản trị lưu lượng chính là mầm mống dẫn đến downtime. Việc hardcode các secret của nhà cung cấp trên nhiều repo cũng gây ra cơn đau đầu lớn về bảo mật. Để giải quyết triệt để, chúng tôi đã đặt một reverse proxy nằm giữa các ứng dụng và các nhà cung cấp AI upstream: một AI gateway tập trung.

Tại sao lại chọn LiteLLM?

Tự viết một LLM proxy từ đầu sẽ ngốn hàng tuần bảo trì. LiteLLM giải quyết trọn vẹn vấn đề này ngay khi cài đặt. Nó hoạt động như một proxy server nhẹ và tương thích hoàn toàn với chuẩn OpenAI. Điều này có nghĩa là bất kỳ Python script, LangChain agent hay request cURL nào được viết cho OpenAI SDK đều hoạt động ngay lập tức—bạn chỉ cần đổi lại base URL.

Dưới đây là những lợi ích mà mô hình này mang lại:

  • Chuẩn hóa API duy nhất: Các upstream request gửi tới Gemini 1.5 Pro, Claude 3.5 Sonnet hay các instance vLLM tự host đều tiếp nhận payload theo chuẩn /v1/chat/completions.
  • Virtual Key theo từng nhóm: Các service sẽ nhận virtual token với phạm vi sử dụng được giới hạn (bắt đầu bằng tiền tố sk-) thay vì dùng master key của nhà cung cấp. Bạn có thể gán từng token với các model cụ thể, hạn mức request mỗi phút (RPM) và giới hạn ngân sách tính bằng USD.
  • Cân bằng tải & Fallback thông minh: Lưu lượng được phân bổ mượt mà qua nhiều key tổ chức hoặc khu vực địa lý khác nhau. Nếu GPT-4o trả về mã lỗi 429 hoặc 503, proxy sẽ âm thầm chuyển hướng payload sang Claude 3.5 Sonnet chỉ trong vài mili-giây.
  • Tự động chặn vượt ngân sách: PostgreSQL theo dõi mức tiêu thụ token theo thời gian thực. Ngay khi virtual key của một bạn thực tập sinh chạm ngưỡng hạn mức 50 USD/tháng, LiteLLM sẽ tự động từ chối các lượt gọi tiếp theo.

Từng bước triển khai: Cài đặt LiteLLM với Docker

Chúng ta sẽ cấu hình một LiteLLM proxy sẵn sàng cho môi trường production kết hợp cùng PostgreSQL để theo dõi user key, ghi nhận chi phí và kiểm tra health check.

Bước 1: Thiết lập thư mục dự án và cấu hình biến môi trường

Tạo một thư mục riêng biệt trên máy chủ của bạn để chứa các file cấu hình:

mkdir -p /opt/ai-gateway && cd /opt/ai-gateway
touch docker-compose.yml litellm_config.yaml .env
chmod 600 .env

Thêm mật khẩu database và các master API key của nhà cung cấp vào file .env:

# .env
POSTGRES_USER=litellm
POSTGRES_PASSWORD=Secr3t_Postgres_P@ss!2024
POSTGRES_DB=litellm_proxy

LITELLM_MASTER_KEY=sk-admin-master-prod-9988
OPENAI_API_KEY_PRIMARY=sk-proj-primaryKey-12345
OPENAI_API_KEY_SECONDARY=sk-proj-backupKey-67890
ANTHROPIC_API_KEY=sk-ant-liveKey-abcdef

Bước 2: Cấu hình định tuyến model và tự động failover

Định nghĩa các quy tắc định tuyến bên trong litellm_config.yaml. Cấu hình bên dưới chia đều request gọi GPT-4o cho hai tài khoản OpenAI (mỗi tài khoản 1.000 RPM) và tự động chuyển sang Anthropic Claude 3.5 Sonnet nếu cả hai đều gặp lỗi.

model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY_PRIMARY
      rpm: 1000
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY_SECONDARY
      rpm: 1000
  - model_name: gpt-4o-fallback
    litellm_params:
      model: anthropic/claude-3-5-sonnet-20241022
      api_key: os.environ/ANTHROPIC_API_KEY

router_settings:
  routing_strategy: usage-based-routing-v2
  fallbacks:
    - gpt-4o: ["gpt-4o-fallback"]
  num_retries: 2
  retry_after: 1
  timeout: 30

general_settings:
  master_key: os.environ/LITELLM_MASTER_KEY
  database_url: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}

Bước 3: Khai báo các service trong Docker Compose

Thêm PostgreSQL 16 và container LiteLLM proxy vào file docker-compose.yml. Cấu hình health check nhằm đảm bảo LiteLLM chỉ khởi động sau khi socket của database đã sẵn sàng chấp nhận kết nối.

version: '3.8'

services:
  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 5s
      timeout: 3s
      retries: 5

  litellm:
    image: ghcr.io/berriai/litellm:main-latest
    restart: unless-stopped
    ports:
      - "4000:4000"
    environment:
      DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}"
      LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY}
      OPENAI_API_KEY_PRIMARY: ${OPENAI_API_KEY_PRIMARY}
      OPENAI_API_KEY_SECONDARY: ${OPENAI_API_KEY_SECONDARY}
      ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
    volumes:
      - ./litellm_config.yaml:/app/config.yaml
    command: ["--config", "/app/config.yaml", "--port", "4000", "--detailed_debug"]
    depends_on:
      db:
        condition: service_healthy

volumes:
  pgdata:

Khởi chạy các container ở chế độ chạy ngầm (detached mode):

docker compose up -d
docker compose logs -f litellm

Kiểm tra dòng LiteLLM: Proxy running on http://0.0.0.0:4000 trong log để xác nhận quá trình migration database đã hoàn tất thành công.

Bước 4: Tạo Virtual Key có phân quyền và giới hạn ngân sách

Từ giờ, bạn không bao giờ phải chia sẻ master key của nhà cung cấp nữa. Hãy dùng management API của LiteLLM để tạo các virtual token có giới hạn phạm vi cho từng team hoặc môi trường. Dưới đây là cách tạo một key cho team staging với hạn mức nghiêm ngặt 50 USD mỗi tháng:

curl -s -X POST http://localhost:4000/key/generate \
  -H "Authorization: Bearer sk-admin-master-prod-9988" \
  -H "Content-Type: application/json" \
  -d '{
    "models": ["gpt-4o"],
    "max_budget": 50.0,
    "budget_duration": "30d",
    "user_id": "team-analytics-staging",
    "metadata": {"environment": "staging", "cost_center": "cc-402"}
  }' | jq

LiteLLM sẽ trả về một virtual key có định dạng tương tự sk-litellm-1234.... Proxy sẽ ghi nhận số lượng token từ mỗi response. Ngay khi key này tích lũy đủ 50.00 USD chi phí, LiteLLM sẽ lập tức chặn lại bằng lỗi HTTP 400 BudgetExceededError. Các key dùng cho production vẫn hoàn toàn không bị ảnh hưởng.

Bước 5: Chuyển đổi mã nguồn Client sang Gateway

Việc tích hợp vào các ứng dụng hiện có chỉ mất chưa đầy hai phút. Bạn chỉ cần trỏ base_url về endpoint của gateway và truyền vào virtual token:

from openai import OpenAI

# Trỏ client tới reverse proxy LiteLLM
client = OpenAI(
    base_url="http://localhost:4000/v1",
    api_key="sk-litellm-analytics-key-here"
)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "Bạn là một kỹ sư SRE (Site Reliability Engineer)."},
        {"role": "user", "content": "Giải thích cách TCP connection pool ngăn ngừa tình trạng cạn kiệt thread (thread starvation)."}
    ]
)

print(response.choices[0].message.content)

Hệ thống microservice của chúng tôi đã hoạt động ổn định với mô hình gateway này suốt sáu tháng qua mà không gặp bất kỳ sự cố nào. Trong đợt bùng phát độ trễ nghiêm trọng của OpenAI vào tháng 11 khiến thời gian phản hồi p99 vượt quá 14 giây, LiteLLM đã tự động chuyển 800 request đang chạy sang Claude 3.5 Sonnet. Người dùng cuối của chúng tôi không hề gặp phải bất kỳ kết nối bị gián đoạn nào.

Các bước tiếp theo để sẵn sàng cho Production

Việc triển khai một AI gateway sẽ chấm dứt tình trạng rò rỉ secret bừa bãi và chi tiêu mất kiểm soát. Các API key chính của nhà cung cấp được cô lập an toàn bên trong máy chủ proxy. Cân bằng tải được xử lý ngay tại tầng mạng (networking tier)—đúng nơi nó thuộc về.

Trước khi đưa vào production, hãy đặt một reverse proxy như Traefik hoặc Caddy phía trước cổng 4000 để xử lý TLS termination và rate-limiting. Cuối cùng, hãy kích hoạt endpoint /metrics tích hợp sẵn của LiteLLM để chuyển trực tiếp biểu đồ độ trễ, mức tiêu thụ token và tỷ lệ lỗi vào dashboard Prometheus và Grafana.

Share: