DEV Community

BeanBean
BeanBean

Posted on Originally published at nextfuture.io.vn

Spring AI hay LangGraph? Ranh giới mới quyết định kiến trúc

Originally published on NextFuture

Team bạn đang tranh luận Spring AI hay LangGraph cho con agent đầu tiên, và cuộc họp vẫn chưa kết thúc. Câu hỏi đó cảm giác như một quyết định kiến trúc, nhưng có một lập trình viên đã trả lời nó bằng cách đắt nhất: viết cùng một agent hai lần, bằng cả hai framework.

Kết quả thí nghiệm đó, cộng với một quy trình review prompt từ một team C++, cho bạn một cách xếp lại thứ tự quyết định khi build agent — và biết chỗ nào thực sự đáng họp.

Thí nghiệm: cùng một agent, viết hai lần

Tác giả xây một support agent có ranh giới xác định, rồi implement lại toàn bộ bằng framework thứ hai. Mô tả của anh về vai trò framework rất hẹp: trong cả hai bản, framework làm đúng một việc — biến message của khách thành một Classification, tức một typed record ghi tên action và mang theo order id.

Nguyên văn phần sau đó: "Everything after that point is identical: eligibility rules, risk-tier gate, approval queue. Same code, same tests, same behaviour." Toàn bộ luật xét điều kiện, cổng phân loại rủi ro và hàng đợi phê duyệt nằm ngoài framework, và không đổi một dòng.

Anh gọi phần tích hợp Spring AI là "the entire integration surface — one class, one method": một class implement IntentClassifier, gọi chatClient.prompt().user(...).call().entity(Classification.class). Bản LangGraph khác về cơ chế, không khác về nhiệm vụ.

Khác biệt thật sự nằm ở đâu

Bảng so sánh trong bài gốc gói gọn toàn bộ phần khác nhau về mặt cơ chế:

Mối quan tâmSpring AILangGraph

Định nghĩa tool@Tool trên method@tool decorator
Structured output.entity(Classification.class)response_format= Pydantic
Vòng orchestrationAdvisor chainReAct graph
Đổi providerĐổi starter dependencyĐổi model class

Đây là bốn dòng đáng dán vào tài liệu quyết định của team: chúng đều là khác biệt về ergonomics của developer, không có dòng nào nói hệ thống của bạn được phép làm gì.

Bài test chứng minh điều đó

Phần thuyết phục nhất không phải lập luận mà là một test. Repo đi kèm có một end-to-end test mà classifier trong đó không phải Spring AI cũng không phải LangGraph — nó là một bản keyword fallback, thứ mà tác giả ghi chú là kiêm luôn "provider-outage insurance".

Test đưa vào câu "I want a refund for ORD-101, it never arrived", đẩy classification qua gate.propose(...), rồi assert kết quả là QUEUED_FOR_APPROVAL. Đổi implementation phía sau port, test không đổi.

"Spring AI, LangGraph, keyword matching — all three produce the same record, hit the same gate, land in the same queue. If your framework choice changes what your system does, that logic was in the wrong place to begin with."

Đây là một bài kiểm tra bạn có thể áp lên codebase của mình ngay chiều nay: thay classifier bằng một hàm match keyword thô. Nếu bộ test nghiệp vụ vẫn xanh, ranh giới của bạn đặt đúng chỗ. Nếu nó đỏ, logic nghiệp vụ đang nằm lẫn trong prompt hoặc trong vòng lặp framework.

Chỗ hai framework thực sự khác nhau

Bài gốc không kết luận rằng hai framework thay thế được nhau ở mọi chiều. Spring AI giữ mọi thứ trong một ngôn ngữ và một build; LangGraph cho bạn control flow dạng graph, dễ chịu hơn cho reasoning nhiều bước phức tạp — và đổi lại bạn nuôi thêm một runtime thứ hai.

Tác giả nói thêm: advisor model của Spring AI mỏng hơn cách composition node/edge của LangGraph; nếu agent lớn lên thành orchestration thật sự phức tạp thì khoảng cách đó có ý nghĩa. Agent trong thí nghiệm chỉ có đúng hai bước, nên nó chưa có ý nghĩa.

Một chi tiết đáng chú ý cho team đang cân nhắc khoá chặt vào một hệ sinh thái: bài gốc ghi nhận cả hai đều nói Model Context Protocol, nên tool định nghĩa một lần có thể dùng được từ cả hai stack.

Câu chốt của tác giả: chọn framework agent là một quyết định thật, nhưng là quyết định của tuần thứ hai về ergonomics, không phải quyết định thiết kế về việc hệ thống được phép làm gì. Anh cũng dẫn hai ví dụ ngoài ngành AI theo dạng khẳng định cá nhân — hệ thống thẩm định khoản vay không đổi khi thay scoring engine, hệ thống lâm sàng giữ nguyên ranh giới kê đơn qua ba thế hệ decision support — nên hãy đọc chúng như minh hoạ cho luận điểm, không phải dữ liệu.

Nếu ranh giới là kiến trúc, prompt phải được review như code

Vấn đề còn lại: ranh giới nằm ngoài framework, nhưng một phần hành vi vẫn nằm trong prompt — và prompt thường không có ai review. Một bài khác trên Dev.to kể đúng ca đó. Tác giả sửa một dòng trong system prompt của agent sửa code C++: "Prefer readable code" thành "Be concise".

Sprint kế tiếp, agent lặng lẽ ngừng chèn throw std::invalid_argument trong một parser. Unit test vẫn xanh vì test chưa bao giờ chạy qua nhánh đó. Patch merge, và thứ Ba tuần sau một khách hàng gửi input sai định dạng. Anh mô tả gốc rễ rất gọn: prompt sống ngoài version control nên "I had no diff to review".

Nhận xét phân tích, không lấy từ nguồn: đây là mặt còn thiếu của luận điểm framework. Đẩy quyết định nghiệp vụ ra khỏi model là điều kiện cần; phần hành vi buộc phải ở lại trong prompt thì cần một quy trình thay đổi riêng.

Vòng lặp PCR và một cổng regression tối thiểu

Quy trình tác giả bài C++ dùng gồm bốn bước, anh gọi là PCR (Prompt Change Request):

  • Mô tả thay đổi hành vi dự định trong một câu. Viết không nổi thì chưa sửa.

  • Chạy regression gate với prompt hiện tại để lấy baseline.

  • Áp dụng chỉnh sửa, chạy lại gate, so hai danh sách fail.

  • Review diff theo nhóm.

Cổng gate của anh là một file tools/prompt_gate.py, nhận hai đầu vào: một JSON danh sách golden case và một prompt template. Với mỗi case, script gọi model adapter, ghi patch sinh ra ra file tạm, compile một test driver nhỏ rồi chạy assertion; exit code 0 chỉ khi tất cả case pass — đủ để cắm vào CI. Lý do anh không tin cách kiểm tra thủ công: model nhạy với cách diễn đạt và hiệu ứng là bất định, nên "manual spot checks with three examples are statistically worthless".

Quyết định gì trong sprint này

Ba việc theo thứ tự tác động: (1) chạy bài test keyword fallback — nếu test nghiệp vụ đỏ, dừng tranh luận framework và kéo logic ra khỏi prompt trước; (2) đưa file prompt vào repo và bắt nó đi qua PR như mọi artifact khác; (3) chỉ khi hai việc trên xong mới chọn framework, và chọn theo tiêu chí ergonomics — một ngôn ngữ một build, hay graph-shaped control flow đáng giá một runtime thứ hai.


This article was originally published on NextFuture. Follow us for more fullstack & AI engineering content.

Top comments (0)