Sau 3 bài đầu, bạn đã biết:
- 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
Mở đầu: Từ "hiểu concept" đến "chạy code"
- 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
Bây giờ, trong 20 phút, bạn sẽ chuyển từ biết sang làm. Chạy request thật. Nhìn response thật. Hiểu từng trường output.
Đây là bài short but critical — mọi code sau trong khóa dựa trên pattern bạn học ở đây.
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):
pip install anthropic python-dotenv
Verify:
python -c "from anthropic import Anthropic; print('OK')"
Nếu in OK — SDK cài thành công.
Trong Jupyter notebook
%pip install anthropic python-dotenv
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.
Request đầ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
from dotenv import load_dotenv
load_dotenv()
from anthropic import Anthropic
client = Anthropic()
model = "claude-sonnet-4-6-20260205"
Phân tích:
load_dotenv()— đọc file.envvàoos.environAnthropic()— tạo client. Tự đọcANTHROPIC_API_KEYtừ env.model— biến lưu model ID. Pin snapshot để production stable.
Cell 2: Tạo messages
messages = [
{
"role": "user",
"content": "What is quantum computing? Answer in one sentence."
}
]
Phân tích:
messageslà list of dicts- Mỗi dict có 2 trường:
rolevàcontent rolephải là"user"hoặc"assistant"contentlà text bạn muốn gửi
Cell 3: Gọi API
message = client.messages.create(
model=model,
max_tokens=1000,
messages=messages,
)
Phân tích tham số:
| 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 |
Cell 4: Extract text
print(message.content[0].text)
Phân tích:
messagelà object Anthropic Message.contentlà list content blocks[0]= block đầu tiên (usually chỉ có 1).text= text content của block
Output dự kiến:
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.
Chúc mừng — bạn vừa gọi Claude API thành công!
Đi sâu vào response object
Thay vì chỉ .content[0].text, in full object để hiểu:
print(message)
Output (rút gọn):
Message(
id='msg_01XYZ...',
type='message',
role='assistant',
model='claude-sonnet-4-6-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
)
)
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 │
│ │
└──────────────────────────────────────────────────┘
max_tokens — Cần lưu ý gì?
max_tokens là trần cứng cho output, không phải target.
Ví dụ
msg = client.messages.create(
model=model,
max_tokens=50,
messages=[{"role": "user", "content": "Say hi"}]
)
msg = client.messages.create(
model=model,
max_tokens=50,
messages=[{"role": "user", "content": "Write a 500-word essay about AI"}]
)
Quy tắc chọn max_tokens
| 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 4.6 output | 64000 |
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í.
Messages — cấu trúc chi tiết
Single-turn (1 user message)
messages = [
{"role": "user", "content": "Hello"}
]
Multi-turn (conversation history)
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
1. Phải bắt đầu bằng user:
messages = [{"role": "assistant", "content": "Hi!"}]
messages = [{"role": "user", "content": "Hi"}]
2. Role phải alternating:
messages = [
{"role": "user", "content": "Hello"},
{"role": "user", "content": "Are you there?"}
]
messages = [
{"role": "user", "content": "Hello"},
{"role": "assistant", "content": "Yes!"},
{"role": "user", "content": "Are you there?"}
]
3. Message cuối phải là user (để Claude có gì để reply):
messages = [
{"role": "user", "content": "Hi"},
{"role": "assistant", "content": "Hello!"}
]
Ví 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
from dotenv import load_dotenv
load_dotenv()
from anthropic import Anthropic
client = Anthropic()
model = "claude-sonnet-4-6-20260205"
Bước 2: Câu hỏi đầu tiên
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
Claude có thể trả lời:
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
print(f"Input tokens: {msg.usage.input_tokens}")
print(f"Output tokens: {msg.usage.output_tokens}")
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ộ.
Case studies theo ngành
Data Analyst
Task: Generate SQL query từ câu hỏi tiếng Việt.
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)
Output: Query PostgreSQL chuẩn. Cost: $0.002/query.
Content Writer
Task: Rewrite title cho SEO.
messages = [{
"role": "user",
"content": "Rewrite thành 5 tiêu đề SEO khác nhau: 'Cách dùng Claude API'"
}]
Support Ops
Task: Classify intent của ticket.
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
)
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ạoAnthropic().
messages không là list
Hiện tượng: BadRequestError: messages must be a list
messages = {"role": "user", "content": "Hi"}
messages = [{"role": "user", "content": "Hi"}]
Access .content như string
print(message.content) # In [TextBlock(...)] → không đẹp
print(message.content[0].text) # In text thật
Không handle exceptions
Hiện tượng: App crash khi có network blip.
Fix:
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
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.
Á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:
- 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
Với mỗi request, in ra:
- Response text
input_tokensvàoutput_tokens- Model đã dùng
stop_reason
Bài tập 2: Viết utility function (15 phút)
Viết function ask(prompt: str, model: str = None) -> str:
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
print(ask("What is 2+2?"))
Mở rộng (optional): Thêm tham số max_tokens với default = 1000, và print usage nếu verbose=True.
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. Checkstop_reasontrước khi trust response. - max_tokens là trần cứng, không phải target. Set realistic cho use case cụ thể.