Chuyển đến nội dung
22/30Chương 22 trên 30

AI agent là gì: năm kiểu kinh điển, hai định nghĩa đối nghịch

Thế giới máy hút bụi bị phá bốn lần, mỗi lần tạo ra một trong năm kiểu agent kinh điển. Rồi một công cụ biến 39 token thành 420.

Trên trang này

Đây là cùng một câu hỏi, được hỏi hai lần với cùng một mô hình, cùng weights và greedy decoding. Khác biệt duy nhất là lần thứ hai có một công cụ trong catalogue.

TEXT
no tools in the catalogue
  turn 1  prompt=  39  out=  8  finish=stop        TEXT "The capital of France is Paris."
  => model calls=1  prompt tokens=39  output=8  wall=974 ms

one tool in the catalogue: get_temperature(city)
  turn 1  prompt= 185  out= 20  finish=tool_calls  CALL get_temperature({"city": "Paris"})
          tool  get_temperature -> {"city":"Paris","celsius":11}
  turn 2  prompt= 235  out= 18  finish=stop        TEXT "The capital of France is Paris. It is
                                                        currently at 11 degrees Celsius."
  => model calls=2  prompt tokens=420  output=38  wall=6,685 ms

Một lệnh gọi thành hai. Ba mươi chín input token thành 420, hệ số 10,8. Chưa đầy một giây thành gần bảy giây. Và câu trả lời nhận thêm một dữ kiện không ai hỏi, từ một công cụ mà mô hình tự chọn gọi cho một câu hỏi chưa từng nhắc đến thời tiết.

Hệ thống thứ hai là thứ mà phần lớn ngành năm 2026 gọi là agent. Hoặc không phải, tùy bạn mở định nghĩa nào trong hai định nghĩa được đọc rộng rãi nhất — và hai định nghĩa đó không nói cùng một điều. Một định nghĩa thậm chí còn không tự nhất quán với chính nó.

Sự bất đồng đó là nội dung chương này. Đây không phải cuộc cãi nhau về từ vựng: hai định nghĩa vẽ ranh giới trên hai trục khác nhau, và trục bạn chọn quyết định bạn xây gì và bị tính tiền thế nào. Cả hai đều đứng trên một phân loại cũ hơn, và cách rẻ nhất để hiểu nó là xây agent tệ nhất thế giới.

Hiện chi tiết

Chương này cần gì từ các chương trước.

  • Chương 13 đã đo chi phí thời gian của một lệnh gọi đơn; chương này nhân nó lên theo số lượt.
  • Chương 15: prompt là trạng thái đầy đủ của mô hình, vì không có gì sống sót qua lệnh gọi.
  • Chương 16: input token tăng theo bình phương độ dài cuộc trò chuyện.
  • Chương 18: catalogue công cụ, và vòng khứ hồi trong đó mô hình yêu cầu còn mã của bạn thực thi.

Không có tensor ở đây. Chương này dùng TypeScript, đúng nơi quy tắc ngôn ngữ của Chương 14 đặt nó, và vòng lặp của nó là tổ tiên trực tiếp của vòng lặp trong Chương 23.

Ví dụ lâu đời nhất trong lĩnh vực này là một máy hút bụi trong thế giới gồm hai ô vuông, A và B, mỗi ô hoặc sạch hoặc bẩn.1 Nó tồn tại trong mọi giáo trình vì đây là thế giới nhỏ nhất mà một agent có thể đúng hoặc sai.

Percept là một cặp — tôi đang ở đâu, và chỗ này có bẩn không — còn hành động là SUCK, LEFTRIGHT. Toàn bộ chương trình chỉ một dòng.

reflex.tsTS
type Percept = { dirty: boolean; where?: "A" | "B" };
type Action = "SUCK" | "LEFT" | "RIGHT";

const textbook = (p: Percept): Action =>
  p.dirty ? "SUCK" : p.where === "A" ? "RIGHT" : "LEFT";   

Chạy nó với mọi cấu hình khởi đầu của thế giới hai ô:

TEXT
A dirty, B dirty, start A    -> steps=3 clean=true
A clean, B dirty, start A    -> steps=2 clean=true
A dirty, B clean, start B    -> steps=2 clean=true

Đó là một agent phản xạ đơn giản: nó hành động chỉ dựa trên percept hiện tại, không có ký ức nào về những gì trước đó. Đây không phải một hạng mục đồ chơi — bộ điều nhiệt là một ví dụ, và một lệnh gọi đơn đến mô hình ngôn ngữ không kèm cuộc trò chuyện cũng vậy.

Giờ hãy phá nó theo cách thực tế vẫn làm. Một robot hút bụi thật có cảm biến bụi và cản va, chứ không có một ô vuông được dán nhãn A dưới tấm thảm. Lấy vị trí ra khỏi percept và không đổi gì khác:

reflex.tsTS
const dirtOnly = (p: Percept): Action => (p.dirty ? "SUCK" : "RIGHT");
TEXT
A dirty, B dirty, start A    -> steps=3   clean=true   still dirty=0
      t=0 at=A percept={dirty:true}  -> SUCK
      t=1 at=A percept={dirty:false} -> RIGHT
      t=2 at=B percept={dirty:true}  -> SUCK

A dirty, B clean, start B    -> steps=500 clean=false  still dirty=1
      t=0 at=B percept={dirty:false} -> RIGHT
      t=1 at=B percept={dirty:false} -> RIGHT
      t=2 at=B percept={dirty:false} -> RIGHT
      t=3 at=B percept={dirty:false} -> RIGHT

Cùng một chương trình, hai ô vuông. Từ một trạng thái khởi đầu, nó hoàn thành trong ba bước; từ một trạng thái khác, nó lao vào bức tường bên phải năm trăm lần và sẽ tiếp tục cho đến khi hết pin. Nó không thể cảm nhận được khác biệt giữa hai tình huống, nên nó không thể hành động khác đi. Russell và Norvig nêu kết quả tổng quát trong một dòng: vòng lặp vô hạn thường là không thể tránh khỏi với agent phản xạ đơn giản trong môi trường quan sát được một phần.1

Có một cách sửa tốn một dòng và không cần bộ nhớ, đáng đo trước khi ta tìm đến thứ thông minh hơn.

reflex.tsTS
let seed = 12345;
const rnd = () => ((seed = (seed * 1103515245 + 12345) & 0x7fffffff) / 0x7fffffff);

const coin = (p: Percept): Action => (p.dirty ? "SUCK" : rnd() < 0.5 ? "LEFT" : "RIGHT");  

Hai nghìn lần chạy trong một hành lang toàn bẩn ở ba kích thước, dùng cùng một bộ sinh ngẫu nhiên có seed xuyên suốt:

roomsmean stepsmedianworst of 2,000never finished
24.04130
416.614810
868.7523060

Ngẫu nhiên hóa loại bỏ hoàn toàn vòng lặp. Nó cũng có chi phí: tám phòng cần mười lăm bước nếu bạn biết mình đang làm gì, còn agent này trung bình cần 68,7 bước và có lần mất 306 bước. Đó là toàn bộ chương ở dạng thu nhỏ. Mỗi năng lực ta thêm vào mua lại tính đúng đắn trong một trường hợp mà agent trước không xử lý được, và thu phí bằng một loại tiền tệ mà trước hết bạn phải đặt tên.

Một agent cảm nhận môi trường qua cảm biến và hành động qua bộ chấp hành. Chương trình agent là hàm từ percept sang hành động — mọi listing ở trên đều là một chương trình như vậy. Chuỗi percept là tất cả những gì đã được cảm nhận cho đến nay, và agent phản xạ đơn giản bỏ qua tất cả trừ mục cuối cùng.

Tính hợp lý là từ mà đa số bài viết hiểu sai, và hiểu đúng nó khiến phần còn lại của chương này dùng được. Một agent tự thân không hợp lý hay phi lý. Russell và Norvig định nghĩa agent hợp lý là agent, với mỗi chuỗi percept có thể có, chọn hành động được kỳ vọng tối đa hóa thước đo hiệu năng của nó, dựa trên bằng chứng của chuỗi đó và bất kỳ tri thức tích hợp nào nó có.1 Thước đo hiệu năng không nằm bên trong agent: nó thuộc về nhà thiết kế, và tính hợp lý chỉ được định nghĩa tương đối với thước đo đó.

Đặc tả thường được viết thành bốn thứ, PEAS: performance measure, environment, actuators, sensors.

robot hút bụisupport agent trong production
Performance measuresố ô sạch, trên mỗi đơn vị pinticket được giải quyết, trên mỗi đô la, không escalation
Environmentsàn nhà, bụi bẩn, đồ đạc, thảmhàng đợi ticket, cơ sở dữ liệu của bạn, khách hàng
Actuatorsbánh xe, lực hútlệnh gọi công cụ
Sensorscảm biến bụi, cản vatin nhắn của người dùng, kết quả công cụ

Hãy để ý hàng nào là hàng lệch nhịp. Hầu như mọi đội xây agent năm 2026 đều ghi E, A và S — schema công cụ, tích hợp, định dạng tin nhắn — vì thiếu chúng thì code không chạy. Hầu như không ai ghi P. Không có nó, câu “agent của chúng ta đang làm tốt” không có nghĩa nào kiểm chứng được, và “hợp lý” không thể áp dụng cho hệ thống, chỉ áp dụng cho một màn demo. Chương 29 nói về việc biến P thành một con số, và đây là lý do nó tồn tại.

TEXT
    ┌───────────────────────── the environment ─────────────────────────┐
    │                                                                   │
    │   ┌──────────────────────── the agent ─────────────────────┐      │
    │   │                                                        │      │
 ───┼──►│  sensors  ──►  the agent program  ──►  actuators  ─────┼──────┼──►
percept │                                                        │    action
    │   └────────────────────────────────────────────────────────┘      │
    └───────────────────────────────────────────────────────────────────┘

              the performance measure lives out here, in the head of
              whoever built the thing, and the agent cannot change it

Môi trường tác vụ còn được phân loại theo bảy trục, trong đó năm trục quyết định phần lớn độ khó ở đây: quan sát được đầy đủ hay một phần, tất định hay không, episodic hay sequential, static hay dynamic, known hay unknown.1 Một agent nói chuyện với công cụ thật qua mạng thật nằm ở góc khó của cả năm — phi tất định ngay cả ở temperature bằng không (Chương 17), và điểm bị đánh giá thấp là unknown, vì bạn không có mô hình đáng tin cậy về việc chính công cụ của bạn tác động gì đến thế giới. Đó là lý do vòng lặp của Chương 23 cần xử lý lỗi nhiều hơn là lập kế hoạch.

Thêm bộ nhớ, rồi tìm thấy bức tường tiếp theo

Liên kết đến mục: Thêm bộ nhớ, rồi tìm thấy bức tường tiếp theo

Sàn nhà thật không một chiều, nên hãy nâng thế giới thành một sơ đồ. Dấu thăng là tường, dấu hoa thị là bụi, và robot bắt đầu ở buồng giữa:

TEXT
        col  0 1 2 3 4 5 6
      row 0  * . . # . . *
      row 1  . # . # . # .
      row 2  . # . S . # .        S = the robot starts here
      row 3  . # . # . # .
      row 4  * . . # . . *

Nâng cấp hiển nhiên là bộ nhớ. Agent giữ một bản đồ: mọi ô nó từng đứng lên và mọi ô nơi cản va đã kích hoạt. Quy tắc của nó là đi vào một ô kề bên chưa từng ghé — phải, rồi xuống, rồi trái, rồi lên — và lùi lại khi mọi thứ xung quanh đã biết. Đây là một agent phản xạ dựa trên mô hình: nó duy trì trạng thái nội bộ từ lịch sử percept, nên có thể hành động dựa trên thứ hiện tại nó không nhìn thấy.

Đó là cải tiến thật, và vẫn chưa đủ:

TEXT
5,000 steps allowed -> steps=5,000  distinct squares visited=13/25  still dirty=2/4

Năm nghìn bước, nửa sàn chưa từng được nhìn thấy. Bản đồ đúng và quy tắc đúng. Thứ agent không làm được là dùng bản đồ để đi đến nơi nào đó: quy tắc của nó chỉ luôn trả lời “trong bốn hàng xóm của tôi, tôi nên bước vào ô nào”, nên một khi hết ô chưa ghé ngay cạnh, nó không có cách diễn đạt ý nghĩ có một ô chưa ghé cách tám bước và tôi muốn đứng trên đó. Nó biết mình đang ở đâu. Nó không biết mình muốn ở đâu.

Một mục tiêu, rồi một lý do để thích tuyến này hơn tuyến khác

Liên kết đến mục: Một mục tiêu, rồi một lý do để thích tuyến này hơn tuyến khác

Một agent dựa trên mục tiêu giữ, bên trên mô hình thế giới của nó, một mô tả về tình huống nó muốn tạo ra, và chọn hành động bằng cách tìm kiếm trên các chuỗi hành động cho đến khi tìm được chuỗi kết thúc ở đó. Mục tiêu biến việc chọn hành động từ tra cứu thành tìm kiếm.

Mục tiêu là “không còn ô bẩn”. Tìm kiếm là một bước đi breadth-first đến ô bẩn gần nhất, và đường đi nó trả về là kế hoạch.

TEXT
goal-based (fewest moves)      -> moves=27  battery=52  still dirty=0
      from 2,3 -> 4,6 via 5 moves:  2,3 2,4 3,4 4,4 4,5 4,6
      from 4,6 -> 0,6 via 4 moves:  4,6 3,6 2,6 1,6 0,6
      from 0,6 -> 4,0 via 10 moves: 0,6 0,5 0,4 1,4 2,4 2,3 2,2 3,2 4,2 4,1 4,0
      from 4,0 -> 0,0 via 4 moves:  4,0 3,0 2,0 1,0 0,0

Hai mươi bảy bước, sàn sạch. Nhưng hãy nhìn cột pin và chặng cuối của kế hoạch. Cột 0 có thảm: băng qua một ô có thảm tốn sáu đơn vị pin, một ô lát gạch tốn một. Agent đi về nhà theo cột 0 vì đó là bốn bước thay vì tám, và bốn bước trên thảm đó tốn 24 trong khi đường vòng tám bước chỉ tốn 13.

Nó không thể làm khác. Mục tiêu là một phép kiểm tra nhị phân: sàn sạch hoặc không. Mọi kế hoạch kết thúc với sàn sạch đều thỏa mãn như nhau, nên khi nhiều kế hoạch cùng thành công, agent không có gì để chọn giữa chúng. Ưu tiên một thành công hơn một thành công khác cần một con số trên các kết quả, và con số đó là hàm tiện ích. Agent tối đa hóa nó là agent dựa trên tiện ích.

Thay đổi trong code chỉ là một hạng tử bên trong tìm kiếm. Breadth-first search đếm số bước; đổi nó thành đếm chi phí và bạn có thuật toán Dijkstra cùng một agent khác:

search.tsTS
const nd = dist.get(k)! + (byCost ? cell.cost : 1);   // <- the entire difference
TEXT
goal-based    (fewest moves)   -> moves=27  battery=52  still dirty=0
utility-based (cheapest route) -> moves=31  battery=41  still dirty=0
      from 4,0 -> 0,0 via 8 moves: 4,0 4,1 4,2 3,2 2,2 1,2 0,2 0,1 0,0

Thêm bốn bước, ít hơn mười một đơn vị pin: rẻ hơn hai mươi mốt phần trăm. Cùng mục tiêu, cùng bản đồ, cùng code trừ một hạng tử. Hai agent chỉ khác nhau ở thứ chúng đang cố giỏi, và chúng chọn đường về nhà khác nhau.

Đây cũng là điểm đầu tiên agent cần một thứ nó không tự tạo ra được. Ai đó phải quyết định một đơn vị pin đáng giá bao nhiêu so với một bước di chuyển. Tiện ích là thước đo hiệu năng được viết ở dạng agent có thể tính toán, và viết nó là việc của nhà thiết kế. Khi người ta nói một agent “tối ưu sai thứ”, họ hầu như không bao giờ nói về bug. Họ muốn nói dòng này đã được viết cẩu thả.

Giờ hãy để bụi quay lại. Bốn phòng bẩn trở lại với bốn tốc độ khác nhau, và agent không bao giờ được cho biết các tốc độ đó. Nó ghé một phòng mỗi tick và chỉ thấy phòng đó. Thước đo hiệu năng là room-tick bị bẩn trong 4.000 tick — càng thấp càng tốt.

Một agent học trong phân rã của giáo trình là bất kỳ agent nào ở trên cộng thêm ba phần: một phần tử học thay đổi agent, một critic cho nó biết agent đang làm thế nào so với một tiêu chuẩn hiệu năng cố định, và một problem generator đề xuất các hành động đáng thử vì những gì chúng có thể dạy.1 Ba policy trong cùng môi trường. Policy đầu tiên không học; policy thứ hai và thứ ba học cùng một thứ và dùng nó khác nhau.

policydirty-room-ticks over 4,000versus the patrol
tuần tra round-robin cố định, không học2,290
learner A: ước lượng tốc độ bẩn của từng phòng, rồi đi nơi có khả năng bẩn cao nhất11,820tệ hơn 5,2×
learner B: cùng ước lượng, có trọng số theo thời gian từ lần ghé cuối1,576tốt hơn 31 %

Các tốc độ ẩn là 0,35 cho bếp, 0,05 cho hành lang, 0,02 cho phòng làm việc và 0,01 cho gác mái — và learner A đã tìm ra chúng. Nó xác định đúng bếp là phòng bẩn nhất nhà, rồi đi đến bếp ở mọi tick còn lại của mô phỏng trong khi ba phòng kia cứ bẩn mãi. Nó tệ gấp năm lần so với không học gì, và nó không hỏng.

Bài học là bài học của phần tiện ích. Learner A tối đa hóa “xác suất căn phòng tôi sắp ghé bị bẩn”. Thước đo hiệu năng là “room-tick bị bẩn”. Hai con số khác nhau; con số thứ hai là thứ critic chấm điểm, và không ai nói với agent. Learner B nhân cùng tốc độ đã học với thời gian từ lần ghé cuối — lượng bụi nó kỳ vọng tìm thấy thay vì cơ hội tìm thấy bất kỳ bụi nào — và đánh bại cuộc tuần tra mà nó bắt đầu từ đó.

Một chi tiết triển khai quyết định kết quả. Trong phiên bản đầu của learner B, một phòng mà không có bụi xuất hiện trong ba lần ghé có tốc độ đúng bằng không — và không nhân với bất cứ gì vẫn là không, nên nó không bao giờ được ghé lại và ước lượng không bao giờ được sửa. Làm mượt phân số, số lần thành công cộng một trên số lần thử cộng hai, biến 11.895 thành 1.576. “Chưa quan sát thấy” và “đã đo và ra bằng không” là hai mệnh đề khác nhau, và một hệ thống lưu chúng vào cùng một trường sẽ đưa ra những quyết định nó không thể hoàn tác.

TEXT
  1  simple reflex    percept ────────────────────────────────► rules ────► action
  2  model-based      percept ──► [state] ──────────────────► rules ────► action
  3  goal-based       percept ──► [state] ──► [goal] ──────► search ───► action
  4  utility-based    percept ──► [state] ──► [goal] ──► [U] ──► argmax ► action
  5  learning         all of the above, plus [critic] ──► changes the parts above

Cả năm kiểu đều đang chạy trong production ngày nay dưới tên khác.

classic typewhat it carries between perceptsits 2026 shapewhat it cannot do
simple reflexkhông gìmột lệnh gọi mô hình không có lịch sử: classifier, endpoint trích xuất, completion một lượtbất kỳ thứ gì phụ thuộc vào lượt trước
model-based reflextrạng thái nội bộ xây từ lịch sử perceptmột chat: transcript, được gửi lại toàn bộ ở mọi lệnh gọichọn cuộc trò chuyện nên kết thúc ở đâu
goal-basedtrạng thái cộng mô tả tình huống mong muốnvòng lặp reason-and-act với điều kiện dừng2ưu tiên một kế hoạch thành công hơn kế hoạch khác
utility-basedtrạng thái, mục tiêu, và một con số trên kết quảvòng lặp evaluator–optimiser, và xếp hạng câu trả lời ứng viên theo tiêu chí được viết ra (Chương 25)phát minh tiêu chí
learningtất cả những thứ đó, cộng critic và problem generatorReflexion, ghi bài học của chính nó vào episodic buffer thay vì cập nhật weights;3 bộ nhớ người dùng bền vững (Chương 24)chọn tiêu chuẩn mà critic chấm theo

Hai hàng gần hơn một phép loại suy, theo một cách tốn tiền.

Chat là một agent phản xạ dựa trên mô hình mà mô hình của nó không nằm bên trong. Trong giáo trình, trạng thái là một biến bên trong chương trình agent. Trong chat, nó là transcript: nó sống ở phía bạn, được gửi lại đầy đủ ở mọi lệnh gọi, và được dựng lại từ đầu bên trong mô hình mỗi lần. Đó là hóa đơn bậc hai của Chương 16, và nó là cùng đối tượng mà giáo trình vẽ thành một hộp dán nhãn “state”. Đây là khác biệt, được đo trên một câu hỏi tiếp nối có và không có hai tin nhắn trước nó:

TEXT
with the transcript      prompt=67  "The current temperature in Lisbon, Portugal is 15°C."
without the transcript   prompt=29  "Lisbon is the capital of Portugal, not a city in Portugal."

Cùng mô hình, cùng ba từ đầu vào của người dùng, và câu thứ hai là robot hành lang đang lao vào tường. Không có công cụ nào trong lần chạy đó, nên con số 15 là bịa — nhưng trạng thái là thứ khiến câu hỏi tiếp nối có nghĩa. Bạn dựng lại nó mỗi lần và trả 2,3× input token cho nó trong một cuộc trò chuyện hai lượt. Chương 16 đã đo hệ số đó đạt đến đâu ở lượt bốn mươi.

Reflexion là một agent học thay đổi input thay vì chương trình. Trong phân rã giáo trình, phần tử học sửa đổi phần tử hiệu năng. Reflexion giữ nguyên weights và ghi văn bản phản tư vào một episodic buffer mà lần thử tiếp theo đọc.3 Phần tử học là một prompt, bộ nhớ là một hàng cơ sở dữ liệu, phần tử hiệu năng là một mô hình đóng băng — và sơ đồ vẫn là sơ đồ trong giáo trình, không đổi.

Và đây là giới hạn trung thực của phép ánh xạ. Năm kiểu phân loại chương trình agent. Năm 2026, chương trình đó bị chẻ đôi: một phần là code của bạn, một phần nằm trong weights mà bạn không huấn luyện. Khi một mô hình tự quyết định gọi công cụ, phép kiểm tra mục tiêu nằm trong chương trình của bạn hay trong mô hình? Phân loại không có câu trả lời, vì khi nó được viết thì không còn nơi nào khác để đặt nó — và chính câu hỏi đó là nơi hai định nghĩa hiện đại tách nhau.

Các định nghĩa là tranh luận về hành vi, và dễ đánh giá hơn nhiều khi có một trace trước mặt.

Vòng lặp bên dưới gửi cuộc trò chuyện đến một mô hình; nếu phản hồi chứa lệnh gọi công cụ thì nó thực thi công cụ, nối kết quả vào và gửi lại toàn bộ. Nó chạy với một Qwen2.5-0.5B-Instruct cục bộ đằng sau endpoint dạng OpenAI trên máy này — đường nối từ Chương 14, nên vòng lặp không biết và không quan tâm thứ gì nằm sau cổng.

loop.tsTS
const BASE = process.env.LLM_BASE_URL ?? "http://127.0.0.1:8799/v1";

async function loop(question: string, maxTurns = 6) {
  const messages: Msg[] = [
    { role: "system", content: SYSTEM },
    { role: "user", content: question },
  ];

  for (let turn = 1; turn <= maxTurns; turn++) {
    const reply = await call(messages, TOOLS);
    const calls = reply.choices[0].message.tool_calls ?? [];
    messages.push(reply.choices[0].message);

    if (!calls.length) return messages;                      

    for (const c of calls) {
      const out = runTool(c.function.name, JSON.parse(c.function.arguments));
      messages.push({ role: "tool", name: c.function.name, content: out });
    }
  }
  throw new Error("turn cap reached");                       
}

Hai dòng mang toàn bộ ý tưởng, và cả hai đều được đánh dấu; phần còn lại là bookkeeping. Cả ba hành vi đều hiện ra trong một lần chạy. Khi được hỏi thứ nó tự làm được, mô hình trả lời. Khi được hỏi thứ nó không làm được, nó gọi:

TEXT
=== a question the model cannot answer, one tool available
  turn 1  prompt= 187  out= 21  finish=tool_calls  CALL get_temperature({"city": "Oslo"})
          tool  get_temperature -> {"city":"Oslo","celsius":4}
  turn 2  prompt= 238  out= 12  finish=stop        TEXT "The current temperature in Oslo is 4
                                                        degrees Celsius."
  => model calls=2  prompt tokens=425  output=33  wall=6,257 ms
  => stopped by: the model produced text instead of a call

Và nó dừng — hành vi thứ ba, cũng là hành vi dễ bỏ lỡ nhất, vì trông như không có gì xảy ra. Vòng lặp kết thúc vì lượt 2 quay lại không có lệnh gọi công cụ. Không ai quyết định điều đó; mô hình quyết định, bằng cách phát ra văn xuôi. Điều kiện kết thúc của chương trình này là dấu hiệu của một sự vắng mặt.

Hai lần chạy nữa đáng để ghi lại. Khi được yêu cầu so sánh hai thành phố, mô hình phát hành cả hai lệnh gọi công cụ trong một lượt, nhận cả hai số đo, rồi so sánh sai:

TEXT
  turn 1  prompt= 188  out= 43  finish=tool_calls  CALL get_temperature({"city": "Oslo"}),
                                                        get_temperature({"city": "Lisbon"})
          tool  get_temperature -> {"city":"Oslo","celsius":4}
          tool  get_temperature -> {"city":"Lisbon","celsius":19}
  turn 2  prompt= 284  out= 13  finish=stop        TEXT "Oslo is currently warmer than Lisbon
                                                        at 4°C."

Công cụ hoạt động. Lệnh gọi song song hoạt động. Vòng lặp hoạt động. Câu trả lời sai, dù cả hai con số đúng đang nằm trong transcript. Bọc một mô hình trong vòng lặp không làm nó biết suy luận; nó cho một mô hình đang sai khả năng hành động dựa trên cái sai của nó — đó là Chương 30 được báo trước, và một nửa Chương 29.

Giờ xóa return đã được đánh dấu và để vòng lặp chạy đến giới hạn. Cùng câu hỏi, cùng mô hình:

TEXT
  turn 1  prompt= 187  out= 21  CALL get_temperature({"city": "Oslo"})
  turn 2  prompt= 238  out= 12  TEXT "The current temperature in Oslo is 4 degrees Celsius."
  turn 3  prompt= 261  out= 30  TEXT "Could you please specify the exact location you're..."
  turn 4  prompt= 302  out= 14  TEXT "Sure! Could you tell me which city you're interested in?"
  turn 5  prompt= 327  out= 35  TEXT "I'm sorry, but I need more details to provide an..."
  turn 6  prompt= 373  out= 12  TEXT "Which city would you like to know the temperature for?"
  => model calls=6  prompt tokens=1,688  output=124  wall=25,261 ms  stopped by: turn cap

Gấp bốn lần input token, gấp bốn lần wall clock, và một kết thúc trong đó agent đã quên nó được hỏi gì và đang chất vấn người dùng về một câu hỏi họ đã trả lời ở lượt một. Câu trả lời đúng đã ở trên màn hình tại lượt 2, và mọi lượt sau đó làm transcript tệ hơn.

Vậy agent không phải một vòng lặp. Nó là một vòng lặp cộng một quy tắc để rời khỏi nó, và vòng lặp này có đúng một quy tắc như vậy. Chương 23 tìm thấy năm quy tắc, và cho thấy điều gì hỏng khi thiếu từng quy tắc.

Cả hai được trích nguyên ý thay vì diễn giải, vì diễn giải là nơi sự nhầm lẫn được sản xuất.

Định nghĩa một đặt ranh giới ở chỗ ai kiểm soát luồng. Building effective agents của Anthropic gọi tên sự mơ hồ và đưa ra phán quyết:

“Tại Anthropic, chúng tôi phân loại tất cả các biến thể này là agentic systems, nhưng vạch ra một khác biệt kiến trúc quan trọng giữa workflows và agents: Workflows là các hệ thống nơi LLMs và công cụ được điều phối qua các đường dẫn code định sẵn. Ngược lại, agents là các hệ thống nơi LLMs linh hoạt chỉ đạo quy trình và việc dùng công cụ của chính chúng, duy trì quyền kiểm soát cách chúng hoàn thành tác vụ.”4

Bài kiểm tra là một câu hỏi về source code của bạn: ai chọn bước tiếp theo? Một switch trong chương trình của bạn: workflow. Mô hình: agent. Cùng tài liệu nói agents “thường chỉ là LLMs dùng công cụ dựa trên phản hồi môi trường trong một vòng lặp” — chính xác là listing ở trên.

Định nghĩa hai đặt ranh giới ở mức độc lập với người dùng. A practical guide to building agents của OpenAI mở trang định nghĩa như sau:

“Trong khi phần mềm thông thường giúp người dùng tinh giản và tự động hóa workflows, agents có thể thực hiện cùng các workflows đó thay mặt người dùng với mức độ độc lập cao. Agents là các hệ thống độc lập hoàn thành tác vụ thay mặt bạn.”5

Hai câu sau, trên cùng trang, nó loại trừ:

“Các ứng dụng tích hợp LLMs nhưng không dùng chúng để kiểm soát việc thực thi workflow — chẳng hạn chatbots đơn giản, LLMs một lượt, hoặc sentiment classifiers — không phải agents.”5

Đọc các trích dẫn đó theo thứ tự. Các câu mở đầu vạch ranh giới ở tính độc lập: thứ này có tự đi làm và hoàn tất công việc mà không cần tôi không? Câu thứ tư vạch ranh giới ở quyền kiểm soát thực thi, đúng y như ranh giới của Anthropic. Hai bài kiểm tra khác nhau, cùng một trang, và có những hệ thống thật mà chúng bất đồng.

Bên dưới là một va chạm từ vựng, và nó gây tranh luận trong các cuộc họp thật. Trong tài liệu thứ nhất, workflow là một kiến trúc, và là thứ không phải agent. Trong tài liệu thứ hai, workflow là “một chuỗi bước phải được thực thi để đạt mục tiêu của người dùng” — chính công việc, thứ mà mọi agent đều có một cái. “Chúng tôi thay workflow bằng agent” là câu mạch lạc theo định nghĩa thứ nhất và gần như vô nghĩa theo định nghĩa thứ hai.

Ba hệ thống tồn tại năm 2026, dưới cả hai định nghĩa.

Bạn mô tả một tác vụ; nó đọc file, chạy bộ kiểm thử, chỉnh sửa, chạy lại, và dừng khi kiểm thử pass hoặc khi nó bỏ cuộc. Không có gì trong code của bạn quyết định bước tiếp theo là “chạy kiểm thử” — mô hình quyết định, từ thứ công cụ cuối trả về.

Định nghĩa một: agent, vì mô hình tự chỉ đạo quy trình của nó. Định nghĩa hai: agent, vì nó độc lập hoàn thành tác vụ, nhận ra hoàn thành và trả quyền kiểm soát lại. Cả hai tài liệu đều trích dạng này làm ví dụ trung tâm.

Với mỗi support ticket mới, ba lệnh gọi mô hình theo thứ tự cố định — phân loại, trích xuất trường, soạn câu trả lời — rồi gửi. Không mô hình nào từng chọn điều gì xảy ra tiếp theo; một vòng lặp for làm việc đó. Nó chạy lúc 03:00 và không ai theo dõi.

Định nghĩa một: không phải agent. Đây là prompt chaining, được liệt kê đích danh là workflow. Định nghĩa hai: cả hai câu trả lời. Theo các câu mở đầu, nó độc lập hoàn thành tác vụ thay mặt bạn; theo câu thứ tư, nó không dùng mô hình để kiểm soát việc thực thi workflow, và bị loại trừ. Hệ thống này là lý do bạn đọc cả trang thay vì chỉ pull quote.

Một lượt người dùng. Mô hình tự quyết định có tìm kiếm trước khi trả lời hay không, rồi trả lời và chờ bạn.

Định nghĩa một: agent, vì mô hình linh hoạt chỉ đạo việc dùng công cụ của chính nó trên kết quả từ môi trường, đúng bài kiểm tra đã nêu. Định nghĩa hai: không phải agent, vì không có tính độc lập — một lượt, rồi trả lại — và “chatbots đơn giản” có tên trong danh sách loại trừ.

Hai trong ba hệ thống đổi phe. Đó không phải thất bại của tài liệu nào. Đó là lời cảnh báo về một kiểu cuộc họp trong đó hai người hoàn toàn đồng ý về việc một hệ thống làm gì lại mất một giờ bất đồng về việc gọi nó là gì.

Các định nghĩa va nhau vì mỗi định nghĩa ép hai câu hỏi độc lập vào một từ. Tách chúng ra và bất đồng trở thành một bảng, hữu ích hơn một phán quyết.

code của bạn chọn bước tiếp theomô hình chọn bước tiếp theo
một người theo dõi từng lượtmột form có mô hình bên trong: classifiers, trích xuất, completion một lượtchat có công cụ — định nghĩa một nói là agent, định nghĩa hai nói không
không ai theo dõi cho đến khi xongmột pipeline — phần mở đầu của định nghĩa hai nói là agent, câu thứ tư nói khôngmọi người đồng ý: agent

Mỗi định nghĩa tranh chấp một ô khác nhau, còn hai ô kia không có gì tranh chấp. Vì vậy khi nhãn gọi quan trọng — trong hợp đồng, đánh giá rủi ro, postmortem — hai câu đáng viết không phải “nó có phải agent không” mà là ai chọn bước tiếp theoai đang theo dõi. Cả hai đều trả lời được bằng cách đọc code, không câu nào cần định nghĩa của ai, và cùng nhau chúng mang mọi hệ quả mà cái nhãn từng đại diện.

Không có gì trong này là mới. Wooldridge và Jennings đã khảo sát các nghĩa cạnh tranh của “agent” vào năm 1995;6 Franklin và Graesser hỏi câu hỏi của chương này năm 1996, gom các định nghĩa đang lưu hành và thấy chúng bất đồng.7 Một khảo sát năm 2023 vẫn định nghĩa agents từ nguyên lý đầu tiên — “các thực thể nhân tạo cảm nhận môi trường, đưa ra quyết định và thực hiện hành động”8 — vì không có gì đã được chốt để trích dẫn, còn CoALA mô tả các phần thay vì vạch ranh giới.9 Ba mươi năm từ chối thống nhất cho thấy từ này đang làm nhiều hơn một việc.

Giờ đến hệ quả xuất hiện trước triết học: hóa đơn.

Mọi phép đo ở đây có cùng hình dạng. Lệnh gọi đơn tốn 39 input token; cùng câu hỏi với một công cụ tốn 420 qua hai lệnh gọi; vòng lặp bị gỡ quy tắc dừng tốn 1.688 qua sáu lệnh gọi. Tăng trưởng tệ hơn tuyến tính, vì lượt n mang theo mọi lượt trước đó: cột prompt của lần chạy sáu lượt đó là 187, 238, 261, 302, 327, 373. Chương 16 đã suy ra tổng là Θ(n2)\Theta(n^2) và fit đường cong trên một cuộc trò chuyện thật. Một agent biến mọi tác vụ thành cuộc trò chuyện đó, dù có người nào từng nhìn thấy nó hay không.

Nếu các số token đo được đó được gửi đến một endpoint thương mại theo mức giá Chương 16 đọc ngày 6 tháng 9 năm 2026 — $2,00 mỗi triệu input token và $12,00 mỗi triệu output token — bốn lần chạy có giá như sau:

runmodel callsinput tokensoutput tokenscost
câu hỏi, không công cụ1398$0.000174
cùng câu hỏi, một công cụ trong catalogue242038$0.001296
một câu hỏi cần công cụ242533$0.001246
cũng câu đó, với quy tắc dừng bị gỡ61,688124$0.004864

Hàng hai so với hàng một là con số cần giữ lại. Chi phí gấp bảy lần rưỡi, cho một câu trả lời tệ hơn với câu hỏi mô hình vốn đã biết. Không có gì cấu hình sai: một công cụ tồn tại, nên mô hình dùng nó — và phát hiện của Chương 18, rằng giá của một catalogue chứ không phải độ chính xác của nó mới là thứ gây đau, có minh họa rẻ nhất ở đây với catalogue chỉ có một mục.

Đó là lý do nửa hữu ích của cả hai tài liệu là nửa nói về việc đừng xây thứ này. Anthropic nói thẳng: hãy tìm giải pháp đơn giản nhất có thể và chỉ thêm độ phức tạp khi cần, điều này “có thể nghĩa là hoàn toàn không xây agentic systems”, vì agentic systems “đổi latency và chi phí lấy hiệu năng tác vụ tốt hơn” và “với nhiều ứng dụng, tối ưu các lệnh gọi LLM đơn với retrieval và ví dụ trong context thường là đủ”.4 Trường hợp nên dùng agent của họ hẹp: bài toán mở, nơi bạn không thể dự đoán số bước và không thể hardcode một đường đi, trong một môi trường bạn tin tưởng, chấp nhận “chi phí cao hơn, và khả năng lỗi cộng dồn”.4 Màn hình của OpenAI là ảnh phản chiếu — phán đoán phức tạp, bộ quy tắc không thể bảo trì, dữ liệu không cấu trúc — và kết thúc giống vậy: “nếu không, một giải pháp tất định có thể là đủ”.5

Vậy, trong phân loại của chương này: một số bước cố định theo thứ tự cố định là pipeline, và gọi nó là agent sẽ không làm nó nhanh hơn. Nếu số bước phụ thuộc vào thứ bạn tìm thấy trên đường, bạn muốn một vòng lặp — và bạn mua sự linh hoạt đó bằng N lệnh gọi, transcript bậc hai, và một hệ thống có thể sai N lần thay vì một lần.

Giờ bạn đã có phân loại, cả hai định nghĩa hiện đại, hai trục khiến chúng tương thích, và một vòng lặp ngắn biết trả lời, gọi và dừng.

Vòng lặp đó có một cách kết thúc: mô hình ngừng yêu cầu công cụ. Chương 23 cố ý phá nó bảy lần, và mỗi lần phá thêm một mảnh. Một tác vụ bất khả thi, và nó không bao giờ kết thúc — giới hạn lượt. Một đêm chạy liên tục, và hóa đơn đến — ngân sách đô la. Một công cụ thất bại — lỗi mà mô hình có thể hành động dựa trên đó. Cùng một lệnh gọi hai lần — idempotency key. Một file nó không nên chạm vào — phê duyệt của con người. Khởi động lại giữa chừng — session persistence. Một công cụ mất ba phút trong im lặng — tiến trình và hủy. Thứ đi ra là một harness, file mà phần còn lại của khóa học này chạy trên đó.

Điều đó để lại câu hỏi mà đường chéo gây tranh cãi của chương này thật sự nhắm đến. Một vòng lặp tự quyết định bước tiếp theo phải quyết định khi nào dừng, và ta vừa xem điều gì xảy ra khi nó không thể: sáu lượt, hóa đơn gấp bốn, và một agent chất vấn người dùng về câu hỏi nó đã trả lời rồi. Dừng không phải một điều kiện. Có bao nhiêu điều kiện, và điều kiện nào kích hoạt trước?


LLM Powered Autonomous Agents (2023) của Lilian Weng là phân rã nổi tiếng nhất của một language agent thành planning, memory và tool use, và là bài đọc tiếp theo đúng đắn bên cạnh hai tài liệu của nhà cung cấp; ba thành phần của nó lần lượt là Chương 23, 24 và 18 của khóa học này.

Mọi con số trong chương này được tạo trên máy này và không có gì được ước lượng. Hành lang, sơ đồ sàn, bốn agent đi trên đó và ba policy tuần tra là TypeScript ở trên, chạy trên Node 22; số liệu của agent ngẫu nhiên là trung bình trên 2.000 lần chạy có seed mỗi loại và số liệu tuần tra là các lần chạy có seed đơn trong 4.000 tick. Model traces đến từ Qwen2.5-0.5B-Instruct ở float32 trên CPU với greedy decoding, được phục vụ qua loopback bởi một endpoint Python cục bộ nhỏ tải weights và nói theo dạng OpenAI chat-completions — lại là đường nối đó, với tensor ở phía Python và vòng lặp ở phía TypeScript — nên số token là tokenizer của mô hình đó và latency là của máy đó. Các số duy nhất lấy từ nơi khác là hai mức giá trong bảng chi phí, tức mức giá Chương 16 đọc từ trang giá của OpenAI ngày 6 tháng 9 năm 2026, được áp dụng ở đây cho số token đo cục bộ như một minh họa chứ không phải hóa đơn quan sát được.

  1. Russell, S. và Norvig, P. Artificial Intelligence: A Modern Approach, tái bản lần 4, chương 2, Intelligent Agents. Nguồn của thế giới máy hút bụi, đặc tả PEAS, định nghĩa tính hợp lý tương đối với một thước đo hiệu năng, bảy thuộc tính của môi trường tác vụ, năm kiểu agent dùng ở đây, và quan sát rằng vòng lặp vô hạn thường là không thể tránh khỏi với agent phản xạ đơn giản trong môi trường quan sát được một phần. Code đồng hành của sách là aimacode/aima-python trên GitHub (8.806 stars, lần push cuối 30 tháng 6 năm 2026, đọc ngày 7 tháng 9 năm 2026) — đáng gọi tên chính xác theo bản chất của nó. Đó là repository đi kèm một cuốn sách, không phải reference implementation mà các dự án khác xây dựa trên như karpathy/micrograd (17.412) và karpathy/nanoGPT (62.852). Đó là lý do chương này trích và liên kết nó thay vì dịch nó, và là lý do lập luận hệ sinh thái từng giữ Chương 5 ở Python không áp dụng ở đây: không có gì trong chương này chạm đến tensor, và vòng lặp viết ở trên là tổ tiên trực tiếp của Chương 23. 2 3 4 5

  2. Yao, S., Zhao, J., Yu, D., Du, N., Shafran, I., Narasimhan, K. và Cao, Y. ReAct: Synergizing Reasoning and Acting in Language Models. arXiv:2210.03629 (2022). Sự đan xen giữa reasoning traces và hành động mà hàng dựa trên mục tiêu của bảng ánh xạ nhắc đến.

  3. Shinn, N., Cassano, F., Berman, E., Gopinath, A., Narasimhan, K. và Yao, S. Reflexion: Language Agents with Verbal Reinforcement Learning. arXiv:2303.11366 (2023). Tóm tắt cơ chế của chính bài báo là lý do nó ánh xạ vào agent học: nó củng cố agents “không bằng cách cập nhật weights, mà thông qua phản hồi ngôn ngữ”, với agents “phản tư bằng lời về tín hiệu phản hồi tác vụ, rồi duy trì văn bản phản tư của chính chúng trong episodic memory buffer để tạo ra quyết định tốt hơn trong các lần thử sau”. 2

  4. Anthropic, Building effective agents, 19 tháng 12 năm 2024, anthropic.com/engineering/building-effective-agents, đọc ngày 7 tháng 9 năm 2026. Nguồn của phân biệt workflow/agent được trích ở trên, của thuật ngữ bao trùm “agentic systems”, của mô tả agents là “thường chỉ là LLMs dùng công cụ dựa trên phản hồi môi trường trong một vòng lặp”, của hướng dẫn tìm giải pháp đơn giản nhất có thể và rằng điều này “có thể nghĩa là hoàn toàn không xây agentic systems”, và của các trường hợp nên và không nên dùng agents, bao gồm “chi phí cao hơn, và khả năng lỗi cộng dồn” cùng khuyến nghị về điều kiện dừng “như số vòng lặp tối đa” để duy trì kiểm soát. 2 3

  5. OpenAI, A practical guide to building agents, trang 4 đến 7, đọc ngày 7 tháng 9 năm 2026. Nguồn của “Agents là các hệ thống độc lập hoàn thành tác vụ thay mặt bạn”, của việc loại trừ “chatbots đơn giản, LLMs một lượt, hoặc sentiment classifiers”, của định nghĩa workflow là “một chuỗi bước phải được thực thi để đạt mục tiêu của người dùng”, của hai đặc tính cốt lõi của agent, của ba thành phần — mô hình, công cụ, chỉ dẫn — và của tiêu chí sàng lọc khi nào nên xây một agent, kết thúc bằng “nếu không, một giải pháp tất định có thể là đủ”. 2 3

  6. Wooldridge, M. và Jennings, N. R. Intelligent Agents: Theory and Practice. The Knowledge Engineering Review, tập 10, số 2 (1995). Khảo sát đã chia cách dùng của lĩnh vực thành một khái niệm yếu về agency — tự chủ, năng lực xã hội, phản ứng, chủ động — và các khái niệm mạnh hơn mượn từ vựng tinh thần. Đọc hôm nay, nó là bản ghi của cùng cuộc tranh luận mà hai tài liệu trong chương này vẫn đang có.

  7. Franklin, S. và Graesser, A. Is It an Agent, or Just a Program? A Taxonomy for Autonomous Agents. Proceedings of the Third International Workshop on Agent Theories, Architectures, and Languages, Springer (1996). Được trích ở đây đúng với bản chất của nó thay vì vì một câu trích: một khảo sát gom các định nghĩa “agent” đang lưu hành khi đó, thấy chúng bất đồng, và đề xuất một phân loại để thay thế cuộc tranh luận. Ba mươi năm sau, cuộc tranh luận nằm trong tài liệu được thiết kế tốt hơn và ngoài ra không đổi.

  8. Xi, Z. et al. The Rise and Potential of Large Language Model Based Agents: A Survey. arXiv:2309.07864 (2023). Được trích ở trên cho định nghĩa mở đầu, “AI agents là các thực thể nhân tạo cảm nhận môi trường, đưa ra quyết định và thực hiện hành động”, tức định nghĩa giáo trình được phát biểu lại vào năm 2023 vì không có định nghĩa hiện đại được đồng thuận để trích dẫn.

  9. Sumers, T. R., Yao, S., Narasimhan, K. và Griffiths, T. L. Cognitive Architectures for Language Agents. arXiv:2309.02427 (2023). Tổ chức language agents thành “các thành phần bộ nhớ module, một không gian hành động có cấu trúc để tương tác với bộ nhớ nội bộ và môi trường bên ngoài, và một quy trình ra quyết định tổng quát để chọn hành động”, đồng thời đặt chúng rõ ràng trong lịch sử AI biểu tượng và khoa học nhận thức. Phân loại bộ nhớ quay lại ở Chương 24, nơi bảng ba kho là bóng thực dụng của nó.

Sẵn sàng để LIA chọn giúp bạn chưa?

Xây dựng cùng mọi mô hình AI ở một nơi — bắt đầu miễn phí ngay hôm nay.