# AI 代理：即時步驟、人工核准與通知

> 代理每完成一個步驟就即時顯示；有風險的工具呼叫先放進即時收件匣，等人核准後才執行；結果從代理、MCP 用戶端與無程式碼流程送到瀏覽器和手機。

Source: https://hibira.io/zh-tw/use-cases/ai-agents

AI 代理在背景跑了一分鐘，畫面上卻什麼都沒有，看起來就像當掉了；沒問一聲就把訂單退款，更糟。Hibira 讓你的代理使用和 App 其他部分相同的即時頻道：每完成一個步驟就顯示出來，有風險的工具呼叫先在即時收件匣裡等人核准，結果則送到該看到的人的瀏覽器或手機上。

## 使用者得到什麼

- 代理每完成一個步驟（「查到訂單了」「回覆草稿寫好了」），每個開著的分頁都立刻顯示。
- 核准請求一送出就出現在收件匣，也看得到還有哪些審核者在看，兩個人不會重複處理同一筆退款。
- 代理完成或需要人做決定、卻沒有人開著頁面時，會收到推播通知。

![左邊是代理的執行過程，右邊是審核收件匣：每一步完成就出現，退款等審核人決定，按下核准後代理繼續做完。](https://hibira.io/portal/articles/demo-ai-agents-zh-TW.mp4)

## 用到的功能

- 每次執行一個**私人頻道**，例如 `private-agent-run-42`，用來送步驟與結果。
- **[@hibira-io/approvals](https://github.com/hibira-io/approvals)** 提供核准收件匣：支援 Vercel AI SDK、Mastra 與 LangGraph（JavaScript 與 Python）的伺服器輔助函式，以及 React 與 Vue 元件。
- **Presence 頻道**，讓審核者看到還有誰開著同一個請求。
- **[MCP 伺服器](https://hibira.io/zh-tw/mcp-server)**的 `publish_event`、`send_push` 與 `request_approval` 工具，給在 Claude、Cursor 或其他 MCP 用戶端裡執行的代理使用。
- 透過相容 Beams 的 API 發送**推播通知**。

```text
flow: 代理的步驟即時送到使用者面前，有風險的工具呼叫先等人核准
== 步驟與結果
你的代理|每個步驟一個事件 --`trigger()`--> *Hibira --WebSocket--> 使用者的頁面|即時步驟清單
== 需要核准的工具呼叫
你的代理|暫停執行 --`approvals.request()`--> *Hibira --WebSocket--> 審核者的收件匣|核准、修改或拒絕
```

## 步驟 1：從代理發布每個步驟

在 Vercel AI SDK 裡，每個步驟結束後都會執行 `onStepFinish`。只送工具名稱、不送輸入內容，事件就能保持精簡，敏感資料也不會經過 WebSocket：

```js
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 });
```

在瀏覽器裡，先訂閱再開始執行，並為每個工具顯示一個標籤。你的頻道授權路由應該只讓啟動第 42 次執行的使用者訂閱 `private-agent-run-42`：

```js
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())));
```

其他代理框架也一樣：在步驟結束的地方呼叫 `trigger()` 即可。

## 步驟 2：有風險的工具執行前先問人

用 `needsApproval` 標記工具。執行停在這個工具時，建立一個請求：審核者會立刻在 `private-hibira-approvals.support.inbox` 收到 `approval` 事件。

```js
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 } });
}
```

審核者在收件匣元件裡做決定。元件透過 `approvals.handler()` 的路由呼叫你的後端，從不使用用戶端事件；你的 `resume(request)` 會把答案交回代理，而且只執行一次，就算兩位審核者同時按下送出也一樣：

```jsx
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} />;
}
```

同一個套件也有 Mastra（`requireApproval` 與 `suspend()`）和 LangGraph（`interrupt()`）的輔助函式。Python 方面，`pip install "hibira-approvals[pusher,fastapi]"` 讓 LangGraph Python 建立同樣的請求，並提供收件匣用的 FastAPI 路由。用 Laravel 開發嗎？[Filament AI 核准](https://hibira.io/zh-tw/guides/filament-approvals)會把收件匣放進你的 Filament 面板，給用 Laravel AI SDK 建立的代理使用。

## 步驟 3：在 Claude、Cursor 等 MCP 用戶端裡的代理

在 MCP 用戶端裡執行的代理，不必你寫任何程式碼就能使用 Hibira。加入 [MCP 伺服器](https://hibira.io/zh-tw/mcp-server)後，代理可以：

- 用 `publish_event` 把進度與結果送到你的頻道，讓儀表板或隊友的瀏覽器跟著看到工作進展，
- 完成時用 `send_push` 依 interest 或使用者發送推播通知，
- 用 `request_approval` 問人：它會回傳一個託管頁面的連結，讓對方選擇答案，再用 `get_approval` 等待結果。指定頻道的話，請求也會出現在上面的收件匣裡。

```sh
claude mcp add --transport http hibira https://hibira.io/mcp
```

## 步驟 4：無程式碼流程

自動化工具也能送出同樣的事件。流程可以把步驟或結果發布到頻道、發送推播通知，或在頻道上發生事情時啟動：

- [n8n](https://hibira.io/zh-tw/guides/n8n)，其 Hibira 節點也能當作 n8n AI 代理的工具
- [Make](https://hibira.io/zh-tw/guides/make)
- [Node-RED](https://hibira.io/zh-tw/guides/node-red)
- [Activepieces](https://hibira.io/zh-tw/guides/activepieces)

## 小提醒

- 事件保持精簡：只送 ID 與簡短標籤，完整結果從你的伺服器載入。大小上限依方案而定，請看[價格](https://hibira.io/zh-tw/pricing)。
- 每個步驟與請求也存進資料庫，之後才打開的頁面也能看到整個執行過程。
- 代理要一個字一個字寫出回答的話，請看[長時間工作的進度與 AI 回答串流](https://hibira.io/zh-tw/use-cases/job-progress)。
- 核准請求不會把工具的輸入內容送上 WebSocket。收件匣會向你的後端載入內容，由後端確認這位使用者可以審核。
- 沒有審核者在線上時，用 `createApprovals()` 的 `notify` 選項，照[推播通知指南](https://hibira.io/zh-tw/guides/push-notifications)發推播給審核者。
