12-Factor Agent: Mẫu ứng dụng LLM đáng tin cậy
(github.com/humanlayer)- 12-Factor Agents là một hướng dẫn công khai tổng hợp 12 nguyên tắc để xây dựng phần mềm dựa trên LLM đủ đáng tin cậy để cung cấp cho khách hàng production
- Quan điểm của tài liệu là agent tốt thường gần với cấu trúc chèn các bước LLM vào đúng những điểm cần thiết trong phần mềm mang tính quyết định, hơn là kiểu “đưa prompt và bộ công cụ rồi lặp cho đến khi đạt mục tiêu”
- Vòng lặp agent điển hình để LLM quyết định bước tiếp theo bằng gọi công cụ JSON có cấu trúc, sau đó mã quyết định thực thi và thêm kết quả vào context window, lặp lại cho đến khi hoàn tất
- Nhiều nhà phát triển SaaS khởi đầu nhanh bằng framework và đạt 70–80% chất lượng, nhưng mức này chưa đủ cho tính năng hướng tới khách hàng, nên họ thường phải đảo ngược framework, prompt và luồng hoặc làm lại từ đầu
- Cách nhanh nhất để đưa phần mềm AI chất lượng cao đến khách hàng không phải là áp dụng trọn bộ framework agent, mà là tích hợp các khái niệm xây dựng agent nhỏ và mô-đun vào sản phẩm hiện có
Vấn đề mà dự án muốn giải quyết
- 12-Factor Agents là một dự án công khai nhằm áp dụng tinh thần của 12 Factor Apps vào các nguyên tắc xây dựng ứng dụng LLM
- Câu hỏi cốt lõi là: “Có thể dùng những nguyên tắc nào để tạo ra phần mềm dựa trên LLM thực sự đủ tốt để giao cho khách hàng production sử dụng?”
- Dự án bắt đầu từ trải nghiệm thử nhiều framework agent khác nhau và trò chuyện với các nhà sáng lập công nghệ trong và ngoài YC
- Nhiều nhà sáng lập thay vì dùng nhiều framework cho agent production hướng tới khách hàng, lại đang tự xây stack riêng
- Nhiều sản phẩm được gọi là “AI Agent” thực ra không hoàn toàn agentic, mà chủ yếu là mã quyết định được trộn hợp lý với các bước LLM
Góc nhìn cơ bản về agent
- Agent tốt không chỉ được cấu thành từ mẫu “prompt, bộ công cụ và lặp đến khi hoàn thành mục tiêu”
- Có thể xem phần mềm như một đồ thị có hướng (DG), và đây cũng là lý do trước kia chương trình thường được biểu diễn bằng lưu đồ
- Từ khoảng 20 năm trước, các DAG orchestrator đã bắt đầu được sử dụng rộng rãi
- Lời hứa của agent là thay vì kỹ sư phải viết mã cho mọi bước và ngoại lệ, chỉ cần cung cấp mục tiêu và các chuyển trạng thái, còn LLM sẽ quyết định đường đi theo thời gian thực
- Cách làm này kỳ vọng giúp viết ít mã hơn, phục hồi từ lỗi và cho phép LLM tìm ra lời giải mới
- Tuy vậy, tài liệu cho rằng trong thực tế cách tiếp cận này không hoạt động tốt như kỳ vọng
Mô hình thực thi của vòng lặp agent
- Vòng lặp agent cơ bản gồm LLM phán đoán → thực thi công cụ → thêm kết quả vào ngữ cảnh → lặp lại
- Luồng hoạt động như sau
- Ngữ cảnh ban đầu là sự kiện khởi động như tin nhắn người dùng, chạy cron hoặc webhook
- LLM quyết định bước tiếp theo hoặc liệu đã hoàn thành hay chưa
- Bước tiếp theo được xuất ra dưới dạng gọi công cụ JSON có cấu trúc
- Mã quyết định thực thi lời gọi công cụ
- Kết quả thực thi được thêm vào context window
- Nếu bước tiếp theo là
donethì trả về câu trả lời cuối cùng
- Ví dụ trong README cho thấy một vòng lặp dùng
llm.determine_next_step(context)để xác định bước tiếp theo, rồiexecute_step(next_step)để thực thi và gắn kết quả vào ngữ cảnh
Vì sao cần 12 nguyên tắc
- Khi xây HumanLayer, nhóm tác giả đã trò chuyện với ít nhất 100 nhà phát triển SaaS, phần lớn là các nhà sáng lập kỹ thuật muốn làm sản phẩm hiện có trở nên agentic hơn
- Hành trình phổ biến thường là
- Quyết định xây agent
- Thiết kế sản phẩm, lập bản đồ UX và xác định vấn đề cần giải quyết
- Chọn một framework cụ thể để tăng tốc
- Đạt mức chất lượng 70–80%
- Nhận ra 80% là chưa đủ với hầu hết tính năng hướng tới khách hàng
- Muốn vượt 80% thì phải đảo ngược framework, prompt, luồng và các thành phần khác
- Cuối cùng lại phải làm lại từ đầu
- Bài viết nhấn mạnh đây không phải lời công kích framework hay người tạo framework, và thừa nhận framework đã giúp tăng tốc hệ sinh thái AI
- Tài liệu không bàn về MCP, và dù ví dụ chủ yếu dùng TypeScript, các nguyên tắc vẫn áp dụng được cho Python hoặc ngôn ngữ khác
12 yếu tố
- Tài liệu cho rằng dù LLM tiếp tục mạnh lên, những kỹ thuật kỹ thuật cốt lõi giúp phần mềm dựa trên LLM đáng tin cậy hơn, dễ mở rộng hơn và dễ bảo trì hơn vẫn sẽ còn nguyên giá trị
- 12 yếu tố gồm
- Factor 1: Natural Language to Tool Calls: Chuyển ngôn ngữ tự nhiên thành lời gọi công cụ
- Factor 2: Own your prompts: Tự kiểm soát prompt của bạn
- Factor 3: Own your context window: Tự kiểm soát context window của bạn
- Factor 4: Tools are just structured outputs: Công cụ chỉ là đầu ra có cấu trúc
- Factor 5: Unify execution state and business state: Hợp nhất trạng thái thực thi và trạng thái nghiệp vụ
- Factor 6: Launch/Pause/Resume with simple APIs: Khởi chạy/Tạm dừng/Tiếp tục bằng API đơn giản
- Factor 7: Contact humans with tool calls: Liên hệ con người bằng lời gọi công cụ
- Factor 8: Own your control flow: Tự kiểm soát luồng điều khiển của bạn
- Factor 9: Compact Errors into Context Window: Nén lỗi vào context window
- Factor 10: Small, Focused Agents: Agent nhỏ, tập trung
- Factor 11: Trigger from anywhere, meet users where they are: Kích hoạt từ bất cứ đâu, gặp người dùng tại nơi họ đang ở
- Factor 12: Make your agent a stateless reducer: Biến agent thành một reducer không trạng thái
- Ngoài ra còn có lời khuyên bổ sung Factor 13: Pre-fetch all the context you might need: Tải trước toàn bộ ngữ cảnh mà bạn có thể cần
Cách áp dụng và tài liệu liên quan
- Tài liệu cho rằng việc đưa vào toàn bộ framework rồi gần như đi đến một lần viết lại kiểu greenfield có thể phản tác dụng
- Những nguyên tắc cốt lõi làm nên một agent tốt phần lớn có thể đạt được khi dùng framework, nhưng con đường nhanh hơn để đưa phần mềm AI chất lượng cao đến khách hàng là tích hợp các khái niệm nhỏ hơn và có tính mô-đun vào sản phẩm hiện hữu
- Theo tài liệu, ngay cả kỹ sư phần mềm giàu kinh nghiệm nhưng không có nền tảng AI cũng có thể xác định và áp dụng các khái niệm mô-đun này
- Tài liệu liên kết thêm Building Effective Agents của Anthropic, Prompts are Functions, Library patterns: Why frameworks are evil, The Wrong Abstraction
- Nội dung và hình ảnh được cung cấp theo giấy phép CC BY-SA 4.0, mã nguồn theo Apache 2.0
1 bình luận
Ý kiến trên Hacker News
Các luận điểm trong bài này rất hay. Tôi cũng có một danh sách các bài học rút ra sau vài năm tự làm: https://mg.dev/lessons-learned-building-ai-agents/
Nếu là bây giờ, mục lớn nhất tôi sẽ thêm vào là hãy tự sở hữu vòng lặp lập kế hoạch ở mức thấp nhất. Lập kế hoạch động thì ổn, nhưng bạn cần tự có vòng lặp quan sát–định hướng–quyết định–hành động (OODA), cùng các heuristic (ví dụ: chấm điểm) để xác định liệu hệ thống có đang hội tụ tới lời giải hay không, hoặc các điều kiện thoát (ví dụ: số vòng lặp tối đa)
Ngoài ra cũng đáng cân nhắc đưa vào một workflow engine. Thay vì bắt mô hình duy trì và tiến hành một workflow ngầm qua nhiều lượt, tốt hơn là để mô hình tạo đặc tả workflow sẽ chạy trong engine đó, rồi ở từng bước gọi lại mô hình khi cần
Tôi tò mò các thư viện như DSPY khớp với factor-2 như thế nào: https://dspy.ai/, https://github.com/humanlayer/12-factor-agents/blob/main/con...
Khi đọc, tôi thấy có đoạn nói về việc tạo prompt bằng BAML. Cá nhân tôi thấy việc viết prompt thủ công để trích xuất thông tin có cấu trúc từ dữ liệu phi cấu trúc không hề dễ, còn với DSPY thì đến nay trải nghiệm khá tốt
Nếu dùng prompt thô của BAML, tôi tò mò bạn nhìn nhận thế nào về cách dùng prompt thô của DSPY: https://dspy.ai/tutorials/observability/#using-inspect_histo...
Tôi không hoàn toàn đồng ý với bài https://www.chrismdp.com/beyond-prompting/, nhưng phép so sánh thẻ đục lỗ → assembly → C → ngôn ngữ bậc cao khá hữu ích trong bối cảnh này
Tôi vẫn chưa biết khi nào mới xuất hiện mức trừu tượng phù hợp, và tôi không nghĩ LangChain hay DSPY đã là “ngôn ngữ lập trình C” của AI. Một ngày nào đó có thể chúng sẽ là như vậy
Còn hiện tại, tôi sẽ dùng một bàn thao tác low-level cho phép kiểm tra token, thay đổi thứ tự các token đặc biệt như system/user/JSON, và nhanh chóng điều chỉnh theo các đặc thù của mô hình mới mà không bị trói buộc trong lúc chờ thư viện hỗ trợ
Có một bài cũ không mấy nổi tiếng về mẫu framework đã luôn khiến tôi thấy thấm trong suốt sự nghiệp, và tôi nghĩ nó cũng áp dụng ở đây: https://tomasp.net/blog/2015/library-frameworks/
Vì những lý do được giải thích trong bài và còn hơn thế nữa, đặc biệt ở thời điểm mọi thứ thay đổi nhanh như hiện nay, LLM nên được dùng như thư viện hơn là framework. Tuy vậy, framework trông hấp dẫn hơn, dễ bán hơn, và dẫn tới lock-in cùng các dịch vụ bổ sung, nên được quảng bá nhiều hơn
Tôi đã xây dựng SecAI, một “AI agent framework” của riêng mình, dựa trên actor model, state machine và lập trình hướng khía cạnh, và vừa công bố: https://github.com/pancsta/secai
Tôi đặc biệt thích số 5 “hợp nhất trạng thái thực thi và trạng thái nghiệp vụ” và số 8 “tự sở hữu luồng điều khiển”. Cốt lõi của SecAI là một thư viện luồng điều khiển dạng đồ thị; nó dùng multigraph chứ không phải DAG, và các lệnh gọi LLM được nhúng trong các node của đồ thị
Luồng được tăng cường bằng thương lượng, hủy bỏ và các quan hệ có trạng thái, nên vận hành tự nhiên hơn. Nó cũng bao gồm các công cụ phát triển chuyên dụng (dbg, repl, svg) vốn thường thiếu trong các framework khác, lập trình với giả định thất bại sẽ xảy ra, khả năng kiểm tra chi tiết mọi bước, tự động xuất dữ liệu (metric, trace, log, SQL), và tích hợp đơn giản (bash)
Tôi cũng đã công bố demo kỹ thuật đầu tiên, dùng bản triển khai tham chiếu deepresearch được port từ AtomicAgents để trình diễn các công cụ phát triển: https://youtu.be/0VJzO1S-gV0
Các nút Send/Stop về thực chất là “Factor 6. khởi động/tạm dừng/tiếp tục bằng API đơn giản”, và cũng có tính minh bạch mạng nên có thể mở rộng
Nếu bổ sung thêm một điều nữa, thì đó là cần lập kế hoạch cho chi phí khi mở rộng quy mô
Những hệ thống kiểu này không rẻ khi quy mô lớn lên, nên nếu một tác vụ có thể được xử lý bằng thành phần tất định thì nên thử hướng đó trước. Nó không chỉ giảm ảo giác và độ trễ, mà còn có thể tạo khác biệt lớn cho lợi nhuận cuối cùng
Để giúp dễ theo dõi từng nguyên tắc, sẽ tốt hơn nếu có một mạch tự sự nhất quán xuyên suốt nhiều factor. Ví dụ như tiếp tục dùng một hệ thống gần với thực tế thì có lẽ sẽ dễ hiểu hơn
Tôi muốn tiếp tục phát triển công khai cùng cộng đồng
Tuyệt vời. 80% thì tôi đã học được qua trải nghiệm vất vả rồi, còn 20% còn lại có vẻ đáng đọc
Cá nhân tôi đã thành công với tổ hợp LangGraph + schema pydantic. Cũng tò mò không biết những công cụ nào người khác đã dùng thấy hữu ích
Bài này xuất hiện đúng lúc tôi đang cần
Tôi đang thử nghiệm ý tưởng sandbox nghe nhìn. Nó giống như vvvv, nhưng đơn giản hơn nhiều và chỉ có các chức năng tối thiểu: https://kfs.mkj.lt/#audiovisllm, https://vvvv.org/
Ý tưởng là chèn vào các “node” LM hoặc mạng nơ-ron cục bộ đơn giản, đảm nhiệm một tác vụ cụ thể và có đầu ra rất hạn chế. Vì vậy những ví dụ như “question -> answer: float” rất hấp dẫn. Trong trường hợp của tôi, một số câu hỏi có thể khá trừu tượng, nhưng pipeline nhiều bước cũng rất thú vị
Tôi chưa đọc kỹ, nhưng muốn dùng càng nhiều mã có tính quyết định càng tốt và tận dụng LLM càng ít càng tốt
Tôi cho rằng như vậy mới có kết quả dự đoán được, chi phí vận hành thấp, và là tín hiệu cho thấy người khác khó có thể nhanh chóng sao chép cùng một ứng dụng. Thay vì dùng nguyên xi thứ keo dán đầy buzzword để kết nối LLM với các hệ thống khác, tôi có xu hướng tự xây công cụ
Nếu những điều kiện này không được đáp ứng hoặc không cần thiết, tôi nghĩ ai đó có thể vibe coding ra cùng một giải pháp trong nháy mắt. Phải giữ quyền kiểm soát. Tôi sẵn sàng chết trên ngọn đồi mang tên kiểm soát. Nói vậy không có nghĩa là tôi không kinh ngạc trước LLM; ngược lại hoàn toàn