Đây là trái tim của agent: vòng lặp để LLM nghĩ → gọi tool → nhận kết quả → nghĩ tiếp cho đến khi hoàn thành. Bài này bạn ghép LLM (bài 2), system prompt (bài 3) và tool (bài 4) thành một agent chạy thật.
Kiến trúc vòng lặp
Nhận yêu cầu người dùng
Loop (tối đa N vòng):
1. Gọi LLM với toàn bộ hội thoại + kết quả tool trước đó
2. Đọc quyết định của LLM:
- nếu là {action: "final"} -> trả lời, thoát
- nếu là {action: "<tool>"} -> thực thi tool
3. Đưa kết quả tool vào hội thoại, quay lại bước 1
Nếu chạm giới hạn N -> dừng an toàn, báo "chưa hoàn thành"
Code vòng lặp tối giản
import json
from llm import call_llm
from tools import TOOLS
def run_agent(user_input, system_prompt, max_steps=6):
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_input},
]
for step in range(max_steps):
raw = call_llm(messages)
try:
decision = json.loads(raw)
except json.JSONDecodeError:
# LLM lỡ trả văn xuôi -> coi như câu trả lời cuối
return raw
if decision.get("action") == "final":
return decision.get("answer", "")
tool = TOOLS.get(decision["action"])
if not tool:
result = f"Loi: khong co cong cu '{decision['action']}'"
else:
try:
result = tool["fn"](**decision.get("args", {}))
except Exception as e:
result = f"Loi khi chay cong cu: {e}"
# Ghi lại điều agent vừa làm + kết quả để vòng sau LLM thấy
messages.append({"role": "assistant", "content": raw})
messages.append({"role": "user",
"content": f"Ket qua cong cu: {result}"})
return "Chua hoan thanh trong gioi han buoc cho phep."
Các bước triển khai
- Khởi tạo hội thoại với system prompt và yêu cầu người dùng.
- Đặt
max_steps(ví dụ 6) — chốt chặn chống lặp vô tận. - Parse quyết định của LLM; bọc
try/exceptphòng khi LLM trả sai định dạng. - Thực thi tool an toàn, bắt mọi exception thành chuỗi kết quả.
- Nối kết quả tool vào hội thoại — đây là bước sống còn: nếu quên, LLM không biết tool đã chạy và sẽ gọi lại mãi.
- Điều kiện thoát: khi
action == finalhoặc chạmmax_steps.
Khung tư duy: agent là một máy trạng thái
[Thinking] --chọn tool--> [Acting] --nhận kết quả--> [Observing] --> [Thinking] ...
\--đủ--> [Done]
Mỗi vòng lặp đẩy agent qua các trạng thái này. Bug hầu như luôn nằm ở chỗ state không được cập nhật — thường là quên đưa observation trở lại messages.
Checklist vòng lặp an toàn
- [ ] Có
max_stepschống lặp vô tận. - [ ] Parse JSON có try/except.
- [ ] Tool lỗi trả về chuỗi, không làm sập loop.
- [ ] Kết quả tool được nối lại vào hội thoại.
- [ ] Có nhánh thoát rõ ràng (
finalhoặc hết bước). - [ ] Log lại mỗi bước để debug (bài 8).
Sai lầm thường gặp
- Quên đưa observation vào messages → agent gọi cùng một tool lặp đi lặp lại. Đây là bug phổ biến nhất.
- Không giới hạn số bước → chi phí token nổ, agent chạy vô tận.
- Tin tưởng LLM luôn trả JSON đúng → không có try/except là loop sập.
- Gộp nhiều hành động trong một bước rồi khó lần lỗi. Mỗi vòng một hành động cho dễ debug.
- Không phân biệt lỗi tool với kết quả hợp lệ → agent tưởng lỗi là dữ liệu và trả lời sai. Hãy prefix rõ "Loi:".
Debug vòng lặp: hãy in ra mọi bước
Vòng lặp agent là nơi khó debug nhất vì lỗi ẩn trong dòng suy nghĩ của LLM. Mẹo cứu bạn nhiều giờ: in ra từng bước với số thứ tự — nội dung LLM trả về (raw), tool được chọn, tham số, và kết quả tool. Khi agent hành xử lạ, bạn đọc lại chuỗi Thought → Action → Observation sẽ thấy ngay nó "rẽ nhầm" ở đâu: chọn sai tool (lỗi mô tả tool ở Bài 4), điền sai tham số (lỗi schema), hay không thấy kết quả cũ (lỗi quên nối observation). Đừng debug agent bằng cách đoán; hãy debug bằng cách đọc nhật ký từng bước. Ở Bài 8 ta sẽ nâng cấp việc in này thành logging có cấu trúc để giám sát khi chạy thật.
Agent của bạn đã chạy được vòng lặp! Bài 6 chúng ta thêm trí nhớ để nó nhớ ngữ cảnh qua nhiều lượt.