Điều làm agent trở thành agent chính là vòng lặp. Không có vòng lặp, bạn chỉ có một lời gọi LLM. Hiểu vòng lặp này bạn sẽ thiết kế được agent và cũng biết vì sao nó "loạn".
Ba pha của vòng lặp
- Sense (Cảm nhận): agent thu thập thông tin — câu hỏi người dùng, kết quả từ tool ở bước trước, trạng thái hệ thống. Đây là "đầu vào" cho bước suy nghĩ.
- Think (Suy nghĩ): LLM lập luận: "Mình đang ở đâu? Mục tiêu là gì? Bước tiếp theo nên làm gì? Có cần gọi tool không, tool nào, tham số gì?".
- Act (Hành động): agent thực hiện — gọi một tool (tra DB, gửi API, tính toán) HOẶC kết luận là đã xong và trả lời cuối cùng.
┌─────────────────────────────┐
▼ │
[SENSE] ──► [THINK] ──► [ACT] ─────┘
(quan sát) (lập luận) (gọi tool /
/ trả lời)
Ví dụ chạy từng vòng
Mục tiêu: "Tìm và đặt lịch họp 30 phút với anh Nam tuần này".
- Vòng 1 — Sense: nhận yêu cầu. Think: "Cần biết lịch trống của tôi và của anh Nam". Act: gọi tool
get_calendar(me). - Vòng 2 — Sense: nhận lịch của tôi. Think: "Cần lịch anh Nam". Act: gọi
get_calendar(nam). - Vòng 3 — Sense: có cả hai lịch. Think: "Chiều thứ Tư 14:00 cả hai đều trống". Act: gọi
create_event(...). - Vòng 4 — Sense: event tạo thành công. Think: "Xong mục tiêu". Act: trả lời "Đã đặt lịch 14:00 thứ Tư".
Pseudocode của vòng lặp
def agent_loop(goal, tools, max_steps=10):
history = [goal]
for step in range(max_steps):
# THINK: LLM quyết định hành động kế tiếp
decision = llm.decide(history, tools)
if decision.type == "final_answer":
return decision.answer
# ACT: thực thi tool
result = tools[decision.tool].run(decision.args)
# SENSE: đưa kết quả trở lại bộ nhớ
history.append(f"Đã gọi {decision.tool} → {result}")
return "Đã đạt giới hạn bước, dừng an toàn."
Hai chi tiết sống còn: max_steps (chống lặp vô tận) và việc đưa kết quả tool trở lại history (nếu quên, agent bị "mù", không học được từ hành động của mình).
Vì sao vòng lặp hay hỏng
- Lặp vô tận: agent gọi đi gọi lại cùng một tool vì không nhận ra đã có đủ thông tin. → luôn đặt
max_stepsvà điều kiện dừng. - Mất trí nhớ: kết quả tool không được đưa lại vào Think. → agent "quên" mình vừa làm gì.
- Nhảy cóc: agent kết luận cuối cùng khi chưa đủ dữ kiện (bịa ra kết quả). → cần yêu cầu "phải dựa trên kết quả tool thật".
Khung tư duy: mỗi vòng, agent trả lời 3 câu
- Tôi đã biết gì rồi? (Sense)
- Còn thiếu gì để đạt mục tiêu? (Think)
- Hành động rẻ-nhất-tiếp-theo để lấp khoảng thiếu là gì? (Act)
So sánh với chatbot: vì sao vòng lặp là ranh giới
Một chatbot cũng nhận input và sinh output, nhưng nó chỉ chạy một lần rồi dừng: không có bước quan sát kết quả hành động của chính mình để đi tiếp. Agent thì khác — nó hành động, nhìn kết quả, rồi hành động tiếp. Chính khả năng "tự nhìn lại kết quả và điều chỉnh" này cho phép agent giải quyết bài toán mà số bước không biết trước. Nếu bạn lấy đi vòng lặp, dù prompt có tinh vi tới đâu, bạn vẫn chỉ có một chatbot đắt tiền. Đây là lý do khi đánh giá một hệ thống có phải agent hay không, câu hỏi quan trọng nhất luôn là: "Kết quả của hành động có quay trở lại làm đầu vào cho quyết định kế tiếp không?".
Điều kiện dừng: nghệ thuật biết khi nào đủ
Một agent tốt không chỉ biết hành động mà còn biết khi nào ngừng hành động. Có ba loại điều kiện dừng bạn nên cài đặt đồng thời: (1) dừng theo mục tiêu — agent tự nhận ra đã đạt đích và đưa ra câu trả lời cuối; (2) dừng theo giới hạn — chạm max_steps hoặc ngân sách token thì dừng an toàn; (3) dừng theo lỗi — gặp lỗi không thể phục hồi thì bàn giao cho con người. Thiếu bất kỳ loại nào cũng gây rủi ro: thiếu (1) agent lan man, thiếu (2) agent chạy vô tận, thiếu (3) agent cố xử lý ca vượt khả năng và làm hỏng việc.
Sai lầm thường gặp
- Bỏ điều kiện dừng — agent chạy tới khi hết token hoặc hết tiền.
- Không log lại từng vòng — khi agent sai, bạn không biết nó sai ở pha nào (Sense/Think/Act), gần như không debug được.
- Nhồi quá nhiều tool khiến pha Think bối rối, chọn sai tool. Bắt đầu với 2–3 tool.
- Coi một lời gọi LLM là agent: nếu không có vòng lặp quay lại, đó chỉ là chatbot.
- Chỉ cài một loại điều kiện dừng (thường là mỗi max_steps) mà quên dừng-theo-mục-tiêu và dừng-theo-lỗi.