본문으로 건너뛰기

© 2026 Molayo

Qiita헤드라인2026. 06. 27. 14:55

【#1】 OpenClaw 해독하기 — 백만 행의 숲의 지도와 헌법

요약

OpenClaw 프로젝트의 구조와 설계 철학을 분석하는 연재의 첫 번째 글로, 100만 행 이상의 대규모 오픈소스 코드베이스를 파악하기 위한 가이드를 제공합니다. 로컬 디바이스에서 동작하는 Gateway 중심의 퍼스널 AI 어시스턴트 아키텍처와 디렉토리 구조를 설명합니다.

핵심 포인트

  • OpenClaw는 클라우드 SaaS가 아닌 로컬 디바이스 기반의 Gateway 중심 AI 어시스턴트임
  • 20개 이상의 메시징 채널과 다양한 모델 프로바이더를 지원하는 대규모 OSS 프로젝트
  • 재사용 로직(packages)과 런타임 조립(src)이 명확히 분리된 아키텍처 구조
  • 대규모 코드베이스 해독을 위한 핵심 요소로 AGENTS.md의 아키텍처 규율 강조

연재 첫 회는 코드를 한 줄도 읽기 전에 파악해 두어야 할 "OpenClaw란 무엇인가", "왜 이러한 구조인가"를 리포지토리의 1차 정보(VISION.md / README.md / AGENTS.md)를 통해 따라가 봅니다. 지도 없이, 테스트를 제외하더라도 100만 행이 넘는 숲에는 들어갈 수 없습니다.

연재 「OpenClaw 해독하기」

VISION.md의 서두는 다음과 같이 선언하고 있습니다.

OpenClaw is the AI that actually does things.
It runs on your devices, in your channels, with your rules.

즉 OpenClaw는 "직접 움직이는(실제로 태스크를 실행하는)" 퍼스널 AI 어시스턴트입니다. 클라우드 SaaS가 아니라, **자신의 머신 위에서 동작하는 Gateway (제어 평면 (control plane))**를 중심에 두는 것이 최대 특징입니다. README.md의 표현을 빌리자면,

The Gateway is just the control plane — the product is the assistant.

Gateway는 어디까지나 토대이며, 사용자가 접하는 "어시스턴트"가 제품 본체라는 위치 설정입니다.

VISION.md에는 개명(改名)의 역사가 기록되어 있습니다.

Warelay -> Clawdbot -> Moltbot -> OpenClaw

개인이 "AI를 배우고, 정말로 도움이 되는 것을 만든다"라는 놀이터로서 시작된 프로젝트가, 이제는 20개 이상의 메시징 채널과 다수의 모델 프로바이더(model provider)를 보유한 기반으로 성장했다는 배경입니다. README에서 대응 채널로 꼽는 것은 WhatsApp, Telegram, Slack, Discord, Google Chat, Signal, iMessage, IRC, Microsoft Teams, Matrix, Feishu, LINE, Mattermost, Nextcloud Talk, Nostr, Synology Chat, Tlon, Twitch, Zalo, Zalo Personal, WeChat, QQ, WebChat …… 등 압권입니다.

2026.6.2 (main 브랜치) 시점의 실측값입니다 (find + wc에 의한 개산).

대상규모
src/ TypeScript8,860 파일 / 약 252만 행 (테스트 포함)
src/ TypeScript (*.test.ts 등을 제외)5,197 파일 / 약 113만 행
extensions/ (플러그인 구현)6,510 파일 / 131개의 package.json
packages/ (공유 패키지)430 파일 / 21 패키지
docs/723 파일 (Markdown/MDX는 671)

이 정도 규모의 OSS를 "해독할 수 있다"라고 말할 수 있는 이유는, 후술할 **명확한 소유 경계 (ownership boundary)**가 일관되게 구축되어 있기 때문입니다.

루트 직하의 주요 디렉토리를 역할별로 분류합니다.

openclaw/
├── src/ # 코어 (플러그인 비의존적 런타임 (runtime))
│ ├── entry.ts # CLI 프로세스의 엔트리 포인트 (#02에서 상세 설명)
...

packages/src/의 구분은 처음에는 이해하기 어려울 수 있지만, 대체로 "여러 곳에서 재사용되는 순수 로직은 packages/*-core로 분리하고, 런타임의 조립은 src/가 수행한다"라는 분담 구조입니다. gateway-protocol · agent-core · llm-core 등이 그 전형적인 예입니다.

OpenClaw의 코드를 읽는 데 있어 가장 중요한 것은 AGENTS.md (리포지토리 루트의 개발 규약)에 적힌 **아키텍처 규율 (architecture discipline)**입니다. 이것은 AI 에이전트에 대한 지시서 형식을 취하고 있지만, 실질적으로 이 프로젝트의 "헌법"입니다. 해독의 나침반이 되므로, 핵심을 3가지로 압축하여 소개합니다.

Core stays plugin-agnostic. No bundled ids/defaults/policy in core when manifest/registry/capability contracts work.

src/

코어에는 특정 채널 이름, 프로바이더 이름, 모델 ID를 직접 쓰지 않습니다. "Telegram이라면 이렇게 한다", "Anthropic이라면 저렇게 한다"와 같은 분기(branch)를 코어에 두지 않고, 매니페스트(manifest)/레지스트리(registry)/capability 계약이라는 범용적인 메커니즘을 통해 플러그인이 자신의 동작을 선언합니다.

플러그인이 코어에 접근할 수 있는 유일한 통로가 src/plugin-sdk/*의 공개 배럴(public barrel)뿐이라는 것 또한 AGENTS.md에 명문화된 규칙입니다.

Plugins cross into core only via openclaw/plugin-sdk/*, manifest metadata, injected runtime helpers, documented barrels.

이러한 "일방향 의존성" 덕분에 130개 이상의 플러그인을 보유하고 있음에도 코어가 비대해지지 않습니다. VISION.md에서도 "Core stays lean; optional capability should usually ship as plugins. (코어는 가볍게 유지하며, 선택적 기능은 원칙적으로 플러그인으로 제공한다)"라고 명시하고 있습니다.

Refactor default: one canonical path. Delete the old path unless user explicitly wants compat or the shipped public contract is obvious and cited.

OpenClaw는 "하위 호환성을 위한 폴백(fallback) 분기"를 극도로 경계합니다. 설정 스키마(configuration schema) 또한 런타임이 현재의 형태만 읽으며, 오래된 형태는 openclaw doctor --fix의 마이그레이션(migration) 코드를 통해서만 정준 형태(canonical form)로 변환한다는 단호한 원칙을 가지고 있습니다.

Runtime reads canonical config only. No silent compat for old/malformed config keys.

이를 통해 "읽어야 할 분기"가 하나로 유지됩니다. 호환 심(compatibility shim), 에일리어스(alias), 폴백 스택(fallback stack)이 흩어져 있지 않기 때문에, 각 서브시스템의 동작을 추적할 때 혼란이 적습니다.

Storage default: SQLite only. Do not add JSON/JSONL/TXT/sidecar files for OpenClaw-owned runtime state...

런타임 상태(캐시, 큐, 레지스트리, 커서, 체크포인트 등)는 원칙적으로 SQLite에 둡니다. 공유 상태는 state/openclaw.sqlite, 에이전트 단위의 상태는 agents/<agentId>/agent/openclaw-agent.sqlite라는 이층 구조로 구성됩니다. SQL 또한 생 문자열이 아닌 Kysely를 경유하여 작성합니다 (DDL이나 마이그레이션 등의 예외 제외).

SQLite runtime access uses Kysely helpers, not raw SQL statement strings, except schema DDL, migrations, low-level DB bootstrap...

파일 스토리지는 "import/export, 첨부, 로그, 백업" 등 이름이 붙은 결과물일 때만 허용된다는 선을 긋고 있습니다. 이에 대해서는 #10에서 상세히 다루겠습니다.

AGENTS.md는 루트(root)에 한 장만 있는 것이 아닙니다. extensions/, src/{plugin-sdk,channels,plugins,gateway,agents}/, packages/, docs/, ui/ 등의 서브트리에는 각각 스코프(scope)가 지정된 AGENTS.md가 배치되어 있습니다 (루트 규약에서는 새로운 AGENTS.md에 동일한 이름의 CLAUDE.md 심볼릭 링크를 첨부하는 방식으로 운영하며, 트리 전체에 반드시 존재하는 것은 아닙니다).

Skills own workflows; root owns hard policy and routing.

즉, "어떤 코드가 무엇을 소유하는가"가 디렉토리 구조와 문서 모두에서 표현되어 있습니다. 본 연재를 통해 각 서브시스템을 살펴볼 때도, 해당 디렉토리의 AGENTS.md를 먼저 여는 것이 가장 빠른 길입니다.

VISION.md의 근거가 매우 명쾌합니다.

OpenClaw는 기본적으로 프롬프트(prompts), 도구(tools), 프로토콜(protocols), 그리고 통합(integrations)을 관리하는 오케스트레이션(orchestration) 시스템입니다.

OpenClaw는 기본적으로 해킹(hackable, 수정 및 확장)이 가능하도록 TypeScript를 선택했습니다.

OpenClaw의 본질은 「프롬프트·도구·프로토콜·연계」를 묶는 오케스트레이션이며, 누구나 읽고 개조하기 쉬운 언어로서 TypeScript (strict ESM)가 선택되었습니다. 실제 코드는 strict 운영 방식을 따르며, any를 피하고 unknown과 narrow adapter를 통해 경계(boundary)를 견고히 한다는 방침이 AGENTS.md의 Code 절에 명시되어 있습니다.

마지막으로 VISION.md의 "What We Will Not Merge"를 살펴보겠습니다. 이는 설계 철학의 이면을 보여줍니다.

  • ClawHub에서 배포할 수 있는 새로운 핵심 기술 (new core skills)
  • 이미 대응 중인 채널에 대한 얇은 래퍼 채널 (thin wrapper channels)
  • 기존의 MCP / ACPX / 플러그인 경로를 중복시키는 것에 불과한 MCP 구현
  • 매니저 오브 매니저(manager-of-managers)형 에이전트 계층 프레임워크 (기본 구조로는 채택하지 않음)
  • 기존의 에이전트/도구 기반을 중복시키는 무거운 오케스트레이션 계층

공통점은 "중복을 만들지 않는다 / 코어를 비대하게 만들지 않는다"라는 일관된 거부입니다. 이것이 거대하면서도 해석 가능한 OpenClaw의 정체라고 보셔도 무방합니다.

#02에서는 src/entry.ts에서 시작되는 **기동 흐름 (startup flow)**을 추적합니다. isMainModule 가드, 컴파일 캐시, 프로세스 재시작(respawn) 계획과 같은 "기동 시의 지뢰"를 어떻게 밟지 않도록 설계했는지, Gateway가 올라오기까지의 일직선 경로를 파헤쳐 봅니다.

참고: VISION.md / README.md / 루트 AGENTS.md / package.json:3 (version 2026.6.2)

AI 자동 생성 콘텐츠

본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0