Onyx는 어떤 LLM이든 연결 가능한 셀프호스팅 AI 챗 플랫폼으로, 40개 이상의 데이터 소스 커넥터 + RAG(검색증강생성) + 에이전트 시스템을 결합한 엔터프라이즈급 오픈소스 솔루션입니다.
쉽게 비유하면 "회사 내부 데이터를 다 연결해서 ChatGPT처럼 대화할 수 있는 시스템을 직접 서버에 설치해 쓰는 것"입니다. GitHub 스타: 30k(2026-06-04 기준), 기여자: 198+.
ChatGPT Enterprise는 회사 데이터를 올리기 꺼려집니다. Onyx는 내 서버 위에서 돌아갑니다. Slack·Notion·Jira·Google Drive의 내용이 실시간으로 인덱싱되고, 어떤 LLM이든 교체 가능합니다.
핵심은 하이브리드 검색 + 지식 그래프입니다. 단순히 문서를 검색하는 게 아니라, 엔티티 간 관계를 그래프로 파악하여 "A 프로젝트와 관련된 B 팀의 결정"을 추적할 수 있습니다.
ChatGPT Enterprise나 Perplexity는 API를 통해 데이터가 외부 서버로 나갑니다. 의료·금융·법무 같은 규제 산업에서는 이것 자체가 불가능합니다. 게다가 특정 LLM 벤더에 종속되면 가격 인상이나 서비스 변경에 속수무책이 됩니다.
인터넷 없는 완전 격리 환경(에어갭)에서도 동작합니다. OpenAI·Anthropic·Google·Ollama·vLLM 중 원하는 LLM을 자유롭게 교체할 수 있고, 40개 이상의 커넥터가 기업이 실제로 쓰는 도구 대부분을 지원합니다.
| 비교 항목 | Onyx | ChatGPT Enterprise | Perplexity | PrivateGPT |
|---|---|---|---|---|
| 셀프호스팅 | ✅ 완전 지원 | ❌ SaaS만 | ❌ SaaS만 | ✅ 제한적 |
| 커넥터 수 | 40개+ | 제한적 | 웹만 | 파일만 |
| LLM 선택 | 모든 LLM | GPT만 | 자체 모델 | 제한적 |
| 에어갭 지원 | ✅ | ❌ | ❌ | ✅ |
| 지식 그래프 | ✅ | ❌ | ❌ | ❌ |
| 가격 | 무료(CE) | 유료 | 유료 | 무료 |
| 카테고리 | 기술 |
|---|---|
| 웹 프레임워크 | FastAPI + Uvicorn + Starlette (비동기 고성능 API 서버) |
| 데이터베이스 | PostgreSQL 15 + SQLAlchemy + Alembic (마이그레이션) |
| 검색 엔진 | Vespa 8.x (벡터+키워드 하이브리드) + OpenSearch 3.x (전문 검색) |
| LLM 통합 | LiteLLM (통합 LLM 인터페이스) + LangChain-core |
| 태스크 큐 | Celery + Redis 7.x (캐시 + 메시지 브로커) |
| 파일 스토리지 | MinIO (S3 호환 오브젝트 스토리지) |
| 모니터링 | Sentry + Prometheus + Langfuse / Langsmith (LLM 옵저빌리티) |
| 카테고리 | 기술 |
|---|---|
| 프레임워크 | Next.js 16 + React 19 + TypeScript 5.9 |
| UI 컴포넌트 | Radix UI (접근성) + Headless UI + Lucide React + cmdk + Motion |
| 상태 관리 | Zustand 5 (글로벌 상태) + SWR (서버 상태 캐싱) |
| 스타일링 | Tailwind CSS 4.x (^4.3.0) + tailwind-merge (^3.6.0) + CVA |
| 테스트 | Playwright (E2E) + Jest + Storybook 8 (컴포넌트 문서화) |
| 기술 | 역할 |
|---|---|
| Docker + Docker Compose | 11개 서비스 컨테이너화 (docker-bake.hcl 멀티플랫폼) |
| Kubernetes + Terraform | 대규모 오케스트레이션 + IaC |
| Nginx 1.25 | 리버스 프록시 + 로드밸런싱 + SSL |
벡터 검색(의미 기반)과 키워드 검색(BM25)을 동시에 수행하고 결과를 합칩니다. "의미를 이해하는 검색"과 "정확한 단어를 찾는 검색"을 동시에 돌려서 최적의 결과를 뽑아내는 방식입니다.
# 커넥터 공통 인터페이스 (간소화)
class BaseConnector:
def load(self) -> Iterator[Document]:
"""전체 데이터 로드 (초기 인덱싱)"""
...
def poll(self, start_time) -> Iterator[Document]:
"""변경분만 가져오기 (증분 인덱싱)"""
...
def slim(self) -> Iterator[DocumentId]:
"""ID만 가져오기 (삭제 감지용)"""
...
40개 커넥터가 공통 인터페이스를 구현합니다. 새 데이터 소스를 추가하려면 이 인터페이스만 맞추면 됩니다. load/poll/slim 3가지 모드로 전체 인덱싱·증분 인덱싱·삭제 감지를 각각 처리합니다.
process_message(검증·세션·권한) → run_chat_loop_with_state_containers(컨텍스트·도구·스트리밍) → run_llm_step(프롬프트 구성·LLM 호출·응답 파싱)으로 계층이 명확히 분리됩니다.
code-interpreter:
volumes:
- /var/run/docker.sock:/var/run/docker.sock # 호스트 Docker 소켓 공유
user: root # Docker 소켓 접근 필요
컨테이너 내부에서 또 컨테이너를 만드는 게 아니라, 호스트의 Docker 소켓을 마운트하여 형제 컨테이너를 생성합니다. 보안과 성능의 균형을 맞춘 코드 실행 패턴입니다.
FastAPI로 대규모 API 서버를 설계하는 방법, Uvicorn 워커 프로세스 관리, SSE(Server-Sent Events)로 채팅 응답을 실시간 전달하는 구현을 배웁니다.
# SSE 스트리밍 응답 패턴
from fastapi.responses import StreamingResponse
async def chat_stream(request):
async def generate():
async for chunk in llm_loop.run():
yield f"data: {chunk.json()}\n\n"
return StreamingResponse(generate(), media_type="text/event-stream")
문서 청킹 전략(고정/재귀/의미 기반), 벡터 임베딩 생성과 인덱싱(Vespa), 하이브리드 검색 구현(벡터+BM25+리랭킹), 지식 그래프로 RAG 정확도 향상시키기, 컨텍스트 윈도우 압축을 익힙니다.
전략 패턴으로 다양한 데이터 소스 통합, load/poll/slim 3가지 인덱싱 모드의 차이, OAuth2 토큰 관리와 API Rate Limiting 처리, 증분 인덱싱(Incremental Indexing) 구현을 배웁니다.
Notion API를 사용하는 미니 커넥터를 직접 만들어보기 — BaseConnector 상속 후 load()·poll()·slim() 구현
11개 서비스를 Docker Compose로 오케스트레이션하는 방법, 헬스체크 설정과 서비스 간 의존성 관리, docker-bake.hcl로 멀티플랫폼 이미지 빌드, DooD 패턴을 배웁니다.
LiteLLM으로 여러 LLM 프로바이더를 하나의 인터페이스로 통합하는 법, RBAC(역할 기반 접근 제어), SSO(OIDC/SAML/OAuth2), 문서 레벨 권한 미러링, 멀티테넌시 설계를 공부합니다.
| 항목 | 사양 |
|---|---|
| CPU | 4코어 이상 |
| RAM | 16GB 이상 (OpenSearch JVM만 4GB) |
| 디스크 | 50GB SSD |
| Docker | Docker Engine 24+ |
| OS | Linux / macOS / Windows (WSL2) |
| 항목 | 사양 |
|---|---|
| CPU | 8코어+ (임베딩 서빙 시 더 필요) |
| RAM | 32GB+ |
| 디스크 | 200GB+ SSD (문서 양에 비례) |
| GPU | 선택 (로컬 임베딩/LLM 시 NVIDIA GPU) |
| 서비스 | 메모리 사용 |
|---|---|
| OpenSearch | 2~4GB (JVM 힙) |
| Vespa | 2~4GB |
| PostgreSQL | 1~2GB |
| API Server | 1~2GB |
| Model Server | 2~4GB (모델 크기에 따라) |
| Redis | 512MB~1GB |
리포지토리를 클론하고 deployment/docker_compose/에서 .env 파일을 설정한 뒤 전체 스택을 실행합니다. Ollama를 연결하거나 OpenAI API 키를 등록하고 RAG 대화를 테스트합니다.
docker compose up -d
# http://localhost:3000 에서 관리자 계정 생성
backend/onyx/connectors/ 구조를 분석하고 BaseConnector 인터페이스를 이해합니다. 간단한 RSS 피드 커넥터 또는 로컬 마크다운 폴더 커넥터를 직접 제작하고 load/poll/slim 3가지 모드를 구현합니다.
backend/onyx/mcp_server/ 코드를 분석하고 커스텀 MCP 도구(날씨 조회·계산기 등)를 작성하여 Onyx 에이전트에 연결합니다. 에이전트가 도구를 활용해 응답하는지 테스트합니다.
Onyx의 document_index/·indexing/·chat/을 정독 후 FastAPI + PostgreSQL + ChromaDB로 미니 RAG 서버를 구축합니다. 문서 청킹 → 임베딩 → 하이브리드 검색 → LLM 생성 파이프라인을 직접 구현하고 Onyx와 검색 품질을 비교합니다.
deployment/kubernetes/ 매니페스트를 분석하고 Minikube 또는 Kind로 로컬 K8s 클러스터를 만들어 전체 스택을 배포합니다. Ingress 설정, SSL 인증서, HPA(오토스케일링)까지 구성합니다.
Onyx 로컬 배포 및 전체 서비스 구조 파악, Docker Compose 11개 서비스 역할 매핑, PostgreSQL + Redis + Vespa 기본 개념
문서 청킹 전략(고정/재귀/의미 기반), 벡터 임베딩 원리(Word2Vec → Sentence Transformers), Vespa로 하이브리드 검색 실습, OpenSearch BM25 검색
FastAPI 비동기 패턴 + SSE 스트리밍, Celery 태스크 큐로 비동기 인덱싱, SQLAlchemy 관계형 모델링, LiteLLM 멀티 프로바이더 통합
Next.js 16 App Router + React 19 서버 컴포넌트, Zustand 상태 관리 패턴, SWR 데이터 페칭 + 실시간 업데이트, Radix UI 컴포넌트 커스터마이징
커넥터 아키텍처 분석 및 커스텀 커넥터 개발, MCP(Model Context Protocol) 이해 및 도구 제작, 에이전트 시스템 설계 패턴, 지식 그래프 구축 기초
Kubernetes 배포 실습, Terraform IaC로 클라우드 인프라 구성, Sentry/Prometheus/Langfuse 모니터링, SSO/RBAC 엔터프라이즈 보안
| 키워드 | 설명 |
|---|---|
| RAG | Retrieval-Augmented Generation. LLM이 답변 생성 시 외부 문서를 검색하여 참고 |
| 하이브리드 검색 | 벡터 검색(의미 유사성)과 키워드 검색(BM25)을 동시에 수행해 최적 결과 도출 |
| 벡터 임베딩 | 텍스트를 고차원 숫자 벡터로 변환하여 의미적 유사성을 계산 가능하게 하는 기술 |
| Vespa | Yahoo에서 만든 고성능 벡터 + 텍스트 검색 엔진. Onyx의 핵심 검색 인프라 |
| OpenSearch | Elasticsearch의 오픈소스 포크. 전문 검색(full-text search) 담당 |
| 청킹 (Chunking) | 긴 문서를 LLM이 처리할 수 있는 작은 조각으로 나누는 과정 |
| 리랭킹 (Reranking) | 1차 검색 결과를 더 정밀한 모델로 다시 순위 매기는 2단계 검색 |
| 지식 그래프 | 엔티티와 관계를 그래프로 구조화하여 RAG 검색 품질을 높이는 기술 |
| LiteLLM | 여러 LLM 프로바이더(OpenAI·Anthropic·Google 등)를 통합 인터페이스로 감싸는 라이브러리 |
| MCP | Model Context Protocol. AI 에이전트가 외부 도구와 상호작용하는 표준 |
| SSE | Server-Sent Events. 서버가 클라이언트로 실시간 데이터를 푸시하는 HTTP 프로토콜 |
| DooD | Docker-out-of-Docker. 컨테이너에서 호스트 Docker 소켓을 공유해 형제 컨테이너 생성 |
| Celery | Python 분산 태스크 큐. 커넥터 인덱싱 같은 무거운 작업을 백그라운드 비동기 처리 |
| RBAC | Role-Based Access Control. 사용자 역할에 따라 데이터 접근을 제한하는 접근 제어 |
| SSO | Single Sign-On. 한 번 로그인으로 여러 시스템 접근. OIDC/SAML/OAuth2 프로토콜 |
| 에어갭 (Air-Gap) | 인터넷과 완전 차단된 네트워크 환경. 보안 요구사항이 높은 조직에서 사용 |
| Zustand | React 상태 관리 라이브러리. Redux보다 간결하고 보일러플레이트가 적음 |
| SWR | Vercel의 데이터 페칭 라이브러리. stale-while-revalidate 전략으로 캐시 + 리프레시 |
| Radix UI | 접근성(WAI-ARIA) 준수 헤드리스 UI 컴포넌트. 스타일 없이 동작만 제공 |
| docker-bake.hcl | Docker BuildKit의 선언적 빌드 설정. 멀티플랫폼(amd64/arm64) 이미지를 한 번에 빌드 |