AI 에이전트: 실시간 진행 단계, 승인, 알림
에이전트가 일하는 단계를 실시간으로 보여 주고, 위험한 도구 호출은 사람이 승인할 때까지 실시간 수신함에서 기다리게 하며, 에이전트와 MCP 클라이언트, 노코드 플로에서 결과를 브라우저와 휴대폰으로 보냅니다.
AI 에이전트가 1분 동안 백그라운드에서 일하는데 화면에 아무것도 없으면 멈춘 것처럼 보입니다. 묻지도 않고 주문을 환불해 버리면 더 곤란합니다. Hibira를 쓰면 에이전트도 앱의 다른 부분과 같은 실시간 채널을 씁니다. 각 단계는 끝나는 대로 표시되고, 위험한 도구 호출은 사람이 승인할 때까지 실시간 수신함에서 기다리며, 결과는 받아야 할 사람의 브라우저나 휴대폰에 도착합니다.
사용자가 얻는 것
- 에이전트 작업의 각 단계("주문을 조회했습니다", "답장 초안을 작성했습니다")가 끝나는 대로 열려 있는 모든 탭에 표시됩니다.
- 승인 요청이 수신함에 바로 나타나고, 다른 검토자 중 누가 보고 있는지도 보이므로 두 사람이 같은 환불을 결정하지 않습니다.
- 에이전트가 끝났거나 결정이 필요한데 아무도 페이지를 열어 두지 않았다면 푸시 알림이 갑니다.
사용하는 기능
- 실행마다 하나의 비공개 채널(예:
private-agent-run-42)로 단계와 결과를 보냅니다. - 승인 수신함은 @hibira-io/approvals: Vercel AI SDK, Mastra, LangGraph(JavaScript와 Python)용 서버 헬퍼와 React, Vue 컴포넌트가 있습니다.
- 프레즌스 채널로 같은 요청을 누가 또 열어 두었는지 검토자에게 보여 줍니다.
- Claude, Cursor 같은 MCP 클라이언트에서 실행되는 에이전트를 위한 MCP 서버 도구
publish_event,send_push,request_approval. - Beams 호환 API를 통한 푸시 알림.
단계와 결과
trigger()승인이 필요한 도구 호출
approvals.request()1단계: 에이전트에서 각 단계 발행
Vercel AI SDK에서는 onStepFinish가 단계마다 실행됩니다. 도구의 입력이 아니라 이름만 보내면 이벤트가 작게 유지되고 민감한 데이터가 소켓을 지나지 않습니다.
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 });브라우저에서는 실행을 시작하기 전에 구독하고, 도구마다 레이블을 보여 주세요. 채널 인가 라우트는 private-agent-run-42를 실행 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())));다른 에이전트 프레임워크도 같습니다. 단계가 끝나는 곳에서 trigger()를 호출하세요.
2단계: 위험한 도구 전에 사람에게 묻기
도구에 needsApproval을 표시합니다. 실행이 그 도구에서 멈추면 요청을 만드세요. 검토자는 private-hibira-approvals.support.inbox에서 approval 이벤트를 바로 받습니다.
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)가 답을 에이전트에 돌려줍니다. 두 검토자가 동시에 보내기를 눌러도 한 번만 실행됩니다.
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 승인이 Laravel AI SDK 에이전트를 위한 수신함을 Filament 패널에 넣어 줍니다.
3단계: Claude, Cursor 등 MCP 클라이언트의 에이전트
MCP 클라이언트에서 실행되는 에이전트는 코드 없이 Hibira를 쓸 수 있습니다. MCP 서버를 추가하면 에이전트가 다음을 할 수 있습니다.
publish_event로 진행 상황과 결과를 채널에 보내, 대시보드나 동료의 브라우저에서 작업을 따라가게 하기- 끝났을 때
send_push로 interest나 사용자에게 푸시 알림 보내기 request_approval로 사람에게 묻기: 답을 고를 수 있는 호스팅 페이지의 링크를 돌려주고,get_approval로 답을 기다립니다. 채널을 지정하면 요청이 위의 수신함에도 나타납니다.
claude mcp add --transport http hibira https://hibira.io/mcp4단계: 노코드 플로
자동화 도구에서도 같은 이벤트를 보낼 수 있습니다. 플로에서 단계나 결과를 채널에 발행하거나, 푸시 알림을 보내거나, 채널에서 무슨 일이 생기면 플로를 시작할 수 있습니다.
- n8n: Hibira 노드는 n8n AI 에이전트의 도구로도 쓸 수 있습니다
- Make
- Node-RED
- Activepieces
팁
- 이벤트는 작게 유지하세요. ID와 짧은 레이블을 보내고 전체 결과는 서버에서 가져옵니다. 크기 한도는 요금제에 따라 다르니 요금을 보세요.
- 단계와 요청을 데이터베이스에도 저장하면 나중에 연 페이지에서도 실행 전체를 보여 줄 수 있습니다.
- 에이전트가 답을 토큰 단위로 쓴다면 오래 걸리는 작업의 진행률과 AI 답변 스트리밍을 보세요.
- 승인 요청은 도구 입력을 소켓에 싣지 않습니다. 수신함이 백엔드에서 가져오고, 백엔드는 그 사용자가 검토할 수 있는지 확인합니다.
- 온라인인 검토자가 없을 때는
createApprovals()의notify옵션으로 푸시 알림 가이드대로 검토자에게 푸시를 보내세요.