Danh sách bài viết

Bài 31: OpenAI API — gọi GPT từ Python

Module 5 mở đầu phần hands-on với API LLM commercial. Bài này đi qua toàn bộ vòng đời một dự án dùng OpenAI: tạo account, lấy API key, cài SDK openai v1.x, viết first call chat.completions, đọc response object, model lineup 2025-2026 (GPT-5, GPT-4o, GPT-4.1, o1/o3, embedding, Whisper, DALL-E, GPT-Image-1), error handling, rate limit theo tier, retry với tenacity, async client, Batch API, Files API, Assistants API, vision multimodal, Whisper / TTS, image generation, streaming preview, usage tracking, các thư viện wrapper (LiteLLM, OpenRouter, LangChain), security và cost.

25/05/2026
13 phút đọc
1 lượt xem
1

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.

2

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 full messages.
  • 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ẹ.

3

Setup account và API key

  1. Truy cập platform.openai.com. Đăng ký bằng email hoặc Google.
  2. Vào BillingPayment 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.
  3. Vào API keysCreate 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.
  4. Lưu key vào biến môi trường:
    export OPENAI_API_KEY="sk-..."
    Trên zsh/bash, thêm vào ~/.zshrc hoặc ~/.bashrc để giữ giữa các session. Trên Windows, dùng setx OPENAI_API_KEY "sk-..." hoặc Git Bash.
  5. Kiểm tra: echo $OPENAI_API_KEY phả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.

4

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.

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ền api_key=..., organization=..., base_url=..., timeout=....
  • client.chat.completions.create(...): gọi endpoint chat completions.
  • model + messages là 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.

6

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-4o hoặc gpt-5.
  • Long doc (1M token): gpt-4.1.
  • Math / reasoning phức tạp: o3 hoặc o5.
  • RAG vector: text-embedding-3-small cho cost-effective, large nế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.

7

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.

8

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" — đạt max_tokens, response có thể bị cắt. Cần tăng max_tokens hoặ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).
9

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.

10

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).

11

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.

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.
13

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).

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.

15

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).

16

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.

17

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.

18

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).

19

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.

20

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.

21

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.

22

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 model là đổ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_url và 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.

23

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.
24

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_tokens sá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.
25

Common issues

  • AuthenticationError: Invalid API key: env var rỗng, sai prefix (sk-...), hoặc key đã revoke. Check echo $OPENAI_API_KEY, tạo lại key.
  • RateLimitError liê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. Check client.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ăng max_tokens.
  • Latency cao bất thường: OpenAI status page (status.openai.com) có incident? Region chậm? Thử timeout ngắ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.
26

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()
27

Bài tập

  1. 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.usager.model.
  2. Chatbot 5-turn: viết script CLI giữ messages trong list, mỗi lượt append userassistant message. 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?
  3. Retry với tenacity: viết hàm safe_call(prompt) retry tối đa 5 lần với wait_exponential(1, 30), chỉ retry với RateLimitError, APITimeoutError, APIConnectionError. Test bằng cách set client = OpenAI(timeout=0.001) (timeout rất ngắn để force timeout) — quan sát số lần retry trong log của tenacity.
  4. 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.
  5. (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ự.