Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 5 — Xây vòng lặp Agent (ReAct loop) hoàn chỉnh

Đã đọc 0/8 mục · còn khoảng 4 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Đâ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/except phò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 == final hoặc chạm max_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_steps chố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 (final hoặ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.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi