- **AG-UI(AgentโUser Interaction Protocol)**๋ AI ์์ด์ ํธ์ ์ฌ์ฉ์ ๋๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ฌ์ด์ ์ค์๊ฐ ํต์ ์ ํ์คํํ๋ ์คํ ์ด๋ฒคํธ ๊ธฐ๋ฐ ํ๋กํ ์ฝ
- ์์ด์ ํธ ๋ฐฑ์๋๊ฐ ~16๊ฐ์ ํ์ค ์ด๋ฒคํธ ํ์ ์ ์คํธ๋ฆฌ๋ฐ์ผ๋ก emitํ๋ ๊ฒฝ๋ ์ถ์ํ ๋ ์ด์ด
- MCP(๋๊ตฌ ์ฐ๊ฒฐ), A2A(์์ด์ ํธ ๊ฐ ํต์ )์ ํจ๊ป ์์ด์ ํธ ํ๋กํ ์ฝ ์คํ์ 3๋ฒ์งธ ์ถ (Agent โ User)
- CopilotKit์์ LangGraphยทCrewAI ํํธ๋์ญ์ ๊ธฐ๋ฐ์ผ๋ก ํ์ํ MIT ๋ผ์ด์ ์ค ์คํ์์ค
AG-UI๊ฐ ํด๊ฒฐํ๋ ค๋ ๋ฌธ์
AG-UI ๊ณต์ ๋ฌธ์์์๋ ๋ค์ ๋ ๊ฐ์ง ํต์ฌ ๋ฌธ์ ๋ฅผ ๋ช ์ํ๋ค.
1. ์ ํต์ ํด๋ผ์ด์ธํธ-์๋ฒ ๋ชจ๋ธ์ ํ๊ณ
Agentic applications break the simple request/response model that dominated frontend-backend development in the pre-agentic era.
์์ด์ ํธ๋ ์ผ๋ฐ ์ํํธ์จ์ด์ ๋ค๋ฅธ ํน์ฑ์ ๊ฐ๊ณ ์์ด ๊ธฐ์กด REST/GraphQL API๋ก๋ ๋์์ด ์ด๋ ต๋ค:
- Long-running + streaming: ์์ด์ ํธ๋ ์ฅ๊ธฐ ์คํ๋๋ฉฐ ์ค๊ฐ ์์ ์ ์คํธ๋ฆฌ๋ฐํ๋ค (๋ฉํฐํด ์ธ์ )
- Nondeterministic UI control: ์์ด์ ํธ๊ฐ ๋น๊ฒฐ์ ์ ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ UI๋ฅผ ์ ์ดํ ์ ์๋ค
- Mixed IO: ํ ์คํธยท์์ฑ ๊ฐ์ ๋น๊ตฌ์กฐํ ๋ฐ์ดํฐ์ tool callยทstate update ๊ฐ์ ๊ตฌ์กฐํ ๋ฐ์ดํฐ๋ฅผ ๋์์ ํผํฉํ๋ค
- Recursive composition: ์๋ธ ์์ด์ ํธ๋ฅผ ์ฌ๊ท์ ์ผ๋ก ํธ์ถํ๋ฉฐ ์ฌ์ฉ์์ ์ํธ์์ฉํด์ผ ํ๋ค
2. ๋ฒค๋๋ณ ์ด๋ฒคํธ/ํ๋กํ ์ฝ ํํธํ
LangGraph, CrewAI, Google ADK, AWS Strands, Mastra ๋ฑ ๊ฐ ์์ด์ ํธ ํ๋ ์์ํฌ๋ ์์ฒด ๋ค์ดํฐ๋ธ ์ด๋ฒคํธ ํฌ๋งท์ ์ฌ์ฉํ๋ค. ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๊ฐ ๊ฐ ๋ฒค๋๋ง๋ค ๋ณ๋์ ad-hoc ์ฐ๊ฒฐ ์ฝ๋๋ฅผ ์์ฑํด์ผ ํ๋ ๋ฌธ์ ๋ฅผ AG-UI๋ ๋ ๊ฐ์ง ๋ฉ์ปค๋์ฆ์ผ๋ก ํด๊ฒฐํ๋ค:
- Flexible Event Structure: ์ด๋ฒคํธ๊ฐ AG-UI ํฌ๋งท๊ณผ ์ ํํ ์ผ์นํ์ง ์์๋ ๋จ โ AG-UI ํธํ์ด๋ฉด ์ถฉ๋ถ. ๊ธฐ์กด ํ๋ ์์ํฌ๊ฐ ์ต์ํ์ ์์ ์ผ๋ก ๋ค์ดํฐ๋ธ ์ด๋ฒคํธ๋ฅผ ์ ์์ํฌ ์ ์๋ค
- Middleware Layer: ๋์จํ ์ด๋ฒคํธ ํฌ๋งท ๋งค์นญ์ ํตํด ๋ค์ํ ์์ด์ ํธ์ ์ฑ ๊ฐ์ ๊ด๋ฒ์ํ ์ํธ์ด์ฉ์ฑ์ ๋ณด์ฅ
โThis allows existing agent frameworks to adapt their native event formats with minimal effort.โ โ AG-UI Architecture Docs
ํด๋น ๊ฐ๋ ์ด ํ์ํ ์ด์
- ํ๋ ์์ํฌ๋ง๋ค ad-hoc์ผ๋ก ํ๋ก ํธ ์ฐ๊ฒฐ ์ฝ๋๋ฅผ ์์ฑํ๋ ๋์ ํ์คํ๋ ์ด๋ฒคํธ ํ๋กํ ์ฝ์ด ํ์
- ๋ฒค๋ ๊ต์ฒด ์ ํ๋ก ํธ์๋ ์ฝ๋ ๋ณ๊ฒฝ ์์ด ๋ฐฑ์๋ ์์ด์ ํธ๋ง ๊ต์ฒดํ ์ ์๋ ์ถ์ํ ๋ ์ด์ด ํ๋ณด
- ํ๋์ ์ฑ์์ ์ฌ๋ฌ ์์ด์ ํธ ํ๋ ์์ํฌ๋ฅผ ๋์์ ์ฌ์ฉํด์ผ ํ ๋ ํตํฉ ์ธํฐํ์ด์ค ์ญํ
AS-IS: ๋ฒค๋๋ณ ad-hoc ์คํธ๋ฆฌ๋ฐ ๊ตฌํ
ad-hoc: โ์ด๊ฒ์ ์ํดโ๋ผ๋ ๋ผํด์ด. ๋ฒ์ฉ์ ์ธ ํ์ค ์์ด ํน์ ์ํฉ์ ๋ง์ถฐ ์ฆ์์์ ๋ง๋ ์ผํ์ฑ ๊ตฌํ์ ๋ปํ๋ค. ์ฌ๊ธฐ์๋ ๊ฐ ๋ฒค๋ ํ๋ ์์ํฌ๋ง๋ค ๋ณ๋๋ก ์์ฑํ๋ ์ ์ฉ ์ด๋ํฐยทํ์ฑ ์ฝ๋๋ฅผ ์๋ฏธ.
sequenceDiagram autonumber participant App as Frontend App participant A1 as LangGraph Adapter participant A2 as CrewAI Adapter participant A3 as Google ADK Adapter participant LG as LangGraph Agent participant CR as CrewAI Agent participant GK as Google ADK Agent App->>A1: LangGraph ์ ์ฉ SSE ์ฐ๊ฒฐ A1->>LG: LangGraph ๋ค์ดํฐ๋ธ ์ด๋ฒคํธ LG-->>A1: astream_events() ํฌ๋งท A1-->>App: ํ์ฑ ๋ก์ง A App->>A2: CrewAI ์ ์ฉ SSE ์ฐ๊ฒฐ A2->>CR: CrewAI ๋ค์ดํฐ๋ธ ์ด๋ฒคํธ CR-->>A2: kickoff() ํฌ๋งท A2-->>App: ํ์ฑ ๋ก์ง B App->>A3: ADK ์ ์ฉ ์ฐ๊ฒฐ A3->>GK: ADK ๋ค์ดํฐ๋ธ ์ด๋ฒคํธ GK-->>A3: ADK ์์ฒด ํฌ๋งท A3-->>App: ํ์ฑ ๋ก์ง C Note over App: ๋ฒค๋๋ง๋ค ์ด๋ํฐยทํ์ฑ ๋ก์ง ๋ณ๋ ๊ตฌํ<br/>๋ฐฑ์๋ ๊ต์ฒด ์ ํ๋ก ํธ์๋๋ ์ ๋ฉด ์์
TO-BE: AG-UI ํ์ค ์ด๋ฒคํธ๋ก ํตํฉ
sequenceDiagram autonumber participant App as Frontend App participant Client as AG-UI Client participant MW as AG-UI Middleware participant LG as LangGraph Agent participant CR as CrewAI Agent participant GK as Google ADK Agent App->>Client: runAgent(input) Client->>MW: ํ์ค RunAgentInput alt LangGraph ์ฌ์ฉ ์ MW->>LG: ๋ค์ดํฐ๋ธ ํธ์ถ LG-->>MW: LangGraph ์ด๋ฒคํธ โ AG-UI ๋ณํ else CrewAI ์ฌ์ฉ ์ MW->>CR: ๋ค์ดํฐ๋ธ ํธ์ถ CR-->>MW: CrewAI ์ด๋ฒคํธ โ AG-UI ๋ณํ else Google ADK ์ฌ์ฉ ์ MW->>GK: ๋ค์ดํฐ๋ธ ํธ์ถ GK-->>MW: ADK ์ด๋ฒคํธ โ AG-UI ๋ณํ end MW-->>Client: ๋์ผํ AG-UI ํ์ค ์ด๋ฒคํธ Client-->>App: Observable BaseEvent Note over App: ๋ฐฑ์๋ ๊ต์ฒดํด๋<br/>ํ๋ก ํธ์๋ ์ฝ๋ ๋ณ๊ฒฝ ์์
Agentic Protocol Stack์์์ ์์น
| ํ๋กํ ์ฝ | ์ฐ๊ฒฐ ๋์ | ์ญํ |
|---|---|---|
| MCP | Agent โ Tools & Data | ์์ด์ ํธ๊ฐ ์ธ๋ถ ๋๊ตฌยท๋ฐ์ดํฐ ์์ค์ ์ฐ๊ฒฐ |
| A2A (Agent to Agent) | Agent โ Agent | ์์ด์ ํธ ๊ฐ ์กฐ์จยท์์ ์์ |
| AG-UI | Agent โ User | ์์ด์ ํธ๋ฅผ ์ฌ์ฉ์ ๋๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฐ๊ฒฐ |
์ธ ํ๋กํ ์ฝ์ ์ํธ๋ณด์์ ์ด๋ฉฐ ํ๋์ ์์ด์ ํธ๊ฐ ๋์์ ์ธ ๊ฐ์ง ๋ชจ๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค. AG-UI๋ MCP/A2A์์ ํธ๋์ ฐ์ดํฌ๋ ์ ๊ณตํ์ฌ AG-UI ํด๋ผ์ด์ธํธ ์ฑ์ด MCP/A2A ๊ธฐ๋ฐ ์์ด์ ํธ๋ฅผ ํฌ๋ช ํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
ํต์ฌ ์ํคํ ์ฒ
์ค๊ณ ์์น
- Event-Driven Communication: ์์ด์ ํธ๊ฐ 16๊ฐ ํ์ค ์ด๋ฒคํธ ํ์ ์ ์คํธ๋ฆฌ๋ฐ์ผ๋ก emit
- Bidirectional Interaction: ์ฌ์ฉ์ ์ ๋ ฅ์ ์์ด์ ํธ์ ์ ๋ฌํ์ฌ ํ์ ์ํฌํ๋ก ์ง์
- Transport Agnostic: SSE, WebSocket, Webhook ๋ฑ ์ ์ก ๋ฐฉ์์ ๋ฌด๊ด
- Flexible Event Structure: ๋ค์ดํฐ๋ธ ์ด๋ฒคํธ ํฌ๋งท์ AG-UI ํธํํ๊ฒ ๋งคํ๋ง ํ๋ฉด ๋จ
๊ตฌ์ฑ ์์
graph LR subgraph Frontend A[Application] --> B[AG-UI Client] end subgraph Backend C[AI Agent A] D[AI Agent B] E[Secure Proxy] end B <-->|AG-UI Protocol| E E --> C E --> D
- Application: ์ฌ์ฉ์ ๋๋ฉด ์ฑ (์ฑํ UI, AI ๊ธฐ๋ฅ์ด ์๋ ์ฑ)
- AG-UI Client:
HttpAgent๋ฑ ํต์ ํด๋ผ์ด์ธํธ.run(input) โ Observable<BaseEvent>์ธํฐํ์ด์ค - Agents: ์์ฒญ ์ฒ๋ฆฌ ํ ์คํธ๋ฆฌ๋ฐ ์ด๋ฒคํธ๋ฅผ ์์ฑํ๋ ๋ฐฑ์๋ ์์ด์ ํธ
- Secure Proxy: ๋ณด์ ํ๋ก์ (API ํค ๋ณดํธ ๋ฑ)
16๊ฐ ์ด๋ฒคํธ ํ์ ์ฒด๊ณ
AG-UI์ ๋ชจ๋ ํต์ ์ BaseEvent๋ฅผ ์์ํ๋ ํ์
๋ ์ด๋ฒคํธ๋ก ์ด๋ฃจ์ด์ง๋ค.
interface BaseEvent {
type: EventType;
timestamp?: number;
rawEvent?: any;
}Lifecycle Events (์คํ ์๋ช ์ฃผ๊ธฐ)
| ์ด๋ฒคํธ | ์ค๋ช |
|---|---|
RUN_STARTED | ์์ด์ ํธ ์คํ ์์. threadId, runId ํฌํจ |
RUN_FINISHED | ์คํ ์ฑ๊ณต ์๋ฃ. ์ ํ์ result ํฌํจ |
RUN_ERROR | ์คํ ์ค ๋ณต๊ตฌ ๋ถ๊ฐ ์๋ฌ. message, code ํฌํจ |
STEP_STARTED | ์คํ ๋ด ๋จ๊ณ ์์. stepName (๋
ธ๋/ํจ์๋ช
) |
STEP_FINISHED | ๋จ๊ณ ์๋ฃ |
Text Message Events (ํ ์คํธ ๋ฉ์์ง ์คํธ๋ฆฌ๋ฐ)
Start โ Content(๋ฐ๋ณต) โ End ํจํด:
| ์ด๋ฒคํธ | ์ค๋ช |
|---|---|
TEXT_MESSAGE_START | ๋ฉ์์ง ์์. messageId, role |
TEXT_MESSAGE_CONTENT | ํ
์คํธ ์ฒญํฌ. delta (non-empty) |
TEXT_MESSAGE_END | ๋ฉ์์ง ์๋ฃ |
TEXT_MESSAGE_CHUNK | ํธ์ ์ด๋ฒคํธ โ Start/Content/End ์๋ ํ์ฅ. ์ฒซ ์ฒญํฌ์์ TEXT_MESSAGE_START ์๋ ์์ฑ, ๊ฐ delta๋ง๋ค TEXT_MESSAGE_CONTENT ์๋ emit, ์คํธ๋ฆผ ์ข
๋ฃ ์ TEXT_MESSAGE_END ์๋ ์์ฑ. LLM API์ ์ฒญํฌ ์คํธ๋ฆฌ๋ฐ ํฌ๋งท์ ๊ฑฐ์ ๊ทธ๋๋ก ๋งคํํ ์ ์์ด ๋ฐฑ์๋ ์ด๋ํฐ ๊ตฌํ ๋ณต์ก๋๋ฅผ ์ค์ด๋ sugar syntax |
TEXT_MESSAGE_CHUNK ์ฝ๋ ์์
// โ Start/Content/End ์๋ ๊ด๋ฆฌ (๋ณด์ผ๋ฌํ๋ ์ดํธ)
yield { type: EventType.TEXT_MESSAGE_START, messageId: "msg-1", role: "assistant" };
for await (const chunk of llmStream) {
yield { type: EventType.TEXT_MESSAGE_CONTENT, messageId: "msg-1", delta: chunk.text };
}
yield { type: EventType.TEXT_MESSAGE_END, messageId: "msg-1" };
// โ
TEXT_MESSAGE_CHUNK๋ก ๋จ์ํ (ํด๋ผ์ด์ธํธ๊ฐ ์๋ ํ์ฅ)
for await (const chunk of llmStream) {
yield {
type: EventType.TEXT_MESSAGE_CHUNK,
messageId: "msg-1", // ์ฒซ ์ฒญํฌ์์๋ง role ํฌํจ ์ START ์๋ ์์ฑ
role: "assistant",
delta: chunk.text,
};
}
// ์คํธ๋ฆผ ์ข
๋ฃ ์ END ์๋ ์์ฑTool Call Events (๋๊ตฌ ํธ์ถ ์คํธ๋ฆฌ๋ฐ)
Start โ Args(๋ฐ๋ณต) โ End โ Result ํจํด:
| ์ด๋ฒคํธ | ์ค๋ช |
|---|---|
TOOL_CALL_START | ๋๊ตฌ ํธ์ถ ์์. toolCallId, toolCallName |
TOOL_CALL_ARGS | ์ธ์ ์ฒญํฌ(JSON fragment). delta |
TOOL_CALL_END | ๋๊ตฌ ํธ์ถ ์๋ฃ |
TOOL_CALL_RESULT | ๋๊ตฌ ์คํ ๊ฒฐ๊ณผ. content |
TOOL_CALL_CHUNK | ํธ์ ์ด๋ฒคํธ โ Start/Args/End ์๋ ํ์ฅ. ์ฒซ ์ฒญํฌ์์ TOOL_CALL_START ์๋ ์์ฑ, ๊ฐ delta(JSON fragment)๋ง๋ค TOOL_CALL_ARGS ์๋ emit, ์คํธ๋ฆผ ์ข
๋ฃ ์ TOOL_CALL_END ์๋ ์์ฑ. LLM API์ tool call ์คํธ๋ฆฌ๋ฐ ํฌ๋งท์ ๊ฑฐ์ ๊ทธ๋๋ก ๋งคํํ ์ ์์ด ๋ฐฑ์๋ ์ด๋ํฐ ๊ตฌํ ๋ณต์ก๋๋ฅผ ์ค์ด๋ sugar syntax |
TOOL_CALL_CHUNK ์ฝ๋ ์์
// โ Start/Args/End ์๋ ๊ด๋ฆฌ (๋ณด์ผ๋ฌํ๋ ์ดํธ)
yield { type: EventType.TOOL_CALL_START, toolCallId: "tc-1", toolCallName: "search_web" };
for await (const chunk of llmStream) {
yield { type: EventType.TOOL_CALL_ARGS, toolCallId: "tc-1", delta: chunk.arguments };
}
yield { type: EventType.TOOL_CALL_END, toolCallId: "tc-1" };
// โ
TOOL_CALL_CHUNK๋ก ๋จ์ํ (ํด๋ผ์ด์ธํธ๊ฐ ์๋ ํ์ฅ)
for await (const chunk of llmStream) {
yield {
type: EventType.TOOL_CALL_CHUNK,
toolCallId: "tc-1", // ์ฒซ ์ฒญํฌ์์๋ง toolCallName ํฌํจ ์ START ์๋ ์์ฑ
toolCallName: "search_web",
delta: chunk.arguments, // JSON fragment: '{"q' โ '":"hello' โ '"}'
};
}
// ์คํธ๋ฆผ ์ข
๋ฃ ์ END ์๋ ์์ฑState Management Events (์ํ ๋๊ธฐํ)
Snapshot-Delta ํจํด:
| ์ด๋ฒคํธ | ์ค๋ช |
|---|---|
STATE_SNAPSHOT | ์ ์ฒด ์ํ ์ค๋ ์ท |
STATE_DELTA | JSON Patch (RFC 6902) ๊ธฐ๋ฐ ์ฆ๋ถ ์ ๋ฐ์ดํธ |
MESSAGES_SNAPSHOT | ๋ํ ํ์คํ ๋ฆฌ ์ ์ฒด ์ค๋ ์ท |
Activity Events
| ์ด๋ฒคํธ | ์ค๋ช |
|---|---|
ACTIVITY_SNAPSHOT | ํ๋ ๋ฉ์์ง ์ ์ฒด ์ํ. activityType (์: โPLANโ, โSEARCHโ) |
ACTIVITY_DELTA | JSON Patch ๊ธฐ๋ฐ ํ๋ ์ฆ๋ถ ์ ๋ฐ์ดํธ |
Reasoning Events (์ถ๋ก ๊ณผ์ ์๊ฐํ)
| ์ด๋ฒคํธ | ์ค๋ช |
|---|---|
REASONING_START / REASONING_END | ์ถ๋ก ๊ณผ์ ์์/์ข ๋ฃ |
REASONING_MESSAGE_START / CONTENT / END | ์ถ๋ก ๋ฉ์์ง ์คํธ๋ฆฌ๋ฐ |
REASONING_ENCRYPTED_VALUE | ์ํธํ๋ chain-of-thought (ZTR ์ง์) |
Special Events
| ์ด๋ฒคํธ | ์ค๋ช |
|---|---|
RAW | ์ธ๋ถ ์์คํ
์ด๋ฒคํธ ํจ์ค์ค๋ฃจ. event, source |
CUSTOM | ์ฑ ์ ์ฉ ์ปค์คํ
์ด๋ฒคํธ. name, value |
3๊ฐ์ง ์ด๋ฒคํธ ํ๋ฆ ํจํด
- Start-Content-End: ์คํธ๋ฆฌ๋ฐ ์ฝํ ์ธ ์ฉ (ํ ์คํธ ๋ฉ์์ง, ๋๊ตฌ ํธ์ถ)
- Snapshot-Delta: ์ํ ๋๊ธฐํ์ฉ (์ ์ฒด ์ค๋ ์ท โ JSON Patch ์ฆ๋ถ)
- Lifecycle: ์คํ ๋ชจ๋ํฐ๋ง์ฉ (Started โ Finished/Error)
์ฌ์ฉ์ ์ง์ ์ ์ด๋ฒคํธ ํ๋ฆ ์์
โ์ค๋ ๋ ์จ ์ด๋?โ ์ง์ ์ ์ค์ ์ด๋ฒคํธ ์์:
RUN_STARTED
REASONING_START
REASONING_MESSAGE_CONTENT { delta: "๋ ์จ ๋๊ตฌ๋ฅผ ์จ์ผ๊ฒ ๋ค..." }
REASONING_END
TOOL_CALL_START { toolCallId: "tc-1", toolCallName: "get_weather" }
TOOL_CALL_ARGS { delta: '{"location":"seoul"}' }
TOOL_CALL_END
TOOL_CALL_RESULT { content: "์์ธ ๋ง์ 22๋" }
TEXT_MESSAGE_START { messageId: "m1", role: "assistant" }
TEXT_MESSAGE_CONTENT { delta: "์ค๋ ์์ธ์ ๋ง๊ณ 22๋์
๋๋ค." }
TEXT_MESSAGE_END
RUN_FINISHED
(MESSAGES_SNAPSHOT) โ ์ ํ์ . ์ ์ฒด ๋ํ ํ์คํ ๋ฆฌ ๋๊ธฐํ
์ด๋ฒคํธ ์ญํ ๋ถ๋ฆฌ
| ์ด๋ฒคํธ ์ข ๋ฅ | UI ํํ | ๋ํ ํ์คํ ๋ฆฌ ๊ธฐ๋ก |
|---|---|---|
REASONING_* | ์ ์ ์ ์๋ โThinkingโฆโ ์์ญ | โ |
TOOL_CALL_* | ์์ ๋ฐฐ์ง/์ธ๋์ผ์ดํฐ | โ |
TEXT_MESSAGE_* | ๋ฉ์ธ ์๋ต ์์ญ | โ |
ํต์ฌ: ๊ณผ์ (REASONING/TOOL_CALL)๊ณผ ๊ฒฐ๊ณผ(TEXT_MESSAGE)๋ ๋ชจ๋ ์ด๋ฒคํธ๋ก ์ ๋ฌ๋๋ค. ๋จ,
TEXT_MESSAGE๋งmessages๋ฐฐ์ด์ ๊ธฐ๋ก๋์ด ๋ค์ LLM ํธ์ถ ์ ์ปจํ ์คํธ๋ก ์ ๋ฌ๋๋ค. ๊ณผ์ ์ด๋ฒคํธ๋ฅผ โ์จ๊ธด๋คโ๋ ๊ฒ์ ํ๋กํ ์ฝ ๋์์ด ์๋๋ผ ํ๋ก ํธ์๋์ UI ์ค๊ณ ์ ํ์ด๋ค.
Building Blocks (๊ธฐ๋ฅ ๋ธ๋ก)
| ๊ธฐ๋ฅ | ์ค๋ช |
|---|---|
| Streaming Chat | ์ค์๊ฐ ํ ํฐยท์ด๋ฒคํธ ์คํธ๋ฆฌ๋ฐ, ์ทจ์/์ฌ๊ฐ |
| Multimodality | ํ์ผ, ์ด๋ฏธ์ง, ์ค๋์ค, ํธ๋์คํฌ๋ฆฝํธ ๋ฑ ๋ค์ค ๋ชจ๋ฌ |
| Generative UI (static) | ๋ชจ๋ธ ์ถ๋ ฅ์ ์ฑ์ด ์ ์ดํ๋ ์์ ์ ์ปดํฌ๋ํธ๋ก ๋ ๋๋ง |
| Generative UI (declarative) | ์์ด์ ํธ๊ฐ UI ํธ๋ฆฌ์ ์ ์ฝ์ ์ ์, ์ฑ์ด ๊ฒ์ฆยท๋ง์ดํธ |
| Shared State | ์์ด์ ํธโ์ฑ ๊ฐ ํ์ ๋ ์คํ ์ด. ์ด๋ฒคํธ ์์ฑ diff + ์ถฉ๋ ํด๊ฒฐ |
| Frontend Tool Calls | ์์ด์ ํธ โ ํ๋ก ํธ์๋ ์คํ ์ก์ ํธ๋์คํ |
| Interrupts (HITL) | ์ค๊ฐ์ ์น์ธยทํธ์งยท์ฌ์๋ยท์์ค์ปฌ๋ ์ด์ |
| Sub-agents | ์ค์ฝํ๋ ์ํยทํธ๋ ์ด์ฑยท์ทจ์๊ฐ ์๋ ์ค์ฒฉ ์์ |
์ฝ๋ ์์ : HttpAgent ์ฌ์ฉ
import { HttpAgent, EventType } from '@ag-ui/core';
const agent = new HttpAgent({
url: "https://your-agent-endpoint.com/agent",
agentId: "unique-agent-id",
threadId: "conversation-thread"
});
agent.runAgent({
tools: [...],
context: [...]
}).subscribe({
next: (event) => {
switch(event.type) {
case EventType.TEXT_MESSAGE_CONTENT:
// UI์ ์คํธ๋ฆฌ๋ฐ ํ
์คํธ ํ์
break;
case EventType.TOOL_CALL_START:
// ๋๊ตฌ ํธ์ถ ์์ ํ์
break;
case EventType.STATE_DELTA:
// JSON Patch๋ก ๋ก์ปฌ ์ํ ์
๋ฐ์ดํธ
break;
}
},
error: (err) => console.error("Agent error:", err),
complete: () => console.log("Agent run complete")
});์ง์ ํตํฉ ํํฉ
Agent ํ๋ ์์ํฌ
| ํ๋ ์์ํฌ | ์ํ | ๋น๊ณ |
|---|---|---|
| LangGraph | โ Supported | ํํธ๋์ญ |
| CrewAI | โ Supported | ํํธ๋์ญ |
| Microsoft Agent Framework | โ Supported | 1st Party |
| Google ADK | โ Supported | 1st Party |
| AWS Strands Agents | โ Supported | 1st Party |
| Mastra | โ Supported | 1st Party |
| Pydantic AI | โ Supported | 1st Party |
| Agno, LlamaIndex, AG2 | โ Supported | 1st Party |
| OpenAI Agent SDK | ๐ ๏ธ In Progress | ์ปค๋ฎค๋ํฐ |
SDK
TypeScript(๊ณต์), Python, Kotlin, Golang, Dart, Java, Rust, Ruby ์ง์
ํด๋ผ์ด์ธํธ
| ํด๋ผ์ด์ธํธ | ์ํ |
|---|---|
| CopilotKit | โ Supported (1st Party) |
| Terminal + Agent | โ Supported (Community) |
| React Native | ๐ ๏ธ Help Wanted |