Dựng agent với hệ LangChainBuilding agents with the LangChain stack
Chuỗi chỉ đi tới. Đồ thị có thể quay lui.A chain goes forward. A graph can go back.
LangChain dựng agent, LangGraph chạy nó, LangSmith quan sát nó. Ba công cụ, ba câu hỏi độc lập — và rất nhiều trường hợp không cần cái nào.
LangChain builds the agent, LangGraph runs it, LangSmith watches it. Three tools, three independent questions — and plenty of cases where you need none of them.
Một lần chạy, tua lại đúng 10,1 giâyOne run, replayed in its real 10.1 seconds
Bên trái là đồ thị LangGraph điều khiển. Bên phải là trace LangSmith ghi lại. Bài viết lần đầu bị chấm lệch giọng thương hiệu, nên đồ thị quay lui theo nét đứt và viết lại.
Left: the graph LangGraph controls. Right: the trace LangSmith records. The first draft fails the brand check, so the graph loops back along the dashed edge and rewrites.
LangSmith trace
0.0 s
research
1.2s
plan
0.8s
create
3.4s
review
0.9s
create
3.1s
review
0.7s
6 span, 10,1 s, 1 lần thử lại. Lần thử lại tốn 3,8 s, khoảng 38% tổng thời gian.
6 spans, 10.1 s, 1 retry. The retry cost 3.8 s, about 38% of the total.
Khi có lỗi, trace trả lời được:
When it breaks, the trace answers:
Node nào hỏng?
Lần thử thứ mấy?
Lần thử lại tốn bao nhiêu thời gian và token?
Which node failed?
Which attempt was it?
What did the retry cost in time and tokens?
Nhãn LangChain trên mỗi node nghĩa là bên trong node dùng linh kiện LangChain để gọi model. Việc đi sang node nào tiếp theo, kể cả quay lui, là do LangGraph quyết định lúc chạy.
The LangChain badge on each node means the node uses LangChain components to call the model. Which node runs next, including looping back, is decided by LangGraph at runtime.
Chọn cái nàoWhich one to use
Câu hỏi đầu tiên luôn là: có cần cái nào không?
The first question is always: do you need any of them?
Không dùng gì cả, khi:Use none of them when:
Chỉ có 1–3 lần gọi LLM theo thứ tự cố định.
Chỉ dùng một nhà cung cấp model và không định đổi.
Thử lại gói gọn trong một vòng for có giới hạn.
Không bước nào phải dừng chờ người duyệt hàng giờ.
It's 1–3 LLM calls in a fixed order.
You use one model provider and won't switch.
Retrying fits in a bounded for loop.
No step waits hours for human approval.
Phương án rẻ nhất: SDK của nhà cung cấp + hàm Python + structured output bằng Pydantic + log JSON. Agent trong ảnh, bỏ bước chờ duyệt, gói trong khoảng 50 dòng. Bạn vượt baseline khi bắt đầu tự viết code lưu trạng thái để chạy tiếp, tự dựng hàng đợi chờ duyệt, hoặc không biết lần chạy hôm qua hỏng ở đâu.
Cheapest option: the provider SDK + Python functions + Pydantic structured output + JSON logs. The image's agent, minus the approval pause, fits in about 50 lines. You've outgrown it when you start writing your own state persistence to resume runs, building an approval queue, or can't tell where yesterday's run failed.
Có cần nhiều lần gọi LLM nối nhau không?
├─ Không ──────────────────────► SDK nhà cung cấp. Xong.
└─ Có
├─ Luồng cố định, chỉ đi tới? ─► Hàm Python, hoặc chain LCEL
└─ Rẽ nhánh, quay lui, chờ người?
├─ Agent gọi tool kiểu chuẩn ─► LangChain create_agent
│ (đã chạy trên LangGraph)
└─ Luồng tự thiết kế, dừng–tiếp tục,
nhiều vai trò ───────────────► LangGraph StateGraph
Câu hỏi riêng: có người dùng thật, cần debug hoặc đo chất lượng?
└─ Có ─► LangSmith (hoặc Langfuse / Phoenix nếu cần tự host)
Do you need several chained LLM calls?
├─ No ─────────────────────────► Provider SDK. Done.
└─ Yes
├─ Fixed flow, forward only? ─► Python functions, or an LCEL chain
└─ Branching, looping back, waiting on a human?
├─ Standard tool-calling agent ─► LangChain create_agent
│ (already runs on LangGraph)
└─ Custom flow, pause/resume,
multiple roles ──────────────► LangGraph StateGraph
Separate question: real users, need to debug or measure quality?
└─ Yes ─► LangSmith (or Langfuse / Phoenix to self-host)
Dựng, chạy, quan sátBuild, run, watch
Ba công cụ theo đúng thứ tự vòng đời của một agent.
The three tools in the order of an agent's lifecycle.
01
LangChain
Framework, dựngFramework, build
Bộ linh kiện chung cho ứng dụng LLM: model, prompt, tool, retriever, structured output, cộng một agent gọi tool dựng sẵn.
A common kit of LLM app parts: models, prompts, tools, retrievers, structured output, plus a prebuilt tool-calling agent.
Chọn LangChain là đổi quyền kiểm soát chi tiết và sự ổn định API lấy tốc độ lắp ráp và khả năng thay nhà cung cấp.
Choosing LangChain trades fine-grained control and API stability for assembly speed and swappable providers.
Dùng choUse for
Hỏi đáp trên tài liệu nội bộ (RAG)
Trích xuất JSON từ email, hoá đơn
Chatbot gọi 3–5 tool
Q&A over internal docs (RAG)
JSON extraction from email, invoices
Chatbots with 3–5 tools
ĐượcGain
Hàng trăm integration, một giao diện
Đổi model bằng một chuỗi
Agent chạy được trong ~10 dòng
Hundreds of integrations, one interface
Swap models with a string
A working agent in ~10 lines
MấtLose
Lớp trừu tượng dày, khó lần ra lỗi
API đổi nhiều, tutorial cũ đã sai
Prompt thật bị giấu
Thick abstraction, hard-to-trace errors
API churn, old tutorials are wrong
The real prompt is hidden
Dấu hiệu nhận biết: luồng chỉ đi tới, hoặc chỉ là vòng gọi tool chuẩn.
The tell: the flow only goes forward, or it's just a standard tool loop.
02
LangGraph
Runtime, chạyRuntime, run
Runtime điều phối: ứng dụng là một đồ thị gồm node, edge có điều kiện, state chung và checkpointer lưu state sau mỗi bước.
An orchestration runtime: your app is a graph of nodes, conditional edges, shared state, and a checkpointer that saves state after every step.
Chọn LangGraph là đổi sự đơn giản và tốc độ viết code lấy quyền kiểm soát tường minh luồng chạy, khả năng quay lui và dừng – chạy tiếp.
Choosing LangGraph trades simplicity and writing speed for explicit control of the flow, looping back, and pause/resume.
Dùng choUse for
Vòng tạo – duyệt nội dung
Cổng duyệt trước hành động không đảo ngược được
Tác vụ dài, hệ nhiều agent
Create–review loops
Approval gates before irreversible actions
Long-running tasks, multi-agent systems
ĐượcGain
Vòng lặp, rẽ nhánh tường minh
Dừng – chạy tiếp, kể cả sau khi khởi động lại
Human-in-the-loop có sẵn
Explicit loops and branches
Pause/resume across restarts
Built-in human-in-the-loop
MấtLose
Nhiều khái niệm phải học
Quên điều kiện thoát là lặp tới recursion_limit
State phải serialize được
Many concepts to learn
No exit condition means looping until recursion_limit
State must be serializable
Dấu hiệu nhận biết: yêu cầu có câu “chưa đạt thì làm lại” hoặc “chờ người duyệt”.
The tell: the requirement says “redo it if it’s not good enough” or “wait for approval”.
03
LangSmith
Nền tảng, quan sátPlatform, watch
Nền tảng SaaS để ghi trace từng lần chạy, đánh giá bằng dataset và giám sát production; dùng được cả với code không viết bằng LangChain.
A SaaS platform to trace every run, evaluate against datasets, and monitor production; works with code that doesn’t use LangChain.
Chọn LangSmith là đổi chi phí, sự phụ thuộc vendor và việc gửi dữ liệu ra ngoài lấy khả năng nhìn thấu và đo lường agent mà không tự xây hạ tầng.
Choosing LangSmith trades cost, vendor dependency, and sending data out for deep visibility and measurement without building the infrastructure.
Dùng choUse for
Gỡ lỗi không tái hiện được
Đổi prompt mà sợ hỏng chỗ khác
Theo dõi chi phí của vòng thử lại
Debugging failures you can’t reproduce
Changing prompts without regressions
Tracking the cost of retries
ĐượcGain
Thấy prompt thật ở mọi bước
Biết node nào hỏng, lần thử mấy
Lỗi thật thành ca kiểm thử hồi quy
The real prompt at every step
Which node failed, which attempt
Real failures become regression tests
MấtLose
Dữ liệu ra bên thứ ba
Chi phí tăng theo số trace
Mã nguồn đóng; tự host chỉ ở gói enterprise
Data goes to a third party
Cost grows with trace volume
Closed source; self-host is enterprise-only
Dấu hiệu nhận biết: bạn không trả lời được “lần chạy hôm qua hỏng ở đâu”.
The tell: you can’t answer “where did yesterday’s run fail”.
Bảng đánh đổiTrade-off table
Trục
Không dùng gì
LangChain
LangGraph
LangSmith
Mức trừu tượng
Không có
Cao
Thấp
Không đụng tới logic
Kiểm soát luồng
Toàn quyền, tự làm hết
Thấp, vòng agent cố định
Cao, tường minh
—
Quay lui, chờ người
Tự xây
Qua middleware, có giới hạn
Có sẵn, bền vững
—
Thời gian học
Gần như không
Vài giờ
Vài ngày
Vài giờ
Chi phí
0
0 (MIT)
0 (MIT)
Theo trace, có gói miễn phí
Khoá vendor
Không
Trung bình
Trung bình
Có, SaaS đóng
Thay bằng
—
SDK nhà cung cấp, LiteLLM
Temporal, code tự viết
Langfuse, Phoenix
Axis
None
LangChain
LangGraph
LangSmith
Abstraction
None
High
Low
Doesn’t touch logic
Flow control
Full, but DIY
Low, fixed agent loop
High, explicit
—
Loop back, wait on human
Build it
Via middleware, limited
Built in, durable
—
Learning time
Almost none
Hours
Days
Hours
Cost
0
0 (MIT)
0 (MIT)
Per trace, free tier
Vendor lock-in
None
Medium
Medium
Yes, closed SaaS
Replace with
—
Provider SDK, LiteLLM
Temporal, custom code
Langfuse, Phoenix
Sai lầm thường gặpAnti-patterns
Sai lầm
Vì sao sai
Sửa thế nào
LangGraph cho luồng ba bước thẳng hàng
Thêm khái niệm mà không thêm khả năng
Hàm Python hoặc chain LCEL
Vòng thử lại không giới hạn
Đốt tiền, cuối cùng lỗi ở recursion_limit
Đếm attempts, hết lượt thì đẩy cho người
Thử lại mà không gửi phản hồi
Model viết lại gần y hệt
Đưa phản hồi của review vào prompt của create
Gửi email, đăng bài trong node có interrupt()
Chạy tiếp sẽ chạy lại node từ đầu, gửi hai lần
Đặt side effect ở node sau, kèm khoá idempotency
Model tự duyệt bài của nó bằng prompt chung chung
Thiên vị, gần như luôn “đạt”
Rubric cụ thể, structured output, kèm kiểm tra bằng code
Học theo tutorial cũ (LLMChain, initialize_agent)
API đã bỏ hoặc chuyển sang langchain-classic
Tài liệu v1, create_agent, LCEL
Coi LangSmith là eval
Nhìn trace không đo được chất lượng
Dataset + evaluator chạy trước mỗi lần đổi prompt
InMemorySaver trên production
Khởi động lại là mất mọi thread đang dở
PostgresSaver
Mistake
Why it’s wrong
Fix
LangGraph for a three-step linear flow
Adds concepts without adding capability
Python functions or an LCEL chain
Unbounded retry loop
Burns money, ends in a recursion_limit error
Count attempts, hand off to a human when out
Retrying without passing feedback
The model rewrites nearly the same thing
Feed the review’s feedback into the create prompt
Emailing or publishing inside a node with interrupt()
Resume re-runs the node from the start, sends twice
Side effects in a later node, with an idempotency key
Model reviews its own output with a vague prompt
Biased, almost always passes
Concrete rubric, structured output, plus code checks
Following old tutorials (LLMChain, initialize_agent)
APIs removed or moved to langchain-classic
v1 docs, create_agent, LCEL
Treating LangSmith as evaluation
Looking at traces doesn’t measure quality
Datasets + evaluators before each prompt change
InMemorySaver in production
A restart wipes every in-flight thread
PostgresSaver
Ba câu cần nhớThree things to remember
Chuỗi chỉ đi tới; cần quay lui, rẽ nhánh hay chờ người thì cần đồ thị.
LangChain cho linh kiện, LangGraph cho luồng điều khiển, LangSmith cho khả năng nhìn thấy — ba lựa chọn độc lập.
Bắt đầu không có framework; chỉ thêm khi bạn đang tự viết lại đúng thứ nó đã giải sẵn.
A chain only goes forward; to loop back, branch, or wait on a human, you need a graph.
LangChain gives components, LangGraph gives control flow, LangSmith gives visibility — three independent choices.
Start with no framework; add one only when you catch yourself rewriting what it already solves.
Hiệu đính so với ảnh gốcCorrections to the source image
“LangChain là DAG, không có vòng lặp” chỉ đúng với chain LCEL. Từ bản 1.0 (10/2025), create_agent chạy trên runtime LangGraph và có vòng lặp model ↔ tool.
“Zero-config tracing, any framework” bị nói quá: chỉ LangChain/LangGraph bật bằng biến môi trường; code khác cần @traceable, wrapper hoặc OpenTelemetry.
Nhãn “langchain” trên node chỉ linh kiện dùng bên trong node; luồng giữa các node là của LangGraph.
“LangChain is a DAG, not a loop” only holds for LCEL chains. Since 1.0 (Oct 2025), create_agent runs on the LangGraph runtime and loops between model and tools.
“Zero-config tracing, any framework” is overstated: only LangChain/LangGraph switch on via env vars; other code needs @traceable, a wrapper, or OpenTelemetry.
The “langchain” badge marks components used inside a node; the flow between nodes belongs to LangGraph.