Product Management
Đăng nhập
ESC

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

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

Bài 6 — Xây agent đầu tiên (pro-code): vòng lặp tool use và nâng cấp lên LangGraph

Đã đọc 0/7 mục · còn khoảng 3 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.

Bài này bạn viết một agent bằng code, bắt đầu từ tool use thuần (hiểu bản chất), rồi biết khi nào nên nâng lên LangGraph. Cùng bài toán CSKH ở Bài 5 để dễ đối chiếu.

Bước 1 — Định nghĩa tool

tools = [
  {"name": "search_faq", "description": "Tra FAQ theo câu hỏi",
   "input_schema": {"type": "object",
     "properties": {"query": {"type": "string"}}, "required": ["query"]}},
  {"name": "get_order", "description": "Tra đơn hàng theo mã",
   "input_schema": {"type": "object",
     "properties": {"order_id": {"type": "string"}}, "required": ["order_id"]}},
]

Bước 2 — Vòng lặp agent (tool use thuần)

def run_tool(name, args):
    if name == "search_faq": return faq_lookup(args["query"])
    if name == "get_order":  return order_lookup(args["order_id"])

messages = [{"role": "user", "content": user_question}]
while True:
    resp = client.messages.create(
        model="claude-...", max_tokens=1024,
        system="Chỉ trả lời dựa trên tool. Không chắc thì nói không biết.",
        tools=tools, messages=messages)
    if resp.stop_reason != "tool_use":
        print(resp.content[0].text); break        # câu trả lời cuối
    messages.append({"role": "assistant", "content": resp.content})
    results = []
    for block in resp.content:
        if block.type == "tool_use":
            out = run_tool(block.name, block.input)
            results.append({"type": "tool_result",
                            "tool_use_id": block.id, "content": str(out)})
    messages.append({"role": "user", "content": results})

Đây là trái tim của mọi agent. Framework nào cũng bọc quanh vòng lặp này.

Bước 3 — Khi nào nâng lên LangGraph

Dừng lại và nâng cấp khi bạn gặp một trong các dấu hiệu:

  • Cần rẽ nhánh có điều kiện rõ ràng (nếu là khiếu nại → nhánh khác).
  • Cần lưu state qua nhiều lượt / nhiều phiên (persistence, checkpoint).
  • Cần human-in-the-loop (dừng chờ người duyệt rồi chạy tiếp).
  • Vòng lặp tự viết bắt đầu rối, khó test.
# LangGraph (ý tưởng): mô hình hóa thành đồ thị state
# builder.add_node("agent", call_model)
# builder.add_node("tools", tool_node)
# builder.add_conditional_edges("agent", should_continue, {"tools": "tools", "end": END})
# builder.add_edge("tools", "agent")
# graph = builder.compile(checkpointer=memory)  # có persistence

Các bước triển khai

  • Viết tool use thuần trước để hiểu và kiểm soát.
  • Thêm giới hạn số vòng lặp (tránh loop vô hạn đốt token).
  • Test các nhánh: FAQ, tra đơn, ngoài phạm vi.
  • Chỉ khi chạm giới hạn (state/branch/human-in-loop) mới chuyển LangGraph.
  • Giữ tool tách biệt, tái dùng được ở cả hai kiến trúc.
Hãy để ý một chi tiết quan trọng trong đoạn code: khi model xin gọi tool, bạn phải thêm cả message của assistant (chứa tool_use) VÀ message chứa tool_result vào lịch sử rồi mới gọi model lần nữa. Bỏ sót một trong hai sẽ khiến model mất ngữ cảnh và lặp lại yêu cầu, hoặc lỗi. Đây là lỗi phổ biến nhất khi người ta tự viết vòng lặp lần đầu. Hiểu đúng cơ chế này chính là lý do nên viết tay tool use ít nhất một lần trước khi dựa vào framework — vì khi framework hỏng, bạn cần biết bên dưới nó đang làm gì.

Một điểm khác biệt then chốt giữa tool use thuần và LangGraph là quản lý state. Trong vòng lặp thuần, state của bạn chính là biến messages — mất khi tiến trình kết thúc. LangGraph cho phép gắn checkpointer để lưu state ra bộ nhớ/CSDL, nên agent có thể tạm dừng chờ người duyệt rồi chạy tiếp đúng chỗ đã dừng, hoặc phục hồi sau khi server restart. Nếu bài toán của bạn là một câu hỏi–một câu trả lời trong một request, tool use thuần là đủ. Nếu là quy trình dài nhiều chặng, có phê duyệt, có gián đoạn, thì state bền vững của LangGraph mới đáng giá.

Khung tư duy pro-code

> Bắt đầu từ vòng lặp tool use tối giản. Nâng lên framework khi — và chỉ khi — bạn cần state, branch, hoặc human-in-the-loop. Framework là để giải quyết độ phức tạp, không phải để trông "pro".

Sai lầm thường gặp

  • Không giới hạn số vòng lặp: agent kẹt loop, đốt token và có thể gọi tool lặp vô hạn.
  • Nhảy thẳng vào LangGraph mà chưa hiểu tool use, dẫn tới không debug được khi lỗi.
  • Trộn logic tool vào vòng lặp: khó test, khó tái dùng. Tách hàm tool riêng.
  • Bỏ qua xử lý lỗi tool: khi API đơn hàng sập, agent nhận rác và trả lời sai thay vì báo lỗi.
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