# 🔁 Vòng lặp ReAct: Thought, Action, Observation

By Ngọc Vương Trương

> Sign in to view the full content of this lesson.

Bài trước mình dừng ở chỗ workflow kiểu `summary = llm("Tóm tắt email sau: ...")` chỉ là một lần gọi, tuyến tính: vào một prompt, ra một kết quả, hết. Không có bước nào để LLM nhìn lại dữ liệu vừa lấy về rồi quyết định làm gì tiếp. ReAct chính là chỗ khác biệt bắt đầu: một vòng lặp, nơi kết quả của hành động trước quay lại làm đầu vào cho lượt suy luận sau. Đây là xương sống của mọi agent bạn sẽ gặp về sau, nên nắm chắc phần này là nắm được 60% môn học.

Sau 30 phút này, bạn sẽ:

- Đọc được một trace ReAct hoàn chỉnh và gọi đúng tên từng nhịp.
- Chỉ ra được vòng lặp dừng ở đâu, vì sao nó dừng.
- Nhận diện được 4 lỗi thường gặp khiến vòng lặp chạy sai hoặc chạy mãi.
- Phân biệt được "nghĩ" và "làm" trong một trace, thứ mà nhiều người mới hay gộp làm một.

## Vì sao một lần gọi LLM là chưa đủ

LLM bị giới hạn bởi hai thứ: kiến thức đóng băng tại thời điểm train, và không có khả năng tự chạm vào thế giới bên ngoài. Nếu bạn hỏi "đơn hàng #4412 đang ở đâu", một lần gọi LLM chỉ có thể đoán hoặc trả lời "tôi không biết". ReAct giải quyết bằng cách cho model quyền **gọi tool**, rồi **đọc kết quả trả về**, rồi **suy nghĩ tiếp** trên cơ sở dữ liệu thật. Cái vòng đó lặp cho tới khi đủ thông tin.

```mermaid
flowchart TD
    Q["❓<br/>Câu hỏi hoặc task"] --> T["🤔<br/>Thought"]
    T --> A["🔧<br/>Action: gọi tool"]
    A --> O["👁️<br/>Observation"]
    O --> C{"Đủ thông tin chưa?"}
    C -->|Chưa| T
    C -->|Rồi| F["✅<br/>Final Answer"]
```

## Ba nhịp của vòng lặp: Thought, Action, Observation

**Thought** là đoạn suy luận nội bộ: agent tự nhủ mình đang thiếu gì, nên gọi tool nào, với tham số gì. Thought không tác động ra bên ngoài, nó chỉ định hình hành động kế tiếp.

**Action** là lời gọi tool cụ thể, có tên và tham số. Đây là điểm duy nhất agent thực sự "chạm" vào hệ thống bên ngoài.

**Observation** là những gì hệ thống trả về: dữ liệu, hoặc thông báo lỗi. Điểm mấu chốt mà người mới hay bỏ qua: Observation phải được **chèn trở lại context** trước lượt suy nghĩ tiếp theo. Nếu không chèn, agent sẽ nghĩ lại từ đầu và lặp y hệt hành động cũ.

Một lưu ý thực tế: không phải model nào cũng phơi Thought ra cho bạn đọc. Nhiều model ẩn phần reasoning, trace chỉ còn Action và Observation. Khi debug, bạn vẫn nên log cả phần đó nếu API cho phép, vì 80% lỗi nằm ở Thought sai chứ không phải tool sai.

## Mổ xẻ một trace ReAct hoàn chỉnh

Bài toán: "Tổng chi phí vé máy bay Hà Nội đi Đà Nẵng ngày 15/03 cộng khách sạn 2 đêm là bao nhiêu?" Tool có sẵn: `get_flight_price`, `get_hotel_price`, `finish`.

```text
Thought 1: Cần giá vé Hà Nội → Đà Nẵng ngày 15/03. Chưa có số liệu, phải gọi tool.
Action 1:  get_flight_price(from="Hà Nội", to="Đà Nẵng", date="2025-03-15")
Observation 1: {"price": 1450000, "currency": "VND"}

Thought 2: Đã có vé. Còn thiếu giá khách sạn 2 đêm ở Đà Nẵng.
Action 2:  get_hotel_price(city="Đà Nẵng", nights=2)
Observation 2: {"price_per_night": 800000, "currency": "VND"}

Thought 3: Đủ dữ liệu. Tổng = 1.450.000 + 2 × 800.000 = 3.050.000 VND.
           Không cần gọi tool nào nữa, trả lời luôn.
Action 3:  finish("Tổng chi phí khoảng 3.050.000 VND")
```

Đọc trace này theo ba câu hỏi: mỗi Thought có nêu rõ **thiếu gì** không? Mỗi Action có **tham số đầy đủ** không? Mỗi Observation có được **dùng** ở Thought ngay sau đó không? Ở đây cả ba đều đạt. Và để ý: chỉ có 3 vòng, không phải 20. Agent tốt là agent dừng sớm.

Giờ xem một trace hỏng, kiểu hay gặp khi tool trả lỗi:

```text
Thought 1: Cần thời tiết Đà Nẵng ngày 16/03.
Action 1:  get_weather(city="Đà Nẵng", date="2025-03-16")
Observation 1: ERROR 400: date out of range (API chỉ hỗ trợ 7 ngày tới)

Thought 2: 16/03 nằm ngoài cửa sổ 7 ngày. Không sửa được bằng cách đổi tham số,
           phải báo người dùng và đề xuất ngày gần nhất.
Action 2:  finish("API chỉ trả dữ liệu 7 ngày tới, bạn muốn xem ngày gần nhất không?")
```

Điểm đáng học: agent **đọc nội dung lỗi** rồi đổi chiến lược, thay vì thử lại y nguyên. Đây là khác biệt giữa agent có vòng lặp tốt và một script gọi API được gắn nhãn "agent".

## Điều kiện lặp và điểm dừng

Vòng lặp tiếp tục khi agent tự đánh giá là **chưa đủ thông tin**. Nó dừng ở một trong bốn trường hợp:

1. **Dừng bình thường:** agent phát ra final answer, thường qua một tool `finish` hoặc một marker kết thúc.
2. **Dừng vì ngân sách:** chạm `max_iterations` hoặc `max_tokens`. Đây là lưới an toàn, không phải thành công.
3. **Dừng vì lỗi không phục hồi:** tool chết, sai quyền, tham số không thể sửa.
4. **Dừng vì guardrail:** timeout, hoặc agent vi phạm chính sách và bị chặn.

Điều quan trọng: khi dừng vì (2), (3) hay (4), hệ thống phải **trả về trạng thái thất bại rõ ràng**, không được giả vờ như đã trả lời xong. Rất nhiều agent production trả về câu trả lời nghe rất tự tin sau khi hết 10 vòng mà không lấy được gì.

_____ là kết quả tool trả về và phải được chèn lại vào context trước lượt suy luận kế tiếp. Nhịp _____ nêu lý do chọn hành động, còn nhịp Action mới là hành động thật. Vòng lặp kết thúc bình thường khi agent phát ra _____, và luôn cần thêm ngưỡng _____ để chặn trường hợp agent không tiến triển. Khi Observation là thông báo lỗi, việc đúng là _____ chứ không phải lặp lại y hệt hành động cũ.

## Khi vòng lặp đi sai: bốn lỗi thường gặp

**Lỗi 1: lặp y hệt.** Cùng tool, cùng tham số, cùng Observation, quay lại Thought 1. Dấu hiệu nhận biết rất cơ học: hai Action liên tiếp giống nhau từng ký tự. Nguyên nhân thường là Observation không được chèn vào context, hoặc bị chèn nhưng model phớt lờ.

**Lỗi 2: gộp Thought vào Action.** Model viết `Action: Tôi sẽ tra giá vé vì cần tính tổng`. Không parse được, tool không chạy, vòng lặp chết ngay vòng đầu. Phải tách bạch: Thought là văn xuôi tự do, Action là JSON hoặc function call đúng schema.

**Lỗi 3: gọi tool thừa.** Đã có đủ dữ liệu ở Thought 3 nhưng vẫn gọi thêm `get_hotel_price` lần nữa "cho chắc". Mỗi vòng thừa là token, tiền và độ trễ, và cũng là thêm một cửa sổ để sai.

**Lỗi 4: kết thúc giả.** Hết `max_iterations`, agent vẫn xuất ra một câu trả lời trông hợp lý nhưng không dựa trên Observation nào. Đây là lỗi nguy hiểm nhất vì nó âm thầm: người dùng không biết mình đang đọc kết quả bịa.

## Mẹo thực chiến khi đọc và viết trace ReAct

- **Đọc trace từ dưới lên trước.** Xem câu trả lời cuối dựa trên Observation nào. Nếu không truy được về Observation cụ thể, đó là kết thúc giả.
- **Đếm số vòng trước khi đọc chi tiết.** Task đơn giản mà trace 12 vòng là dấu hiệu Thought đang mô tả mơ hồ, khiến agent không bao giờ "thấy đủ".
- **Đặt `max_iterations` nhỏ trước, rồi nới.** Bắt đầu ở 5, xem nó hỏng ở đâu, hiểu nguyên nhân rồi mới tăng. Nới lên 30 ngay từ đầu chỉ làm lỗi đắt hơn.
- **Log nguyên văn Observation, kể cả lỗi.** Đừng nuốt lỗi thành chuỗi rỗng. Một `ERROR 400` rõ ràng giúp agent tự sửa; một `null` khiến nó đoán mò.
- **Một tool, một việc.** Tool trả về quá nhiều thứ trong một lần gọi làm Observation dài, dễ bị cắt cụt, và agent mất dấu thông tin quan trọng.

## Chốt lại và bước tiếp theo

Bốn điều cần mang theo: ReAct là vòng lặp, không phải một lần gọi; mỗi vòng gồm Thought (lý do), Action (gọi tool), Observation (kết quả, phải quay lại context); vòng lặp chỉ dừng khi có final answer hoặc chạm ngưỡng an toàn; và failure phải được báo là failure. Khi đọc bất kỳ trace nào, hãy kiểm tra ba thứ: Thought có nêu rõ thiếu gì, Action có đủ tham số, Observation có được dùng hay không.

Bài tới mình sẽ mở rộng đúng chỗ này: ReAct quyết định từng bước một, vậy khi nào nên lập cả kế hoạch trước rồi mới thực thi (Plan-and-Execute), và reflection giúp agent tự sửa sai ở đâu. Đó là lúc bạn bắt đầu có tiêu chí để chọn kiến trúc, chứ không chỉ đọc trace.

Front: ReAct là viết tắt của gì?
Back: Reasoning + Acting: agent xen kẽ suy luận và hành động trong một vòng lặp.

Front: Ba nhịp của một bước ReAct?
Back: Thought, Action, Observation.

Front: Thought trong trace ReAct là gì?
Back: Đoạn suy luận nội bộ nêu lý do và dự định cho hành động kế tiếp.

Front: Action trong trace ReAct là gì?
Back: Lời gọi tool cụ thể, có tên tool và tham số.

Front: Observation là gì và phải làm gì với nó?
Back: Kết quả tool trả về (dữ liệu hoặc lỗi); phải chèn lại vào context trước lượt suy luận sau.

Front: Khác biệt cốt lõi giữa ReAct và workflow một lần gọi LLM?
Back: ReAct lặp: output của tool quay lại làm input cho lượt suy luận tiếp theo.

Front: Điều kiện dừng bình thường của vòng lặp ReAct?
Back: Agent phát ra final answer, thường qua tool finish hoặc marker kết thúc.

Front: Vì sao luôn cần max_iterations?
Back: Chặn vòng lặp vô hạn khi agent không tiến triển, và giới hạn chi phí.

Front: Dấu hiệu kinh điển của vòng lặp vô hạn?
Back: Hai Action liên tiếp giống nhau từng ký tự, kèm Observation giống nhau.

Front: Agent nên làm gì khi Observation là thông báo lỗi?
Back: Đọc nội dung lỗi, sửa tham số hoặc đổi tool, rồi thử lại.

Front: Vì sao không được gộp Thought vào Action?
Back: Action phải parse được theo schema; Thought là văn xuôi tự do, gộp lại sẽ hỏng định dạng.

Front: Kết thúc giả là gì?
Back: Agent xuất câu trả lời nghe hợp lý nhưng không dựa trên Observation nào.

Front: Chi phí nào tăng theo số vòng lặp?
Back: Số token, tiền và độ trễ, vì mỗi vòng thêm Thought, Action và Observation vào context.

---

## Contents

Part of [🤖 Agentic AI: hiểu vòng lặp ReAct và chọn kiến trúc agent phù hợp](https://everwise.study/courses/agentic-ai-hieu-vong-lap-react-va-chon-kien-truc-agent-phu-hop.md)

- **🔄 Nền tảng Agentic AI và vòng lặp suy luận**
  - [🧭 Agentic AI là gì và khác gì workflow gọi LLM](https://everwise.study/courses/agentic-ai-hieu-vong-lap-react-va-chon-kien-truc-agent-phu-hop/agentic-ai-la-gi.md)
  - [🔁 Vòng lặp ReAct: Thought, Action, Observation](https://everwise.study/courses/agentic-ai-hieu-vong-lap-react-va-chon-kien-truc-agent-phu-hop/vong-lap-react.md) (sign-in required) — this lesson
  - [🗺️ Planning và reflection: ReAct so với Plan-and-Execute](https://everwise.study/courses/agentic-ai-hieu-vong-lap-react-va-chon-kien-truc-agent-phu-hop/planning-va-reflection.md)
  - [✅ Checkpoint: Vòng lặp suy luận và ra quyết định](https://everwise.study/courses/agentic-ai-hieu-vong-lap-react-va-chon-kien-truc-agent-phu-hop/checkpoint-vong-lap-suy-luan.md)
- **🧰 Tool use, memory và chọn kiến trúc agent**
  - [🔧 Function calling và thiết kế tool cho agent](https://everwise.study/courses/agentic-ai-hieu-vong-lap-react-va-chon-kien-truc-agent-phu-hop/function-calling-va-thiet-ke-tool.md)
  - [🧠 Memory và quản lý trạng thái trong agent](https://everwise.study/courses/agentic-ai-hieu-vong-lap-react-va-chon-kien-truc-agent-phu-hop/memory-va-quan-ly-trang-thai.md)
  - [⚖️ Đánh giá agent và tiêu chí chọn kiến trúc](https://everwise.study/courses/agentic-ai-hieu-vong-lap-react-va-chon-kien-truc-agent-phu-hop/danh-gia-va-chon-kien-truc.md) (premium content)
  - [✅ Checkpoint: Tool, memory và kiến trúc agent](https://everwise.study/courses/agentic-ai-hieu-vong-lap-react-va-chon-kien-truc-agent-phu-hop/checkpoint-tool-memory-kien-truc.md) (premium content)
- [Course cheatsheet](https://everwise.study/courses/agentic-ai-hieu-vong-lap-react-va-chon-kien-truc-agent-phu-hop/cheatsheet.md) (premium content)
