Chạy được Claude API trong 5 phút đầu tiên
Mình mất gần một buổi sáng để tìm hiểu docs của nhiều AI API khác nhau trước khi thử Claude. Kết quả: Claude API là cái dễ bắt đầu nhất — SDK rõ ràng, response nhất quán, ít quirk bất ngờ. Nếu bạn đã từng dùng OpenAI SDK thì sẽ quen tay ngay.
Cài thư viện trước:
pip install anthropic
Xong. Giờ thử gọi API ngay:
import anthropic
client = anthropic.Anthropic(api_key="sk-ant-api03-...")
message = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "Giải thích Docker là gì trong 3 câu ngắn"}
]
)
print(message.content[0].text)
Chạy thử — bạn sẽ thấy câu trả lời xuất hiện trong vài giây. Đó là tất cả những gì cần để có một ứng dụng AI hoạt động được. Phần còn lại là làm cho nó tốt.
API key lấy ở console.anthropic.com → API Keys → Create Key. Đừng bao giờ hardcode key vào code — dùng biến môi trường:
# Thêm vào ~/.bashrc hoặc ~/.zshrc
export ANTHROPIC_API_KEY="sk-ant-api03-..."
# SDK tự đọc biến này nếu không truyền api_key
client = anthropic.Anthropic() # Không cần api_key!
Hiểu cấu trúc API để tránh lỗi vặt
Messages API — cách dùng đúng
Claude dùng Messages API, không phải Completion API như các model cũ. Cấu trúc conversation là một list các message xen kẽ user và assistant:
messages = [
{"role": "user", "content": "Mình đang học Python"},
{"role": "assistant", "content": "Python là lựa chọn tốt! Bạn muốn bắt đầu từ đâu?"},
{"role": "user", "content": "Bắt đầu từ list comprehension được không?"}
]
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
messages=messages
)
Quy tắc: message đầu tiên phải là user, các message phải xen kẽ user/assistant. Vi phạm quy tắc này ra lỗi ngay — mình đã bị dính lỗi này lúc build chatbot vì quên không trim history đúng cách.
System prompt — vũ khí chính để kiểm soát output
System prompt không nằm trong messages mà là tham số riêng:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=2048,
system="Bạn là senior DevOps engineer. Trả lời ngắn gọn, dùng bullet points. Luôn đề cập security implications.",
messages=[
{"role": "user", "content": "Setup nginx reverse proxy như thế nào?"}
]
)
Nhiều API khác nhét system message vào đầu list messages như một message bình thường. Claude tách riêng thành parameter độc lập — model xử lý instruction này với priority cao hơn, ít bị “quên” yêu cầu hơn khi conversation kéo dài.
Streaming — bắt buộc phải dùng cho UX tốt
Không ai muốn nhìn màn hình trắng 10 giây rồi mới thấy text xuất hiện. Streaming giải quyết vấn đề này:
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Viết script backup database PostgreSQL"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
print() # Xuống dòng sau khi xong
Với Flask hoặc FastAPI, bạn có thể stream thẳng về browser dùng Server-Sent Events:
from flask import Flask, Response, stream_with_context
import anthropic
import json
app = Flask(__name__)
client = anthropic.Anthropic()
@app.route("/chat")
def chat():
def generate():
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
) as stream:
for text in stream.text_stream:
yield f"data: {json.dumps({'text': text})}\n\n"
yield "data: [DONE]\n\n"
return Response(
stream_with_context(generate()),
mimetype="text/event-stream"
)
Kỹ thuật nâng cao cho ứng dụng production
Prompt caching — giảm 90% chi phí
Có system prompt dài vài nghìn token mà gọi đi gọi lại cả trăm lần/ngày? Bạn đang ném tiền qua cửa sổ. Mình đã bật caching cho một project có system prompt ~3000 token, khoảng 120 request/ngày — bill giảm từ $2.1 xuống còn $0.4/ngày:
# Bật prompt caching cho system prompt dài
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{
"type": "text",
"text": """Bạn là trợ lý kỹ thuật cho hệ thống e-commerce.
[... 5000 từ tài liệu hệ thống ...]""",
"cache_control": {"type": "ephemeral"} # Cache lại!
}
],
messages=[{"role": "user", "content": query}]
)
Request đầu tiên tốn full cost để build cache. Từ request thứ hai, phần cached chỉ tính 10% giá thông thường. Với system prompt 3000 token và 100 request/ngày, đây là khoản tiết kiệm xấp xỉ $50/tháng.
Retry tự động với exponential backoff
Rate limit và lỗi mạng là chuyện bình thường. Đừng để ứng dụng crash vì những lỗi thoáng qua:
import anthropic
import time
def call_claude_with_retry(messages, max_retries=3, **kwargs):
client = anthropic.Anthropic()
for attempt in range(max_retries):
try:
return client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=messages,
**kwargs
)
except anthropic.RateLimitError:
if attempt == max_retries - 1:
raise
wait_time = (2 ** attempt) * 1 # 1s, 2s, 4s
print(f"Rate limit, chờ {wait_time}s...")
time.sleep(wait_time)
except anthropic.APIConnectionError as e:
if attempt == max_retries - 1:
raise
time.sleep(1)
return None
Structured output với JSON mode
Khi cần parse response thành dữ liệu có cấu trúc, đừng dùng regex — dùng JSON trong prompt:
import json
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system="Luôn trả lời dưới dạng JSON hợp lệ, không có text nào ngoài JSON.",
messages=[{
"role": "user",
"content": """Phân tích câu sau và trả về JSON:
'Server PostgreSQL version 14.5 bị lỗi OOM lúc 3h sáng ngày 15/2'
Format: {\"component\": str, \"version\": str, \"error_type\": str, \"time\": str}"""
}]
)
data = json.loads(response.content[0].text)
print(data["error_type"]) # "OOM"
Tips thực tế từ kinh nghiệm làm dự án thật
Gọi được API là xong bước đầu. Phần tốn não hơn — và dễ bị phớt lờ cho đến khi nhận bill — là kiểm soát chi phí và giữ output quality ổn định. Mấy điều dưới đây mình học được, phần lớn sau khi đã mắc sai lầm rồi:
- Chọn model phù hợp với task: Haiku cho task đơn giản (classify, extract), Sonnet cho task trung bình (summarize, translate, code review), Opus cho task phức tạp (analysis, reasoning). Dùng Opus cho mọi thứ tốn tiền gấp 15 lần Haiku.
- Đặt
max_tokenssát với nhu cầu thật: Nếu câu trả lời chỉ cần 200 token, đừng set 4096. Bạn chỉ bị tính tiền theo output thực tế — nhưng set max_tokens cao khiến model có xu hướng generate verbose hơn cần thiết, tăng latency và tốn thêm tiền. - Log usage tokens: Response object trả về
message.usagevớiinput_tokensvàoutput_tokens. Log lại để theo dõi chi phí và phát hiện prompt nào đang ngốn token bất thường. - Test với
claude-haiku-4-5-20251001trước: Khi đang develop, dùng Haiku để iterate nhanh và rẻ. Chỉ switch sang Sonnet/Opus khi cần test quality thật. - Giới hạn conversation history: Giữ lại tối đa 10-20 message gần nhất thay vì toàn bộ history. Context window lớn nhưng chi phí cộng dồn nhanh lắm.
# Pattern quản lý conversation history hiệu quả
def trim_history(messages, max_pairs=10):
"""Giữ lại max_pairs cặp user/assistant gần nhất"""
if len(messages) > max_pairs * 2:
return messages[-(max_pairs * 2):]
return messages
# Log usage để theo dõi chi phí
response = client.messages.create(...)
print(f"Input: {response.usage.input_tokens} tokens | Output: {response.usage.output_tokens} tokens")
Một điều nữa mình hay thấy người mới mắc phải: đừng để lộ API key trong source code commit lên GitHub. Anthropic có hệ thống scan tự động và sẽ revoke key ngay nếu phát hiện. Dùng python-dotenv và file .env được add vào .gitignore.
# .env
ANTHROPIC_API_KEY=sk-ant-api03-...
# .gitignore
.env
*.env
# main.py
from dotenv import load_dotenv
load_dotenv()
client = anthropic.Anthropic() # Tự đọc từ .env
Quick start ở trên đủ để có prototype chạy được trong vài tiếng. Từ đó mở rộng theo thứ tự ưu tiên: streaming trước (cải thiện UX ngay lập tức), rồi đến caching khi chi phí bắt đầu tăng, cuối cùng là retry và error handling khi deploy production. Claude API khá ổn định — codebase mình viết từ 8 tháng trước vẫn chạy tốt, chưa gặp breaking change nào cần migration lớn.

