LLM Gateway 2026 - Cổng Kết nối AI Thông minh cho Multi-Agent với Redis và ClickHouse
Posted on: 4/14/2026 1:11:51 PM
Table of contents
- 1. LLM Gateway là gì và tại sao 2026 không thể thiếu?
- 2. Bốn thách thức cốt lõi của Multi-Agent LLM Workloads
- 3. Kiến trúc tổng thể LLM Gateway sản xuất
- 4. Request Routing: Model Pool, Fallback và Load Balancing
- 5. Rate Limiting với Redis Token Bucket
- 6. Tích hợp Semantic Cache vào Gateway
- 7. Cost Tracking và Budget Enforcement
- 8. Observability với ClickHouse cho Multi-Agent
- 9. Bảo mật: API Keys, Tenant Isolation, PII Redaction
- 10. So sánh: LiteLLM, Portkey, Helicone, Kong AI vs Gateway tự xây
- 11. Production Pattern với Claude Code và Claude Agent SDK
- 12. Vận hành: capacity, bảo trì và checklist production
- 13. Xu hướng 2026+: Gateway như một "AI Control Plane"
- 14. Kết luận
- Nguồn tham khảo
Năm 2026, bài toán "gọi một LLM từ ứng dụng" không còn là chuyện viết vài dòng client.messages.create(...). Với hệ thống Multi-Agent production, mỗi request từ người dùng có thể kích hoạt 10–40 lời gọi LLM trải dài trên nhiều model (Claude Opus 4.6, Claude Sonnet 4.6, Haiku 4.5, GPT, Gemini, Llama self-hosted), nhiều tenant, nhiều mức ưu tiên khác nhau. Việc để từng microservice tự gọi trực tiếp provider nhanh chóng biến thành một mớ bòng bong về chi phí, rate limit, fallback và observability. Bài viết này đi sâu vào LLM Gateway — tầng proxy thông minh đứng giữa ứng dụng và các nhà cung cấp LLM — với kiến trúc production-grade, triển khai bằng Redis cho rate limiting và caching, ClickHouse cho observability thời gian thực, cùng các pattern tương thích với Claude Code và Claude Agent SDK.
1. LLM Gateway là gì và tại sao 2026 không thể thiếu?
Một LLM Gateway (còn gọi là AI Gateway, LLM Proxy, Model Router) là một tầng abstraction đứng giữa ứng dụng và các nhà cung cấp LLM (Anthropic, OpenAI, Google, Bedrock, Vertex, self-hosted vLLM, SGLang...). Nhiệm vụ của nó không chỉ là chuyển request đi — mà là quản lý, bảo vệ và quan sát toàn bộ dòng chảy AI của tổ chức.
Nếu ví hệ thống Multi-Agent như một thành phố, thì mỗi agent là một công dân cần dịch vụ LLM — gateway chính là hệ thống điều phối giao thông trung tâm: phân luồng xe tải (request lớn) sang đường riêng, giữ làn ưu tiên cho xe cứu thương (realtime user), gắn camera giám sát mọi ngã tư (tracing) và thu phí cầu đường tự động (cost tracking).
Không có Gateway, bạn sẽ gặp phải
Mỗi team tự giữ API key → rò rỉ bí mật. Mỗi service tự xử lý rate limit → duplicate logic + inconsistent behavior. Không ai biết tổng chi phí tháng đó là bao nhiêu và chia cho ai. Khi provider sập, toàn bộ agent chết theo. Không có nơi áp dụng PII redaction tập trung. Chuyển model mới phải sửa code ở 50 chỗ.
1.1. Vì sao 2026 là thời điểm không thể trì hoãn
Trong 18 tháng qua, ba xu hướng kết hợp đã khiến LLM Gateway trở thành một thành phần bắt buộc trong stack AI production:
- Bùng nổ Multi-Agent: các framework như Claude Agent SDK, LangGraph, CrewAI, AutoGen đưa số lượng LLM call mỗi request lên gấp 10–30 lần so với ứng dụng chat đơn giản. Không thể quản lý chi phí nếu không có lớp tổng hợp.
- Hybrid Multi-Provider: chiến lược "một model duy nhất" đã lỗi thời. Teams production 2026 kết hợp Opus cho reasoning khó, Sonnet cho tool-use, Haiku cho filter/classify, Llama self-hosted cho batch — cần một router quyết định model phù hợp theo policy.
- Quy định và kiểm soát: Các framework tuân thủ như NIST AI RMF, ISO/IEC 42001, EU AI Act yêu cầu đo đạc, audit log và kiểm soát nội dung. Gateway là nơi tập trung thực thi guardrails.
2. Bốn thách thức cốt lõi của Multi-Agent LLM Workloads
Trước khi thiết kế gateway, phải nhìn rõ bài toán. Khi một hệ thống chạm mức vài triệu request/ngày, bốn loại rủi ro bắt đầu lộ diện cùng lúc:
2.1. Chi phí không kiểm soát được
Một phiên Claude Code trung bình có thể đốt 300k–1.2M token. Nếu để agent tự do gọi Opus cho mọi thao tác, hoá đơn tháng có thể vượt hàng chục nghìn USD chỉ vì một vài agent "loose cannon". Kiểm soát chi phí đòi hỏi quota theo tenant, fallback sang model rẻ hơn, và circuit breaker khi spike bất thường.
2.2. Rate limit giòn và cascading failure
Anthropic và OpenAI đều áp dụng RPM (requests/minute), TPM (tokens/minute) và daily cap theo tổ chức. Khi bạn chạm trần, provider trả về HTTP 429. Nếu nhiều agent đang chạy trong cùng một vòng lặp, chúng retry đồng thời — tạo ra thundering herd đánh sập luôn luồng phản hồi cho người dùng realtime. Cần một cơ chế xếp hàng công bằng thay vì retry mù.
2.3. Provider outage và SLA chênh lệch
Tháng 6/2025, một trong các provider LLM lớn đã downtime 2h38m. Nếu toàn bộ hệ thống bạn ghim cứng vào một provider, nghĩa là SLA của bạn không thể vượt SLA của họ. Gateway phải biết health-check từng upstream và failover nóng sang provider dự phòng — lý tưởng nhất là cùng một họ model tương đương (vd: Claude Sonnet ↔ GPT-4.1, hoặc Claude Sonnet ↔ Llama 3.3 405B self-hosted).
2.4. Không quan sát được chuỗi request
Khi một agent fail, câu hỏi đầu tiên là: "nó đã gọi model nào, với prompt gì, tốn bao nhiêu token, mất bao lâu, và tại sao thất bại?". Trả lời câu này trong kiến trúc microservice phân mảnh cực kỳ khó nếu không có lớp trung tâm ghi lại trace. Gateway là điểm duy nhất vừa biết input/output vừa biết cost — vị trí lý tưởng để ghi vào ClickHouse.
Đừng nhầm Gateway với Proxy đơn thuần
Nginx hay Envoy có thể làm reverse proxy cho LLM, nhưng chúng không hiểu ngữ nghĩa của LLM call. Một LLM Gateway thực thụ phải nhận diện được model, input_tokens, output_tokens, cache_read_tokens, tool_use, stop_reason... và ra quyết định dựa trên chúng.
3. Kiến trúc tổng thể LLM Gateway sản xuất
Một LLM Gateway production-grade không phải một binary duy nhất — mà là một tập hợp các component được sắp xếp hợp lý. Sơ đồ dưới đây mô tả luồng một request từ agent đi qua gateway đến provider và quay lại:
flowchart TB
subgraph Clients["Agent Clients"]
A1["Claude Code"]
A2["LangGraph Agent"]
A3["Internal API"]
end
subgraph Gateway["LLM Gateway"]
Auth["1. Auth & Tenant
Identify"]
Guard["2. Guardrails
PII / Safety"]
Cache["3. Semantic
Cache Lookup"]
RL["4. Rate Limit
Token Bucket"]
Router["5. Model Router
Policy Engine"]
Circuit["6. Circuit Breaker
+ Retry Budget"]
Tele["7. Telemetry
Emitter"]
end
subgraph Data["Data Plane"]
R["Redis Cluster"]
CH["ClickHouse"]
end
subgraph Upstreams["Upstream Pool"]
U1["Anthropic
Claude 4.6"]
U2["OpenAI
GPT"]
U3["Bedrock"]
U4["vLLM
self-hosted"]
end
A1 --> Auth
A2 --> Auth
A3 --> Auth
Auth --> Guard
Guard --> Cache
Cache --> RL
RL --> Router
Router --> Circuit
Circuit --> U1
Circuit --> U2
Circuit --> U3
Circuit --> U4
Cache <--> R
RL <--> R
Circuit --> Tele
Tele --> CH
style Auth fill:#0f3460,stroke:#fff,color:#fff
style Guard fill:#0f3460,stroke:#fff,color:#fff
style Cache fill:#4CAF50,stroke:#fff,color:#fff
style RL fill:#ff9800,stroke:#fff,color:#fff
style Router fill:#e94560,stroke:#fff,color:#fff
style Circuit fill:#e94560,stroke:#fff,color:#fff
style Tele fill:#0f3460,stroke:#fff,color:#fff
style R fill:#dc382d,stroke:#fff,color:#fff
style CH fill:#ffcc00,stroke:#333,color:#333
Kiến trúc luồng 7 tầng cho một LLM Gateway production
Bảy tầng trên đại diện cho bảy quyết định độc lập mà gateway phải thực hiện trong vài mili-giây. Mỗi tầng có state store riêng: auth trong Redis Hash, semantic cache trong Redis Vector Index, token bucket trong Redis Sorted Set, telemetry đẩy thẳng vào ClickHouse qua buffer Kafka (hoặc Redis Streams nếu không có Kafka).
3.1. Tách Control Plane và Data Plane
Mọi gateway sống được ở quy mô lớn đều tách rõ hai mặt phẳng:
- Data Plane: tối ưu cho throughput và độ trễ. Xử lý từng request, ra quyết định theo policy đã được biên dịch sẵn. Không bao giờ gọi database trong critical path. Giao tiếp với Redis (dữ liệu nóng) và emit telemetry async.
- Control Plane: tối ưu cho cấu hình và quan sát. Lưu policy, quota, API key trong SQL; biên dịch policy thành snapshot và push xuống data plane qua pub/sub. Ingest telemetry từ ClickHouse để render dashboard.
Tách biệt này cho phép update policy không restart data plane, và giúp dễ dàng chạy data plane ở edge (gần agent) trong khi control plane chỉ cần một cụm trung tâm.
4. Request Routing: Model Pool, Fallback và Load Balancing
Router là trái tim của gateway. Nó nhận một logical model name từ agent (vd: smart-reasoner, fast-classifier) và dịch thành physical upstream dựa trên policy. Ba kỹ thuật routing phổ biến:
4.1. Policy-based Routing
Mỗi logical model có một mảng providers theo thứ tự ưu tiên. Mỗi provider có trọng số, tính năng yêu cầu (streaming, tool-use, vision), và điều kiện kích hoạt:
models:
smart-reasoner:
description: "Dùng cho plan tool use và critique"
providers:
- name: anthropic-claude-opus-4-6
weight: 70
max_input_tokens: 200000
features: [tool_use, prompt_cache, streaming]
- name: anthropic-claude-sonnet-4-6
weight: 25
conditions:
cost_ceiling_usd_per_day: 500
- name: openai-gpt
weight: 5
circuit_breaker:
error_threshold: 0.1
window_sec: 60
fallback_from: [anthropic-claude-opus-4-6]
fast-classifier:
providers:
- name: anthropic-claude-haiku-4-5
weight: 100
- name: self-hosted-llama-70b
weight: 0
activate_when: "anthropic_rl_remaining < 0.2"Policy được đánh giá bởi một evaluator thuần tuý — không gọi I/O — dựa trên snapshot đã được cache sẵn. Gateway đọc snapshot qua atomic pointer swap mỗi khi control plane publish version mới.
4.2. Fallback và Retry Budget
Khi primary provider trả lỗi (429, 500, timeout), gateway không retry vô hạn. Kỹ thuật Retry Budget (Finagle-style) giới hạn tỉ lệ retry ở mức vd 10% so với lượng request thành công trong cửa sổ 60s — tránh tạo amplification attack lên chính upstream đang yếu. Fallback hoạt động như sau:
sequenceDiagram
participant Agent
participant GW as Gateway
participant Opus as Claude Opus
participant Sonnet as Claude Sonnet
participant Llama as Self-hosted Llama
Agent->>GW: POST /messages (smart-reasoner)
GW->>Opus: forward (attempt 1)
Opus-->>GW: 429 Too Many Requests
Note over GW: Retry budget OK
(7% burned)
GW->>Sonnet: forward (attempt 2)
Sonnet-->>GW: 200 OK (degraded flag)
GW->>GW: Stamp x-llm-fallback: sonnet
GW-->>Agent: 200 OK with degraded flag
Note over GW: Circuit breaker
opens for Opus
Agent->>GW: (next request)
GW->>Sonnet: direct (Opus open)
Fallback với retry budget và circuit breaker — agent nhận được header chỉ báo mức degraded
4.3. Load Balancing thông minh: Least-Outstanding + Latency-Aware
Round-robin hoặc random không đủ cho LLM upstream. Thời gian hoàn thành một request phụ thuộc độ dài context và output tokens — không phải hằng số. Thuật toán hoạt động tốt nhất trong thực tế là P2C Least-Outstanding Requests (Power of Two Choices) kết hợp với EWMA latency:
# Pseudo-code: chọn 2 upstream random, lấy cái ít tải hơn
def pick_upstream(pool):
a, b = random.sample(pool, 2)
score_a = a.outstanding + a.ewma_latency_ms * 0.1
score_b = b.outstanding + b.ewma_latency_ms * 0.1
return a if score_a <= score_b else bKỹ thuật này có lý thuyết nền rằng chỉ cần nhìn 2 node random và chọn node ít tải hơn, phân phối tải sẽ gần tối ưu với overhead O(1). Trong Envoy và NGINX đây cũng là default khi bật least_request.
5. Rate Limiting với Redis Token Bucket
Rate limit trong LLM Gateway phức tạp hơn API thông thường vì phải tính đồng thời RPM, TPM, và daily cost cap. Thuật toán Token Bucket đặc biệt phù hợp vì nó cho phép burst ngắn — đúng với hành vi của agent thực tế (nhiều call song song trong một turn, rồi im lặng).
5.1. Hierarchical Buckets
Không tồn tại một rate limit duy nhất. Gateway cần ít nhất 4 tầng lồng nhau, request chỉ được pass khi cả bốn tầng đều còn token:
flowchart LR
R["Request"] --> G["Global
tpm=10M"]
G --> T["Tenant
tpm=500k"]
T --> U["User
tpm=20k"]
U --> M["Model
rpm=1000"]
M --> OK["Pass"]
G -. fail .-> RJ["429 Too Many"]
T -. fail .-> RJ
U -. fail .-> RJ
M -. fail .-> RJ
style OK fill:#4CAF50,stroke:#fff,color:#fff
style RJ fill:#e94560,stroke:#fff,color:#fff
Four-layer token bucket: global → tenant → user → model
5.2. Atomic Lua Script trên Redis
Để tránh race condition giữa nhiều instance gateway, phép check-and-decrement phải là atomic. Cách tối ưu nhất là đóng gói trong một Lua script chạy nguyên khối trên Redis:
-- KEYS[1] = bucket key
-- ARGV[1] = capacity
-- ARGV[2] = refill_rate_per_sec
-- ARGV[3] = requested_tokens
-- ARGV[4] = now_ms
local key = KEYS[1]
local capacity = tonumber(ARGV[1])
local refill = tonumber(ARGV[2])
local need = tonumber(ARGV[3])
local now = tonumber(ARGV[4])
local state = redis.call('HMGET', key, 'tokens', 'ts')
local tokens = tonumber(state[1]) or capacity
local ts = tonumber(state[2]) or now
-- Refill từ lần cập nhật cuối
local delta = (now - ts) / 1000.0 * refill
tokens = math.min(capacity, tokens + delta)
if tokens >= need then
tokens = tokens - need
redis.call('HSET', key, 'tokens', tokens, 'ts', now)
redis.call('PEXPIRE', key, 120000)
return {1, tokens}
else
redis.call('HSET', key, 'tokens', tokens, 'ts', now)
redis.call('PEXPIRE', key, 120000)
return {0, tokens}
endScript này chạy ~30–60µs trên Redis 7+, đủ nhanh để thực hiện 4 lần liên tiếp cho 4 tầng. Với Redis Cluster, dùng hash tag để cả 4 key cùng landing vào một slot, cho phép gọi trong một EVAL duy nhất.
5.3. Đếm token trước khi gọi
Vấn đề đặc trưng của LLM: bạn phải dự đoán số token sẽ tiêu tốn trước khi gọi provider (vì TPM tính theo token, không phải request). Hai kỹ thuật phổ biến:
- Tokenizer nội bộ: gọi
tiktoken(OpenAI) hoặcanthropic.count_tokensđể đếm chính xác. Overhead ~200µs cho 8k token. - Byte heuristic: ước lượng 1 token ≈ 3.5–4 byte (en) hoặc ≈ 2 byte (vi). Nhanh hơn nhưng có sai số 10%; ổn cho enforcement mềm.
Reservation pattern
Để tránh "thiếu token sau khi đã gọi", gateway đặt trước (reserve) max_tokens của response vào bucket, rồi sau khi provider trả về thực tế, refund lại phần thừa. Pattern này giúp TPM bucket chính xác 99%+ và ngăn overrun.
6. Tích hợp Semantic Cache vào Gateway
Semantic caching (đã bàn kỹ trong Semantic Caching cho LLM Agents 2026) đạt hiệu quả cao nhất khi được đặt bên trong gateway, thay vì từng service tự triển khai. Lý do: gateway thấy toàn bộ traffic, embedding cache giữa các tenant có thể share với partition riêng, và chi phí embedding được amortize qua batch.
6.1. Ba tầng cache phối hợp
Gateway kích hoạt ba tầng cache theo thứ tự, chỉ miss hết cả ba mới đi đến provider:
| Tầng | Khớp ở mức | Store | Thời gian lookup | Tỉ lệ hit thực tế |
|---|---|---|---|---|
| L1 Exact | Hash SHA-256 của (model + normalized prompt) | Redis String | ~500µs | 15–25% |
| L2 Semantic | Cosine similarity ≥ 0.87 trong embedding space | Redis 8 Vector (HNSW) | ~8ms | 30–50% |
| L3 Prompt Cache | Prefix token giống nhau (KV-cache provider) | Phía Anthropic/OpenAI | transparent | 60–90% với Claude Code |
6.2. Cache Policy an toàn
Không phải request nào cũng nên cache. Các nguyên tắc không-đàm-phán:
- Không cache request có PII chưa redact — dùng scanner trong tầng Guardrails (regex + Presidio).
- Partition theo tenant trong Redis key để tránh rò rỉ giữa khách hàng:
cache:{tenant_id}:.... - TTL ngắn cho câu hỏi thời sự: Gateway detect keyword kiểu "hôm nay", "đang diễn ra", "vừa xảy ra" → giảm TTL xuống 5 phút.
- Không cache phản hồi tool-use: vì tool kết quả có thể đã thay đổi ở lần sau.
7. Cost Tracking và Budget Enforcement
Đây là phần mà đa số gateway thương mại bán được giá cao nhất — và cũng là phần dễ tự xây nhất. Công thức cơ bản: mỗi response có usage.input_tokens, usage.output_tokens, usage.cache_read_tokens. Nhân với bảng giá model là ra chi phí.
7.1. Emit event cost chuẩn hoá
Sau mỗi response thành công, gateway tạo một cost event theo schema chung:
{
"event_id": "01HX...",
"timestamp": "2026-04-14T10:15:23.412Z",
"tenant_id": "acme-corp",
"user_id": "u_42",
"agent_id": "claude-code-session-9a",
"logical_model": "smart-reasoner",
"physical_model": "claude-opus-4-6",
"provider": "anthropic",
"input_tokens": 12840,
"cache_read_tokens": 10200,
"cache_write_tokens": 0,
"output_tokens": 512,
"tool_use_count": 3,
"latency_ms": 1847,
"cost_usd": 0.0389,
"x_request_id": "req_01HX9K...",
"parent_trace_id": "tr_01HX9K..."
}Event này được LPUSH vào Redis Stream cost_events. Một worker consume từ stream, batch 10.000 event mỗi 2 giây và INSERT vào ClickHouse. Latency end-to-end từ khi agent nhận response tới khi chi phí xuất hiện trong dashboard thường dưới 5 giây.
7.2. Budget Enforcement thời gian thực
Ghi nhận chi phí là bước một, nhưng quan trọng hơn là ngắt request khi tenant vượt ngân sách. Gateway duy trì một biến spent_usd_today:{tenant_id} trong Redis — mỗi cost event tăng nó qua INCRBYFLOAT. Khi vượt 80% quota, gateway bắt đầu degrade mode: chỉ pass các request priority cao, hoặc tự động downgrade smart-reasoner thành fast-classifier. Khi vượt 100%, trả về HTTP 402.
Cẩn thận với concurrency khi enforce
Nếu bạn check-and-commit chi phí trước khi gọi provider, bạn có thể dự đoán sai và over-charge. Nếu check sau, bạn bị race condition (nhiều request parallel đều thấy chưa vượt quota). Giải pháp: check trước bằng predicted cost, reserve một phần, và reconcile sau.
8. Observability với ClickHouse cho Multi-Agent
ClickHouse là lựa chọn mặc định cho AI observability 2026 nhờ khả năng nuốt hàng trăm nghìn event/giây với storage nén 10–100x so với JSON log. Schema tối ưu cho LLM Gateway events:
CREATE TABLE llm_events
(
event_id UUID,
ts DateTime64(3, 'UTC'),
tenant_id LowCardinality(String),
user_id String,
agent_id String,
logical_model LowCardinality(String),
physical_model LowCardinality(String),
provider LowCardinality(String),
input_tokens UInt32,
cache_read_tokens UInt32,
cache_write_tokens UInt32,
output_tokens UInt32,
tool_use_count UInt16,
cache_layer_hit LowCardinality(String), -- none|L1|L2|L3
latency_ms UInt32,
ttft_ms UInt32,
cost_usd Decimal64(8),
status_code UInt16,
error_class LowCardinality(String),
trace_id String,
parent_span_id String
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(ts)
ORDER BY (tenant_id, ts, logical_model)
TTL ts + INTERVAL 90 DAY DELETE;8.1. Materialized Views cho dashboard real-time
Truy vấn tổng hợp trên bảng raw mỗi lần render dashboard sẽ quá chậm. Dùng Materialized View với SummingMergeTree để roll-up theo phút/giờ:
CREATE MATERIALIZED VIEW llm_events_1m_mv
ENGINE = SummingMergeTree()
PARTITION BY toYYYYMM(ts_minute)
ORDER BY (tenant_id, ts_minute, logical_model, provider)
AS SELECT
toStartOfMinute(ts) AS ts_minute,
tenant_id,
logical_model,
provider,
count() AS req_count,
sum(input_tokens + output_tokens) AS total_tokens,
sum(cost_usd) AS total_cost,
avg(latency_ms) AS avg_latency,
quantileExactWeightedState(0.95)(latency_ms, 1) AS p95_state
FROM llm_events
GROUP BY ts_minute, tenant_id, logical_model, provider;Dashboard giờ chỉ cần query llm_events_1m_mv (~10–100x nhanh hơn). Phân vị p95 được merge từ p95_state với quantileExactWeightedMerge.
8.2. Tracing liên kết với agent framework
Gateway nên tôn trọng header traceparent (W3C Trace Context) từ caller. Mỗi request tạo một span llm.gateway kế thừa trace_id, với các thuộc tính chuẩn:
llm.logical_model = smart-reasoner
llm.physical_model = claude-opus-4-6
llm.provider = anthropic
llm.cache.layer = L2
llm.cache.hit = true
llm.usage.input = 12840
llm.usage.output = 512
llm.cost.usd = 0.0389
llm.fallback.used = falseSpan được đẩy sang OpenTelemetry collector, cuối cùng landing vào ClickHouse hoặc Langfuse. Khi một agent dùng Claude Code crash, developer có thể nhảy từ trace ID trên terminal thẳng vào dashboard Langfuse và xem đầy đủ 30 LLM call đã diễn ra — tính năng mà bài LLM Observability 2026 đã phân tích.
9. Bảo mật: API Keys, Tenant Isolation, PII Redaction
Là điểm tập trung duy nhất nắm API key của tất cả provider, gateway trở thành target ưu tiên số một của attacker. Ba yêu cầu tối thiểu:
9.1. API Key Vaulting và Rotation
- Key provider không bao giờ lưu trong env variable của pod. Dùng HashiCorp Vault, AWS Secrets Manager, hoặc SealedSecrets cho k8s — lấy ra khi khởi động và giữ trong bộ nhớ.
- Rotate tự động mỗi 30 ngày. Gateway hỗ trợ dual-key: giữ đồng thời key cũ và key mới trong cửa sổ 24h để zero-downtime rotation.
- Dùng key theo tenant khi quy mô cho phép — giúp Anthropic/OpenAI áp rate limit riêng thay vì dùng chung key của bạn.
9.2. Tenant Isolation nghiêm ngặt
Một trong những lỗi nguy hiểm nhất của gateway tự xây là cross-tenant data leakage qua cache. Hai request từ hai tenant khác nhau có cùng embedding có thể trả về kết quả của nhau nếu cache key không namespace đúng. Nguyên tắc:
- Cache key luôn bắt đầu bằng
tenant_idhoặc dùng Redis logical database riêng. - Embedding index trong Redis Vector dùng
PREFIXcố định theo tenant. - ClickHouse bảng raw cũng nên partition theo
tenant_idđể tránh query sai khách hàng. - Audit log mọi truy cập chéo tenant (admin query).
9.3. PII Redaction trước khi gửi provider
Khi quy định compliance yêu cầu (HIPAA, GDPR, Nghị định 13/2023/NĐ-CP ở Việt Nam), gateway phải redact các thực thể nhạy cảm trước khi request rời khỏi tổ chức. Pipeline điển hình:
flowchart LR
IN["Input prompt"] --> DET["NER Model
(Presidio / custom)"]
DET --> CLS{"Detected?"}
CLS --> |no| FWD["Forward as-is"]
CLS --> |yes| MASK["Mask with placeholder
[[EMAIL_1]], [[PHONE_1]]"]
MASK --> KEEP["Lưu map
trong request scope"]
KEEP --> FWD
FWD --> LLM["Provider"]
LLM --> RESTORE["Restore placeholder
sau khi trả về"]
RESTORE --> OUT["Output cho agent"]
style DET fill:#e94560,stroke:#fff,color:#fff
style MASK fill:#ff9800,stroke:#fff,color:#fff
style KEEP fill:#4CAF50,stroke:#fff,color:#fff
Pipeline PII redaction hai chiều giữ nguyên ý nghĩa prompt
Map placeholder chỉ tồn tại trong phạm vi request — không lưu ra Redis để tránh rò rỉ. Sau khi provider trả response, gateway thay placeholder lại bằng giá trị thật và trả về cho agent. Người dùng không nhận ra bất cứ sự thay đổi nào, nhưng provider chỉ nhìn thấy dữ liệu đã ẩn danh.
10. So sánh: LiteLLM, Portkey, Helicone, Kong AI vs Gateway tự xây
Bạn không cần lúc nào cũng tự xây. Dưới đây là bảng so sánh ngắn gọn dựa trên trải nghiệm production 2026:
| Giải pháp | Điểm mạnh | Điểm yếu | Phù hợp khi |
|---|---|---|---|
| LiteLLM | Hỗ trợ 100+ provider, unified API, cộng đồng lớn, fallback mature | Chạy Python, memory phình ở >2k RPS, cần tuning aggressive | Start-up và team vừa, throughput < 1k RPS |
| Portkey | Full AI control plane, guardrails, prompt versioning, UI đẹp | SaaS phụ thuộc, giá theo usage, khó tùy biến sâu | Team không muốn vận hành, cần dashboard ngay |
| Helicone AI Gateway | Rust, throughput cao, load-balancing sophisticated, observability tốt | Tùy biến policy phải sửa source, hệ sinh thái còn mới | Production có constraint performance, accept self-host Rust |
| Kong AI Gateway | Plugin cho Kong, tích hợp được với API management sẵn có | Cấu hình phức tạp, feature LLM chưa bằng chuyên dụng | Đã dùng Kong cho API chung, muốn thêm LLM thay vì deploy stack mới |
| OpenRouter | Zero-setup, gọi được >200 model, markup mỏng | SaaS, không isolation tenant, giới hạn ở layer hosted | Prototype nhanh, agent cá nhân, không cần compliance |
| Tự xây (Go/Rust) | Tối ưu hoàn toàn theo nhu cầu, tích hợp trực tiếp stack nội bộ | Tốn 2–4 tháng engineer, rủi ro bug subtle, ít feature đi kèm | Tổ chức lớn có team platform, cần feature đặc biệt không có sẵn |
Chiến lược hybrid đang thắng thế
Pattern phổ biến 2026: dùng LiteLLM làm data plane cho unified API (nhờ hỗ trợ provider nhiều nhất), bọc bên ngoài bằng một thin wrapper Go/Rust cho policy engine, và đẩy telemetry về Helicone hoặc Langfuse cho observability. Kết quả: operational overhead thấp, flexibility cao, total ownership tối đa 1 engineer.
11. Production Pattern với Claude Code và Claude Agent SDK
Claude Code và Claude Agent SDK là hai điểm nóng của traffic LLM trong nhiều tổ chức hiện nay. Khi đặt chúng sau một LLM Gateway, bạn mở khóa năm khả năng mà provider không cho trực tiếp:
11.1. Pattern 1: Gateway-aware base URL
Claude Code hỗ trợ biến môi trường ANTHROPIC_BASE_URL — gateway chỉ cần expose endpoint tương thích Anthropic Messages API là Claude Code tự đi qua. Cùng pattern với Agent SDK: truyền base_url khi khởi tạo Anthropic(client). Gateway có thể thêm x-tenant-id, x-budget-id vào header để phân luồng.
11.2. Pattern 2: Sub-agent Routing per Role
Claude Code cho phép định nghĩa sub-agents với model khác nhau. Gateway có thể dịch tên sub-agent → logical model → physical model, tùy theo role:
- planner →
smart-reasoner→ Claude Opus 4.6 - coder →
code-specialist→ Claude Sonnet 4.6 - classifier →
fast-classifier→ Claude Haiku 4.5 - batch-summarizer →
cheap-batch→ Llama 3.3 70B self-hosted
11.3. Pattern 3: Prompt Cache awareness
Gateway nên tránh re-order hay transform phần prefix của prompt Claude Code gửi — vì Anthropic hash prefix để khớp prompt cache. Nếu gateway vô tình thêm hoặc xóa một byte trong system prompt, toàn bộ cache hit biến mất. Quy tắc: pass-through bytes trong critical path; chỉ manipulate metadata và header.
11.4. Pattern 4: Per-session Budget
Gateway có thể cấp một session_token gắn với budget USD giới hạn. Claude Code truyền token này vào header. Khi session tiêu hết budget, gateway trả 402 và developer thấy thông báo rõ ràng. Bảo vệ khỏi "runaway agent" đốt 500 USD trong 10 phút.
11.5. Pattern 5: MCP Server Authentication Proxy
Gateway cũng có thể làm proxy cho MCP servers (đã phân tích trong MCP 2026), áp dụng cùng guardrails: rate limit theo tool, audit log, cost tracking cho MCP tool invocations. Điều này đặc biệt quan trọng khi agent được phép gọi các công cụ đắt tiền (vd gọi ClickHouse query tốn CPU, hoặc API bên ngoài tính phí).
12. Vận hành: capacity, bảo trì và checklist production
12.1. Capacity planning
Quy tắc ngón tay cái từ các production run thực tế:
- 1 core CPU data plane xử lý được ~500–1500 RPS (Go/Rust) hoặc ~100–300 RPS (Python asyncio).
- Redis cluster 3 shard xử lý >500k ops/s cho token bucket và cache; dùng replicas đọc cho semantic lookup.
- ClickHouse 3 node nuốt 100k event/s với buffer Kafka; giữ data 90 ngày TTL.
- Đặt data plane ở nhiều region nếu agent phân tán toàn cầu — giảm round trip tới provider gần nhất (Anthropic có endpoint US và EU).
12.2. Checklist trước khi go-live
| Hạng mục | Trạng thái yêu cầu |
|---|---|
| Canary deploy 5% traffic qua gateway | Bắt buộc |
| Feature flag để bypass gateway (emergency off-switch) | Bắt buộc |
| Rate limit test: simulate tenant overflow | Bắt buộc |
| Chaos test: kill upstream primary → verify failover | Bắt buộc |
| Audit log mọi admin action | Bắt buộc |
| Dashboard cost/latency/error p95 real-time | Bắt buộc |
| Budget alerts Slack/email khi >80% quota | Khuyến nghị |
| Shadow traffic tới model mới trước khi cutover | Khuyến nghị |
| Secret rotation tự động | Khuyến nghị |
| Playbook incident response có ghi "ai trực", "làm gì", "rollback" | Bắt buộc |
13. Xu hướng 2026+: Gateway như một "AI Control Plane"
Gateway thế hệ tiếp theo không dừng lại ở proxy. Ba hướng đang hình thành rõ rệt:
14. Kết luận
LLM Gateway không phải một "nice-to-have" nữa. Nếu bạn đang chạy bất kỳ agent nào ở quy mô production — dù chỉ với 10 developer đang dùng Claude Code — sớm hay muộn bạn sẽ gặp đủ cả bốn thách thức: chi phí vượt kiểm soát, rate limit sập, provider outage, và không trace được lỗi. Xây dựng một lớp gateway dựa trên Redis (rate limit + semantic cache) và ClickHouse (observability) không còn là công trình kỹ thuật xa vời mà là một sprint 2–4 tuần với kết quả đo đếm được ngay: giảm 30–60% chi phí, tăng SLA lên 99.95%+, và cho bạn một điểm duy nhất để vận hành toàn bộ stack AI.
Bước đầu tiên? Không cần viết Rust hay Go. Hãy bắt đầu bằng LiteLLM hoặc Helicone để gom traffic vào một chỗ, bật rate limit và logging ClickHouse. Sau vài tuần, bạn sẽ có đủ dữ liệu để quyết định phần nào xứng đáng tự build, phần nào nên mua. Gateway là chiếc cầu nối biến một tập agent rời rạc thành một hệ thống có thể vận hành dài hạn — và 2026 là năm bạn không thể bỏ qua nó nữa.
Nguồn tham khảo
- Top 5 LLM Gateways in 2026 — DEV Community
- Helicone: Top LLM Gateways Comparison
- Kong: AI Gateway Benchmark (Kong vs Portkey vs LiteLLM)
- Portkey: AI Gateway Buyer's Guide
- werun.dev: LLM API rate limits in production
- Redis Tutorials: Rate Limiting Patterns
- Markaicode: API Gateway Rate Limiting & Fallback Models
- Anthropic Docs: Prompt Caching
- Anthropic Docs: Claude Code Overview
- ClickHouse: SummingMergeTree
- Redis Docs: Vector Search (RediSearch)
- W3C: Trace Context Specification
Agent Memory Architecture - Kiến trúc Bộ nhớ Đa tầng cho AI Agents với Redis, Vector DB, ClickHouse và Knowledge Graph 2026
Event-Driven Multi-Agent Orchestration 2026 - Kiến trúc Kafka, Redis Streams, Temporal và ClickHouse cho hệ thống AI Agent Production
Disclaimer: The opinions expressed in this blog are solely my own and do not reflect the views or opinions of my employer or any affiliated organizations. The content provided is for informational and educational purposes only and should not be taken as professional advice. While I strive to provide accurate and up-to-date information, I make no warranties or guarantees about the completeness, reliability, or accuracy of the content. Readers are encouraged to verify the information and seek independent advice as needed. I disclaim any liability for decisions or actions taken based on the content of this blog.