← AI-Hands-on Real-time AI · Part 5 of 7AI thời gian thực · Phần 5/7

Waiting for one JSON blob versus watching AI think in real timeChờ một cục JSON, hay xem AI suy nghĩ theo thời gian thực

Every earlier part in this series blocks: the client sends a request and waits for one final answer. This walkthrough swaps hand-rolled code for Google's official A2A SDK plus LangChain, and turns that silent wait into a live stream of status updates.

Mọi phần trước trong series này đều chặn: client gửi yêu cầu rồi chờ một câu trả lời cuối cùng duy nhất. Video này thay code tự viết bằng SDK chính thức của Google cộng LangChain, biến khoảng chờ im lặng đó thành một luồng cập nhật trạng thái sống động.

Video demo: a LangGraph ReAct agent streams working / input_required / completed events through an AgentExecutor.

Video demo: một agent ReAct chạy trên LangGraph phát trực tiếp các sự kiện working / input_required / completed qua AgentExecutor.

English

What problem does this solve?

A blocking call is fine for a task that finishes in under a second. It is a poor experience for anything that takes real reasoning time — the user just sees a spinner with no signal that anything is happening, and no way to know if the agent needs more information before it can continue. This walkthrough continues studying the open-source theailanguage/a2a_samples reference implementation.

How the mechanism works

The hand-rolled server code from earlier parts is replaced with Google's official A2A SDK, combined with LangChain and LangGraph to build a ReAct-style reasoning agent. A component called AgentExecutor is the bridge — it plugs the LangChain agent into the official A2A server's request lifecycle correctly, instead of reimplementing that lifecycle by hand.

As the agent works, it emits one of three states — working, input_required, or completed — and each state is pushed immediately into an event queue that streams to the client. If the agent is missing information, it can pause mid-task, ask the user a clarifying question through input_required, and resume once it gets an answer — a real multi-turn conversation instead of one shot per call.

Trade-offs and alternatives

The benefit is a client experience that mirrors what a good chat product should feel like: live progress instead of silence, and the ability to interrupt for clarification. The trade-off is more implementation surface — event queues, streaming transport, and state machine logic that a simple blocking call never had to deal with.

The alternative — client-side polling of a status endpoint — gets partway there but adds latency (you only find out about a state change on the next poll) and unnecessary request volume compared to a proper push-based stream.

Conclusion

Streaming is not a cosmetic upgrade. It's the difference between an agent that looks broken during a slow operation and one that visibly shows its work — and it's also the mechanism that makes real clarifying questions possible mid-task.

Tiếng Việt

Vấn đề gì đang được giải quyết?

Một lệnh gọi chặn thì ổn với tác vụ xong trong chưa tới một giây. Nhưng đó là trải nghiệm tệ cho bất kỳ việc gì cần thời gian suy luận thật — người dùng chỉ thấy một vòng xoay loading, không có tín hiệu gì đang diễn ra, và không cách nào biết agent có cần thêm thông tin trước khi tiếp tục hay không. Video này tiếp tục nghiên cứu bản triển khai tham chiếu mã nguồn mở theailanguage/a2a_samples.

Cơ chế hoạt động ra sao?

Code server tự viết ở các phần trước được thay bằng SDK chính thức của Google, kết hợp LangChain và LangGraph để xây một agent suy luận kiểu ReAct. Một thành phần gọi là AgentExecutor đóng vai trò cầu nối — nó gắn agent LangChain đúng vào vòng đời xử lý yêu cầu của server A2A chính thức, thay vì tự viết lại vòng đời đó từ đầu.

Khi agent xử lý, nó phát ra một trong ba trạng thái — working, input_required, hoặc completed — và mỗi trạng thái được đẩy ngay vào một hàng đợi sự kiện, phát trực tiếp về client. Nếu agent thiếu thông tin, nó có thể dừng giữa chừng, hỏi lại người dùng qua input_required, rồi chạy tiếp khi nhận được câu trả lời — một hội thoại nhiều lượt thật, không phải một lượt gọi một lần.

Đánh đổi và các hướng khác

Cái được là trải nghiệm client giống một sản phẩm chat tốt nên có: tiến trình hiển thị trực tiếp thay vì im lặng, và khả năng ngắt để hỏi lại. Cái đánh đổi là bề mặt triển khai lớn hơn — hàng đợi sự kiện, truyền tải streaming, và logic máy trạng thái mà một lệnh gọi chặn đơn giản chưa bao giờ phải xử lý.

Hướng thay thế — client tự polling một endpoint trạng thái — giải quyết được một phần nhưng thêm độ trễ (chỉ biết trạng thái đổi ở lần poll tiếp theo) và lượng request thừa so với một luồng đẩy trực tiếp đúng nghĩa.

Kết luận

Streaming không phải nâng cấp cho đẹp. Đó là khác biệt giữa một agent trông như bị treo khi xử lý chậm, và một agent cho thấy rõ nó đang làm gì — đồng thời cũng là cơ chế giúp những câu hỏi làm rõ thật sự khả thi giữa tác vụ.