Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 1 — Vì sao agent cần State Machine? Tư duy graph thay cho chuỗi if/else

Đã đọc 0/7 mục · còn khoảng 4 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Khi mới xây agent, đa số chúng ta viết một vòng while gọi LLM, parse output, rồi dùng if/else để quyết định bước tiếp theo. Cách này chạy được với demo, nhưng vỡ trận khi agent thật cần: quay lại bước cũ để thử lại (retry), chờ người duyệt, chạy song song, hoặc khôi phục sau khi tiến trình crash. Lúc đó code biến thành một mớ cờ (flag) chằng chịt mà không ai dám sửa, mỗi lần thêm tính năng lại kéo theo vài bug ẩn.

LangGraph giải quyết vấn đề này bằng cách mô hình hóa agent thành state machine: một đồ thị (graph) gồm các node (việc cần làm) nối với nhau bằng edge (luồng đi), cùng một khối state dùng chung được truyền qua từng node. Bạn mô tả agent như một sơ đồ, và LangGraph lo phần chạy, lưu, khôi phục.

Ba khái niệm nền tảng

  • State: một cấu trúc dữ liệu (thường là TypedDict) chứa toàn bộ thông tin agent cần — tin nhắn, kết quả tool, biến điều khiển. Mỗi node đọc state, trả về phần cập nhật.
  • Node: một hàm Python nhận state, làm đúng một việc (gọi LLM, gọi API, xử lý dữ liệu), trả về dict cập nhật state.
  • Edge: đường nối quyết định node nào chạy tiếp. Có edge cố định (luôn đi một hướng) và edge có điều kiện (conditional, tự chọn hướng theo state).

Ví dụ cụ thể: agent trả lời câu hỏi có tra cứu

Hãy hình dung agent hỗ trợ khách hàng. Luồng nghiệp vụ:

  • Node classify: phân loại câu hỏi (hỏi giá, khiếu nại, chào hỏi...).
  • Node search: tra cứu tài liệu nếu câu hỏi cần dữ liệu.
  • Node answer: soạn câu trả lời cuối.
  • Edge có điều kiện: sau classify, nếu là câu hỏi cần dữ liệu thì đi search, nếu chỉ chào hỏi thì đi thẳng answer.
Vẽ ra giấy, nó là một sơ đồ rõ ràng. LangGraph cho bạn viết đúng sơ đồ đó thành code, thay vì nhồi tất cả vào một hàm khổng lồ với hàng chục nhánh if.

from typing import TypedDict
from langgraph.graph import StateGraph, START, END

class State(TypedDict):
    question: str
    category: str
    context: str
    answer: str

def classify(state: State) -> dict:
    # gọi LLM để phân loại; ở đây minh họa đơn giản
    cat = "faq" if "giá" in state["question"] else "chat"
    return {"category": cat}

Mỗi node ngắn gọn, một trách nhiệm. Khi cần sửa cách phân loại, bạn chỉ đụng vào classify mà không sợ ảnh hưởng phần soạn câu trả lời.

Các bước tư duy khi thiết kế agent bằng graph

  • Liệt kê các "việc" agent phải làm — mỗi việc là một node ứng viên.
  • Xác định dữ liệu chung cần truyền giữa các việc — đó chính là state.
  • Vẽ luồng giữa các việc: đâu là đường thẳng, đâu là ngã rẽ (conditional edge), đâu là vòng lặp.
  • Đánh dấu điểm dừng: nơi cần chờ người, nơi có thể lặp lại.
  • Chỉ khi sơ đồ đã rõ mới bắt tay code từng node.

Khung tư duy: "Node làm, Edge quyết, State nhớ"

Ghi nhớ câu này. Mỗi khi bí, tự hỏi: dữ liệu này thuộc State hay là logic của Node? Quyết định rẽ nhánh này là Edge có điều kiện hay là việc bên trong Node? Ranh giới rõ ràng giúp graph dễ đọc và cho phép test từng phần độc lập — điều gần như bất khả thi với vòng while khổng lồ.

So sánh nhanh

Cách viết vòng lặp thủ côngCách state machine (LangGraph)
Logic trộn lẫn trong một hàmMỗi node một trách nhiệm
Khó lưu/khôi phục giữa chừngCheckpoint có sẵn
Human-in-loop phải tự chếCó cơ chế interrupt
Khó test từng bướcTest từng node dễ dàng
Vòng lặp khó kiểm soátCycle có ngưỡng rõ ràng

Sai lầm thường gặp

  • Nhồi mọi thứ vào một node: node "god function" gọi LLM, parse, gọi tool và quyết định — đánh mất toàn bộ lợi ích của graph. Hãy chia nhỏ.
  • Đặt logic rẽ nhánh bên trong node thay vì dùng conditional edge, khiến luồng bị ẩn và khó theo dõi khi vẽ sơ đồ.
  • Cho state chứa dữ liệu tạm không cần thiết, làm state phình to, khó debug và tốn token khi truyền cho LLM.
  • Bắt đầu code trước khi vẽ sơ đồ: bạn sẽ liên tục refactor. Vẽ trước, code sau.
Sau bài này, bạn đã có tư duy nền: agent = graph gồm node/edge/state. Bài 2 sẽ cài đặt môi trường và dựng graph chạy được đầu tiên.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi