AI API Gateway là gì? Sáu chặng của một yêu cầu và giới hạn của nó
AI API Gateway là gì? Sáu chặng của một yêu cầu
AI API Gateway là một dịch vụ nhận yêu cầu API ở định dạng chuẩn, phân giải yêu cầu đó tới một model cụ thể trên một nhà cung cấp upstream cụ thể, chuyển tiếp yêu cầu, rồi trả kết quả về đúng định dạng chuẩn đó. Phía client chỉ nói chuyện với gateway; khoá của nhà cung cấp, quyết định định tuyến và cách đặt tên model đều nằm ở phía gateway.
Định nghĩa này cố tình viết theo cơ chế, vì phần lớn nhầm lẫn về gateway đến từ việc trộn ba thứ khác nhau: chuyển đổi giao thức, quản lý khoá và định tuyến. Bài này đi qua từng chặng của một yêu cầu, rồi nói rõ relay thay đổi được gì và không thay đổi được gì.
Phạm vi được kiểm chứng trong bài
Endpoint và mã model trong bài tham chiếu tài liệu công khai và catalog trực tiếp của EXAIV (/docs/api/chat-completions, /models). Cổng mặc định của Ollama, llama.cpp và vLLM là giá trị mặc định trong tài liệu của các dự án đó và có thể đổi qua cấu hình. Việc một model có nhận một tham số cụ thể hay không phụ thuộc vào model và tuyến đường — ví dụ trong bài là cách bạn tự kiểm tra, không phải khẳng định năng lực của bất kỳ model nào.
Sáu chặng của một yêu cầu
Lấy một yêu cầu chat bình thường gửi tới https://exaiv.com/api/ai/v1/chat/completions. Nó không đi trong một bước, mà qua những chặng tách biệt được, và mỗi chặng có thể hỏng theo cách khác nhau.
Hai chặng trong đó giải thích gần như toàn bộ câu hỏi hỗ trợ. Chặng 3 giải thích vì sao một tên model dùng được ở nơi khác có thể trả lỗi không tìm thấy model ở đây: thứ quyết định là catalog ở phía này, không phải cái tên bạn nhớ từ nhà cung cấp khác. Chặng 4 là chặng liên quan tới bảo mật: khoá của bạn chỉ dùng để định danh bạn với gateway, và nhà cung cấp upstream không bao giờ thấy nó.
Gateway làm gì và không làm gì
| Gateway làm | Gateway không làm |
|---|---|
| Dùng một khoá và một giao thức cho nhiều model | Thay đổi kiến thức của model hay cách nó được huấn luyện |
| Giữ khoá upstream và luân chuyển chúng | Bảo đảm một mức độ trễ cụ thể cho khu vực của bạn |
| Phân giải tên model thành nhà cung cấp, chuyển hướng khi cấu hình cho phép | Biến một tham số không được hỗ trợ thành được hỗ trợ |
| Chuẩn hoá phản hồi và event streaming | Cache prompt của bạn (trừ khi tài liệu nói rõ có tính năng này) |
| Đo mức dùng theo khoá và theo model | Thay thế việc kiểm tra kết quả bằng chính code của bạn |
Ô cuối cùng của cột phải là thứ các nhóm hay quên. Gateway làm cho việc gọi đồng nhất, không làm cho kết quả của model đúng. Phân tích, kiểm tra theo schema và chính sách thử lại vẫn là việc của code bạn.
Vì sao relay tồn tại
Nếu gateway chỉ là thêm một chặng giữa, sao không gọi trực tiếp nhà cung cấp? Có ba lý do thực tế lặp lại nhiều lần, và không lý do nào liên quan tới việc che giấu điều gì.
Một khoá cho nhiều nhà cung cấp. Một sản phẩm dùng model nhanh để phân loại và model lớn hơn để suy luận sẽ cần hai tài khoản, hai quan hệ thanh toán và hai bộ khoá trong môi trường chạy thật. Với relay, ứng dụng giữ một khoá.
Một hợp đồng ổn định trước catalog đang thay đổi. Nhà cung cấp đổi tên model, phát hành snapshot có ngày và ngừng các phiên bản cũ. Nếu mã model nằm ở một chỗ phía gateway, ứng dụng có thể hấp thụ một phần biến động bằng cách sửa cấu hình thay vì sửa code.
Một đường ra cố định cho client trong khu vực. Với lập trình viên ở Đông Nam Á hoặc EU, đường mạng tới một nhà cung cấp là một biến số vận hành: có thể nhanh trên một nhà mạng và chậm trên nhà mạng khác. Relay cho một endpoint có hành vi đã biết, thay vì nhiều endpoint của nhà cung cấp với hành vi chưa biết. Nó không xoá độ trễ; nó biến endpoint mà bạn gắn code vào thành một hằng số.
Điểm nhiều người bỏ qua: giao thức giống nhau ở cả môi trường nội bộ
Lý do mạnh nhất để học dạng yêu cầu tương thích OpenAI không phải vì relay dùng nó, mà vì gần như mọi server suy luận nội bộ nghiêm túc cũng dùng nó. Ollama, server của llama.cpp và vLLM đều cung cấp endpoint tương thích OpenAI, nên cùng một thư viện client, cùng một mảng messages và cùng một bộ phân tích streaming hoạt động với cả relay lẫn model chạy trên laptop.
Điều đó nghĩa là trong một kiến trúc hợp lý, vị trí của model chỉ nên là một biến duy nhất:
import os
from openai import OpenAI
# Hai đích, một đoạn code: chỉ đổi base_url và model
TARGETS = {
"relay": {
"base_url": "https://exaiv.com/api/ai/v1",
"api_key": os.environ["EXAIV_API_KEY"],
"model": "deepseek-v4.1-flash",
},
"local": {
"base_url": "http://localhost:11434/v1", # endpoint mac dinh cua Ollama
"api_key": "ollama", # server noi bo thuong khong kiem tra khoa
"model": "qwen3.8-flash",
},
}
def ask(target: str, prompt: str) -> str:
cfg = TARGETS[target]
client = OpenAI(base_url=cfg["base_url"], api_key=cfg["api_key"])
r = client.chat.completions.create(
model=cfg["model"],
messages=[{"role": "user", "content": prompt}],
temperature=0,
)
return r.choices[0].message.content
print(ask("relay", "Tom tat changelog nay thanh ba y."))
Cùng phép kiểm tra đó bằng curl, hữu ích để xác nhận endpoint trước khi đưa SDK vào:
curl -s https://exaiv.com/api/ai/v1/chat/completions \\
-H "Authorization: Bearer $EXAIV_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"model": "kimi-k3",
"messages": [{"role": "user", "content": "Chi tra loi mot tu: ok"}],
"temperature": 0
}'
Trả về 401 nghĩa là thiếu hoặc sai khoá; trả về 404 có nêu tên model nghĩa là mã đó không có trong catalog. Hai lỗi này chiếm phần lớn thất bại ở lần tích hợp đầu, và phân biệt được mà không cần mở tài liệu.
Khi nào relay là lựa chọn sai
Gateway là một quyết định kiến trúc có đánh đổi, và có trường hợp gọi trực tiếp nhà cung cấp mới đúng:
- Yêu cầu về nơi lưu trữ dữ liệu có nêu tên bên xử lý. Nếu một quy định chỉ rõ ai được xử lý dữ liệu, relay là thêm một bên trong phân tích đó. Hãy đọc yêu cầu trước khi cho rằng nó tương thích.
- Một nhà cung cấp duy nhất và ngân sách độ trễ tính bằng mili giây. Mỗi chặng thêm là một chỗ thời gian bị tiêu. Nếu khối lượng công việc nhạy cảm với độ trễ và chỉ dùng một nhà cung cấp, gọi trực tiếp dễ suy luận hơn.
- Môi trường tách biệt hoàn toàn khỏi mạng. Nếu mạng không ra được internet, endpoint duy nhất khả dụng là cái chạy cạnh model. Đây đúng là chỗ server tương thích OpenAI nội bộ là toàn bộ câu trả lời.
Không điều nào khiến relay trở nên tồi; chúng khiến đây thành câu hỏi phù hợp hay không, thay vì một mặc định.
Đánh giá một relay trong mười phút
Tài liệu mô tả ý định; năm phép thử sau mô tả hành vi. Hãy chạy chúng trước khi gắn codebase vào một endpoint.
Một, gửi một yêu cầu nhỏ nhất và lưu lại phản hồi thô. So sánh tên các trường nhận được với những trường code bạn đọc. Yêu cầu đầu tiên trả 200 nhưng thiếu một trường bạn phụ thuộc là vấn đề thiết kế, không phải lỗi để sửa sau.
Hai, gửi một mã model sai có chủ đích. Đọc nội dung lỗi. Endpoint nêu rõ model không tồn tại dễ vận hành hơn endpoint trả về thất bại chung chung, vì logic thử lại của bạn phân biệt được lỗi cấu hình với sự cố tạm thời.
Ba, giữ một yêu cầu streaming mở lâu hơn mọi ngưỡng timeout của proxy trên đường đi. Proxy doanh nghiệp và một số CDN cắt kết nối rảnh; một luồng đứng sau sáu mươi giây có thể chạy tốt trên laptop và hỏng trong văn phòng. Phép thử này cũng cho biết client có cần đặt timeout đọc rõ ràng hay không.
Bốn, cố tình đẩy yêu cầu vượt giới hạn ngữ cảnh. Việc từ chối nên xuất hiện dưới dạng lỗi rõ ràng trước khi bất kỳ token nào bị tính phí, không phải biến thành một câu trả lời bị cắt mà bạn chỉ phát hiện ở môi trường chạy thật.
Năm, gọi cùng model hai lần với cùng đầu vào và temperature bằng không. Kết quả sẽ không giống nhau từng byte, và điều đó là bình thường. Điều bạn kiểm tra là cấu trúc phản hồi có ổn định không: cùng khoá, cùng kiểu, cùng cách lồng nhau. Cấu trúc trôi đi là kiểu hỏng âm thầm phá code phía sau.
Giữ lại năm phản hồi đó
Lưu phần thân thô của năm phép thử này vào repository, cạnh code tích hợp. Khi có gì thay đổi sau vài tháng, bạn có bản so sánh trước và sau, thay vì ký ức về việc nó từng như thế nào.
Gỡ lỗi theo từng chặng
| Triệu chứng | Chặng có thể hỏng | Kiểm tra gì trước |
|---|---|---|
| 401 ở mọi yêu cầu | Chặng 2 | Khoá có trong header không, có khoảng trắng thừa không, khoá hết hạn chưa |
| 404 có nêu tên model | Chặng 3 | Mã đó có trong catalog trực tiếp phía gateway không |
| 429 khi có tải | Chặng 2 | Mức đồng thời của bạn so với giới hạn tốc độ; lùi lại thay vì thử lại ngay |
| Luồng bắt đầu rồi đứng | Chặng 5 | Timeout đọc phía client và việc đệm của proxy giữa bạn và gateway |
| Một mạng chạy được, mạng khác thì không | Chặng 4/5 | Proxy hoặc tường lửa doanh nghiệp có can thiệp vào kết nối streaming không |
| Có phản hồi nhưng thiếu trường bạn đọc | Chặng 5/6 | Tham số được nhận nhưng model được định tuyến tới không hỗ trợ; kiểm tra bằng yêu cầu nhỏ nhất |
Quy luật cần nhớ là: mã trạng thái cho biết chặng nào đã hỏng. 401 không bao giờ là vấn đề model, và không tìm thấy model không bao giờ là vấn đề xác thực. Khi thôi coi gateway là một hộp đen, việc gỡ lỗi nhanh hơn nhiều.
Danh sách kiểm tra trước khi dùng
- Tôi biết mã model phải lấy từ catalog nào, và đọc nó ở đâu
- Tôi biết phần nào của yêu cầu do ứng dụng của tôi kiểm tra, phần nào do gateway chuẩn hoá
- Tôi có phương án dự phòng khi một mã model biến mất khỏi catalog
- Tôi đã thử streaming qua chính mạng của mình, không chỉ trên laptop có mạng sạch
- Tôi đã quyết định khối lượng công việc này cần relay, gọi trực tiếp hay server nội bộ
- Tôi đã xác nhận cùng một code client chạy được với cả relay lẫn endpoint nội bộ