AI Agents
Agent Design Patterns, LangGraph, Workflow Orchestration, Multi-agent Systems, Tool Ecosystems.
"Agent" là từ khoá tuyển dụng nóng nhất 2025-2027: hệ thống AI không chỉ trả lời một câu hỏi mà tự lập kế hoạch, gọi công cụ, kiểm tra kết quả, và lặp lại cho đến khi hoàn thành một nhiệm vụ nhiều bước. Đây là nơi giá trị kinh doanh lớn nhất của AI ứng dụng hiện nay, và cũng là nơi khó làm đúng nhất.
🎯 Mục tiêu học tập
- Phân biệt được các agent design pattern: ReAct, Plan-and-Execute, Reflection, Orchestrator-Worker
- Xây dựng agent workflow bằng LangGraph (graph-based state machine)
- Thiết kế multi-agent system với phân chia trách nhiệm rõ ràng giữa các agent
- Hiểu rủi ro và giới hạn thực tế của agent tự động (vòng lặp vô hạn, chi phí bùng nổ, quyết định sai)
Agent Design Patterns
- ReAct (Reason + Act): vòng lặp suy nghĩ → hành động (gọi tool) → quan sát kết quả → suy nghĩ tiếp, lặp đến khi xong. Pattern nền tảng, đơn giản, dễ debug.
- Plan-and-Execute: agent lập kế hoạch nhiều bước trước, rồi thực thi tuần tự — tiết kiệm chi phí hơn ReAct thuần cho nhiệm vụ có cấu trúc rõ ràng vì không phải suy nghĩ lại sau mỗi bước.
- Reflection: agent tự đánh giá/phê bình kết quả của chính mình trước khi trả về, cải thiện chất lượng đáng kể cho tác vụ sáng tạo/code, đánh đổi bằng chi phí và độ trễ gấp đôi.
- Orchestrator-Worker: một agent điều phối chia nhỏ nhiệm vụ, giao cho các agent con chuyên biệt xử lý song song, rồi tổng hợp — mô hình phổ biến nhất cho hệ thống multi-agent production.
Luôn bắt đầu từ workflow xác định (deterministic pipeline) — chỉ chuyển sang agent tự chủ hoàn toàn khi thực sự cần xử lý các trường hợp không lường trước được. Agent càng "tự do" càng khó kiểm soát chi phí và độ tin cậy.
LangGraph — xây agent như một state machine
LangGraph mô hình hoá agent workflow thành một đồ thị có trạng thái (graph of nodes), mỗi node là một bước xử lý (gọi LLM, gọi tool, rẽ nhánh điều kiện), các cạnh (edge) định nghĩa luồng đi tiếp theo — kể cả vòng lặp có kiểm soát. Ưu điểm so với "vòng lặp while tự viết": có sẵn cơ chế checkpointing (lưu trạng thái giữa các bước, phục hồi khi lỗi), human-in-the-loop (tạm dừng chờ người duyệt trước bước nhạy cảm), và visualize được toàn bộ luồng agent.
from langgraph.graph import StateGraph, END
def plan(state): ...
def execute_tool(state): ...
def should_continue(state) -> str:
return "execute_tool" if state["needs_tool"] else END
graph = StateGraph(AgentState)
graph.add_node("plan", plan)
graph.add_node("execute_tool", execute_tool)
graph.add_conditional_edges("plan", should_continue)
graph.add_edge("execute_tool", "plan")
graph.set_entry_point("plan")
app = graph.compile()
Multi-agent Systems
Khi một nhiệm vụ cần nhiều "vai trò" khác nhau (ví dụ: agent nghiên cứu + agent viết + agent kiểm tra chất lượng), chia thành nhiều agent chuyên biệt thường tốt hơn một agent "biết tuốt": mỗi agent có system prompt, tool, và context nhỏ gọn hơn nên ít bị nhiễu (context pollution), dễ test độc lập, và có thể dùng model khác nhau cho từng vai trò (agent điều phối dùng model mạnh, agent thực thi đơn giản dùng model rẻ).
Thách thức chính: giao tiếp giữa các agent (qua state chung, message passing, hay blackboard pattern), và tránh vòng lặp vô hạn khi hai agent liên tục "đẩy việc" qua lại nhau — luôn đặt giới hạn số bước tối đa cứng (hard max iterations).
Tool Ecosystems
Một agent hữu ích cần bộ công cụ (tools) được thiết kế tốt: mỗi tool nên có một trách nhiệm rõ ràng, tên và mô tả tham số phải đủ rõ để model tự chọn đúng công cụ mà không cần đoán, và nên trả về lỗi có cấu trúc (không phải raw exception) để agent có thể tự sửa và thử lại. Xem Module 9 (MCP) để biết cách chuẩn hoá tool ecosystem dùng chung giữa nhiều agent/ứng dụng.
🔬 Đào sâu — Viết vòng lặp ReAct từ đầu (không dùng framework)
Trước khi dùng LangGraph/CrewAI, nên tự viết một vòng lặp ReAct thô để hiểu rõ "bên dưới framework đang làm gì" — điều này giúp debug framework dễ hơn rất nhiều về sau:
def run_agent(user_msg: str, tools: dict, max_steps: int = 8) -> str:
messages = [{"role": "user", "content": user_msg}]
for step in range(max_steps):
resp = client.messages.create(
model="claude-sonnet-5", max_tokens=1024,
tools=[t["schema"] for t in tools.values()],
messages=messages,
)
messages.append({"role": "assistant", "content": resp.content})
tool_calls = [b for b in resp.content if b.type == "tool_use"]
if not tool_calls:
return "".join(b.text for b in resp.content if b.type == "text")
tool_results = []
for call in tool_calls:
try:
result = tools[call.name]["fn"](**call.input)
except Exception as e:
result = {"error": str(e)} # trả lỗi có cấu trúc để model tự sửa
tool_results.append({
"type": "tool_result", "tool_use_id": call.id, "content": str(result),
})
messages.append({"role": "user", "content": tool_results})
return "Đã vượt quá số bước tối đa — dừng agent để tránh chi phí bùng nổ."
Ba điều quan trọng thể hiện rõ trong đoạn code trên mà framework thường "giấu đi": (1) giới hạn
max_steps cứng, (2) lỗi tool được bắt và trả về dưới dạng nội dung cho model đọc thay vì làm
sập chương trình, (3) toàn bộ lịch sử hội thoại + tool call/result được tích luỹ trong messages —
đây chính là "state" mà LangGraph quản lý hộ bạn ở quy mô lớn hơn.
🔬 Đào sâu — LangGraph: Checkpointing & Human-in-the-loop
Hai tính năng khiến LangGraph vượt trội so với vòng lặp tự viết khi lên production: checkpointing (lưu state sau mỗi bước, phục hồi được khi service restart giữa chừng) và interrupt (tạm dừng chờ con người duyệt trước bước nhạy cảm).
from langgraph.graph import StateGraph, END
from langgraph.checkpoint.postgres import PostgresSaver
checkpointer = PostgresSaver.from_conn_string(DATABASE_URL)
graph = StateGraph(AgentState)
graph.add_node("plan", plan_node)
graph.add_node("execute_tool", execute_tool_node)
graph.add_node("send_payment", send_payment_node) # hành động có tác dụng phụ, cần duyệt
graph.add_conditional_edges("plan", route_next)
graph.set_entry_point("plan")
app = graph.compile(
checkpointer=checkpointer,
interrupt_before=["send_payment"], # tạm dừng, chờ con người duyệt trước khi thực thi
)
# Chạy đến điểm interrupt
config = {"configurable": {"thread_id": "order-8842"}}
app.invoke({"messages": [...]}, config=config)
# ... sau khi người duyệt xác nhận trên UI riêng ...
app.invoke(None, config=config) # tiếp tục từ đúng checkpoint đã lưu
Mẫu thiết kế này (checkpoint + interrupt) là cách chuẩn để đưa agent tự động vào các quy trình có rủi ro tài chính/pháp lý mà vẫn giữ được tốc độ tự động hoá cho phần còn lại của luồng xử lý.
🔬 Đào sâu — So sánh framework Agent 2026
| Framework | Điểm mạnh | Khi nào dùng |
|---|---|---|
| LangGraph | Kiểm soát luồng chi tiết (graph), checkpointing mạnh, hệ sinh thái LangChain rộng | Workflow phức tạp cần rẽ nhánh/vòng lặp tường minh, cần human-in-the-loop |
| OpenAI Agents SDK | Đơn giản, tích hợp chặt với model OpenAI, có sẵn tracing | Team đã gắn với hệ sinh thái OpenAI, muốn triển khai nhanh |
| Claude Agent SDK | Tối ưu cho coding agent & tác vụ dài hơi, quản lý context tự động tốt | Agent cần chạy tác vụ dài, nhiều bước, liên quan đến code/file system |
| CrewAI | Trừu tượng hoá cao ở mức "vai trò" (role-based), dễ tiếp cận | Prototype nhanh multi-agent theo mô hình "đội nhóm" (researcher, writer, reviewer...) |
| Microsoft Agent Framework / Semantic Kernel | Tích hợp sâu hệ sinh thái Azure/.NET, hỗ trợ đa ngôn ngữ lập trình | Doanh nghiệp đã dùng hệ sinh thái Microsoft/Azure |
Lời khuyên: học kỹ một framework có kiểm soát luồng tường minh (LangGraph là lựa chọn phổ biến nhất để học vì tư duy graph áp dụng được sang framework khác) — đừng cố học hết 5 framework, khái niệm nền tảng (state, node, edge, checkpoint) giống nhau ở mọi nơi.
🔬 Đào sâu — Lỗi thường gặp & cách xử lý
| Triệu chứng | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
| Agent lặp vô hạn giữa 2 bước | Điều kiện dừng (routing logic) sai, hoặc tool trả kết quả khiến model luôn nghĩ "chưa xong" | Giới hạn max_steps cứng + log lại lý do dừng để phát hiện pattern lặp |
| Chi phí bùng nổ bất thường | Agent gọi lại tool tốn kém (ví dụ retrieval) nhiều lần không cần thiết, hoặc context tích luỹ quá dài qua nhiều bước | Cache kết quả tool trong 1 phiên, tóm tắt/cắt bớt lịch sử hội thoại cũ khi context vượt ngưỡng |
| Model "bịa" tên tool không tồn tại | Mô tả tool không đủ rõ, hoặc có quá nhiều tool (>20) khiến model nhầm lẫn | Viết lại mô tả tool cụ thể hơn; nhóm tool theo domain, chỉ expose tool liên quan đến bước hiện tại thay vì toàn bộ cùng lúc |
| Agent "quên" chỉ thị ban đầu sau nhiều bước | Context pollution — lịch sử tool call/result quá dài làm loãng system prompt | Tóm tắt định kỳ, hoặc dùng multi-agent để mỗi agent con có context ngắn gọn hơn thay vì 1 agent ôm hết |
🏋️ Bài tập thực hành
Xây một multi-agent system với LangGraph: Agent điều phối nhận yêu cầu nghiên cứu một chủ đề → giao cho Agent tìm kiếm (dùng tool search có sẵn hoặc RAG từ Module 6) thu thập thông tin → Agent viết tổng hợp thành báo cáo → Agent kiểm tra chất lượng/tính nhất quán trước khi trả kết quả cuối. Thêm giới hạn cứng tối đa 10 bước lặp và log lại toàn bộ quyết định của agent để debug.
📚 Tài nguyên học tập
-
Anthropic — Building Effective AgentsNguyên tắc thiết kế agent hiệu quảBài viết
-
LangGraph — DocumentationTài liệu chính thức LangGraphDocs
-
OpenAI Agents SDKSDK xây agent của OpenAIDocs
-
Claude Agent SDKSDK xây agent của AnthropicDocs
✅ Tự đánh giá hoàn thành
- Giải thích được sự khác nhau giữa ReAct, Plan-and-Execute, và Orchestrator-Worker
- Xây được ít nhất 1 agent workflow bằng LangGraph có rẽ nhánh điều kiện
- Triển khai multi-agent system với 2+ agent chuyên biệt phối hợp nhau
- Có cơ chế giới hạn số bước lặp cứng để tránh chi phí bùng nổ