Sau 3 bài đầu, bạn đã biết: - Claude có nhiều tier (Opus/Sonnet/Haiku) - Request đi qua 5 bước từ client → server → API - Cách lấy và bảo vệ API key
- Cài đặt Anthropic Python SDK và cấu hình client
- Thực hiện request đầu tiên với đầy đủ 4 tham số bắt buộc
- Giải mã response object và extract text
- Hiểu ý nghĩa của từng tham số trong messages.create()
- Phân biệt user message và assistant message
Cài đặt SDK
Anthropic có SDK chính thức cho Python, TypeScript, Go, Ruby, Java. Trong khóa này dùng Python.
Cài package
Trong virtual env của project (source .venv/bin/activate):
Verify:
pip install anthropic python-dotenvCài package
Nếu in OK — SDK cài thành công.
Trong Jupyter notebook
python -c "from anthropic import Anthropic; print('OK')"Trong Jupyter notebook
Lưu ý dùng %pip thay vì !pip: %pip cài vào đúng kernel của notebook, !pip có thể cài vào Python khác.
%pip install anthropic python-dotenvRequest đầu tiên — Full example
Tạo file 01_first_request.ipynb hoặc .py. Gõ từng dòng (không copy — cơ tay cần nhớ):
Cell 1: Setup
Phân tích:
Cell 2: Tạo messages
- load_dotenv() — đọc file .env vào os.environ
- Anthropic() — tạo client. Tự đọc ANTHROPIC_API_KEY từ env.
- model — biến lưu model ID. Pin snapshot để production stable.
from dotenv import load_dotenv
load_dotenv()
from anthropic import Anthropic
client = Anthropic()
model = "claude-sonnet-5-20260205"Cell 2: Tạo messages
Phân tích:
Cell 3: Gọi API
- messages là list of dicts
- Mỗi dict có 2 trường: role và content
- role phải là "user" hoặc "assistant"
- content là text bạn muốn gửi
messages = [
{
"role": "user",
"content": "What is quantum computing? Answer in one sentence."
}
]Cell 3: Gọi API
Phân tích tham số:
Cell 4: Extract text
| Tham số | Kiểu | Ý nghĩa |
|---|---|---|
| model | str | Model ID (đã gán ở cell 1) |
| max_tokens | int | Trần cứng cho output |
| messages | list | Lịch sử hội thoại |
message = client.messages.create(
model=model,
max_tokens=1000,
messages=messages,
)Cell 4: Extract text
Phân tích:
Output dự kiến:
- message là object Anthropic Message
- .content là list content blocks
- [0] = block đầu tiên (usually chỉ có 1)
- .text = text content của block
print(message.content[0].text)Request đầu tiên — Full example (tiếp)
Chúc mừng — bạn vừa gọi Claude API thành công!
Quantum computing is a form of computation that leverages the principles
of quantum mechanics—such as superposition and entanglement—to process
information in fundamentally different ways than classical computers.Đi sâu vào response object
Thay vì chỉ .content[0].text, in full object để hiểu:
Output (rút gọn):
print(message)Đi sâu vào response object (tiếp)
Mỗi trường có ý nghĩa gì?
┌──────────────────────────────────────────────────┐ │ │ │ id → Unique identifier của message │ │ Dùng để log, debug, reference │ │ │ │ role → Luôn là "assistant" (Claude) │ │ │ │ model → Model thật đã chạy (full date) │ │ │ │ content → List content block │ │ TextBlock → type='text', text='...' │ │ (sau này) ToolUseBlock, ThinkingBlock │ │ │ │ stop_reason → Vì sao dừng (bài 6.4) │ │ │ │ usage → Metrics billing │ │ input_tokens → Tính tiền input │ │ output_tokens → Tính tiền output │ │ │ └──────────────────────────────────────────────────┘
Message(
id='msg_01XYZ...',
type='message',
role='assistant',
model='claude-sonnet-5-20260205',
content=[
TextBlock(
type='text',
text='Quantum computing is...'
)
],
stop_reason='end_turn',
stop_sequence=None,
usage=Usage(
input_tokens=15,
output_tokens=62,
cache_creation_input_tokens=0,
cache_read_input_tokens=0
)
)max_tokens — Cần lưu ý gì?
max_tokens là trần cứng cho output, không phải target.
Ví dụ
# max_tokens=50, câu hỏi ngắn
msg = client.messages.create(
model=model,
max_tokens=50,
messages=[{"role": "user", "content": "Say hi"}]
)
# Output: "Hi! How can I help you today?"
# output_tokens: 9
# → Dừng sớm do end_turn, KHÔNG chạm 50Ví dụ
Quy tắc chọn max_tokens
Pro tip: Set max_tokens gấp 1.5x số bạn dự kiến. Vừa đủ safety margin, vừa không lãng phí.
| Use case | max_tokens đề xuất |
|---|---|
| Classification (yes/no) | 10 |
| Short answer chat | 500 |
| Medium chat response | 1000-2000 |
| Long explanation | 4000 |
| Article / document | 8000-16000 |
| Reasoning chain | 16000-32000 |
| Max Sonnet 5 output | 64000 |
# max_tokens=50, câu hỏi cần trả lời dài
msg = client.messages.create(
model=model,
max_tokens=50,
messages=[{"role": "user", "content": "Write a 500-word essay about AI"}]
)
# Output: "AI is a rapidly evolving field that..."
# output_tokens: 50
# stop_reason: 'max_tokens' ← Bị cắt!Messages — cấu trúc chi tiết
Single-turn (1 user message)
Multi-turn (conversation history)
messages = [
{"role": "user", "content": "Hello"}
]Multi-turn (conversation history)
Quy tắc cứng
1. Phải bắt đầu bằng user:
messages = [
{"role": "user", "content": "What is 2+2?"},
{"role": "assistant", "content": "2+2 equals 4."},
{"role": "user", "content": "What about 3+3?"}
]Quy tắc cứng
2. Role phải alternating:
# ❌ Sai
messages = [{"role": "assistant", "content": "Hi!"}]
# ✅ Đúng
messages = [{"role": "user", "content": "Hi"}]Messages — cấu trúc chi tiết (tiếp)
3. Message cuối phải là user (để Claude có gì để reply):
# ❌ Sai — 2 user liên tiếp
messages = [
{"role": "user", "content": "Hello"},
{"role": "user", "content": "Are you there?"}
]
# ✅ Đúng — xen kẽ user/assistant
messages = [
{"role": "user", "content": "Hello"},
{"role": "assistant", "content": "Yes!"},
{"role": "user", "content": "Are you there?"}
]Messages — cấu trúc chi tiết (tiếp)
# ❌ Sai — kết thúc bằng assistant, Claude không biết phải nói gì
messages = [
{"role": "user", "content": "Hi"},
{"role": "assistant", "content": "Hello!"}
]
# Nếu gọi với messages này, Claude sẽ continue từ assistant → kỳ quặcVí dụ thực chiến: Query về dữ liệu công ty
Tình huống
Bạn là HR Manager, muốn test xem Claude có trả lời tốt câu hỏi policy không.
Bước 1: Setup
Bước 2: Câu hỏi đầu tiên
from dotenv import load_dotenv
load_dotenv()
from anthropic import Anthropic
client = Anthropic()
model = "claude-sonnet-5-20260205"Bước 2: Câu hỏi đầu tiên
Bước 3: Đọc response
Claude có thể trả lời:
messages = [
{
"role": "user",
"content": "Công ty tôi có policy về work from home như sau: nhân viên được WFH tối đa 2 ngày/tuần, thứ 2 phải có mặt. Giải thích lý do có thể có cho policy này."
}
]
msg = client.messages.create(
model=model,
max_tokens=800,
messages=messages,
)
print(msg.content[0].text)Bước 3: Đọc response
Bước 4: Xem usage
Có nhiều lý do hợp lý cho policy WFH này:
1. **Thứ 2 là ngày quan trọng**: Đây thường là ngày kick-off tuần,
cần họp planning, align priorities...
2. **Giới hạn 2 ngày đảm bảo collaboration**: Face-to-face 3 ngày/tuần...
3. **Cân bằng quyền lợi**: WFH giúp work-life balance, đặc biệt với...Bước 4: Xem usage
Kết quả
Thời gian: ~3 giây. Cost: 100 VNĐ. Chất lượng: Sẵn sàng dùng trong app nội bộ.
print(f"Input tokens: {msg.usage.input_tokens}")
print(f"Output tokens: {msg.usage.output_tokens}")
# Input tokens: 85
# Output tokens: 247
# Cost tính:
# input: 85 / 1M * $3 = $0.000255
# output: 247 / 1M * $15 = $0.003705
# Total: ~$0.004 (~100 VNĐ)Case studies theo ngành
📊 Data Analyst
Task: Generate SQL query từ câu hỏi tiếng Việt.
Output: Query PostgreSQL chuẩn. Cost: $0.002/query.
📝 Content Writer
Task: Rewrite title cho SEO.
messages = [{
"role": "user",
"content": """
Schema:
- orders(id, user_id, amount, created_at)
- users(id, name, email)
Câu hỏi: Liệt kê top 10 user có tổng đơn hàng cao nhất trong 30 ngày.
Trả về SQL query.
"""
}]
msg = client.messages.create(model=model, max_tokens=300, messages=messages)📝 Content Writer
🎧 Support Ops
Task: Classify intent của ticket.
messages = [{
"role": "user",
"content": "Rewrite thành 5 tiêu đề SEO khác nhau: 'Cách dùng Claude API'"
}]🎧 Support Ops
messages = [{
"role": "user",
"content": """
Phân loại ticket sau vào 1 trong 4 category: refund, technical, feature_request, other
Ticket: "Tôi không login được app từ hôm qua, màn hình trắng xóa"
Trả về duy nhất tên category, không giải thích.
"""
}]
msg = client.messages.create(
model="claude-haiku-4-5", # Haiku đủ cho task này
max_tokens=10,
messages=messages
)
# Output: "technical"Anti-patterns phổ biến
❌ Quên load_dotenv()
Hiện tượng: AuthenticationError: missing API key
Fix: Gọi load_dotenv() TRƯỚC khi tạo Anthropic().
❌ messages không là list
Hiện tượng: BadRequestError: messages must be a list
❌ Access .content như string
# ❌ Sai
messages = {"role": "user", "content": "Hi"}
# ✅ Đúng (wrap trong list)
messages = [{"role": "user", "content": "Hi"}]❌ Access .content như string
❌ Không handle exceptions
Hiện tượng: App crash khi có network blip.
Fix:
# ❌ Sai
print(message.content) # In [TextBlock(...)] → không đẹp
# ✅ Đúng
print(message.content[0].text) # In text thật❌ Không handle exceptions
❌ Set max_tokens quá cao "for safety"
Ví dụ: max_tokens=64000 cho chatbot ngắn.
Hậu quả: Không hỏng code, nhưng tính tiền sai. Nhiều cloud provider charge dựa trên max_tokens reserved, không phải actual output.
Fix: Set realistic, tăng khi cần.
from anthropic import APIError, RateLimitError
try:
msg = client.messages.create(...)
except RateLimitError:
# Wait and retry
time.sleep(60)
msg = client.messages.create(...)
except APIError as e:
print(f"API error: {e}")
# Graceful degradeÁp dụng ngay
Bài tập 1: "Hello World" với 3 câu hỏi khác nhau (15 phút)
Trong notebook 01_first_request.ipynb, làm 3 request:
Với mỗi request, in ra:
Bài tập 2: Viết utility function (15 phút)
Viết function ask(prompt: str, model: str = None) -> str:
Mở rộng (optional): Thêm tham số max_tokens với default = 1000, và print usage nếu verbose=True.
- Classification: "Phân loại cảm xúc của câu: 'Hôm nay trời đẹp quá!'" — dùng Haiku
- Creative: "Viết 1 câu thơ về mùa thu Hà Nội" — dùng Sonnet
- Reasoning: "Nếu A > B và B > C, A có > C không? Giải thích" — dùng Sonnet
- Response text
- input_tokens và output_tokens
- Model đã dùng
- stop_reason
def ask(prompt: str, model: str = None) -> str:
"""
Gửi prompt đơn giản tới Claude, trả về text response.
"""
# Code của bạn
pass
# Test
print(ask("What is 2+2?"))
# Output: "2+2 equals 4."Tóm tắt bài học
🎯 Setup 3 dòng: load_dotenv() → Anthropic() → model_id. Mọi request sau dùng client này.
🎯 messages.create() cần 3 tham số bắt buộc: model, max_tokens, messages. Đủ cho 80% use case.
🎯 Messages là list dict với role alternating (user → assistant → user...). Phải bắt đầu và kết thúc bằng user.
🎯 Extract text bằng message.content[0].text. Check stop_reason trước khi trust response.
🎯 max_tokens là trần cứng, không phải target. Set realistic cho use case cụ thể.
- Anthropic Python SDK
- Messages API reference
- anthropic-cookbook/quickstart