FDE PulseViệc làm FDE đang mở 316Mới đăng 7 ngày qua 10Chủ đề nổi bật: Đào tạo kỹ năng FDE tại Đông Nam Á

Tờ báo của nghề Forward Deployed Engineer

Bách khoa

Khi nào agent phải dừng: bốn lớp chặn và lúc bàn giao cho con người

Một agent không có điều kiện dừng có thể chạy vô hạn và đốt chi phí mà không ném ra lỗi nào, và người phải giải thích với khách hàng là FDE.

Đồ hoạMỗi lý do dừng dẫn tới việc gì của con người
Khi nào xảy raCon người làm gì
max_stepsVòng lặp chạm số bước tối đaKỹ sư tìm chu trình trước khi nghĩ đến chuyện nâng giới hạn
repeat_loopGọi cùng tool, cùng tham số quá 3 lầnKiểm tra tool đang lỗi gì, xử lý ticket thủ công nếu cần
budget / timeoutĐã dùng 80% ngân sách token hoặc chạy quá 90 giâyNhân viên đọc tóm tắt, quyết định cho chạy tiếp hay tự làm nốt
needs_approvalSắp gọi issue_refund hoặc send_emailNhân viên kiểm tra hành động đang chờ rồi duyệt hoặc từ chối

Agent dừng chỉ có ích khi mỗi lý do dừng gắn với một hành động rõ ràng của người tiếp nhận.

Đồ hoạ: FDE Times

Tóm tắt nhanh

  • Vòng lặp agent về bản chất là một vòng while, chỉ tự dừng khi đạt mục tiêu. Vì thế lúc nào cũng phải thêm giới hạn bước, ngân sách và thời gian.
  • Nên kết hợp nhiều điều kiện dừng, vòng lặp kết thúc khi bất kỳ điều kiện nào thỏa. Vercel AI SDK mặc định dừng sau 20 bước.
  • Dừng không có nghĩa là im lặng: mỗi lần dừng phải trả về lý do và bàn giao đủ ngữ cảnh cho con người, nhất là trước hành động không hoàn tác được.
Chia sẻLinkedInFacebookX

Thử hình dung buổi sáng thứ Hai ở văn phòng khách hàng. Agent xử lý ticket hoàn tiền mà bạn deploy tuần trước đã chạy suốt đêm trên đúng một ticket: tra đơn hàng, đọc kết quả, tra lại đơn hàng, đọc lại. Không có lỗi nào được ném ra, chỉ có log dài hàng nghìn dòng và hóa đơn API tăng vọt.

Agent không trả lời sai. Nó chỉ không biết lúc nào phải dừng. Một FDE sẽ thấy sự cố kiểu này khó giải thích với khách hàng, vì không có dòng lỗi nào để chỉ vào, chỉ có một hệ thống cứ chạy mãi.

Tin tốt là cách phòng chuyện này không có gì bí ẩn. Nó gồm hai phần: đặt giới hạn cho vòng lặp, và thiết kế thời điểm agent bàn giao việc cho con người.

Vì sao một agent không tự biết dừng?

Hugging Face Agents Course mô tả vòng lặp agent giống một vòng while: chu trình suy nghĩ, hành động, quan sát cứ tiếp tục cho đến khi mục tiêu được hoàn thành. Hành động cuối cùng là gửi câu trả lời về cho người dùng, và vòng lặp khép lại ở đó.

Vấn đề nằm ở chữ “cho đến khi”. Nếu model không bao giờ tin rằng mình đã đạt mục tiêu, vì dữ liệu thiếu, tool trả lỗi mơ hồ hay prompt tự mâu thuẫn, thì điều kiện dừng tự nhiên sẽ không bao giờ thỏa. Tài liệu Vercel AI SDK nói thẳng: không có giới hạn bước, agent có thể chạy vô hạn hoặc gây chi phí lớn.

Vì thế, trong hướng dẫn xây dựng agent, Anthropic khuyên thêm điều kiện dừng, chẳng hạn số vòng lặp tối đa, để giữ quyền kiểm soát. Nhưng đặt ngưỡng ở đâu là một đánh đổi thật. Một bài hướng dẫn của Metric Coders tóm lại thế này: dừng quá sớm thì kết quả thiếu, dừng quá muộn thì lan man, lặp lại hoặc ảo giác.

Bốn lớp chặn, mỗi lớp bắt một kiểu hỏng

Không giới hạn nào đủ dùng một mình, vì mỗi cái bắt một loại sự cố khác nhau. AI SDK cho phép ghép nhiều điều kiện dừng, và vòng lặp kết thúc khi bất kỳ điều kiện nào thỏa. Dù dùng framework nào, bạn cũng nên nghĩ theo cách đó.

Lớp chặn Bắt được gì Điểm yếu cần biết
Số bước tối đa Vòng lặp quay mãi, chu trình logic Ngưỡng quá thấp làm tác vụ dài bị cắt
Ngân sách token Chi phí phình to dù số bước ít Chỉ giới hạn token đầu ra thì có thể bị cắt giữa câu
Deadline thời gian Tool chậm, người dùng đang chờ Không nói gì về chất lượng kết quả
Phát hiện lặp lại Gọi cùng tool, cùng tham số nhiều lần Phải định nghĩa thế nào là “giống nhau”

Về số bước, AI SDK mặc định dừng ToolLoopAgent sau 20 bước. Đó là điểm khởi đầu hợp lý chứ không phải con số thần kỳ. Về token, bài của Metric Coders lưu ý rằng giới hạn số token được sinh ra là cách đơn giản nhưng dễ cắt ngang câu, nên khuyên kết hợp nhiều cách.

Stop sequence, tức dừng ngay khi model phát ra một chuỗi định trước, hợp với đầu ra có cấu trúc. Nhưng cách này mong manh nếu model không phát ra đúng chuỗi đó.

Trong ví dụ bên dưới, lớp phát hiện lặp lại và deadline thời gian đều được viết tay ngay trong vòng lặp, cạnh hai giới hạn quen thuộc là bước và token.

Dừng không phải là bỏ cuộc: bàn giao cho con người

Anthropic mô tả việc agent có thể tạm dừng để lấy phản hồi của con người tại các điểm kiểm tra, hoặc khi gặp vật cản.

Trang agentpatterns.ai cụ thể hóa thành ba vị trí. Một là khi độ tin cậy thấp. Hai là khi vòng lặp đã tiêu một tỷ lệ cấu hình được của ngân sách token, tiền hoặc số lần gọi tool. Ba là trước mọi hành động mà vòng lặp không thể tự hoàn tác từ trạng thái của nó.

Với khách hàng doanh nghiệp, vị trí thứ ba đáng lo nhất. Tra cứu đơn hàng sai thì tra lại được. Hoàn tiền sai hay gửi nhầm email cho khách thì không lấy lại được.

Ví dụ: agent hoàn tiền cho một sàn thương mại điện tử

Giả sử bạn làm agent xử lý ticket hoàn tiền, với các tool: tra đơn, tra chính sách, hoàn tiền và gửi email. Các ngưỡng dưới đây chỉ là con số giả định để minh họa: tối đa 20 bước, ngân sách 40.000 token, bàn giao cho nhân viên khi đã dùng 80% ngân sách, deadline 90 giây.

import time

MAX_STEPS = 20
TOKEN_BUDGET = 40_000
SOFT_FRACTION = 0.8          # chạm 80% ngân sách thì dừng để hỏi con người
DEADLINE_S = 90
MAX_REPEAT = 3               # cùng tool + cùng tham số quá 3 lần = đang lặp
IRREVERSIBLE = {"issue_refund", "send_email"}

def run(task):
    s = {"steps": 0, "tokens": 0, "history": [], "calls": {}}
    start = time.monotonic()
    while True:
        if s["steps"] >= MAX_STEPS:
            return handoff(task, s, "max_steps")
        if s["tokens"] >= TOKEN_BUDGET * SOFT_FRACTION:
            return handoff(task, s, "budget")
        if time.monotonic() - start > DEADLINE_S:
            return handoff(task, s, "timeout")

        step = llm_next_step(task, s["history"])
        s["steps"] += 1
        s["tokens"] += step.usage.total_tokens

        if step.is_final:
            return {"status": "done", "answer": step.answer, "steps": s["steps"]}

        key = (step.tool, str(sorted(step.args.items())))
        s["calls"][key] = s["calls"].get(key, 0) + 1
        if s["calls"][key] > MAX_REPEAT:
            return handoff(task, s, "repeat_loop", pending=step)

        if step.tool in IRREVERSIBLE:
            return handoff(task, s, "needs_approval", pending=step)

        obs = call_tool(step.tool, step.args)
        s["history"].append((step, obs))

def handoff(task, s, reason, pending=None):
    return {
        "status": "needs_human",
        "reason": reason,
        "steps": s["steps"],
        "tokens": s["tokens"],
        "summary": summarize(s["history"]),
        "pending_action": pending,
    }

Quay lại kịch bản ở đầu bài. Agent tra đơn, nhận lỗi timeout từ API đơn hàng, rồi tra lại với đúng mã đơn đó. Đến lần gọi thứ tư, bộ đếm lặp kích hoạt và trả về repeat_loop kèm tóm tắt lịch sử, thay vì quay suốt đêm.

Ở một ticket khác, agent tra đơn, tra chính sách, kết luận khách đủ điều kiện và định gọi issue_refund. Vòng lặp dừng với lý do needs_approval, kèm hành động đang chờ duyệt. Nhân viên chăm sóc khách hàng chỉ cần kiểm tra rồi bấm duyệt hoặc từ chối, không phải đọc lại từ đầu.

Hãy để ý rằng hàm handoff không chỉ báo “thất bại”. Nó trả về lý do, số bước, số token và bản tóm tắt. Nhờ vậy người tiếp nhận có thể làm tiếp chỉ trong vài giây.

Mỗi lý do dừng nên dẫn tới một việc cụ thể của con người. Với repeat_loop, người nhận kiểm tra tool đang lỗi gì và xử lý ticket thủ công nếu cần. Với budget hay timeout, nhân viên đọc tóm tắt rồi quyết định cho agent chạy tiếp hay tự làm nốt. Còn max_steps là việc của kỹ sư: tìm chu trình trước khi nghĩ đến chuyện nâng giới hạn.

Tự làm ở dự án của bạn

Bắt đầu bằng việc liệt kê mọi tool và chia thành ba nhóm: chỉ đọc, ghi nhưng hoàn tác được, và ghi không hoàn tác được. Nhóm cuối luôn phải qua điểm duyệt, ít nhất là trong giai đoạn đầu deploy.

Tiếp theo, chạy agent trên một mẫu tác vụ thật và ghi lại số bước, số token của những lần thành công. Đặt giới hạn cao hơn mức thường gặp một khoảng vừa đủ, thay vì đoán. Sau đó thống nhất với khách hàng: ai nhận việc khi agent dừng, qua kênh nào, và họ cần thấy những gì.

Cuối cùng, biến “lý do dừng” thành một metric. Nếu tỷ lệ dừng vì max_steps tăng lên sau một lần đổi prompt, bạn biết ngay có chỗ hỏng.

Những lỗi hay gặp

Lỗi đầu tiên cần tránh là nâng giới hạn ngay khi thấy agent bị cắt. Tài liệu LangGraph về lỗi GRAPH_RECURSION_LIMIT nhắc rằng nếu bạn không nghĩ đồ thị sẽ lặp nhiều mà nó vẫn chạm giới hạn, nhiều khả năng đang có chu trình. Bạn có thể tăng recursionLimit, nhưng phải kiểm tra logic vòng lặp vô hạn trước.

Lỗi thứ hai là chỉ dựa vào giới hạn token đầu ra, khiến người dùng nhận câu trả lời đứt giữa chừng. Lỗi thứ ba là dừng trong im lặng: vòng lặp kết thúc mà người dùng không nhận được gì, trái với nguyên tắc vòng lặp phải khép lại bằng một câu trả lời.

Lỗi thứ tư khó thấy hơn: bàn giao cho nhân viên mà không kèm ngữ cảnh. Người nhận phải mở log và đọc lại toàn bộ. Khi đó, rất dễ hiểu nếu họ bắt đầu coi agent là gánh nặng chứ không phải trợ thủ.

Biến kỹ năng này thành điểm cộng khi đi phỏng vấn

Khi đọc mô tả công việc FDE, hãy để ý xem có nhắc đến human-in-the-loop hay guardrails không. Nếu có, đó là chỗ để bạn đưa kỹ năng này ra. Trong CV, đừng viết chung chung “xây dựng AI agent”.

Hãy ghi rõ bạn đã thiết kế điều kiện dừng và luồng bàn giao cho con người, kèm một con số đo được, ví dụ tỷ lệ tác vụ phải chuyển cho nhân viên xử lý.

Bài tập tuần này: lấy một agent bạn từng viết, cố tình làm cho một tool luôn trả lỗi, rồi chạy thử. Nếu agent tự dừng sau vài lần thử và trả về một bản bàn giao đọc hiểu được trong mười giây, bạn đã có một câu chuyện cụ thể để kể ở buổi phỏng vấn tiếp theo.

6 nguồn
Đọc tiếp trên lộ trình · Chặng 5: Triển khaiGuardrails cho ứng dụng LLM của khách: chặn đầu vào, khóa đầu ra, thêm moderationPrompt injection gần như chưa có cách chặn triệt để, nên FDE phải xếp nhiều lớp phòng thủ chồng lên nhau, sao cho một lớp thủng thì hậu quả vẫn nhỏ.