Bài 1 — Agent loop: bức tranh chung
Trước khi viết dòng code đầu tiên, bạn cần một mô hình tư duy đúng về "agent" thực sự là gì. Rất nhiều người nghĩ agent là một câu prompt phức tạp. Sai. Agent là một vòng lặp (loop): model nhận input → quyết định gọi tool hay trả lời → nếu gọi tool thì code của bạn chạy tool → kết quả tool được đưa lại cho model → model quyết định tiếp. Vòng lặp dừng khi model trả lời trực tiếp (không còn tool call nào).
Cả OpenAI Agents SDK và Anthropic Messages API đều xoay quanh vòng lặp này. Khác biệt: OpenAI Agents SDK đóng gói sẵn vòng lặp (bạn gọi Runner.run một lần), còn Anthropic tool use để bạn tự viết vòng lặp (bạn kiểm tra stop_reason == "tool_use" rồi lặp lại). Hiểu điều này giúp bạn không bị "ma thuật hóa" SDK.
Giải phẫu một lượt tool use (Anthropic)
1. Bạn gửi messages + danh sách tools cho Claude
2. Claude trả về content block loại "tool_use" với name + input
3. stop_reason = "tool_use" -> bạn PHẢI chạy tool
4. Bạn gửi lại 1 message role=user chứa "tool_result" (khớp tool_use_id)
5. Claude đọc kết quả, trả lời text -> stop_reason = "end_turn"
Điểm chết người: bước 4. Nếu bạn quên gửi tool_result khớp đúng tool_use_id, API sẽ lỗi hoặc Claude bị "treo" chờ kết quả.
Cùng ý tưởng đó trong OpenAI Agents SDK
from agents import Agent, Runner, function_tool
@function_tool
def get_weather(city: str) -> str:
return f"Thời tiết {city}: 30 độ, nắng"
agent = Agent(
name="Trợ lý",
instructions="Bạn là trợ lý tiếng Việt, ngắn gọn.",
tools=[get_weather],
)
result = Runner.run_sync(agent, "Thời tiết Đà Nẵng thế nào?")
print(result.final_output)
Bạn không thấy vòng lặp đâu cả — Runner tự lặp: gọi model, thấy tool call, chạy get_weather, đưa kết quả lại, lấy câu trả lời cuối. Đó là giá trị của SDK.
Các bước để bắt đầu
- Chọn mô hình tư duy: mọi thứ là loop
model ↔ tool. Vẽ nó ra giấy. - Xác định ranh giới: cái gì model quyết định, cái gì code của bạn thực thi. Model KHÔNG chạy code — nó chỉ đề nghị gọi tool.
- Cài đặt môi trường:
pip install openai-agents anthropic, đặtOPENAI_API_KEYvàANTHROPIC_API_KEYvào biến môi trường (đừng hard-code). - Chạy ví dụ nhỏ nhất ở trên để chắc pipeline thông.
- Bật log để nhìn từng lượt: model gọi tool nào, input gì, kết quả gì.
Vì sao phân biệt "đề nghị" và "thực thi" quan trọng
Đây là điểm nhiều người mới vấp. Model KHÔNG có khả năng chạy code, truy vấn cơ sở dữ liệu hay gọi API bên ngoài. Khi bạn khai báo tool get_weather, model chỉ sinh ra một đề nghị: "hãy gọi get_weather với city='Đà Nẵng'". Việc thực thi hoàn toàn nằm ở phía bạn — code Python của bạn nhận đề nghị đó, chạy hàm thật (có thể gọi API thời tiết, đọc DB), rồi trả kết quả về cho model. Điều này có hai hệ quả thực tế: (1) mọi rủi ro bảo mật và tác dụng phụ nằm ở tool bạn viết, không phải ở model, nên bạn kiểm soát được; (2) bạn có thể chèn kiểm tra, log, giới hạn quyền ngay tại chỗ thực thi tool. Nắm chắc ranh giới này, bạn sẽ không bao giờ hỏi "làm sao model tự gửi email được" — nó không tự làm; bạn viết tool send_email và chính bạn quyết định khi nào cho phép gửi.
Khung tư duy: 4 câu hỏi trước khi build agent
- Agent này thay con người làm việc gì cụ thể? (một câu, đo được)
- Nó cần những tool nào để hoàn thành việc đó?
- Khi nào nó được phép dừng? (điều kiện thành công / thất bại)
- Điều tệ nhất nó có thể làm sai là gì, và ta chặn ở đâu?
Sai lầm thường gặp
- Nghĩ agent = prompt dài: prompt chỉ là một phần; sức mạnh nằm ở tool + loop + guardrails.
- Tưởng model tự chạy code: model chỉ trả về ý định gọi tool; bạn phải viết hàm thực thi và trả kết quả về.
- Quên khớp
tool_use_id(Anthropic): dẫn tới lỗi 400 hoặc loop treo. - Không đặt điều kiện dừng: agent lặp vô hạn hoặc gọi tool lung tung, đốt token.
- Trộn lẫn hai SDK trong đầu: OpenAI Agents SDK lo loop giúp bạn; Anthropic tool use bạn tự lo loop. Đừng kỳ vọng hành vi giống hệt nhau.