Tích hợp OpenAI SDK trong 5 phút
Đọc 4 phút
Gateway nói đúng wire format của OpenAI — cùng endpoint, cùng cấu trúc request, cùng khung SSE. Code của bạn đang chạy với api.openai.com thì chạy được với CLF AI Gateway sau hai thay đổi: base URL và key. Dưới đây là cấu hình chạy được cho hai SDK chính thức, LangChain và Vercel AI SDK, kèm streaming và những lỗi thực tế bạn sẽ gặp.
Chuẩn bị
- Tạo key tại app.clfaigateway.dev. Key có prefix
sk-gw-và chỉ hiện đúng một lần — lưu ngay khi thấy. - Base URL:
https://api.clfaigateway.dev/v1 - ID model:
deepseek-v4-flashvàdeepseek-v4-pro(context 1M),kimi-k2.6,kimi-k2.7-code,glm-5.2(262K) vàglm-4.7-flash(131K) — danh sách đầy đủ kèm giá ở /models.
Python — SDK openai chính thức
Chạy với openai ≥ 1.0 (pip install openai):
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.clfaigateway.dev/v1",
api_key=os.environ["CLF_API_KEY"], # sk-gw-...
)
resp = client.chat.completions.create(
model="kimi-k2.6",
messages=[{"role": "user", "content": "Say hello in five words."}],
max_tokens=256,
)
print(resp.choices[0].message.content)max_tokens không bắt buộc nhưng nên thành thói quen: nó kiêm luôn vai trò trần chi tiêu cứng cho mỗi request.
Node / TypeScript — SDK openai chính thức
npm install openai:
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://api.clfaigateway.dev/v1',
apiKey: process.env.CLF_API_KEY, // sk-gw-...
});
const resp = await client.chat.completions.create({
model: 'kimi-k2.6',
messages: [{ role: 'user', content: 'Say hello in five words.' }],
max_tokens: 256,
});
console.log(resp.choices[0].message.content);Streaming
Streaming là SSE tiêu chuẩn qua SDK. Ba điểm riêng của gateway cần biết: truyền stream_options: {"include_usage": true} để chunk cuối mang số token chính thức (đúng số dùng để tính tiền); bắt finish_reason: "error" — thượng nguồn đứt giữa stream thì lỗi đi trong thân stream, vì HTTP status đã gửi 200 từ trước; và Kimi/GLM là model reasoning nên reasoning_content stream về trước phần content nhìn thấy được.
stream = client.chat.completions.create(
model="glm-5.2",
messages=[{"role": "user", "content": "Explain SSE in one sentence."}],
stream=True,
stream_options={"include_usage": True},
)
usage = None
for chunk in stream:
if chunk.usage is not None:
usage = chunk.usage # chunk cuối = số token bạn bị tính tiền
for choice in chunk.choices:
thinking = getattr(choice.delta, "reasoning_content", None)
if thinking:
print(thinking, end="")
if choice.delta.content:
print(choice.delta.content, end="")
if choice.finish_reason == "error":
raise RuntimeError("stream đứt giữa chừng; chỉ token đã nhận mới bị tính")
print(usage)LangChain
langchain-openai nhận thẳng base URL tùy chỉnh (pip install langchain-openai):
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="glm-4.7-flash",
base_url="https://api.clfaigateway.dev/v1",
api_key="sk-gw-...",
)
print(llm.invoke("Summarize SSE in one sentence.").content)Từ đây ChatOpenAI hoạt động bình thường trong chain, agent và .stream() — với LangChain, gateway chỉ là thêm một endpoint hình dạng OpenAI.
Vercel AI SDK
Dùng provider OpenAI-compatible (npm install ai @ai-sdk/openai-compatible):
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
import { streamText } from 'ai';
const clf = createOpenAICompatible({
name: 'clf-ai-gateway',
baseURL: 'https://api.clfaigateway.dev/v1',
apiKey: process.env.CLF_API_KEY,
});
const result = streamText({
model: clf('kimi-k2.6'),
prompt: 'Write a two-line haiku about prepaid credits.',
});
for await (const text of result.textStream) {
process.stdout.write(text);
}generateText, streamText và bộ hook UI useChat chạy nguyên vẹn không đổi gì.
Hai lỗi thực tế bạn sẽ gặp
401 invalid_api_key
Key thiếu, gõ sai, hoặc đã bị revoke. Kiểm tra header Authorization: Bearer sk-gw-... và chắc rằng bạn đã copy trọn key lúc nó hiện ra. SDK báo lỗi này bằng class authentication error tiêu chuẩn của nó.
402 insufficient_credits
Số dư trả trước không đủ cho khoản tạm giữ ước lượng của request. Body nói rõ bạn thiếu bao nhiêu:
{
"error": {
"type": "insufficient_credits",
"code": "insufficient_credits",
"message": "Insufficient credits. Available: $0.0041. This request requires an estimated hold of $0.0269. Top up at https://app.clfaigateway.dev/billing/topup",
"metadata": {
"available_nano": 4100000,
"required_estimate_nano": 26927600,
"topup_url": "https://app.clfaigateway.dev/billing/topup"
}
}
}Nạp thêm (VietQR tự xác nhận sau khoảng 15 giây; thẻ quốc tế cũng dùng được) rồi gọi lại — không cần code gì thêm ngoài việc hiện message cho người dùng. Cũng nên biết: 404 model_not_found nghĩa là ID model không nằm trong danh sách model đang mở (xem trang models), còn 429 rpm_exceeded đi kèm header retry-after mà các SDK chính thức đã tự tôn trọng bằng backoff.
Mấy mặc định giúp tiết kiệm tiền
- Đặt
max_tokenscho mọi lời gọi production — ngắt kết nối giữa stream không hủy được token đã sinh. - Để phần ổn định (system prompt, tools, ví dụ few-shot) lên đầu hội thoại: prefix lặp lại tính theo giá cached input, rẻ hơn khoảng 6 lần trên các model Kimi.
- Lời gọi lặp lại tất định thì thêm
"cache": {"mode": "on"}cùngtemperature: 0— trúng trọn vẹn chỉ tính 10% giá thường. - Đọc
usagetrên mọi response. Phần toán đằng sau nó nằm ở Billing theo token — bạn tự kiểm lại được từng con số.