Mục lục
- Mở đầu Module 5
- OpenAI API — vị trí trong stack
- Setup account và API key
- Cài SDK
- First call
- Model lineup 2025-2026
- Key parameters
- Response object
- Authentication
- Error handling
- Rate limit và tier
- Retry strategy với tenacity
- Async client
- Batch API
- Files API
- Assistants API
- Vision — multimodal
- Audio — Whisper và TTS
- Image generation
- Streaming preview
- Usage tracking
- Compatible libraries
- Security best practices
- Cost — tham khảo
- Common issues
- Code Python tổng hợp
- Bài tập
Mở đầu Module 5
Bốn module đầu xây dựng nền (toán, ML, deep learning, prompt engineering). Module 5 chuyển sang phần hands-on với API thật: gọi LLM commercial từ code, xử lý lỗi, retry, async, tracking chi phí, multimodal. Đây là phần để biến kiến thức thành app chạy được.
Roadmap Module 5 (Bài 31-40):
- Bài 31 — OpenAI API (bài này).
- Bài 32 — Anthropic Claude API.
- Bài 33 — Streaming response.
- Bài 34-35 — Token counting, context management.
- Bài 36-37 — Chatbot end-to-end, conversation history.
- Bài 38-39 — LangChain, LlamaIndex cơ bản.
- Bài 40 — Vercel AI SDK (frontend integration).
Bài 31 chọn OpenAI làm điểm xuất phát vì đây là provider phổ biến nhất, SDK ổn định, docs đầy đủ, và hầu hết library wrapper (LangChain, LlamaIndex, LiteLLM) đều mặc định ưu tiên OpenAI schema. Khi đã quen, chuyển sang Anthropic ở bài 32 sẽ nhanh.
OpenAI API — vị trí trong stack
OpenAI cung cấp ba kiểu endpoint chính:
- Chat Completions (
/v1/chat/completions): endpoint chính cho LLM. Stateless, mỗi call truyền fullmessages. - Responses API (
/v1/responses, ra mắt 2024): superset của Chat Completions, hỗ trợ stateful conversation, built-in tools, multi-turn ngầm. Mục đích thay thế dần Chat Completions cho các app phức tạp. - Specialized: embeddings, images, audio (transcriptions / speech), moderation, files, batches, assistants, fine-tuning.
Bài này tập trung Chat Completions (vẫn là API phổ thông nhất), kèm short tour các endpoint đặc biệt. Responses API có structure tương tự, code chuyển đổi nhẹ.
Setup account và API key
- Truy cập
platform.openai.com. Đăng ký bằng email hoặc Google. - Vào Billing → Payment methods, add thẻ và nạp credit (pay-as-you-go). Tier 1 mặc định cần $5 trở lên để bắt đầu được charge.
- Vào API keys → Create new secret key. Đặt tên rõ ràng (vd
dev-laptop-canh) để revoke đúng cái khi cần. Copy key — chỉ hiện 1 lần. - Lưu key vào biến môi trường:
Trên zsh/bash, thêm vàoexport OPENAI_API_KEY="sk-..."~/.zshrchoặc~/.bashrcđể giữ giữa các session. Trên Windows, dùngsetx OPENAI_API_KEY "sk-..."hoặc Git Bash. - Kiểm tra:
echo $OPENAI_API_KEYphải in ra giá trị (không phải rỗng).
Quy tắc: không commit key vào git. Dùng .env (kèm .gitignore) hoặc secret manager (1Password CLI, AWS Secrets Manager, Doppler). Bài 23 phần security đã đề cập nguyên tắc; ở đây nhắc lại vì là dòng code đầu tiên có thể leak credential.
Cài SDK
pip install openai
SDK Python chính thức tên openai (v1.x trở lên — major rewrite từ v0.x, không backward compatible). Tại tháng 5/2026 version mới nhất quanh 1.5x.
Kiểm tra:
import openai
print(openai.__version__)
Nếu code mẫu cũ dùng openai.ChatCompletion.create(...) (v0.x), đó là API đã deprecate. Phiên bản mới dùng client object như ở bước 5.
First call
from openai import OpenAI
client = OpenAI() # tự đọc OPENAI_API_KEY từ env
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "Xin chào"},
],
)
print(response.choices[0].message.content)
Bốn dòng chính:
OpenAI(): tạo client. Có thể truyềnapi_key=...,organization=...,base_url=...,timeout=....client.chat.completions.create(...): gọi endpoint chat completions.model+messageslà tham số bắt buộc.response.choices[0].message.content: text output.
Chạy thành công nghĩa là pipeline đã thông: env var đúng, network OK, credit còn, model accessible.
Model lineup 2025-2026
Model Loại Context Use case
─────────────────────────────────────────────────────────────────────────
GPT-5 Flagship LLM 256K Task khó, reasoning
GPT-4.1 LLM 1M Long context, code review
GPT-4o Multimodal 128K Text + image, default chat
GPT-4o-mini Multimodal nhỏ 128K Default rẻ, latency thấp
o1, o3, o5 Reasoning 128K-200K Math, multi-step logic
text-embedding-3-small Embedding 8K input RAG, similarity
text-embedding-3-large Embedding 8K input RAG chất lượng cao
whisper-1 ASR N/A Audio → text
gpt-4o-transcribe ASR mới N/A Audio → text (chính xác cao)
tts-1, tts-1-hd TTS N/A Text → audio
dall-e-3 Image gen N/A Image từ prompt text
gpt-image-1 Image gen mới N/A Edit + gen, follow prompt tốt
Quy tắc chọn model nhanh:
- Default production:
gpt-4o-mini(rẻ, đủ cho 80% use case). - Cần chất lượng cao:
gpt-4ohoặcgpt-5. - Long doc (1M token):
gpt-4.1. - Math / reasoning phức tạp:
o3hoặco5. - RAG vector:
text-embedding-3-smallcho cost-effective,largenếu retrieval lệch.
Tên model có thể đổi (rename, deprecate). Luôn check platform.openai.com/docs/models trước khi pin version cho production.
Key parameters
Tham số thường gặp ở chat.completions.create (chi tiết sampling đã đi ở bài 30):
model— tên model.messages— list{"role": "...", "content": "..."}.temperature,top_p,max_tokens/max_completion_tokens— sampling (bài 30).seed— reproducibility (bài 30).stop— stop sequence (bài 30).response_format— JSON mode hoặc Structured Outputs (bài 29).tools+tool_choice— function calling (sẽ chi tiết ở bài 42+).n— số response (bài 30).stream— streaming (bài 33).user— định danh end-user (để OpenAI track abuse).logprobs,top_logprobs— trả thêm log-probability của các token được sinh.
Tham số mới cho reasoning model (o1, o3): reasoning_effort ("low", "medium", "high") điều khiển độ sâu suy luận, ảnh hưởng cả cost lẫn latency.
Response object
Response là Pydantic model. Field hay dùng:
r = client.chat.completions.create(...)
r.id # "chatcmpl-..."
r.model # "gpt-4o-mini-2024-07-18"
r.system_fingerprint # "fp_..." (bài 30)
r.choices[0].message.content # text output
r.choices[0].message.role # "assistant"
r.choices[0].finish_reason # "stop" | "length" | "content_filter" | "tool_calls"
r.choices[0].index # 0
r.usage.prompt_tokens # số token input
r.usage.completion_tokens # số token output
r.usage.total_tokens # tổng
finish_reason nên check trong code production:
"stop"— model kết thúc bình thường (gặp EOS hoặc stop sequence)."length"— đạtmax_tokens, response có thể bị cắt. Cần tăngmax_tokenshoặc chia nhỏ."content_filter"— OpenAI moderation chặn. Cần kiểm tra prompt."tool_calls"— model muốn gọi tool (function calling).
Authentication
Ba cách phổ biến:
# 1. Env var (khuyến nghị)
from openai import OpenAI
client = OpenAI() # đọc OPENAI_API_KEY
# 2. Truyền trực tiếp (chỉ khi đọc từ secret manager)
client = OpenAI(api_key=secret_manager.get("OPENAI_KEY"))
# 3. File .env + python-dotenv
from dotenv import load_dotenv
load_dotenv() # nạp .env vào os.environ
client = OpenAI()
Không hardcode key trong source code. Mỗi key leak là một trong các tình huống:
- Commit nhầm vào git public → key bị scan bot crawl trong vài phút.
- Paste lên Stack Overflow / chat hỗ trợ.
- Push lên image Docker public.
- Log lỗi trên dashboard chứa header Authorization.
OpenAI tự scan public GitHub và revoke key bị leak — nhưng phụ thuộc, đừng dựa. Khi nghi ngờ leak, vào API keys → revoke ngay, tạo key mới.
Error handling
SDK expose một cây exception rõ ràng (tất cả kế thừa OpenAIError):
from openai import (
OpenAI,
OpenAIError,
RateLimitError, # 429
APITimeoutError, # request timeout
APIConnectionError, # network
AuthenticationError, # 401, key sai
PermissionDeniedError, # 403
NotFoundError, # 404, model sai
BadRequestError, # 400
InternalServerError, # 500, 503
)
client = OpenAI(timeout=30)
try:
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Xin chào"}],
)
except RateLimitError as e:
print("Rate limited, retry later", e)
except APITimeoutError:
print("Timeout — request quá lâu")
except AuthenticationError:
print("Key sai hoặc đã revoke")
except BadRequestError as e:
print("Request không hợp lệ:", e)
except OpenAIError as e:
print(f"Lỗi khác từ OpenAI: {e}")
Quy tắc: không catch Exception chung chung khi gọi LLM. Phân biệt được loại lỗi mới quyết định được hành vi (retry, fail fast, fallback model, báo user).
Rate limit và tier
OpenAI áp rate limit theo nhiều chiều:
- RPM — request per minute.
- TPM — token per minute (cả input + output).
- RPD — request per day (chỉ áp với một vài model rẻ).
Tier Yêu cầu (lifetime spend) GPT-4o-mini GPT-4o
──────────────────────────────────────────────────────────────────
Free $0 3 RPM, 40K TPM N/A
Tier 1 $5+ 500 RPM, 200K TPM 500 RPM, 30K TPM
Tier 2 $50+ và 7 ngày 5K RPM, 2M TPM 5K RPM, 450K TPM
Tier 3 $100+ và 7 ngày 5K RPM, 4M TPM 5K RPM, 800K TPM
Tier 4 $250+ và 14 ngày 10K RPM, 10M TPM 10K RPM, 2M TPM
Tier 5 $1000+ và 30 ngày 10K RPM, 30M TPM 10K RPM, 5M TPM
Số chính xác xem ở platform.openai.com/account/limits — thay đổi theo model và policy. Tier tăng tự động khi đạt ngưỡng spend + thời gian.
Khi vượt limit, response trả về 429 Too Many Requests; SDK raise RateLimitError. Header Retry-After (giây) cho biết nên đợi bao lâu. Xử lý ở bước 12.
Retry strategy với tenacity
SDK openai đã có retry built-in (max_retries=2 mặc định, exponential backoff). Đặt cao hơn khi cần:
client = OpenAI(max_retries=5)
Tuy nhiên với production workflow phức tạp (gọi lồng, log custom), tenacity linh hoạt hơn:
pip install tenacity
from openai import OpenAI, RateLimitError, APITimeoutError, APIConnectionError
from tenacity import (
retry,
stop_after_attempt,
wait_exponential,
retry_if_exception_type,
)
client = OpenAI()
@retry(
stop=stop_after_attempt(5),
wait=wait_exponential(multiplier=1, min=1, max=30),
retry=retry_if_exception_type(
(RateLimitError, APITimeoutError, APIConnectionError)
),
)
def call_llm(prompt: str) -> str:
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
)
return r.choices[0].message.content
print(call_llm("Tóm tắt khái niệm rate limit trong 2 câu."))
Lưu ý:
- Chỉ retry lỗi transient: rate limit, timeout, connection, 5xx. Không retry
AuthenticationError,BadRequestError— retry vô ích. - Backoff exponential tránh dồn request làm rate limit nặng hơn.
- Đặt trần (
stop_after_attempt) để không retry vô hạn.
Async client
Khi cần gọi nhiều prompt song song (eval batch, multi-user web server), dùng AsyncOpenAI:
import asyncio
from openai import AsyncOpenAI
client = AsyncOpenAI()
async def ask(prompt: str) -> str:
r = await client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
)
return r.choices[0].message.content
async def main():
prompts = [
"Định nghĩa RAG trong 1 câu.",
"Định nghĩa fine-tuning trong 1 câu.",
"Định nghĩa embedding trong 1 câu.",
]
results = await asyncio.gather(*(ask(p) for p in prompts))
for r in results:
print(r)
asyncio.run(main())
Lợi ích: 3 prompt chạy song song, latency ≈ 1 call thay vì 3. Quan trọng khi build web server với FastAPI / aiohttp.
Cảnh báo: số concurrent task vẫn bị chặn bởi rate limit. Với asyncio.gather hàng nghìn task, nên dùng asyncio.Semaphore để giới hạn concurrency hoặc đẩy sang Batch API (bước 14).
Batch API
Batch API dành cho workload không cần real-time: upload file JSONL chứa N request, OpenAI xử lý offline, trả kết quả trong vòng 24 giờ.
- Discount 50% so với real-time API.
- Không tính vào rate limit thường, có hạn ngạch riêng (queue token).
- Latency: thường vài giờ, SLA tối đa 24h.
- Use case: chấm điểm dataset lớn, gắn nhãn synthetic data, refactor / dịch văn bản hàng loạt.
from openai import OpenAI
client = OpenAI()
# 1. Upload file JSONL (mỗi dòng = 1 request)
file = client.files.create(
file=open("requests.jsonl", "rb"),
purpose="batch",
)
# 2. Tạo batch job
batch = client.batches.create(
input_file_id=file.id,
endpoint="/v1/chat/completions",
completion_window="24h",
)
print(batch.id, batch.status) # "validating" -> "in_progress" -> "completed"
Sau khi status == "completed", download batch.output_file_id qua client.files.content(...). Mỗi line là JSON chứa response cho 1 request.
Files API
Files API cho upload file lên storage OpenAI để các endpoint khác dùng (Batch, Assistants, fine-tuning).
file = client.files.create(
file=open("data.jsonl", "rb"),
purpose="batch", # "fine-tune", "assistants", "vision", ...
)
# liệt kê
for f in client.files.list().data:
print(f.id, f.filename, f.purpose, f.bytes)
# xoá khi không cần
client.files.delete(file.id)
Lưu ý: file được giữ trên server OpenAI, tính phí storage rất nhỏ nhưng nên dọn định kỳ. Mỗi purpose có giới hạn dung lượng và format riêng (vd batch chỉ chấp nhận JSONL hợp lệ schema chat.completions).
Assistants API
Assistants API thêm lớp stateful trên Chat Completions:
- Threads — conversation persistent, không cần truyền lại history mỗi call.
- Built-in tools: code interpreter (Python sandbox), file search (RAG vector store mặc định), function calling.
- Use case: chatbot có context dài, agent đơn giản chạy code và đọc PDF, không muốn tự cài infra.
assistant = client.beta.assistants.create(
name="Math tutor",
model="gpt-4o-mini",
instructions="Bạn là gia sư toán, giải bước rõ ràng.",
tools=[{"type": "code_interpreter"}],
)
thread = client.beta.threads.create()
client.beta.threads.messages.create(
thread_id=thread.id, role="user",
content="Giải x^2 - 5x + 6 = 0.",
)
run = client.beta.threads.runs.create_and_poll(
thread_id=thread.id, assistant_id=assistant.id,
)
msgs = client.beta.threads.messages.list(thread_id=thread.id)
print(msgs.data[0].content[0].text.value)
Trade-off: state server-side tiện cho prototype nhưng khó migrate (lock-in nhẹ với OpenAI). Anthropic không có endpoint tương đương — phải tự quản state khi chuyển provider. OpenAI đang dần định hướng người dùng sang Responses API; Assistants API tồn tại trong giai đoạn chuyển tiếp.
Vision — multimodal
GPT-4o, GPT-4o-mini, GPT-5 nhận input image cùng text:
r = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Trong ảnh có gì?"},
{"type": "image_url",
"image_url": {"url": "https://example.com/cat.jpg"}},
],
}],
)
print(r.choices[0].message.content)
Image truyền theo 2 cách:
"url": "https://..."— URL public."url": "data:image/png;base64,..."— base64 inline. Dùng khi ảnh trên máy local.
import base64
with open("cat.jpg", "rb") as f:
b64 = base64.b64encode(f.read()).decode()
data_url = f"data:image/jpeg;base64,{b64}"
Use case: OCR, mô tả ảnh, kiểm tra layout UI, đọc biểu đồ, phân tích chart. Cost tính theo "tile" 512×512 pixel — ảnh lớn tốn nhiều token, có thể resize trước.
Audio — Whisper và TTS
Speech-to-Text (Whisper):
audio = client.audio.transcriptions.create(
model="whisper-1",
file=open("meeting.mp3", "rb"),
language="vi", # tuỳ chọn, hint cho model
)
print(audio.text)
Format hỗ trợ: mp3, mp4, mpeg, mpga, m4a, wav, webm. Giới hạn 25MB / file — file lớn cần chia trước (vd dùng pydub cắt theo phút). Có thể trả timestamp với response_format="verbose_json", timestamp_granularities=["segment", "word"].
Text-to-Speech (TTS):
speech = client.audio.speech.create(
model="tts-1", # hoặc "tts-1-hd"
voice="alloy", # alloy, echo, fable, onyx, nova, shimmer
input="Xin chào, đây là bài 31.",
)
speech.stream_to_file("hello.mp3")
tts-1 nhanh; tts-1-hd chất lượng cao hơn, latency cao hơn. Có thể chỉnh speed (0.25-4.0).
Image generation
image = client.images.generate(
model="dall-e-3",
prompt="Một con mèo đeo mũ phi hành gia, phong cách minh hoạ phẳng.",
size="1024x1024", # 1024x1024, 1024x1792, 1792x1024
quality="standard", # "standard" | "hd"
n=1, # DALL-E 3 chỉ chấp nhận n=1
)
print(image.data[0].url) # URL ảnh (hết hạn sau ~1 giờ)
Model image gen hiện có:
- DALL-E 3 — phổ thông, prompt tiếng tự nhiên.
- GPT-Image-1 (2025) — model mới, follow prompt chính xác hơn DALL-E 3, hỗ trợ edit (inpainting), input image làm reference.
Lưu ý: URL trả về có TTL (~1 giờ); muốn lưu lâu, download ngay sang storage riêng. Ngoài ra DALL-E 3 sẽ "viết lại" prompt cho an toàn — prompt thực tế model dùng nằm ở image.data[0].revised_prompt.
Streaming preview
Streaming cho phép in token ra ngay khi model sinh, không đợi hết. UX gần với ChatGPT.
stream = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user",
"content": "Liệt kê 5 bước học AI engineer."}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)
print()
Mỗi chunk là ChatCompletionChunk; delta.content là phần text mới. Chunk cuối có finish_reason.
Bài 33 sẽ đi sâu: cách parse Server-Sent Events, tracking token usage khi stream (cần stream_options={"include_usage": True}), cancel mid-stream, kết hợp với function calling.
Usage tracking
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Xin chào"}],
)
print(r.usage.prompt_tokens, r.usage.completion_tokens, r.usage.total_tokens)
Log usage mỗi call để:
- Tính cost real-time, so với budget theo ngày / theo user.
- Phát hiện prompt phình to (vd có lúc accidentally truyền cả raw HTML).
- Phân tích "cost per task" cho từng pipeline.
Pattern phổ biến: wrap call trong helper, ghi (model, prompt_tokens, completion_tokens, timestamp, user_id) ra database hoặc OTEL trace. Khi cost vượt ngưỡng, alert ngay.
Compatible libraries
Vì OpenAI API schema phổ biến nhất, nhiều library wrap quanh nó:
- LiteLLM — unified client cho 100+ provider (OpenAI, Anthropic, Gemini, Mistral, local Ollama). Giữ schema OpenAI, đổi
modellà đổi provider. Tốt cho multi-provider, A/B test, fallback. - OpenRouter — proxy service host hàng trăm model. Endpoint compatible OpenAI, chỉ đổi
base_urlvà key. Có model open-weight, cost rẻ hơn cho một số task. - LangChain — framework xây pipeline / chain / agent. Có integration sâu (memory, retrievers, tools). Bài 38 sẽ chi tiết.
- Instructor — bài 29 đã đề cập, dùng Pydantic ép schema cho output.
- Vercel AI SDK — frontend (TypeScript), streaming UI cho web. Bài 40.
Code mẫu LiteLLM:
from litellm import completion
r = completion(
model="gpt-4o-mini", # đổi sang "claude-opus-4-7" là gọi Anthropic
messages=[{"role": "user", "content": "Xin chào"}],
)
print(r.choices[0].message.content)
Lưu ý: wrapper thêm tầng abstraction, có thể chậm hơn 1 chút và che mất feature mới của từng provider. Khi cần feature đặc biệt (Structured Outputs OpenAI, prompt caching Anthropic), gọi SDK gốc.
Security best practices
- API key trong env var hoặc secret manager. Không hardcode, không log, không commit.
- Rotate key định kỳ (vd 90 ngày). Tạo key mới trước, thay env, revoke key cũ.
- One key per service: key cho dev, prod, CI tách riêng. Khi leak chỉ revoke đúng key đó.
- Organization billing limits (Usage limits trong dashboard): set hard limit theo tháng để giới hạn thiệt hại tối đa.
- Restricted key (project-level): tạo key chỉ với permission cần thiết (vd chỉ Chat Completions, không có Fine-tune).
- Không gửi PII không cần thiết: trừ khi có hợp đồng zero-retention, mặc định OpenAI lưu request 30 ngày để abuse review. Mask CCCD, số thẻ, mật khẩu trước khi gửi.
- Monitor usage dashboard hằng tuần. Tăng đột biến = dấu hiệu key leak hoặc bug loop.
- Truyền
user="..."để OpenAI track theo end-user — giúp report abuse nhanh nếu app bị lạm dụng.
Cost — tham khảo
Số dưới là giá tham khảo tại tháng 5/2026, đơn vị USD trên 1 triệu token. Luôn verify lại trên platform.openai.com/docs/pricing trước khi tính cost production.
Model Input ($/M) Output ($/M) Ghi chú
─────────────────────────────────────────────────────────────────────────
gpt-4o-mini 0.15 0.60 Default rẻ
gpt-4o 2.50 10.00 Multimodal
gpt-4.1 ~2.00 ~8.00 1M context
gpt-5 cao hơn 4o cao hơn 4o Flagship
o1 15.00 60.00 Reasoning
o3 ~10.00 ~40.00 Reasoning
o5 cao nhất cao nhất Reasoning mới
text-embedding-3-small 0.02 — Embedding
text-embedding-3-large 0.13 — Embedding
whisper-1 $0.006 / phút audio ASR
tts-1 $15 / 1M ký tự input TTS
dall-e-3 (1024x1024 std) $0.040 / ảnh Image gen
gpt-image-1 ~$0.04-0.17 / ảnh tuỳ size Image gen
Quy tắc cost-aware:
- Output token đắt gấp 4-5 lần input → giới hạn
max_tokenssát thực tế. - Prompt caching (OpenAI bật mặc định cho prompt > 1024 token): các phần lặp được cache, giảm 50% phí input.
- Batch API giảm 50%, async / overnight workload nên ưu tiên Batch.
- Reasoning model rất đắt — chỉ dùng khi task thực sự cần multi-step logic.
Common issues
AuthenticationError: Invalid API key: env var rỗng, sai prefix (sk-...), hoặc key đã revoke. Checkecho $OPENAI_API_KEY, tạo lại key.RateLimitErrorliên tục: workload vượt TPM. Giảm concurrency, dùng Batch API, hoặc nâng tier (nạp thêm credit).NotFoundError: model not found: model name sai hoặc đã deprecate. Checkclient.models.list()xem những model account access được.BadRequestError: This model's maximum context length is X tokens: prompt + max_tokens vượt context window. Tóm tắt history, dùng RAG, hoặc chuyển sang model context dài (gpt-4.1).- Response cụt:
finish_reason == "length". Tăngmax_tokens. - Latency cao bất thường: OpenAI status page (
status.openai.com) có incident? Region chậm? Thửtimeoutngắn + retry. - Output bị moderation chặn:
finish_reason == "content_filter". Kiểm tra prompt có violate policy không. - Cost tăng đột biến: check Usage dashboard, có khả năng bug loop (vd retry không có trần) hoặc key leak.
Code Python tổng hợp
Bốn snippet ngắn, chạy được với openai SDK v1.x.
(a) First call:
from openai import OpenAI
client = OpenAI()
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello"}],
)
print(r.choices[0].message.content)
print("Tokens:", r.usage.total_tokens)
(b) With temperature, max_tokens:
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "Bạn trả lời ngắn gọn, bullet point."},
{"role": "user", "content": "3 ưu điểm của Python."},
],
temperature=0.3,
max_tokens=200,
)
print(r.choices[0].message.content)
(c) Error handling + retry:
from openai import OpenAI, RateLimitError, APITimeoutError
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
client = OpenAI(timeout=30)
@retry(
stop=stop_after_attempt(4),
wait=wait_exponential(min=1, max=20),
retry=retry_if_exception_type((RateLimitError, APITimeoutError)),
)
def ask(prompt: str) -> str:
r = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
)
return r.choices[0].message.content
print(ask("Một câu mô tả AI engineer."))
(d) Streaming preview:
stream = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Đếm từ 1 đến 5, mỗi số một dòng."}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)
print()
Bài tập
- Setup + first call: tạo account, lấy API key, export env var, viết script in ra response cho prompt "Liệt kê 5 khái niệm AI engineer cần nắm". In thêm
r.usagevàr.model. - Chatbot 5-turn: viết script CLI giữ
messagestrong list, mỗi lượt appenduservàassistantmessage. Sau 5 turn, in toàn bộ history. Quan sát: ở turn thứ 5, prompt_tokens đã lớn hơn turn 1 bao nhiêu lần? - Retry với tenacity: viết hàm
safe_call(prompt)retry tối đa 5 lần vớiwait_exponential(1, 30), chỉ retry vớiRateLimitError,APITimeoutError,APIConnectionError. Test bằng cách setclient = OpenAI(timeout=0.001)(timeout rất ngắn để force timeout) — quan sát số lần retry trong log củatenacity. - So sánh gpt-4o-mini vs gpt-4o: chuẩn bị 5 câu hỏi (1 factual, 1 reasoning, 1 code, 1 summarization, 1 creative). Gọi cả hai model với cùng prompt, log: response, total_tokens, latency (
time.perf_counter). Tính cost ước lượng theo bảng ở bước 24. Viết nhận xét trong 5 dòng: với task nào mini đủ, task nào cần 4o. - (Tuỳ chọn) Async batch: dùng
AsyncOpenAI+asyncio.Semaphore(10)để dịch 50 câu tiếng Anh sang tiếng Việt song song. Đo tổng thời gian, so với loop tuần tự.
- OpenAI — Chat Completions API reference
- OpenAI — Responses API reference
- OpenAI — Models
- OpenAI — Rate limits and tiers
- OpenAI — Error codes
- OpenAI — Batch API guide
- OpenAI — Files API
- OpenAI — Assistants API overview
- OpenAI — Vision guide
- OpenAI — Speech to text (Whisper)
- OpenAI — Text to speech
- OpenAI — Image generation
- OpenAI — Streaming responses
- OpenAI — Pricing
- openai-python — official SDK
- Tenacity — retry library
- LiteLLM — unified LLM client
- OpenRouter — docs
