AI agent: từng bước trực tiếp, phê duyệt và thông báo
Hiển thị từng bước agent làm trong lúc chạy, giữ các lệnh gọi công cụ rủi ro trong hộp duyệt trực tiếp cho đến khi có người duyệt, và gửi kết quả đến trình duyệt và điện thoại từ agent, MCP client và các luồng không cần code.
Một AI agent chạy nền suốt một phút mà màn hình không hiện gì trông như đã treo, còn một agent tự hoàn tiền đơn hàng mà không hỏi ai thì còn tệ hơn. Hibira cho agent của bạn dùng chung các kênh thời gian thực với phần còn lại của ứng dụng. Mỗi bước hiện ra ngay khi xong, lệnh gọi công cụ rủi ro chờ trong hộp duyệt trực tiếp cho đến khi có người duyệt, và kết quả đến đúng người trên trình duyệt hoặc điện thoại.
Người dùng nhận được gì
- Từng bước agent làm ("Đã tra cứu đơn hàng", "Đã soạn câu trả lời") hiện ra ngay khi xong, trên mọi tab đang mở.
- Yêu cầu duyệt xuất hiện trong hộp duyệt ngay lập tức, kèm những người duyệt khác đang xem, nên hai người không quyết cùng một khoản hoàn tiền.
- Thông báo đẩy khi agent xong việc hoặc cần một quyết định mà không ai đang mở trang.
Dùng những gì
- Kênh riêng tư cho mỗi lần chạy, như
private-agent-run-42, để gửi các bước và kết quả. - @hibira-io/approvals cho hộp duyệt: helper phía máy chủ cho Vercel AI SDK, Mastra và LangGraph (JavaScript và Python), cùng component React và Vue.
- Kênh presence, để người duyệt thấy còn ai đang mở cùng yêu cầu.
- Các công cụ
publish_event,send_pushvàrequest_approvalcủa máy chủ MCP, cho agent chạy trong Claude, Cursor hoặc MCP client khác. - Thông báo đẩy qua API tương thích Beams.
Các bước và kết quả
trigger()Lệnh gọi công cụ cần duyệt
approvals.request()Bước 1: phát từng bước từ agent
Với Vercel AI SDK, onStepFinish chạy sau mỗi bước. Chỉ gửi tên công cụ, không gửi đầu vào, để sự kiện nhỏ gọn và dữ liệu nhạy cảm không đi qua socket:
import { generateText, stepCountIs } from 'ai';
const channel = `private-agent-run-${run.id}`;
const result = await generateText({
model,
tools,
messages,
stopWhen: stepCountIs(10),
onStepFinish: async ({ toolCalls }) => {
if (toolCalls.length) {
await pusher.trigger(channel, 'step', { tools: toolCalls.map((c) => c.toolName) });
}
},
});
await saveRun(run.id, result.text);
await pusher.trigger(channel, 'done', { id: run.id });Trong trình duyệt, hãy đăng ký kênh trước khi lần chạy bắt đầu và hiển thị nhãn cho từng công cụ. Route cấp quyền kênh của bạn chỉ nên cho phép private-agent-run-42 với người dùng đã bắt đầu lần chạy 42:
const channel = pusher.subscribe(`private-agent-run-${runId}`);
channel.bind('step', ({ tools }) => tools.forEach((t) => steps.add(LABELS[t] ?? t)));
channel.bind('done', async ({ id }) => showResult(await fetch(`/runs/${id}`).then((r) => r.json())));Các framework agent khác cũng làm như vậy: gọi trigger() ở chỗ một bước kết thúc.
Bước 2: hỏi người trước khi chạy công cụ rủi ro
Đánh dấu công cụ bằng needsApproval. Khi lần chạy dừng ở công cụ đó, hãy tạo một yêu cầu: người duyệt nhận sự kiện approval trên private-hibira-approvals.support.inbox ngay lập tức.
import { tool } from 'ai';
import { createApprovals } from '@hibira-io/approvals';
import { approvalCalls } from '@hibira-io/approvals/ai-sdk';
export const approvals = createApprovals({ pusher, scope: 'support', resume });
const tools = {
refund_order: tool({ inputSchema, needsApproval: true, execute: refund }),
};
const calls = approvalCalls(result);
if (calls.length) {
await approvals.request({ agent: 'Support agent', title: 'Refund order #1042', calls, metadata: { chatId } });
}Người duyệt quyết định trong component hộp duyệt. Component gọi backend của bạn qua các route của approvals.handler(), không bao giờ qua sự kiện client, và resume(request) của bạn trả câu trả lời cho agent đúng một lần, kể cả khi hai người duyệt cùng bấm Gửi:
import { ApprovalInbox, createApprovalsClient } from '@hibira-io/approvals/react';
import '@hibira-io/approvals/styles.css';
const client = createApprovalsClient({ endpoint: '/api/approvals', pusher, scope: 'support' });
export function ApprovalsPage({ me }) {
return <ApprovalInbox client={client} me={me.id} />;
}Cùng gói này có helper cho Mastra (requireApproval và suspend()) và LangGraph (interrupt()). Với Python, pip install "hibira-approvals[pusher,fastapi]" cho LangGraph Python tạo cùng loại yêu cầu và có router FastAPI cho hộp duyệt. Dùng Laravel? Filament AI approvals đặt hộp duyệt vào panel Filament của bạn cho agent xây bằng Laravel AI SDK.
Bước 3: agent trong Claude, Cursor và các MCP client khác
Agent chạy trong một MCP client dùng được Hibira mà bạn không phải viết code. Thêm máy chủ MCP và agent có thể:
- gửi tiến độ và kết quả đến kênh của bạn bằng
publish_event, để dashboard hoặc trình duyệt của đồng đội theo dõi công việc, - gửi thông báo đẩy đến một interest hoặc người dùng bằng
send_pushkhi xong, - hỏi người bằng
request_approval: công cụ trả về liên kết đến một trang chúng tôi lưu trữ, nơi họ chọn câu trả lời, vàget_approvalchờ kết quả. Truyền thêm một kênh thì yêu cầu cũng hiện trong hộp duyệt ở trên.
claude mcp add --transport http hibira https://hibira.io/mcpBước 4: luồng không cần code
Các công cụ tự động hóa cũng gửi được cùng những sự kiện này. Một luồng có thể phát một bước hoặc kết quả lên kênh, gửi thông báo đẩy, hoặc bắt đầu khi có chuyện xảy ra trên một kênh:
- n8n, node Hibira cũng dùng được làm công cụ cho AI agent của n8n
- Make
- Node-RED
- Activepieces
Mẹo
- Giữ sự kiện nhỏ gọn: gửi ID và nhãn ngắn, rồi tải toàn bộ kết quả từ máy chủ của bạn. Giới hạn kích thước tùy gói, xem bảng giá.
- Lưu mọi bước và yêu cầu vào cơ sở dữ liệu, để trang mở sau vẫn thấy toàn bộ lần chạy.
- Với agent viết câu trả lời từng token, xem Tiến độ cho tác vụ dài và stream câu trả lời AI.
- Yêu cầu duyệt không mang đầu vào của công cụ qua socket. Hộp duyệt tải nó từ backend của bạn, nơi kiểm tra người dùng có quyền duyệt hay không.
- Khi không có người duyệt nào trực tuyến, dùng tùy chọn
notifycủacreateApprovals()để gửi thông báo đẩy cho người duyệt theo hướng dẫn thông báo đẩy.