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.

Marketing agent graph: brief, research, plan, create, review, on-brand check with a loop back to create, human approval, publish. no yes campaign brief researchLangChain planLangChain createLangChain reviewLangChain on brand? human approvalinterrupt ready to publish

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ụcKhông dùng gìLangChainLangGraphLangSmith
Mức trừu tượngKhông cóCaoThấpKhông đụng tới logic
Kiểm soát luồngToàn quyền, tự làm hếtThấp, vòng agent cố địnhCao, tường minh—
Quay lui, chờ ngườiTự xâyQua middleware, có giới hạnCó sẵn, bền vững—
Thời gian họcGần như khôngVài giờVài ngàyVài giờ
Chi phí00 (MIT)0 (MIT)Theo trace, có gói miễn phí
Khoá vendorKhôngTrung bìnhTrung bìnhCó, SaaS đóng
Thay bằng—SDK nhà cung cấp, LiteLLMTemporal, code tự viếtLangfuse, Phoenix
AxisNoneLangChainLangGraphLangSmith
AbstractionNoneHighLowDoesn’t touch logic
Flow controlFull, but DIYLow, fixed agent loopHigh, explicit—
Loop back, wait on humanBuild itVia middleware, limitedBuilt in, durable—
Learning timeAlmost noneHoursDaysHours
Cost00 (MIT)0 (MIT)Per trace, free tier
Vendor lock-inNoneMediumMediumYes, closed SaaS
Replace with—Provider SDK, LiteLLMTemporal, custom codeLangfuse, Phoenix

Sai lầm thường gặpAnti-patterns

Sai lầmVì sao saiSửa thế nào
LangGraph cho luồng ba bước thẳng hàngThêm khái niệm mà không thêm khả năngHà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ồiModel 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 chungThiê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-classicTài liệu v1, create_agent, LCEL
Coi LangSmith là evalNhìn trace không đo được chất lượngDataset + evaluator chạy trước mỗi lần đổi prompt
InMemorySaver trên productionKhởi động lại là mất mọi thread đang dởPostgresSaver
MistakeWhy it’s wrongFix
LangGraph for a three-step linear flowAdds concepts without adding capabilityPython functions or an LCEL chain
Unbounded retry loopBurns money, ends in a recursion_limit errorCount attempts, hand off to a human when out
Retrying without passing feedbackThe model rewrites nearly the same thingFeed 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 twiceSide effects in a later node, with an idempotency key
Model reviews its own output with a vague promptBiased, almost always passesConcrete rubric, structured output, plus code checks
Following old tutorials (LLMChain, initialize_agent)APIs removed or moved to langchain-classicv1 docs, create_agent, LCEL
Treating LangSmith as evaluationLooking at traces doesn’t measure qualityDatasets + evaluators before each prompt change
InMemorySaver in productionA restart wipes every in-flight threadPostgresSaver

Ba câu cần nhớThree things to remember

  1. Chuỗi chỉ đi tới; cần quay lui, rẽ nhánh hay chờ người thì cần đồ thị.
  2. 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.
  3. 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.
  1. A chain only goes forward; to loop back, branch, or wait on a human, you need a graph.
  2. LangChain gives components, LangGraph gives control flow, LangSmith gives visibility — three independent choices.
  3. 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

  1. “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.
  2. “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.
  3. 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.
  1. “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.
  2. “Zero-config tracing, any framework” is overstated: only LangChain/LangGraph switch on via env vars; other code needs @traceable, a wrapper, or OpenTelemetry.
  3. The “langchain” badge marks components used inside a node; the flow between nodes belongs to LangGraph.