LangGraph·CrewAI 같은 프레임워크로 만든 에이전트는 '주방'입니다. 요리는 잘하지만 손님(사용자)과 직접 마주칠 창구가 없죠. CopilotKit은 그 창구 — 채팅창, 진행 상황 표시, 에이전트가 직접 띄우는 카드·차트·폼, 그리고 "이대로 진행할까요?"라고 묻는 승인 버튼까지 — 를 React 컴포넌트와 훅으로 제공합니다.
한 줄로 줄이면: "풀스택 에이전트 앱을 만들기 위한 프론트엔드 SDK + 서버 런타임 + 표준 프로토콜(AG-UI)의 3종 세트"입니다. 단순히 채팅창 컴포넌트를 주는 라이브러리가 아니라, 에이전트와 UI가 같은 상태(state)를 실시간으로 읽고 쓰는 구조 전체를 제공한다는 점이 핵심입니다.
2024~2026년 사이 에이전트 백엔드 프레임워크는 폭발적으로 늘었습니다(LangGraph, CrewAI, Mastra, PydanticAI…). 그런데 정작 그 에이전트를 사용자 앞에 내놓는 쪽은 모두가 각자 채팅창을 손으로 짜고 있었죠. CopilotKit은 이 빈칸을 정확히 겨냥했고, 그 결과 만든 AG-UI 프로토콜이 Google, LangChain, AWS, Microsoft, Mastra, PydanticAI 등에 채택되며 사실상의 표준 후보가 됐습니다. "프로토콜을 가진 자가 생태계를 가진다"는 공식 그대로입니다.
경쟁 구도에서 보면 이렇게 정리됩니다.
| 접근 방식 | 장점 | 한계 |
|---|---|---|
| 채팅 UI 직접 구현 | 완전한 자유도 | 스트리밍·도구 호출 표시·상태 동기화를 전부 손으로. 에이전트 프레임워크 바뀌면 다시 작성 |
| Vercel AI SDK (UI 훅) | 가볍고 Next.js와 궁합 좋음 | 'LLM 채팅' 중심. 장시간 도는 에이전트의 상태 공유·HITL·멀티에이전트는 직접 설계해야 |
| CopilotKit + AG-UI | 에이전트 전용 설계. 상태 공유·Generative UI·HITL 내장, LangGraph/CrewAI 등 1군 통합 | 구조가 큰 만큼 학습 비용. 런타임 서버 한 층이 추가됨 |
채팅창은 에이전트의 출력을 글자로 보여줄 뿐, 에이전트가 지금 무엇을 하고 있는지(어떤 도구를 쓰는지, 내부 상태가 어떤지)는 블랙박스로 남습니다. 사용자는 빙글빙글 도는 스피너만 보다가 신뢰를 잃습니다.
CopilotKit은 에이전트의 내부 상태를 React 상태처럼 구독하고(useAgent), 에이전트가 진행 중인 작업을 카드·차트 같은 실제 UI로 렌더링하게 합니다(Generative UI). 에이전트가 일하는 모습이 화면에 '실황 중계'되는 구조라, 블랙박스 문제가 구조적으로 풀립니다.
또 하나의 트렌딩 이유는 Generative UI의 3가지 스펙을 모두 지원한다는 점입니다. 미리 만든 컴포넌트를 에이전트가 골라 쓰는 Static(AG-UI), 선언적 JSON으로 UI를 기술하는 Declarative(A2UI), 에이전트가 자유형 UI를 만들어내는 Open-Ended(MCP Apps) — 어느 진영이 이기든 CopilotKit 사용자는 갈아탈 필요가 없습니다.
이 레포는 단일 라이브러리가 아니라 20개 가까운 패키지가 사는 모노레포입니다. 패키지는 전부 packages/ 아래 평평하게(flat) 놓여 있고, 모두 @copilotkit/ 스코프로 npm에 배포됩니다.
| 기술 | 버전/패키지 | 역할 |
|---|---|---|
| React | 19.x (18도 지원) | 주력 프레임워크. react-core(훅·프로바이더), react-ui(채팅 컴포넌트) |
| Angular / Vue / RN | angular, vue, react-native | 같은 core를 각 프레임워크 방식(시그널·DI 등)으로 감싼 어댑터 |
| Tailwind CSS | v4 | react-core v2 스타일. 빌드 시 CSS로 구워서 배포(사용자는 Tailwind 불필요) |
| Radix UI + CVA | dropdown·tooltip 등 | 접근성 갖춘 헤드리스 UI 부품 + class-variance-authority로 변형 관리 |
| RxJS | 7.8 | 이벤트 스트림 처리의 뼈대 — AG-UI 이벤트가 Observable로 흐름 |
| streamdown / KaTeX | — | 스트리밍 중인 마크다운·수식을 깨지지 않게 렌더링 |
| Lit | web-inspector | 개발용 디버그 콘솔을 웹컴포넌트로 (프레임워크 무관 삽입) |
| 기술 | 버전/패키지 | 역할 |
|---|---|---|
| Node.js | 18 이상 | 실행 환경. Express와 Hono 어댑터 둘 다 제공 |
| Vercel AI SDK | ai v6 + @ai-sdk/* | 내장 에이전트(BuiltInAgent)의 엔진. OpenAI·Anthropic·Google 어댑터 동봉 |
| GraphQL Yoga | + type-graphql | 프론트↔런타임 통신용 GraphQL 서버 (스트리밍은 defer/stream 플러그인) |
| MCP SDK | @modelcontextprotocol/sdk | MCP 서버의 도구를 에이전트에 연결 |
| LangChain/LangGraph | peerDependency(선택) | 본인 에이전트를 가져올 때만 설치하면 되는 선택 의존성 |
| pino | 9.x | 구조화 로깅 — debug 모드에서 AG-UI 이벤트 전체 추적 |
| 도구 | 역할 |
|---|---|
| pnpm 10 + workspace | 패키지 매니저. workspace:*로 내부 패키지 연결 |
| Nx 22 | 빌드 오케스트레이터 — 바뀐 패키지만 골라 빌드/테스트(nx affected) |
| tsdown + vitest | 번들러(ESM/CJS/UMD 동시 출력)와 테스트 러너 |
| oxlint / oxfmt | Rust로 만든 초고속 린터·포매터 (ESLint/Prettier 대체) |
| publint / attw | 배포 전 패키지 메타데이터·타입 호환성 자동 검사 |
모노레포는 한 건물에 입주한 20개 부서입니다. 부서(패키지)마다 독립적으로 일하지만 같은 엘리베이터(공용 설정)와 우편 시스템(workspace 의존성)을 씁니다. Nx는 그 건물의 관리실장 — "오늘 3층만 공사했으니 3층과 3층에 기대는 부서만 재점검하라"고 지시해 시간을 아껴줍니다.
먼저 독수리 시점의 전체 그림입니다. 모든 층은 AG-UI 이벤트로 대화하고, 서버→화면 방향 스트리밍에는 SSE를 씁니다.
부품 이름만 알면 소용없으니, 대표 흐름 하나를 입구부터 출구까지 따라가 봅니다. (해피패스만 — 에러 처리·재시도는 생략)
이 레포에서 "정상적인 모양새"는 모든 통신이 이벤트라는 점입니다. 함수 호출/응답이 아니라 RUN_STARTED, TEXT_MESSAGE_CONTENT, TOOL_CALL_START 같은 이벤트가 Zod 스키마로 검증되며 흐릅니다. 덕분에 중간에 어떤 프레임워크가 끼어도(React든 Angular든, LangGraph든 CrewAI든) 양 끝이 같은 언어로 대화합니다.
프론트엔드에는 진짜 에이전트가 없습니다. 대신 원격 에이전트와 똑같은 인터페이스를 가진 대리인이 살면서, 메서드 호출을 HTTP 요청으로 번역하고 SSE 응답을 다시 이벤트로 풀어놓습니다. 화면 코드 입장에서는 에이전트가 로컬에 있는 것처럼 다룰 수 있죠 — 디자인 패턴 교과서의 '프록시 패턴' 그대로입니다.
대화 기록과 에이전트 상태를 어디에 보관할지를 추상 클래스로 분리했습니다. 기본 InMemoryAgentRunner는 서버를 재시작하면 날아가는 메모리 보관, SQLiteAgentRunner는 파일 DB에 영속화. 같은 인터페이스만 지키면 Redis든 Postgres든 직접 만들어 끼울 수 있습니다 — 전략(Strategy) 패턴의 실전 예시.
에이전트 레지스트리·도구 레지스트리·구독 관리 같은 두뇌는 프레임워크 중립인 @copilotkit/core에 한 번만 구현하고, React·Angular·Vue 패키지는 이를 각자의 관용구(훅, 시그널, DI)로 얇게 감싸기만 합니다. 멀티 프레임워크 SDK를 만들 때 거의 정석이 된 구조입니다.
덤으로, 도구(tool)는 두 종류로 나뉩니다: 핸들러가 브라우저에서 도는 프론트엔드 도구(useFrontendTool — 예: 화면의 폼 채우기)와 서버에서 도는 백엔드 도구(에이전트 설정에 정의 — 예: DB 조회). 에이전트가 화면을 직접 조작할 수 있는 비밀이 전자에 있습니다.
| 위치 | 초보자가 먼저 열어볼 이유 |
|---|---|
| packages/core | 프레임워크 없는 순수 TS 두뇌. 레지스트리·구독 구조를 가장 깨끗하게 볼 수 있음 |
| packages/react-core | "core를 React 훅으로 감싸면 이런 모양"의 모범 답안 |
| packages/runtime | Express/Hono 양쪽 어댑터 + LLM 어댑터가 한 곳에 — 서버 설계 교재 |
| CLAUDE.md / .claude/docs | 저장소 스스로 쓴 아키텍처 문서. 사람에게도 최고의 입문 자료 |
재미있는 관찰 하나: 이 레포는 AI 코딩 에이전트가 일하기 좋게 설계된 저장소이기도 합니다. CLAUDE.md·AGENTS.md·.claude/docs/에 아키텍처·작업 규칙이 문서화돼 있고, 자체 Claude 플러그인(.claude-plugin)과 스킬 동기화 스크립트까지 갖췄습니다. "사람 + AI가 함께 유지보수하는 오픈소스"의 최신 관행을 엿볼 수 있습니다.
요청/응답(REST)이 아니라 이벤트 스트림으로 시스템을 묶는 법을 AG-UI가 보여줍니다. 이벤트 타입을 enum으로 고정하고, 모든 이벤트를 Zod 스키마로 검증하고, 라이프사이클(RUN_STARTED→…→RUN_FINISHED)을 강제하는 방식은 어떤 실시간 시스템에도 이식 가능한 설계입니다.
실습 아이디어: 브라우저 EventSource + Express로 "진행률을 SSE로 중계하는 미니 서버"를 직접 만들어보기.
core(순수 TS) 위에 react-core·angular·vue가 얹히는 구조를 따라 읽으면, "로직은 한 번, 바인딩은 여러 번" 원칙이 실제 코드로 어떻게 구현되는지 배웁니다. 특히 같은 개념이 React에선 훅+컨텍스트로, Angular에선 시그널+DI로 번역되는 대조가 교재급입니다.
20개 패키지의 버전·빌드 순서·배포를 어떻게 관리하는지: workspace:* 의존성, Nx의 영향 범위 빌드, publint/attw로 배포 품질 자동 검증, oxlint로 린트 속도 확보. 모노레포로 넘어가려는 팀이라면 이 레포의 설정 파일들이 그대로 체크리스트가 됩니다.
useAgent로 상태를 구독하고, 에이전트가 멈춰서 사용자 승인을 기다리는 Human-in-the-Loop 흐름을 코드 몇 줄로 구현하는 패턴 — 에이전트 제품을 만들 사람에게 가장 실용적인 수확입니다.
맛보기로, 화면에서 에이전트 상태를 읽고 쓰는 코드는 이 정도로 단순합니다. 복사해서 그대로 써도 되는 형태예요:
// 에이전트 연결 — agentId만 맞추면 끝
const { agent } = useAgent({ agentId: "my_agent" });
// 에이전트의 내부 상태를 일반 React 상태처럼 읽는다
return (
<div>
<h1>{agent.state.city}</h1>
// 화면에서 바꾸면 에이전트도 같은 값을 본다 (양방향)
<button onClick={() => agent.setState({ city: "NYC" })}>
Set City
</button>
</div>
);
풀어쓰면: ① useAgent로 런타임에 등록된 에이전트와 연결되고, ② agent.state는 에이전트가 일하며 갱신하는 상태를 실시간 반영하며, ③ setState로 화면에서 고친 값은 다음 실행 때 에이전트에게 전달됩니다. 채팅이 아니라 상태로 에이전트와 협업하는 게 이 SDK의 정체성입니다.
| 항목 | 요구사항 |
|---|---|
| Node.js | 18 이상 (런타임 서버·빌드 공통) |
| 패키지 매니저 | 사용만 하면 npm/yarn/pnpm 아무거나. 레포 개발 참여는 pnpm 10 필수 |
| 프론트엔드 | React 18/19 (또는 Angular·Vue·React Native) |
| LLM | OpenAI·Anthropic·Google 등 API 키 (BuiltInAgent 사용 시) — 로컬 GPU 불필요 |
| 에이전트(선택) | LangGraph·CrewAI 등 자체 에이전트 — 파이썬이면 sdk-python 사용 |
| 시작 명령 | npx copilotkit@latest create (새 프로젝트) / init (기존 프로젝트) |
npx copilotkit@latest create -f next로 새 프로젝트를 만들고, OpenAI 키를 넣어 채팅 사이드바가 뜨는 것까지 확인합니다. 개발자 도구 네트워크 탭에서 SSE 스트림이 실제로 흐르는 모습을 눈으로 관찰해보세요.
useFrontendTool로 "페이지 배경색을 바꾸는 도구"를 등록하고, 채팅으로 "배경을 파랗게 해줘"라고 시켜봅니다. 에이전트가 브라우저 코드를 호출하는 ⑥번 흐름(4섹션)을 몸으로 익히는 과제입니다.
투두 리스트의 상태를 useAgent로 에이전트와 공유하고, "끝난 일 정리해줘" 같은 명령이 화면에 실시간 반영되게 만듭니다. Generative UI로 에이전트가 요약 카드를 직접 그리게 하면 보너스.
"이메일을 보내기 전 반드시 사용자 승인을 받는" 흐름을 구현합니다. 에이전트가 멈추고, 화면에 승인/거절 버튼이 뜨고, 선택에 따라 이어지는 — 에이전트 제품의 핵심 안전장치를 직접 만들어보는 과제.
sqlite-runner 패키지의 소스를 읽고, 같은 인터페이스로 Redis(또는 Supabase) 영속화 러너를 직접 구현해봅니다. 추상 클래스 → 구현체 패턴과 대화 스레드 상태 모델을 가장 깊게 배우는 길입니다.
| 주차 | 주제 | 학습 자료·활동 |
|---|---|---|
| 1주 | React 훅·컨텍스트 복습 | React 공식 문서 — useState/useContext/커스텀 훅. CopilotKit 훅을 읽을 기초 체력 |
| 2주 | SSE와 스트리밍 | MDN EventSource 문서 → 과제 1의 네트워크 탭 관찰 → 미니 SSE 서버 제작 |
| 3주 | CopilotKit 기본기 | 공식 quickstart + 과제 2·3. docs.copilotkit.ai의 Generative UI 스펙 비교 문서 |
| 4주 | AG-UI 프로토콜 | ag-ui-protocol/ag-ui 레포 — 이벤트 타입 정의를 직접 읽고 이벤트 로그 관찰(web-inspector) |
| 5주 | 에이전트 백엔드 | LangGraph 튜토리얼로 간단한 그래프 에이전트 제작 → sdk-python으로 CopilotKit에 연결 |
| 6주 | 모노레포·배포 운영 | Nx 공식 튜토리얼 + 이 레포의 nx.json·release 스크립트 분석. 과제 5 도전 |
| 용어 | 의미 |
|---|---|
| AG-UI | 에이전트↔UI 표준 이벤트 프로토콜. CopilotKit 팀 제작, SSE 위에서 동작 |
| Generative UI | 에이전트가 글자 대신 실제 UI 컴포넌트(카드·차트·폼)를 생성·갱신하는 패턴 |
| Shared State | 에이전트와 화면이 같은 상태를 실시간으로 읽고 쓰는 동기화 계층 |
| HITL (Human-in-the-Loop) | 에이전트가 실행을 멈추고 사람의 입력·승인을 기다리는 안전장치 패턴 |
| SSE | Server-Sent Events — 서버→브라우저 한 방향 실시간 스트리밍 HTTP 기술 |
| ProxiedAgent | 원격 에이전트를 브라우저에서 대리하는 객체 (프록시 패턴) |
| AgentRunner | 대화 스레드·상태 보관을 담당하는 런타임 추상 클래스 (메모리/SQLite/커스텀) |
| BuiltInAgent | 에이전트 프레임워크 없이 쓰는 기본 내장 에이전트 — Vercel AI SDK 기반 |
| MCP | Model Context Protocol — LLM에 도구·데이터를 연결하는 표준. 런타임이 지원 |
| A2UI | 선언적 JSON으로 UI를 기술하는 Generative UI 스펙 중 하나 |
| 모노레포 | 여러 패키지를 한 저장소에서 관리. 여기선 pnpm workspace + Nx 조합 |
| Frontend Tool | 핸들러가 브라우저에서 실행되는 도구 — 에이전트가 화면을 조작하는 통로 |