Build Systems, Not Code
AI Engineer World's Fair 2026: Online Track · Video gốc
Thiết kế agent vẫn là software engineering: mười nguyên tắc từ systems thinking tới maintainability, minh hoạ qua agent tìm nhà Relocation Scout.
1. Một tối thứ Sáu và cảm giác building quay lại
Angie Jones mở đầu bằng một chuyện rất đời thường. Dạo gần đây cô build agent rất nhiều, chủ yếu cho các tác vụ vận hành (operational tasks). Một tối thứ Sáu đang làm việc, cô thấy mặt trời lặn, rồi giờ ăn tối tới rồi qua lúc nào không hay, và cô chợt nhận ra: mình đang ở trong cái flow quen thuộc của dân dev, và cảm giác phấn khích khi được build đã quay trở lại.

Cô nói thẳng điều mà nhiều người đang code cùng agent cảm thấy: một nỗi sợ lặng lẽ rằng agent đang lấy đi hết những phần vui nhất của việc build, chỉ để lại cho mình những việc chẳng hào nhoáng gì. Lời khuyên của Angie: cứ để chúng lấy phần đó đi. Vì nếu bạn đi lên chỉ một tầng (layer), bạn sẽ thấy sự phấn khích vẫn còn nguyên ở đó.

Khi bạn build agent, chứ không chỉ dùng agent để viết code, bạn bắt đầu bước vào việc thiết kế kiến trúc cho các agentic system. Và bạn nhận ra rằng các viên gạch (building blocks) đã khác, nhưng kỷ luật (discipline) vẫn y như cũ. Angie kể cô thấy mình đang dùng lại đúng những "cơ bắp" engineering mà cô từng dùng trước thời gen AI, và cô đang chơi cực kỳ vui với nó.
Phần còn lại của talk, cô đi qua toàn bộ flow thiết kế một agent, và chỉ ra ở từng bước kỹ năng engineering nào vẫn đang được dùng.
2. Relocation Scout và nguyên tắc 1: Systems Thinking

Agent làm ví dụ tên là Relocation Scout, một agent đi tìm nhà (house hunting agent). Angie chỉ ra rằng nếu làm việc này bằng một prompt chạy một lần, kiểu trỏ agent tới vài listing nhà rồi bảo nó xếp hạng, thì cũng chạy được thôi. Nhưng bạn khó mà tìm được nhà trong một ngày, đúng không? Nên bạn muốn build nó thành một agentic system dùng lại được, một hệ thống có thể lưu kiến thức (persist knowledge) ra bên ngoài session. Hệ thống đó có thể nạp lại hoặc query kiến thức ấy về sau để ra quyết định, kể cả khi bắt đầu trong một context hoàn toàn mới.
Khi nghĩ về cách thiết kế một agent, kỹ năng engineering đầu tiên Angie dùng là systems thinking. Agent không phải là hệ thống. Nó chỉ là một phần của hệ thống, và hệ thống đó gồm file, tool, con người, thậm chí cả những agent khác.

Relocation Scout nằm bên trong một thứ lớn hơn. Nó kéo vào các listing và các tín hiệu về khu dân cư (neighborhood), cân nhắc chúng với những gì Angie quan tâm, rồi trả lại cho cô một shortlist đã xếp hạng.

Angie hay nghe người ta nói: "Cứ để coding agent build nó đi." Cô cho đó là một sai lầm. Đúng, coding agent của cô build được. Nhưng trước khi cho nó làm, cô cần nghĩ về toàn bộ môi trường, toàn bộ hệ thống. Agent này có nhiệm vụ gì? Nó phụ thuộc vào cái gì? Nếu nó hỏng thì chuyện gì xảy ra? Cô muốn đối xử với nó như mọi component khác: có ranh giới (boundaries) và trách nhiệm (responsibilities), có dependencies, và có những cách nó có thể fail. Theo Angie, toàn bộ quá trình suy nghĩ đó chính là engineering.
3. Nguyên tắc 2: Workflow Design
Kỹ năng thứ hai là workflow design. Phần mềm truyền thống đầy rẫy workflow: CI/CD pipeline, vòng đời của ticket, và đủ thứ khác. Agentic system cũng cần được thiết kế theo đúng cách đó.

Dù ai cũng thích lệnh /goal, Angie nhắc rằng một agent cần nhiều hơn một mục tiêu (goal). Nó cần một con đường (path). Khi ta nói "Review listing này", đó là goal. Còn workflow mới là thứ định nghĩa những gì thực sự phải xảy ra: agent phải thu thập những gì nó cần, đánh giá listing so với tiêu chí của Angie, rồi hành động. Và mọi lần chạy đều kết thúc theo một trong ba cách: dừng (stop), thử lại (retry), hoặc đẩy lên người (escalate).

Con đường đó định hình phần còn lại của kiến trúc. Khi đã thấy công việc di chuyển qua hệ thống ra sao, Angie ra quyết định tốt hơn về việc agent cần context gì, phần nào cô muốn agent tự xử lý trực tiếp, và lúc nào thì một tool hoặc một con người nên tiếp quản.
4. The giant prompt và nguyên tắc 3: Decomposition
Ai cũng biết sự nguy hiểm của một thứ khổng lồ làm tất cả mọi việc. Chúng ta bĩu môi (Angie bật cười) khi thấy một class to đùng, một hàm (function) cồng kềnh làm quá nhiều việc, hay một service phình to với cả "gazillion" endpoint. Ta gọi đó là code smell. Agentic system cũng có phiên bản riêng của chuyện này: đó là giant prompt.
Nó bắt đầu rất vô hại. Trong một instructions file, có thể Angie dặn Relocation Scout cách đánh giá một listing. Hợp lý. Rồi cô gặp một edge case, nên cô quay lại thêm một ghi chú cho nó. Rồi cô nhớ ra một safety rule, và tất nhiên cái đó phải được thêm vào. Cô còn tự hào vì mình đã nhớ ra mà thêm nó vào. Rồi, à đúng rồi, còn một ngoại lệ cực kỳ quan trọng nữa. Và trước khi kịp nhận ra, cái prompt đó đã làm tất cả mọi việc.

"Spidey sense" engineering của bạn đã biết ngay thứ này lộn xộn, vậy sao không lùi lại một bước để chia nhỏ nó ra? Decomposition nghĩa là nhận ra những công việc riêng biệt đang ẩn trong một khối (blob) duy nhất và tách chúng thành các mảnh riêng.

Nhìn toàn bộ prompt của Relocation Scout, nó chứa một quy trình dùng lại được để lấy và chuẩn hoá (normalize) một listing; một format cố định cho cách viết shortlist; một mục nhỏ hướng dẫn cách tính thời gian đi lại (commute); và một subtask khá nặng về cách research khu dân cư. Đó là bốn việc khác nhau bị nhồi vào cùng một prompt. Vậy mà bạn còn thắc mắc vì sao agent cứ "drift" và không bám theo kịch bản. Kịch bản dài quá mà (cô cười).

Angie nói rõ cô không bảo phải chia nhỏ chỉ để chia nhỏ. Mục đích là làm cho từng phần dễ suy luận hơn (easier to reason about). Như vậy nó dễ test hơn, và dễ thay đổi hơn khi bạn cần.
5. Nguyên tắc 4: Separation of Concerns
Decomposition là chuyện tách hệ thống ra. Separation of concerns là chuyện đặt mỗi trách nhiệm vào đúng chỗ của nó. Đây là chỗ việc build agent bắt đầu rất quen thuộc với Angie, vì trong phần mềm truyền thống ta vẫn hỏi những câu như "Cái này nên nằm ở controller hay ở service layer?", hay "Đây là business logic hay presentation?".

Khi build agent, bạn cũng có những câu hỏi tương tự, chỉ là có những chỗ khác để đặt mọi thứ:
- Quy trình normalize listing: nên chôn trong prompt, hay nên trở thành một skill?
- Angie muốn mọi listing trong shortlist được format giống hệt nhau, nên structured output đó có lẽ nên được định nghĩa trong một schema. Nếu tự tay code hệ thống thì bạn cũng làm vậy thôi, đúng không? Cô thì chắc chắn có.
- Phần tính commute: có thể đặt vào một script nhỏ, gọn và "nhàm chán" (cô cười).
- Phần research khu dân cư: đủ nặng để giao cho một sub-agent.

Giờ thì bạn đang dùng đúng công cụ cho từng việc, và cũng rõ ràng hơn nhiều khi cần tìm một thứ gì đó bên trong hệ thống.
6. Nguyên tắc 5: Modularity, skill và sub-agent
Modularity cũng quan trọng trong agentic system. Giống như ta có function, class và library dùng lại được, giờ Angie cũng nghĩ tới những năng lực (capabilities) của agent có thể dùng lại. Ví dụ rõ nhất là một agent skill.

Làm một skill để normalize listing trở nên rất tiện khi bạn cần mở rộng nhiệm vụ của agent. Chẳng hạn, nếu Angie mở rộng việc tìm nhà ra ba thành phố thì sao? Mỗi thị trường đều nạp cùng một skill đó. Cô viết một lần, cả ba dùng lại được. Lúc này skill về cơ bản đã thành một component mà cô dùng lại được giữa các agent, hoặc thậm chí chia sẻ cho người khác, theo đúng cách chúng ta vẫn dựa vào các package.

Sub-agent là một loại module dùng lại được khác. Angie kể nhiều người cô nói chuyện cùng không hiểu lắm sub-agent để làm gì. Về mặt kiến trúc, chúng giống như function: bạn giao cho nó một việc cụ thể, gọi nó khi việc đó cần làm, và nó làm rất tốt vì đó là tất cả những gì nằm trong scope của nó. Nó không phải mang theo context của cả session. Sub-agent research khu dân cư cũng vậy: thả nó vào thị trường nào hay workflow nào cũng chạy đúng việc của nó. "It's good in any hood", cô đùa, chơi chữ "hood" (khu phố).
Nhưng như mọi thứ khác, quyết định cái gì nên thành module cần có phán đoán. Không phải thứ gì cũng nên dùng lại. Có những instructions chỉ mang tính local cho một workflow nhất định, và có thể không đáng để trừu tượng hoá (abstract), vì đôi khi việc đó tốn nhiều hơn là nó tiết kiệm được. Đây chỉ là thêm một quyết định engineering nữa: agentic system cũng có đúng những trade-off như vậy.
7. Nguyên tắc 6: Algorithmic Thinking
Algorithmic thinking, theo Angie, là một trong những kỹ năng quan trọng nhất khi thiết kế agentic system. Agent làm được một việc không có nghĩa là nó nên làm việc đó. Có những tác vụ code thuần xử lý tốt hơn, chẳng hạn tính thời gian commute hay loại bỏ trùng lặp (dedupe) những listing cô đã xem rồi. Model của agent giỏi hơn ở những thứ "mờ": phán đoán (judgment), sự mơ hồ (ambiguity), suy luận trên dữ liệu đầu vào lộn xộn.

Bỏ qua sự phân biệt này là chỗ Angie thấy rất nhiều agentic system trở nên phức tạp hơn mức cần thiết. Bạn dùng model, giao cho nó mọi phần của task, rồi bực mình khi output mỗi ngày một khác (cô cười). Trong khi một phần trong đó chỉ cần code bình thường xử lý là đủ: rẻ hơn, và đáng tin cậy hơn. "Tôi hứa với các bạn, AI không phát minh ra automation đâu." Ta vẫn dùng code được trong khi vẫn dùng các hệ thống này.
Quy tắc kinh nghiệm (rule of thumb) của cô: nếu một task có câu trả lời chính xác, hãy dùng code. Nếu nó cần diễn giải hay phán đoán, lúc đó mới giao cho agent. Tóm lại: dùng code cho tính tất định (determinism), dùng agent cho phán đoán (judgment), và dùng con người cho thẩm quyền (authority).

Áp vào Relocation Scout: agent quyết định listing nào đáng xem kỹ hơn. Code tính commute và lọc bỏ những căn cô đã xem rồi. Còn Angie là người duyệt việc thực sự đặt lịch đi xem nhà (booking a tour).
8. Nguyên tắc 7: Contract Design
Văn bản tự do (freeform text) là ổn khi người duy nhất đọc nó là con người. Nhưng khi một hệ thống khác phải hành động dựa trên output của agent, bạn thường nên có một contract. Ta vẫn làm thế ở khắp nơi trong phần mềm (cô cười): bất cứ khi nào hai hệ thống nói chuyện với nhau, giữa chúng có một hình dạng dữ liệu (shape) đã thống nhất. Agentic system cần đúng kỷ luật đó.

Ví dụ, khi Relocation Scout chấm điểm một căn nhà, nó không nên chỉ trả về một tin nhắn rồi coi như xong. Tin nhắn đó đọc lúc ấy thì dễ chịu thật, nhưng với hệ thống thì đó là ngõ cụt. Nếu quyết định bị chôn trong một session hội thoại nào đó, không thứ gì ở downstream tìm lại nó một cách đáng tin cậy được.
Thay vào đó, kết quả được ghi theo một shape có cấu trúc vào memory của agent. Angie dùng LLM Wiki của Karpathy làm memory layer cho phần lớn các agent của cô. Trong đó có quyết định (decision), điểm (score), lý do (reason). Và vì nó có cấu trúc, memory đó trở nên query được.

Nhờ vậy, về sau cô có thể hỏi Relocation Scout: "Cho tôi xem mọi căn được chấm từ bốn điểm trở lên và có commute không quá mười lăm phút." Và nó thật sự lấy ra được, vì score và commute nằm ở những vị trí đã biết trước, không bị nhốt trong cuộc hội thoại của session.
Không chỉ Angie cần lấy thông tin này. Bước shortlist trong hệ thống cũng đọc chính những field đó mà không cần con người trong vòng lặp (human in the loop). Output của agent là input của một bước khác, và contract là thứ giúp lần bàn giao (handoff) đó an toàn.

Phần hay nhất, theo cô: định nghĩa shape buộc bạn phải thật rõ ràng và cụ thể (cô cười). Vì nếu bạn không nói được output nên trông như thế nào, có lẽ bạn chưa thực sự hiểu hết mình đang bảo agent tạo ra cái gì.
9. Nguyên tắc 8: State Management và idempotency
Một prompt có thể chạy một lần rồi xong. Nhưng một agentic system hữu ích phải chạy được trong thực tế lộn xộn: webhook bị bắn hai lần, một lần chạy không hoàn tất vì lý do nào đó và bạn cần retry flow.

Vì vậy agent phải theo dõi state của nó. Hành động này đã được làm chưa? Nếu rồi, input có thay đổi không? Nếu chưa, có phải session đã crash hay gì đó không? Phần nào ở đây có thể retry một cách an toàn? Angie nhấn mạnh đây không phải ngoại lệ, chuyện này xảy ra suốt.

Nên bạn phải thiết kế cho idempotency: chạy cùng một việc hai lần mà lần thứ hai không gây ra mớ hỗn độn nào (cô cười). Phần mềm truyền thống làm việc này thường xuyên. Nhưng agent thêm vào một cái bẫy: bạn không thể tin vào model, vì output của nó có thể thay đổi. Một lần retry có nguy cơ khiến agent diễn đạt lại yêu cầu (rewording) vừa đủ khác để nó trông như một task hoàn toàn mới. Vì thế bạn phải ép idempotency ở tầng hệ thống.
Ví dụ với Relocation Scout: một listing mới về, và Relocation Scout muốn email cho môi giới (realtor) của Angie để hỏi lịch xem nhà. Sau hành động đó, agent bắt buộc phải ghi vào memory rằng email đã được gửi.

Tiếp theo agent vào lịch của Angie và muốn chặn khung giờ đó lại, phòng khi cần. Nhưng nó crash trước khi kịp làm. Lần chạy đó chỉ mới xong một nửa.
Sau đó một lượt lint (lint pass) chạy. Nhân tiện, Angie nói bạn phải có lint pass cho những hệ thống này (cô cười) để giữ chúng khoẻ mạnh. Trong lint pass, nó nhận ra email đã đi nhưng lịch chưa được chặn, nên nó retry task. Nhưng tốt nhất là nó đừng email cho realtor thêm lần nữa. Việc đó đã xảy ra rồi, và Angie không muốn thành vị khách hàng phiền phức cứ gửi email liên tục. Nó chỉ cần hoàn tất phần chưa xảy ra, tức là chặn lịch. Và nó biết điều này chỉ vì nó kiểm tra những gì hệ thống đã ghi lại. Nên khi chạy lại, agent chỉ làm nốt phần còn thiếu thay vì gây ra mớ hỗn độn.
10. Nguyên tắc 9: Threat Modeling
Threat modeling là một kỹ năng rất quan trọng khi thiết kế agentic system. Dạo này ai cũng lo lắng về chuyện này, nhưng security engineering đã dạy ta những điều cơ bản: validate input, chỉ cấp quyền tối thiểu cần thiết (least privilege) (cô cười), và vẽ ranh giới quanh những gì một hành động được phép chạm tới. Agentic system cần tất cả những điều đó.

Relocation Scout sẽ tiêu thụ rất nhiều nội dung từ người lạ. Agent phải đọc phần mô tả listing do người bán viết, các thread trên forum và review khu dân cư từ những người ẩn danh trên internet (cô cười). Nên ta cần coi tất cả những thứ đó là untrusted input, và nói thật rõ với agent rằng đây là bằng chứng (evidence), không phải mệnh lệnh (instructions). Kiểu input giấu lệnh cho agent như vậy được gọi là prompt injection.

Sau khi xét input, bạn cũng muốn nghĩ xem nên đặt ranh giới nào quanh những gì agent được làm. Ví dụ, agent của Angie được đọc listing và build shortlist cả ngày, cứ thoải mái. Nhưng cô không muốn nó tự động email cho người bán, đặt lịch xem nhà, hay, trời đất ơi, nộp đề nghị mua nhà (submit offer) thay cô (cô cười). Những hành động đó phải được đặt sau một bức tường là sự phê duyệt của cô. Khi vẽ bức tường đó, bạn đã thu nhỏ blast radius, và hy vọng là giảm được mức độ phơi nhiễm rủi ro của mình.
11. Nguyên tắc 10: Maintainability
Engineer nào cũng hiểu cảm giác thừa kế một hệ thống mà mình gần như không hiểu nổi. Đây là một trong những lý do chính khiến Angie không để coding agent của cô thiết kế các agent khác. Cô biết kết quả sẽ được ghép vội theo kiểu chạy được về mặt kỹ thuật nhưng không bảo trì được. Nhiều khả năng sẽ có một giant prompt. Và kể cả khi agent có tự decompose, cô vẫn không tin lắm (cô cười) là nó sẽ tách các concern cho đúng. "Tôi có vấn đề về lòng tin. Biết nói sao đây?"

Vì vậy trong các agentic system của mình, Angie đảm bảo maintainability được nướng sẵn vào chính hệ thống. Mỗi cấp của hệ thống đều có một file AGENTS.md giải thích workflow, policy nằm ở đâu, các tài nguyên hỗ trợ như skill, script và sub-agent, và quan trọng nhất là cách giữ memory của nó luôn cập nhật. Nhờ vậy bất kỳ ai, người hay agent, đều có thể bước vào hệ thống và định hướng được ngay, không cần reverse engineer một đống prompt.

Thực ra đó chính là phép thử. Angie thiết kế agent sao cho kể cả trong một context hoàn toàn mới, chúng vẫn nhảy thẳng vào hệ thống, bắt đầu từ trạng thái lạnh (start cold) mà biết chính xác phải làm gì. Điều này cũng giúp rất nhiều mỗi khi cô cần sửa hệ thống. Cô gần như có thể lấy bất kỳ harness nào và nói "Update agent này để làm XYZ." Và vì hệ thống được thiết kế tốt, khả năng lần cập nhật đó thành công cao hơn nhiều. Nếu harness gặp vấn đề khi cập nhật, đó là tín hiệu cho cô biết cần cải thiện maintainability của hệ thống.
12. We still need all of it
Angie kết luận: thiết kế agent chính là software engineering. Các primitive đã khác, nhưng kỷ luật vẫn như cũ. Ta vẫn cần hiểu hệ thống. Ta cần định nghĩa workflow và biết những gì đi vào nó. Ta vẫn cần chia nhỏ vấn đề và đặt trách nhiệm vào đúng chỗ, làm cho đúng những thứ cần dùng lại trở nên dùng lại được, xác định actor nào hợp nhất với việc nào, định nghĩa contract, quản lý state, thiết kế cho an toàn, và làm cho hệ thống dễ hiểu.

Đây là lý do việc build agent có thể mang lại cho bạn đúng cảm giác phấn khích như khi build phần mềm. Chúng ta vẫn đang build. Chỉ là đã đi lên một tầng. Angie cảm ơn khán giả và khép lại talk.

Sources and links
- Trang talk chính thức trên ai.engineer · Video gốc
- angiejones.tech: trang cá nhân của Angie Jones
- Agentic AI Foundation
- Agent Skills: định dạng skill dùng lại được cho agent
- AGENTS.md: định dạng context file cho agent
- llm-wiki: pattern LLM Wiki của Andrej Karpathy, Angie dùng làm memory layer
- Idempotence
- Threat Modeling (OWASP) · LLM01: Prompt Injection (OWASP GenAI)