Paperclip 아키텍처 분석 - AI 에이전트 가상 회사 오케스트레이션
This article is mostly written by Claude Code
프로젝트 개요
Paperclip은 AI 에이전트로 구성된 가상 회사를 오케스트레이션하는 오픈소스 컨트롤 플레인입니다. 단일 에이전트를 실행하는 도구가 아니라, 여러 에이전트를 조직도·예산·목표·거버넌스 체계 아래에서 하나의 "회사"처럼 운영하는 것이 핵심 목적입니다.
공식 설명을 빌리면:
"If OpenClaw is an employee, Paperclip is the company."
핵심 콘셉트
| 개념 | 설명 |
|---|---|
| Company | 데이터가 완전 격리된 가상 조직 단위입니다. 하나의 인스턴스에서 복수 회사를 운영할 수 있습니다. |
| Agent | CEO, CTO, Engineer 등 역할을 부여받은 AI 에이전트입니다. 조직도 상의 보고 체계(reportsTo)를 가집니다. |
| Issue | 에이전트에게 할당되는 작업 단위입니다. 부모-자식 계층 구조를 지원하며, 상위 Goal까지 추적됩니다. |
| Heartbeat | 에이전트가 스케줄에 따라 깨어나 작업을 확인하고 실행하는 주기적 메커니즘입니다. |
| Adapter | 실제 AI 런타임(Claude Code, Codex, Cursor 등)과 Paperclip을 연결하는 어댑터 추상화입니다. |
| Plugin | JSON-RPC 2.0 기반의 격리된 프로세스로 실행되는 확장 모듈입니다. |
기술 스택
| 계층 | 기술 |
|---|---|
| 런타임 | Node.js 20+, pnpm 9.15 모노레포 |
| 서버 | Express.js 5.1, TypeScript |
| 데이터베이스 | PostgreSQL (개발 시 embedded-postgres 자동 구동), Drizzle ORM 0.38 |
| 인증 | better-auth 1.4 (JWT + API 키), 로컬 신뢰 모드 지원 |
| 프론트엔드 | React 19, React Router 7, TanStack React Query 5, Tailwind CSS 4, Radix UI |
| 실시간 | WebSocket (커스텀 구현, LiveUpdatesProvider) |
| CLI | Commander.js, @clack/prompts |
| MCP | Model Context Protocol 서버 (40+ 도구 정의) |
| 플러그인 IPC | JSON-RPC 2.0 over stdio |
| 테스트 | Vitest (단위), Playwright (E2E) |
| 빌드 | esbuild (CLI), Vite (UI) |
아키텍처
모노레포 구조
paperclip/
├── server/ # Express REST API + 오케스트레이션 서비스
├── ui/ # React SPA (Vite)
├── cli/ # CLI 도구 (Commander.js)
├── packages/
│ ├── db/ # Drizzle 스키마 + 마이그레이션 (90+ 테이블)
│ ├── shared/ # 타입, 상수, 검증기 (프론트·백 공유)
│ ├── adapter-utils/ # 어댑터 공통 타입
│ ├── adapters/ # 에이전트 어댑터 구현체 (7종)
│ ├── mcp-server/ # MCP 도구 서버
│ └── plugins/ # 플러그인 SDK + 예제
├── skills/ # 에이전트 스킬 정의
├── docs/ # Mintlify 기반 외부 문서
└── tests/ # E2E + 스모크 테스트
서버 계층 구조
HTTP Request
→ Middleware (auth, logger, validate, board-mutation-guard)
→ Routes (25+ 라우트 모듈)
→ Services (40+ 서비스 모듈)
→ Drizzle ORM → PostgreSQL
라우트는 도메인별로 분리되어 있습니다: companies, agents, issues, goals, approvals, plugins, adapters, costs, routines, dashboard 등.
서비스 레이어가 모든 비즈니스 로직을 담당하며, 라우트에서 직접 DB에 접근하지 않습니다. agentService(db), issueService(db), companyService(db) 형태로 DI 패턴을 사용합니다.
어댑터 시스템
어댑터는 Paperclip의 핵심 추상화로, 실제 AI 런타임과의 연결 지점입니다.
| 어댑터 | 타입 ID | 대상 런타임 |
|---|---|---|
| Claude Local | claude_local | Claude Code CLI |
| Codex Local | codex_local | Codex CLI |
| Cursor | cursor | Cursor IDE |
| Gemini Local | gemini_local | Gemini CLI |
| OpenCode Local | opencode_local | OpenCode |
| Pi Local | pi_local | Pi |
| OpenClaw Gateway | openclaw_gateway | OpenClaw 봇 인프라 |
| Process | process | 셸 커맨드 |
| HTTP | http | HTTP 웹훅 |
각 어댑터는 다음 인터페이스를 구현합니다:
interface ServerAdapterModule {
execute(ctx: AdapterExecutionContext): Promise<AdapterExecutionResult>
testEnvironment(): Promise<TestResult>
listSkills(): Promise<Skill[]>
syncSkills(): Promise<void>
sessionCodec: SessionCodec // 세션 직렬화/역직렬화
models: Model[] // 사용 가능한 LLM 모델 목록
}
에이전트의 adapterType 필드를 변경하면 런타임을 교체할 수 있는 구조입니다 (예: Claude → Cursor).
플러그인 시스템
플러그인은 격리된 Node.js 프로세스로 실행되며, 호스트와 JSON-RPC 2.0으로 통신합니다.
플러그인 매니페스트 구조:
tools— 에이전트가 호출할 수 있는 도구jobs— 비동기 작업webhooks— 인바운드 웹훅launchers— UI 런처ui.slots— UI 슬롯 확장configSchema— 설정 스키마 (JSON Schema)
상태 스코핑: 플러그인 상태는 instance / company / project / issue / agent 단위로 격리됩니다.
라이프사이클: installed → ready → disabled / error → uninstalled
데이터베이스 설계
90+ 테이블로 구성되며, 주요 도메인별 테이블은 다음과 같습니다:
| 도메인 | 주요 테이블 |
|---|---|
| 조직 | companies, agents, agent_config_revisions, agent_api_keys |
| 작업 | issues, issue_comments, issue_approvals, issue_documents, issue_work_products |
| 목표 | goals, projects, project_workspaces |
| 실행 | heartbeat_runs, heartbeat_run_events, execution_workspaces |
| 재무 | cost_events, finance_events, budget_policies, budget_incidents |
| 플러그인 | plugins, plugin_config, plugin_state, plugin_jobs, plugin_webhooks |
| 인증 | auth_users, auth_sessions, board_api_keys, company_memberships |
| 감사 | activity_log |
설계 원칙:
- 모든 도메인 엔티티에
companyId가 외래 키로 포함되어 멀티 테넌시가 보장됩니다. agent_config_revisions테이블로 설정 변경 이력을 스냅샷으로 추적합니다.issues테이블은parentId자기 참조를 통해 계층적 태스크를 지원합니다.
프론트엔드 아키텍처
라우팅: 회사 프리픽스 기반 (/:companyPrefix/dashboard, /:companyPrefix/agents 등)
상태 관리: 중첩 Context Provider 패턴을 사용합니다.
QueryClientProvider (30s stale time)
→ ThemeProvider → CompanyProvider → LiveUpdatesProvider
→ SidebarProvider → PanelProvider → PluginLauncherProvider → App
실시간 업데이트: WebSocket 기반 LiveUpdatesProvider가 자동 재연결, 토스트 알림(10초 쿨다운), 캐시 무효화를 처리합니다.
CLI
Commander.js 기반이며, 다음 커맨드 그룹을 제공합니다:
| 그룹 | 명령 예시 |
|---|---|
onboard | 최초 설정 마법사 |
company | list, create, export, import |
agent | list, get, create, update, skills |
issue | list, create, get, update, comment |
heartbeat | run (에이전트 하트비트 직접 실행) |
routine | list, create, update |
plugin | list, install, uninstall |
doctor | 진단 및 자동 수리 |
빠른 시작: npx paperclipai onboard --yes
MCP 서버
40+ 도구를 Zod 스키마로 정의하여 에이전트가 Paperclip API를 직접 호출할 수 있게 합니다. 주요 도구로는 paperclipMe, paperclipListIssues, paperclipCheckoutIssue, paperclipAddComment, paperclipCreateApproval, paperclipUpsertIssueDocument, paperclipRawRequest 등이 있습니다.
핵심 설계 패턴
Atomic Task Checkout
이슈 체크아웃과 예산 차감이 원자적으로 처리됩니다. 두 에이전트가 동시에 같은 이슈를 체크아웃하는 것은 불가능하며, 이중 실행을 방지합니다.
Goal-Aware Execution
모든 태스크는 상위 Goal까지의 계보(ancestry)를 가집니다. 에이전트는 "무엇을 해야 하는지"뿐 아니라 "왜 해야 하는지"를 항상 컨텍스트로 받습니다.
Config Revision Tracking
에이전트 설정 변경 시마다 전체 스냅샷이 agent_config_revisions에 기록됩니다. 잘못된 변경을 안전하게 롤백할 수 있습니다.
Company-Scoped Multi-Tenancy
모든 엔티티가 companyId로 스코핑되어, 단일 인스턴스에서 완전히 격리된 복수 회사를 운영합니다. 라우트/서비스 레벨에서 회사 경계가 강제됩니다.
Event-Driven Plugin Architecture
도메인 이벤트(issue.created, agent.wakeup 등)가 Activity Log와 Plugin Event Bus를 통해 발행됩니다. 플러그인은 이벤트를 구독하여 외부 시스템 연동, 커스텀 로직 등을 실행합니다.
데이터 흐름 예시: 태스크 생성 → 실행 → 완료
- 사용자(또는 상위 에이전트)가
POST /api/companies/{cid}/issues호출 issueService.create()가 issues 테이블에 레코드 삽입- 에이전트에게 이슈 할당 (
assigneeAgentId설정) - Heartbeat 트리거 또는 수동 wake → 에이전트 깨어남
- 에이전트가 MCP 도구로
paperclipCheckoutIssue()호출 → 원자적 체크아웃 Adapter.execute()→ 실제 AI 런타임(Claude Code 등)에서 작업 수행- 작업 중
onLog()콜백으로 실시간 로그 스트리밍 - 완료 시
costEvents에 토큰 사용량 기록 - 이슈 상태
done으로 전환,activity_log에 기록 - WebSocket을 통해 UI에 실시간 반영
실전 Use Case
AI 스타트업의 자동화된 제품 개발
1인 창업자가 AI 노트 앱을 만들고자 하는 상황을 가정합니다.
- CEO 에이전트 (Claude Code): 전략 수립, 작업 분배, 진행 상황 리뷰
- CTO 에이전트 (Claude Code): 기술 아키텍처 결정, 코드 리뷰
- Engineer 에이전트 3명 (Claude Code / Codex): 백엔드, 프론트엔드, 인프라 각각 담당
- Designer 에이전트 (Cursor): UI/UX 디자인 및 컴포넌트 구현
- QA 에이전트 (Claude Code): 테스트 작성 및 실행
창업자가 Goal을 설정하면 CEO 에이전트가 하위 프로젝트와 이슈로 분해하고, CTO가 기술 스택을 결정하여 Engineer들에게 작업을 위임합니다. 각 Engineer는 Heartbeat에 따라 주기적으로 깨어나 할당된 이슈를 체크아웃하고 구현합니다. 20개 터미널 창을 오가며 에이전트를 수동 관리할 필요 없이, 하나의 대시보드에서 전체 개발 파이프라인을 감독할 수 있습니다.
콘텐츠 마케팅 자동화 회사
기술 블로그, 소셜 미디어, 뉴스레터를 자동으로 생산·배포하는 "콘텐츠 회사"를 운영하는 시나리오입니다. CMO, Researcher, Writer, Designer, Publisher 에이전트로 구성하며, Routine 기능으로 반복 작업을 자동 스케줄링하고 Approval 게이트로 품질 관리를 보장합니다.
오픈소스 프로젝트 유지보수 자동화
인기 오픈소스 라이브러리의 이슈 트리아지, 의존성 업데이트, 릴리스를 자동화하는 시나리오입니다. 플러그인으로 GitHub Webhook을 수신하여 새 이슈가 자동 등록되고, PM → Engineer → QA → DevOps 에이전트 팀이 거버넌스 체계 안에서 체계적으로 처리합니다.
Q&A: 자주 묻는 질문
멀티 테넌시에서 Company 간 데이터 격리는 어떻게 보장됩니까?
Paperclip의 멀티 테넌시는 애플리케이션 레벨 격리로 구현되어 있습니다. 모든 도메인 테이블에 companyId 외래 키가 포함되어 있고, 라우트 미들웨어 및 서비스 레이어에서 회사 경계를 강제합니다. DB 레벨의 RLS(Row-Level Security)는 적용되어 있지 않습니다.
보안 관점에서 보면, 쿼리 하나에 companyId 조건을 빠뜨리면 데이터 누출이 발생할 수 있는 구조입니다. 프로덕션 환경에서 더 강력한 격리가 필요하다면, PostgreSQL RLS 정책을 추가하거나 테넌트별 스키마 분리를 고려할 수 있습니다.
Heartbeat가 동시에 트리거되면 어떻게 됩니까?
Paperclip은 Atomic Issue Checkout 패턴으로 동시 실행 문제를 해결합니다. 하나의 이슈는 한 에이전트에만 할당되고, 체크아웃은 원자적으로 수행됩니다. heartbeat_runs 테이블에서 이미 실행 중인 Run이 있으면 중복 실행을 방지하며, 예산 한도에 도달하면 에이전트가 자동으로 일시 정지됩니다.
플러그인 장애가 호스트에 영향을 줍니까?
각 플러그인은 독립된 Node.js 자식 프로세스로 실행됩니다. 플러그인 크래시 시 호스트 프로세스에는 영향을 주지 않으며, 플러그인 상태가 error로 전환됩니다. 다만 무한 루프나 메모리 누수가 시스템 전체 메모리를 소진하면 간접적으로 영향을 줄 수 있으므로, 프로덕션에서는 cgroup이나 컨테이너 리소스 제한을 함께 적용하는 것이 안전합니다.
비용 폭주를 어떻게 방지합니까?
에이전트 단위 월별 예산(budgetMonthlyCents)과 회사 단위 월별 예산을 설정할 수 있습니다. 한도에 도달하면 에이전트가 자동으로 paused 상태가 되어 더 이상 Heartbeat가 실행되지 않습니다. 다만 예산 차감은 실행 완료 후에 반영되므로, 단일 실행이 매우 비싼 경우 한도를 약간 초과할 수 있습니다.
에이전트끼리 대화할 수 있습니까?
가능합니다. 이슈 코멘트와 @mention으로 다른 에이전트를 호출할 수 있고, 하위 이슈 생성을 통한 위임, Approval 요청을 통한 에스컬레이션이 가능합니다. 다만 실시간 채팅이 아닌 비동기 메시지 방식입니다.
로드맵
| 상태 | 항목 |
|---|---|
| 완료 | Plugin System, OpenClaw 연동, Company Import/Export, AGENTS.md 설정, Skills Manager, Scheduled Routines, Budgeting, Agent Reviews & Approvals |
| 예정 | Multiple Human Users, Cloud/Sandbox Agents, Artifacts, Memory & Knowledge, Deep Planning, Work Queues, Self-Organization, CEO Chat, Cloud Deployments, Desktop App |
총평
Paperclip은 "AI 에이전트 오케스트레이션"이라는 새로운 도메인에서 조직 관리 메타포를 핵심 설계 원리로 삼은 프로젝트입니다. 단순한 태스크 큐나 워크플로우 빌더가 아니라, 조직도·예산·거버넌스·감사 로그라는 기업 운영의 기본 요소를 AI 에이전트 세계에 적용했다는 점이 독특합니다.
강점:
- 어댑터 추상화 덕분에 다양한 AI 런타임을 통합할 수 있는 유연한 아키텍처입니다
- 90+ 테이블에 달하는 포괄적 데이터 모델이 복잡한 에이전트 운영 시나리오를 지원합니다
- 플러그인 시스템이 프로세스 격리 + JSON-RPC로 안정성과 확장성을 동시에 확보합니다
- CLI, MCP 서버, REST API, WebSocket 등 다양한 접근 경로를 제공합니다
도전 과제:
- 90+ 테이블 규모의 스키마는 학습 곡선이 가파릅니다
- 애플리케이션 레벨 테넌시 격리는 대규모 멀티 테넌트 환경에서 보안 검증이 필요합니다
- Embedded PostgreSQL 기반의 로컬 개발 환경이 편리하지만, 프로덕션 전환 시 운영 복잡도가 증가할 수 있습니다
- 로드맵에 Memory & Knowledge, Self-Organization 등 핵심 기능이 아직 미완성입니다