Vấn đề với "Full Automation"
Khi bạn deploy AI agent đầu tiên vào production, cảm giác rất phấn khích: nó hoạt động trong demo, vượt qua các test case, và xử lý dữ liệu mẫu hoàn hảo. Rồi một ngày, agent tự động gửi email hoàn tiền cho 10,000 khách hàng — vì nó hiểu "refund policy" theo nghĩa đen hơn bạn nghĩ.
Autonomous ≠ Trustworthy. Đây là nguyên tắc cốt lõi của Human-in-the-Loop (HITL): con người không phải là trở ngại của tự động hóa — họ là lớp bảo vệ thông minh nhất bạn có.
Câu hỏi không phải là "có nên dùng HITL không?" mà là "đặt HITL ở đâu và khi nào?"
Nếu bạn đang xây dựng hệ thống agent phức tạp, hãy đọc thêm về Hệ thống Multi-Agent: Khi nào cần nhiều hơn một AI để hiểu HITL phù hợp với kiến trúc lớn hơn như thế nào.
Risk Matrix: Phân loại tác vụ trước khi tự động hóa
Trước khi quyết định để agent "tự chạy" hay cần checkpoint, hãy đánh giá mỗi tác vụ theo 2 trục:
- Rủi ro (Risk): Hậu quả nếu agent sai là gì?
- Tính đảo ngược (Reversibility): Có thể undo được không?
| Dễ đảo ngược | Khó đảo ngược |
|---|
| Rủi ro thấp | ✅ Full automation | ⚠️ Auto + logging |
| Rủi ro cao | ⚠️ Auto + alert | 🛑 HITL bắt buộc |
Ví dụ thực tế:
| Tác vụ | Rủi ro | Reversible | Quyết định |
|---|
| Phân loại support ticket | Thấp | Có | ✅ Full auto |
| Draft email marketing | Trung bình | Có | ⚠️ Auto + review |
| Gửi thông báo đến user | Cao | Không | ⚠️ Approval gate |
| Hủy đơn hàng | Cao | Một phần | ⚠️ Auto + alert |
| Xóa dữ liệu người dùng | Rất cao | Không | 🛑 HITL bắt buộc |
| Transfer tiền | Rất cao | Không | 🛑 HITL bắt buộc |
3 Pattern HITL Trong Thực Tế
Pattern 1: Approval Gate
Agent dừng lại và chờ con người phê duyệt trước khi thực hiện action có rủi ro cao.
Agent xử lý → 🔴 Checkpoint → Human review → Tiếp tục / Từ chối
Khi nào dùng: Tác vụ tài chính, gửi thông tin ra ngoài hệ thống, xóa hoặc sửa dữ liệu quan trọng.
const graph = workflow.compile({
checkpointer: new MemorySaver(),
interrupt_before: ["execute_action"],
})
await graph.invoke(
new Command({ resume: { approved: true, note: "Looks good" } }),
{ configurable: { thread_id: "task-123" } }
)
Ưu điểm: An toàn tuyệt đối cho tác vụ không reversible.
Nhược điểm: Tạo ra bottleneck, cần human available.
Pattern 2: Async Override
Agent tự chạy ngay nhưng gửi notification cho con người. Trong một khoảng thời gian nhất định (override window), human có thể can thiệp và veto.
Agent xử lý → Execute → 📩 Notify human → [Override window: 10 phút] → Hoàn tất
↑
Human có thể override trong window này
Khi nào dùng: Gửi email nội bộ, tạo bản nháp content, cập nhật cấu hình không quan trọng, trigger workflow downstream.
async function executeWithAsyncOverride(action: AgentAction) {
const result = await executeAction(action)
await overrideQueue.push({
actionId: action.id,
result,
expiresAt: Date.now() + 10 * 60 * 1000,
})
await notify.send({
channel: "agent-actions",
message: `Agent vừa thực hiện: ${action.description}`,
actions: [{ label: "Undo", url: `/override/${action.id}` }],
})
return result
}
Ưu điểm: Không làm chậm workflow, vẫn giữ được safety net.
Nhược điểm: Human phải phản ứng đủ nhanh trong override window.
Pattern 3: Shadow Mode
Agent chạy song song với process thủ công hiện tại. Output của agent được ghi lại và so sánh nhưng chưa được áp dụng.
Human process ──────────────────────────────→ Output thực tế
Agent process → [Shadow] → Log & Compare → (Dùng để validate, chưa deploy)
Khi nào dùng: Giai đoạn validation khi mới deploy agent lần đầu. Bạn build trust dần dần trước khi "thả tay".
Metrics cần track trong Shadow Mode:
- Agreement rate với human decision (mục tiêu: >95%)
- False positive / false negative rate
- Edge cases agent gặp nhưng chưa xử lý đúng
Implement HITL với LangGraph
LangGraph là framework phù hợp nhất cho HITL vì có khái niệm interrupt built-in:
from langgraph.graph import StateGraph
from langgraph.checkpoint.memory import MemorySaver
from langgraph.types import Command, interrupt
def human_approval_node(state: AgentState):
decision = interrupt({
"question": "Approve action?",
"action": state["pending_action"],
"context": state["reasoning"],
})
if not decision["approved"]:
return {"status": "rejected", "reason": decision.get("note")}
return {"status": "approved"}
graph = (
StateGraph(AgentState)
.add_node("analyze", analyze_node)
.add_node("human_approval", human_approval_node)
.add_node("execute", execute_node)
.add_edge("analyze", "human_approval")
.add_conditional_edges(
"human_approval",
lambda s: s["status"],
{"approved": "execute", "rejected": END},
)
.compile(checkpointer=MemorySaver())
)
Với Anthropic tool use, phân loại tools thành "safe" và "requires_approval":
const SAFE_TOOLS = ["search_web", "read_file", "calculate", "summarize"]
const APPROVAL_REQUIRED = ["send_email", "delete_record", "create_payment", "update_config"]
async function executeWithHITL(toolCall: ToolCall): Promise<ToolResult> {
if (APPROVAL_REQUIRED.includes(toolCall.name)) {
const { approved, note } = await requestHumanApproval({
tool: toolCall.name,
input: toolCall.input,
agentReasoning: toolCall.reasoning,
})
if (!approved) {
return { error: `Action rejected: ${note}` }
}
}
return executeTool(toolCall)
}
Để hiểu thêm về kiến trúc tool-based agent, xem AI Agent Tool Use: MCP kết nối AI với doanh nghiệp.
Tăng / Giảm Mức Tự Chủ Theo Thời Gian
HITL không phải trạng thái cố định. Hãy thiết kế agent để tự động tăng autonomy khi đã build được trust:
Tuần 1–2: Shadow Mode → Ghi log, không action thực tế
Tuần 3–4: Approval Gate → Mỗi action cần phê duyệt
Tháng 2: Async Override → Tự chạy, human có 10 phút để veto
Tháng 3+: Full Auto → Chỉ alert khi có anomaly hoặc low confidence
Metrics để quyết định "lên cấp" autonomy:
- Accuracy > 95% trên ít nhất 100 real cases
- Zero critical errors trong 2 tuần liên tiếp
- Human override rate < 5%
- P99 latency của human review > 30 phút (tức là human review đang là bottleneck)
Mô hình tăng autonomy theo thời gian này kết hợp rất tốt với việc trang bị bộ nhớ bền vững cho agent — agent nhớ càng nhiều context, càng ít cần human can thiệp vào các edge case.
Logging và Observability Là Bắt Buộc
Dù ở bất kỳ cấp độ autonomy nào, bạn đều cần:
- Audit log toàn bộ action của agent — ai, làm gì, khi nào, kết quả ra sao
- Confidence score — agent nên tự báo cáo khi nó không chắc
- Escalation path — khi confidence thấp, tự động chuyển sang HITL
- Real-time dashboard — human observer có thể giám sát
async function agentDecide(context: TaskContext): Promise<Action> {
const { action, confidence, reasoning } = await llm.decide(context)
await auditLog.write({ action, confidence, reasoning, timestamp: new Date() })
if (confidence < 0.80) {
await escalateToHuman({
task: context.task,
suggestedAction: action,
confidence,
reasoning,
urgency: confidence < 0.60 ? "high" : "normal",
})
return { type: "pending_human_review" }
}
return action
}
Kết Luận
Human-in-the-Loop không phải là thừa nhận rằng AI chưa đủ tốt. Đây là thiết kế hệ thống thông minh — biết điểm mạnh và điểm yếu của từng thành phần, rồi phân công đúng việc cho đúng "người".
Nguyên tắc thực hành:
- Bắt đầu với HITL nhiều, giảm dần theo dữ liệu thực tế — đừng bao giờ bắt đầu bằng full auto
- Không bao giờ full-auto những tác vụ không reversible mà không có safety net
- Logging trước, automation sau — bạn cần data để build trust
- Design cho failure — khi agent sai, human phải catch được ngay, không phải sau 3 ngày
Agent tốt nhất không phải agent chạy nhanh nhất — mà là agent bạn có thể tin tưởng deploy vào sản phẩm thực mà không mất ngủ vào ban đêm.