---
title: "AI agent của bạn đang chờ: biến cửa phê duyệt thành cuộc gọi"
description: "Agent tự hành dừng lại và chờ trong im lặng khi cần con người. Không thành phần nào trong hệ agent làm điện thoại bạn đổ chuông. Đây là cách nối cửa phê duyệt và các lần chạy thất bại vào một cuộc gọi thật với Echobell."
date: 2026-08-07
author: Nooc
authorAvatarLink: /images/avatars/nooc.webp
authorLink: https://nooc.me
tags:
  - cảnh báo AI agent
  - con người trong vòng lặp
  - cửa phê duyệt của agent
  - thông báo webhook
  - cảnh báo bằng cuộc gọi
---

# AI agent của bạn đang chờ: biến cửa phê duyệt thành cuộc gọi

Mọi framework agent tự hành ra mắt trong năm 2026 đều có chung một lỗ hổng. Agent chạy hàng giờ mà không cần bạn, gặp một hành động nó không được phép tự làm, dừng lại — rồi chẳng có gì xảy ra nữa. Lần chạy đó không thất bại. Nó không thử lại. Nó nằm im trong bộ nhớ, ôm một đối tượng trạng thái đã tuần tự hóa, chờ một con người hoàn toàn không biết là mình đang bị chờ. Bài viết này chỉ cho bạn cách lấp khoảng trống đó bằng việc biến khoảnh khắc "tôi cần con người" của agent thành một cuộc gọi đổ chuông với [Echobell](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-ai-agent-human-in-the-loop-alerts-vi&mt=8).

Khoảng trống này mang tính cấu trúc, không phải lỗi của riêng sản phẩm nào. Tài liệu về agent của OpenAI mô tả luồng phê duyệt rất rõ: khi một tool cần được phê duyệt, "lần chạy tạm dừng cho tới khi bạn chấp thuận hoặc từ chối", kết quả trả về `interruptions` cùng một `state` có thể tiếp tục, và nếu việc xem xét có thể mất thời gian thì bạn được khuyên tuần tự hóa trạng thái đó, lưu lại và tiếp tục sau ([OpenAI](https://developers.openai.com/api/docs/guides/agents/guardrails-approvals), [hướng dẫn Agents SDK](https://openai.github.io/openai-agents-js/guides/human-in-the-loop/)). Không có chỗ nào trong luồng đó chạm tới một con người. Việc báo cho người phê duyệt hoàn toàn là chuyện của bạn.

Trong khi đó, các lần chạy ngày càng dài hơn. AWS mô tả những agent tiên phong của họ có thể "hoạt động hàng giờ hoặc hàng ngày mà không cần can thiệp" ([About Amazon](https://www.aboutamazon.com/news/aws/amazon-ai-frontier-agents-autonomous-kiro)). Kiro Crew, ra mắt ngày 4 tháng 8 năm 2026, nói thẳng: "Khởi động một cuộc di chuyển dữ liệu và nó cứ đi tiếp qua các mốc kiểm tra và các lần thử lại trong khi bạn đang họp hoặc đang ngủ" — đồng thời lưu ý rằng "các yêu cầu tool có thể đòi hỏi phê duyệt" ([Kiro](https://kiro.dev/blog/introducing-kiro-crew/)). Cả hai nửa đều đúng cùng lúc. Agent làm việc trong lúc bạn ngủ, và agent cũng dừng lại trong lúc bạn ngủ.

## Sự cố liên quan tới agent thực sự phổ biến đến mức nào?

**Phổ biến tới mức hầu hết doanh nghiệp đã gặp ít nhất một lần, và hầu hết đều không để agent chạy mà không giám sát.** Trong một khảo sát 418 chuyên gia CNTT và bảo mật thực hiện tháng 1 năm 2026 bởi Cloud Security Alliance theo đặt hàng của Token Security, **65%** tổ chức báo cáo có ít nhất một sự cố liên quan tới AI agent trong năm qua — **61%** liên quan tới lộ dữ liệu, **43%** gián đoạn vận hành và **35%** thiệt hại tài chính ([thông cáo của CSA](https://cloudsecurityalliance.org/press-releases/2026/04/21/new-cloud-security-alliance-survey-reveals-82-of-enterprises-have-unknown-ai-agents-in-their-environments), [báo cáo](https://cloudsecurityalliance.org/artifacts/autonomous-but-not-controlled-ai-agent-incidents-now-common-in-enterprises)).

Những con số về quản trị trong cùng khảo sát mới là thứ đáng quan tâm với việc cảnh báo. Chỉ **13%** chạy agent hoàn toàn tự hành. **53%** cho phép agent tự hành với các tác vụ rủi ro thấp và có người xem xét với hành động rủi ro cao hơn, còn **24%** giữ con người trong vòng lặp với hầu hết tác vụ. **82%** đã phát hiện agent AI "bóng tối" trong môi trường của mình trong năm qua.

Hãy đọc con số đó như một thực tế vận hành thay vì một thống kê hù dọa: **khoảng ba phần tư tổ chức đã cố ý đặt một điểm dừng vào trong agent của họ.** Mỗi điểm dừng đó là một khoảnh khắc mà một cỗ máy bị chặn lại bởi một con người. Nếu con người đó chỉ biết chuyện lúc 09:00 sáng hôm sau, thì khả năng làm việc xuyên đêm của agent chẳng còn giá trị gì.

## Chuyện gì thực sự xảy ra khi một agent cần con người?

**Nó chờ, trong im lặng, và mọi framework đều để phần thông báo lại cho bạn.** Cơ chế thì khác nhau; kết cục thì không.

| Nền tảng | Cơ chế | Cái gì đến được với con người |
| --- | --- | --- |
| OpenAI Agents SDK | `needsApproval` trên một tool làm lần chạy dừng lại và trả về `interruptions` + `state` có thể tiếp tục | Không gì cả — ứng dụng của bạn tự quyết làm gì với gián đoạn đó |
| MCP server | `elicitation/create` hỏi người dùng giữa chừng một lệnh gọi tool, trả về `accept`, `decline` hoặc `cancel` | Bất cứ giao diện nào MCP client dựng lên — trong một lần chạy headless thì chẳng ai nhìn vào đó |
| Claude Code | Hook `Notification` kích hoạt với các giá trị matcher gồm `agent_needs_input` và `agent_completed` | Bất cứ thứ gì bạn nối hook đó tới |
| Kiro Crew | Yêu cầu tool có thể đòi phê duyệt; hoạt động được ghi lại để xem xét | Màn hình Activity, nếu bạn mở nó ra |

Model Context Protocol nói rõ điều này ngay ở mức đặc tả. Elicitation tồn tại chính là để một server có thể hỏi con người điều gì đó giữa chừng, và bản sửa đổi hiện hành (`2026-07-28`) cảnh báo rằng server "**KHÔNG NÊN** giả định rằng yêu cầu elicitation sẽ luôn thành công" và phải xử lý được các trường hợp từ chối, hủy và client lỗi ([đặc tả MCP](https://modelcontextprotocol.io/specification/2026-07-28/client/elicitation)). Giao thức chuẩn hóa câu hỏi. Nó không, và không thể, chuẩn hóa việc gây được sự chú ý của con người.

Đó chính là toàn bộ cơ hội. Mọi tầng của hệ agent đều có một điểm dừng được thiết kế tử tế. Không tầng nào có một số điện thoại.

## Sự kiện agent nào xứng đáng có một cuộc gọi?

**Hai loại, và với phần còn lại bạn nên thật khắt khe.** Cuộc gọi là tài nguyên khan hiếm; chỉ nên tiêu nó vào chỗ mà một con người đang ngủ thật sự là điểm nghẽn.

1. **Một phê duyệt bị chặn trên một lần chạy không thể tiếp tục nếu thiếu nó.** Agent đứng im, đồng hồ vẫn chạy, và chờ thêm bao lâu cũng không giải quyết được. Đây là trường hợp kinh điển.
2. **Một thất bại chấm dứt của lần chạy dài không người trông.** Sáu tiếng di chuyển dữ liệu mà chết ở giờ thứ hai là sáu tiếng bạn không lấy lại được, và bạn thà biết ngay ở giờ thứ hai.

Mọi thứ khác thuộc về một kênh yên tĩnh hơn. "Tác vụ hoàn thành thành công" là một thông báo đẩy thông thường. "Agent đã dùng 80% ngân sách" cùng lắm là khẩn cấp. "Agent đã bắt đầu" thì chẳng cần thông báo gì cả. Ba [loại thông báo](/vi/docs/notification) của Echobell — Thông thường, Khẩn cấp và Cuộc gọi — sinh ra đúng cho việc phân loại này, và ánh xạ các sự kiện agent vào chúng là quyết định thiết kế quan trọng nhất ở đây. Nếu bạn vốn đã vật lộn với lượng thông báo, hãy đọc [chữa chứng mệt mỏi vì cảnh báo](/vi/blog/fix-alert-fatigue-developer-guide) trước khi thêm một kênh biết đổ chuông.

## Cách nối cửa phê duyệt của agent tới một cuộc gọi

Echobell biến webhook hoặc email thành một cuộc gọi — một cuộc gọi đổ chuông và rung thật sự, xuyên qua chế độ Tập trung và Không làm phiền của iOS đúng như cách một cuộc gọi từ người thân vẫn làm được (xem [vượt qua chế độ Tập trung của iOS](/vi/blog/how-to-bypass-ios-focus-mode-for-critical-alerts)). Nó nằm giữa agent đang dừng và con người có thể cho nó chạy tiếp.

### Bước 1 — Tạo một kênh Cuộc gọi cho agent bị chặn

Hãy tạo một kênh trong ứng dụng và đặt loại thông báo là **Cuộc gọi**. Đặt cho nó cái tên không thể nhầm lẫn như "Agent bị chặn — cần phê duyệt" và đừng dùng nó vào việc gì khác. Sao chép webhook URL trong phần chi tiết kênh; nó trông như `https://hook.echobell.one/t/<channel-token>`. Hãy coi đó là thông tin bí mật — ai cầm nó cũng có thể làm điện thoại bạn đổ chuông ([hướng dẫn webhook](/vi/docs/webhook)).

Hãy đặt mẫu tiêu đề và nội dung thành thứ mà bạn hành động được ngay từ màn hình khóa:

```
Title: Agent blocked: {{agent}}
Body: Waiting on {{action}} in {{project}} — since {{time}} UTC
```

`{{time}}` và các [biến thời gian hệ thống](/vi/docs/template) khác luôn có sẵn theo giờ UTC mà bạn không cần gửi lên.

### Bước 2 — Bắn webhook từ nhánh phê duyệt của bạn

Trong bất kỳ SDK nào trả về gián đoạn, điểm dừng chỉ là một nhánh bình thường trong mã của bạn. Hãy POST tới URL của kênh trước khi bạn tạm cất lần chạy đó đi:

```javascript
let result = await run(agent, input, { stream: false });

if (result.interruptions?.length) {
  await fetch(process.env.ECHOBELL_BLOCKED_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      agent: agent.name,
      action: result.interruptions[0].rawItem.name,
      project: process.env.PROJECT_NAME,
      externalLink: `https://ops.example.com/runs/${runId}`,
    }),
  });
  await saveState(runId, result.state); // tuần tự hóa và chạy tiếp sau khi được phê duyệt
}
```

Biến đặc biệt `externalLink` trở thành một liên kết bấm được trong bản ghi thông báo, nên ai nghe máy sẽ vào thẳng lần chạy đó thay vì phải đi tìm.

### Bước 3 — Dùng hook khi agent là một CLI chứ không phải một thư viện

Claude Code cung cấp hook `Notification` với matcher lọc theo loại thông báo, bao gồm `agent_needs_input` và `agent_completed`, và bộ xử lý hook có thể là lệnh shell hoặc POST HTTP trực tiếp ([tài liệu về hook](https://code.claude.com/docs/en/hooks)). Bộ xử lý kiểu `command` cho bạn quyền kiểm soát hình dạng payload, điều này quan trọng vì Echobell hiển thị đúng những khóa JSON mà bạn gửi:

```json
{
  "hooks": {
    "Notification": [
      {
        "matcher": "agent_needs_input",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c '{agent: \"claude-code\", action: .message, project: .cwd}' | curl -sS -X POST -H 'Content-Type: application/json' -d @- \"$ECHOBELL_BLOCKED_URL\""
          }
        ]
      }
    ]
  }
}
```

Với bộ xử lý `command`, dữ liệu đầu vào của hook đến dưới dạng JSON trên stdin, mang theo các trường như `session_id`, `cwd`, `hook_event_name` và `permission_mode`. Loại xử lý `http` gửi thẳng chính JSON đó tới một URL mà không cần script nào, nghe rất hấp dẫn — nhưng nó cũng kỳ vọng phản hồi phải là một tài liệu kết quả hook, mà phản hồi của Echobell thì không phải vậy. Hãy dùng `command`, trừ khi bạn đã kiểm chứng rằng `http` hoạt động đúng như bạn muốn trong thiết lập của mình.

### Bước 4 — Bắt cả những agent chỉ gửi email

Rất nhiều nền tảng agent, dịch vụ chạy theo lịch và công cụ nội bộ chỉ báo cáo qua email chứ không gì khác. Mỗi kênh Echobell đều có thể có địa chỉ riêng, nên một quy tắc chuyển tiếp là đủ để biến những thư đó thành cuộc gọi ([kích hoạt qua email](/vi/docs/email-trigger), [thiết lập email thành cuộc gọi](/vi/docs/email-to-call)). Kích hoạt qua email cung cấp `from`, `to`, `subject`, `text` và `html` dưới dạng biến mẫu, nên bạn có thể dựng điều kiện theo dòng tiêu đề mà không phải tự phân tích gì cả.

### Bước 5 — Thêm điều kiện để chỉ những lần bị chặn thật sự mới đổ chuông

**Một kênh đổ chuông với mọi sự kiện agent thì thôi không còn là cuộc gọi nữa, nó trở thành tiếng ồn nền.** [Điều kiện](/vi/docs/conditions) của Echobell lọc theo giá trị biến với cùng cú pháp biểu thức như mẫu, nên bạn có thể yêu cầu, ví dụ:

```
blocking == true && risk == "high"
```

Hãy đưa mọi thứ dưới ngưỡng đó sang một kênh Khẩn cấp riêng. Một mục tiêu hữu ích: kênh Cuộc gọi nên đổ chuông nhiều lắm là vài lần mỗi tuần. Nếu nó reo nhiều hơn thế, thì ranh giới tự hành của agent đang bị vạch sai chỗ, và không cài đặt thông báo nào sửa được điều đó.

### Bước 6 — Kiểm thử với Không làm phiền đang bật

Hãy kích hoạt kênh bằng `curl` trong lúc chế độ Không làm phiền đang bật trên chính chiếc điện thoại sẽ nhận nó:

```bash
curl -X POST https://hook.echobell.one/t/<channel-token> \
  -H "Content-Type: application/json" \
  -d '{"agent":"test","action":"deploy to prod","project":"demo","blocking":true,"risk":"high"}'
```

Hãy bật **Gọi lại khi cuộc gọi thất bại** trong ứng dụng để một cuộc gọi bị chế độ Tập trung chặn sẽ được thử lại. Một đường leo thang chưa được kiểm thử chỉ là một giả định.

## Liệu điều này có chỉ tái tạo chứng mệt mỏi vì cảnh báo với một cái chuông to hơn?

**Có, nếu bạn bỏ qua bước 5.** Kiểu thất bại này là có thật và đáng được gọi tên. Agent sinh ra nhiều sự kiện hơn máy chủ rất nhiều — mỗi lệnh gọi tool, mỗi mốc kiểm tra, mỗi lần thử lại — và cám dỗ đưa tất cả tới một nơi nhìn thấy được là rất mạnh.

Kỷ luật hiệu quả là: cuộc gọi chỉ dành cho những sự kiện mà việc một con người đang ngủ là thứ duy nhất chắn giữa agent và tiến độ. Đó là một tập nhỏ hơn nhiều so với "những việc quan trọng agent đã làm". Nếu bạn không mô tả nổi trong một câu rằng người nhận sẽ làm gì trong chín mươi giây sau khi nghe máy, thì việc đó không xứng đáng có một cuộc gọi.

Còn có một lập luận về bảo mật cho việc giữ ngưỡng thật cao. Cũng khảo sát của CSA cho thấy các tổ chức xếp mức rủi ro của hành động (**63%**) và sự cho phép của con người (**53%**) là những tín hiệu quản trị chính. Những tín hiệu đó chỉ có ý nghĩa nếu sự cho phép của con người thật sự diễn ra kịp thời. Một cửa phê duyệt thường xuyên được trả lời muộn tám tiếng sẽ dạy cho mọi người thói quen nới rộng cửa — và đó là cách mà con số **13%** hoàn toàn tự hành lặng lẽ trở thành mặc định vì những lý do sai.

## Những gì Echobell không làm

Nói cho chính xác ở đây là quan trọng, vì hạ tầng agent rất dễ bị nói quá.

**Echobell có:** biến webhook hoặc email thành một cuộc gọi đổ chuông, một cảnh báo khẩn cấp hoặc một thông báo đẩy thông thường; lọc bằng điều kiện; dựng bối cảnh bằng mẫu; gửi cùng một kích hoạt tới một kênh dùng chung của nhóm, nơi mỗi người đăng ký tự chọn mức khẩn cấp của mình.

**Echobell không:**

- **Phê duyệt bất cứ thứ gì.** Nó không phải giao diện phê duyệt và không có kết nối nào tới trạng thái của agent. Nó làm điện thoại bạn đổ chuông; bạn vẫn phải mở laptop, bảng điều khiển hay terminal để chấp thuận hoặc từ chối. Không có chuyện "bấm phím 1 để duyệt".
- **Cho lần chạy tiếp tục.** Việc tuần tự hóa và khôi phục trạng thái agent là việc của framework bạn dùng. Echobell không bao giờ đụng vào đó.
- **Cung cấp chính sách leo thang, xác nhận tiếp nhận hay lịch trực xoay ca.** Không có chuyện "nếu năm phút không ai nghe thì gọi người tiếp theo". Nó gọi cho những người đã đăng ký một kênh. Nếu bạn cần lịch xoay ca và theo dõi xác nhận tiếp nhận, bạn cần một nền tảng quản lý sự cố — xem [bài so sánh các giải pháp thay thế Opsgenie](/vi/blog/opsgenie-end-of-life-alternatives) cho nhóm công cụ đó.
- **Bảo mật cho agent của bạn.** Không có gì ở đây giải quyết được vấn đề agent bóng tối, quyền tool quá rộng, hay khoảng trống khi ngừng vận hành mà báo cáo của CSA mô tả. Việc con người chú ý nhanh hơn là cách giảm nhẹ cho phản ứng chậm, không phải cho kiến trúc tồi.
- **Bảo đảm gửi đến nơi.** Một cuộc gọi phụ thuộc vào hạ tầng push, vào mạng và vào một chiếc điện thoại còn pin. Hãy xem nó là lớp giúp rút ngắn thời gian chờ, chứ không phải một biện pháp kiểm soát mà bạn có thể phó thác tuyệt đối.

Cách nói thật thà nhất: ranh giới tự hành của agent không thay đổi vì ứng dụng nào làm điện thoại bạn đổ chuông. Thứ mà một cuộc gọi thay đổi là số giờ giữa lúc agent dừng lại và lúc một con người nhận ra — và với một lần chạy xuyên đêm, những giờ đó chính là toàn bộ giá trị của việc chạy xuyên đêm.

## Câu hỏi thường gặp

### Tôi có thể phê duyệt một hành động của agent ngay từ cuộc gọi không?

Không. Echobell gửi một cuộc gọi kèm nội dung thông báo và một liên kết bấm được; nó không có đường phản hồi tương tác ngược lại agent của bạn. Cách làm thực tế là: cuộc gọi đánh thức bạn, `externalLink` đưa bạn tới bảng điều khiển lần chạy hoặc endpoint phê duyệt, và bạn quyết định ở đó. Nếu bạn cần phê duyệt bằng cách trả lời, bạn phải tự xây endpoint đó — Echobell chỉ lo nửa phần đánh thức.

### Sự kiện nào của framework nên kích hoạt webhook?

Những sự kiện khiến lần chạy không thể tiếp tục. Trong OpenAI Agents SDK, đó là một mảng `interruptions` không rỗng. Trong MCP, đó là một yêu cầu `elicitation/create` mà client của bạn không thể trả lời nếu thiếu con người. Trong Claude Code, đó là hook `Notification` với matcher `agent_needs_input`. Sự kiện hoàn tất thuộc về kênh Thông thường hoặc Khẩn cấp, không phải kênh Cuộc gọi.

### Cách này có dùng được với agent headless trong CI không?

Có, và đó lại là nơi nó quan trọng nhất, vì chẳng ai đang ngồi nhìn terminal. Bất kỳ bước CI nào chạy được `curl` đều kích hoạt được một kênh. Hãy POST ở nhánh thất bại của một job dài, thay vì ở mọi job, nếu không pipeline của bạn sẽ thành thứ ồn ào nhất mà bạn sở hữu.

### Còn riêng chuyện elicitation của MCP thì sao?

Elicitation được thiết kế cho một client có người dùng đang hiện diện để hiển thị lời nhắc. Trong một lần chạy không người trông thì chẳng có ai để hiển thị, và đặc tả nói thẳng rằng server phải xử lý được trường hợp từ chối và hủy thay vì cho rằng sẽ có phản hồi. Một cách làm hợp lý là lớp bọc MCP client bắn một webhook Echobell khi nó nhận được yêu cầu elicitation mà nó không thể tự trả lời, rồi giữ lại hoặc hủy theo chính sách của riêng bạn.

### Đưa đầu ra của agent vào thông báo có an toàn không?

Hãy gửi càng ít càng tốt. Nên gửi một định danh và một liên kết thay vì đầu ra thật của agent — dùng `externalLink` để trỏ tới bản ghi lần chạy trong một hệ thống được xây để chứa nó. Echobell chỉ lưu nội dung và lịch sử thông báo trên thiết bị của bạn, còn máy chủ chỉ giữ tài khoản, kênh và đăng ký ([mô hình quyền riêng tư](/vi/docs/features)) — điều đó tốt cho việc tối thiểu hóa dữ liệu, nhưng không phải lý do để gửi nhiều hơn mức cần.

### Cả nhóm tôi có thể nhận cùng một cảnh báo agent không?

Có. Hãy chia sẻ kênh và mọi người đăng ký đều nhận được kích hoạt, mỗi người tự chọn loại thông báo của mình. Một cách bố trí phổ biến: kỹ sư phụ trách agent đăng ký ở mức Cuộc gọi, phần còn lại của nhóm ở mức Khẩn cấp.

### Cái này chỉ dành cho iOS thôi à?

Không. Echobell chạy trên iOS và trên Android qua Google Play (xem [bản phát hành Android](/vi/blog/echobell-android-release)). Hành vi của cảnh báo dạng cuộc gọi khác nhau giữa các nền tảng, nên hãy kiểm thử trên đúng thiết bị mà những người trực đang mang theo.

### Cách này khác gì so với thiết lập WebhookMCP?

[WebhookMCP](/vi/blog/get-notified-with-webhook-mcp) trao cho mô hình một tool mà nó có thể chọn gọi khi tác vụ xong — hữu ích, nhưng nó phụ thuộc vào việc agent quyết định báo cho bạn. Cách làm ở đây bắn đi từ chính mã của bạn hoặc từ một hook của framework, nên nó vẫn hoạt động ngay cả khi agent đang kẹt, đang bối rối, hay đã sập. Hãy dùng cả hai: một cho "xong", một cho "bị chặn".

---

## Liên quan

- [Được báo khi tác vụ AI hoàn tất với WebhookMCP](/vi/blog/get-notified-with-webhook-mcp)
- [Cách vượt qua chế độ Tập trung của iOS cho cảnh báo nguy cấp](/vi/blog/how-to-bypass-ios-focus-mode-for-critical-alerts)
- [Chữa chứng mệt mỏi vì cảnh báo: hướng dẫn cho lập trình viên](/vi/blog/fix-alert-fatigue-developer-guide)
- [Cảnh báo lỗi cron job](/vi/blog/cron-job-failure-alerts)
- [Hướng dẫn tích hợp webhook](/vi/docs/webhook)
- [Hướng dẫn về điều kiện](/vi/docs/conditions)
