흔한 "오픈소스 ChatGPT 클론"은 채팅창 하나가 거의 전부다. Odysseus는 거기서 더 나아가 일을 실제로 처리하는 도구(이메일 자동분류, 캘린더 동기화, 할일/예약작업, 문서 편집, 하드웨어에 맞는 모델 추천·다운로드·서빙)까지 한 앱에 묶었다. README의 표현을 빌리면 "더 거칠지만(jank) 더 재미있는" 셀프호스팅 버전이다.
상용 AI 서비스는 "고급 호텔"이다. 편하지만 내 데이터는 호텔 서버에 맡겨야 하고, 매달 방값(구독료)을 낸다. 메뉴(기능)도 호텔이 정한다.
Odysseus는 "내 집에 직접 차린 풀옵션 작업실"이다. 도커로 한 번 올려두면, 어떤 LLM을 쓸지·메일과 캘린더를 어떻게 붙일지·에이전트에게 셸을 줄지 전부 내가 정한다. 데이터(data/ 폴더)는 내 디스크에만 남고, 인터넷에 노출할지조차 내 선택이다.
오픈소스 LLM UI는 많지만(Open WebUI, LibreChat 등) 대부분 채팅 + 약간의 RAG에 머문다. Odysseus는 채팅을 출발점으로 두되, 그 위에 에이전트·딥리서치·이메일·캘린더·노트/할일·문서편집·모델 서빙을 한 묶음으로 올려 "AI로 하루 업무를 처리하는 공간"을 지향한다.
모델을 붙여 대화는 잘 되지만, 메일을 분류하거나 일정에 약속을 넣거나 예약 작업을 돌리는 등 실제 업무 행위는 별도 도구로 흩어진다. 에이전트가 있어도 "도구"가 빈약해 데모 수준에 그치는 경우가 많다.
에이전트가 웹·파일·셸·스킬·메모리 + MCP 서버를 도구로 쥐고 작업 전체를 스스로 굴린다. 이메일은 IMAP/SMTP로 직접 받아 AI가 긴급도 태깅·요약·답장 초안까지 만들고, 캘린더는 CalDAV로 Nextcloud·Apple·Fastmail과 동기화된다. 도구가 풍부하니 에이전트가 "데모"를 넘어 쓸모를 갖는다.
로컬 LLM의 가장 큰 벽은 "내 그래픽카드로 뭘 돌릴 수 있지?"다. Odysseus의 Cookbook은 llmfit을 기반으로 하드웨어(VRAM)를 스캔하고, GGUF/FP8/AWQ 양자화별로 fit 점수를 매겨 "이 카드엔 이 모델"을 추천한다. 클릭하면 받아서 vLLM·llama.cpp로 바로 서빙까지 해준다.
지금까지는 사용자가 직접 모델 카드를 뒤지고, 양자화 종류를 고르고, 서빙 엔진 옵션을 맞춰야 했다. Cookbook은 이 "모델 고르기 → 받기 → 띄우기" 3단계를 하드웨어 인식 기반으로 자동화한다. 초보자가 로컬 LLM에 진입하는 마찰을 크게 줄인 게 트렌딩의 핵심 동력 중 하나다.
Odysseus는 모든 걸 바닥부터 만들지 않고, 검증된 오픈소스를 모듈로 흡수했다. 에이전트 코어는 opencode, 하드웨어 적합도는 llmfit, 딥리서치는 알리바바의 Tongyi DeepResearch를 각색했다. "통합이 곧 가치"라는 전형적인 슈퍼앱 전략이다.
저장소 소유 계정명 pewdiepie-archdaemon은 2025년을 달군 개인 셀프호스팅·로컬 AI 붐의 밈을 그대로 얹은 핸들이다. ("no trojan"·돛단배 ASCII아트 같은 유쾌한 톤이 README 전반에 깔려 있다.) 유명 유튜버 본인이 만들었다는 근거는 저장소에 없으므로, 정확히는 "그 흐름의 정서를 입은 익명/필명 프로젝트"로 보는 게 맞다. 다만 이름값과 별개로, 12.6k 스타·1.6k 포크가 보여주듯 결과물 자체의 완성도가 높다.
언어 비중은 Python 49% · JavaScript 40% · CSS 8% · HTML 2%. 즉 "FastAPI 백엔드 + 빌드 도구 없는 순수 JS 프런트"라는 의외로 클래식한 조합이다. 프레임워크 의존을 최소화해 도커 한 방으로 가볍게 뜨는 걸 노렸다.
| 분류 | 라이브러리 | 역할 |
|---|---|---|
| 웹 프레임워크 | fastapi · uvicorn | 비동기 API 서버. app.py가 진입점 |
| 데이터 검증 | pydantic · pydantic-settings | 요청/설정 스키마, 타입 안전성 |
| DB / ORM | SQLAlchemy (기본 SQLite) | 세션·메시지·문서 저장. DATABASE_URL로 교체 가능 |
| HTTP 클라이언트 | httpx | LLM 백엔드·외부 API 비동기 호출 |
| 벡터 메모리 | chromadb-client · fastembed | 의미 기반 메모리/RAG. 로컬 ONNX 임베딩(외부 API 불필요) |
| 에이전트/도구 | mcp (Model Context Protocol SDK) | 외부 도구를 표준 프로토콜로 연결 |
| 이메일 | 표준 imaplib/smtplib 기반 라우트 | IMAP 수신 · SMTP 발신 + AI 분류/요약 |
| 캘린더 | caldav · icalendar | CalDAV 동기화, .ics 가져오기/내보내기 |
| 예약 작업 | croniter | cron 스타일 스케줄 작업(에이전트가 실행) |
| 보안/인증 | bcrypt · cryptography · pyotp · qrcode | 비밀번호 해시 · 암호화 · TOTP 2FA · QR 발급 |
| 문서 처리 | pypdf · beautifulsoup4 · markdown | PDF 추출 · HTML 파싱 · 리포트 렌더 |
| 유튜브 | youtube-transcript-api | 영상 자막을 컨텍스트로 끌어오기 |
| SDK | @anthropic-ai/sdk (package.json) | Anthropic 모델 연동(JS 측) |
| 테스트 | pytest · @antithesishq/bombadil | 단위 테스트 + Antithesis 결정론적 시뮬레이션 테스트 |
React·Vue 같은 프레임워크나 Webpack/Vite 같은 번들러가 없다. static/index.html + app.js + style.css + 모듈화된 js/ 폴더로 구성된 클래식 SPA에 가깝다. 덕분에 빌드 단계 없이 파일만 서빙하면 되고, 도커 이미지가 가벼워진다.
요즘 웹은 거의 다 React + 번들러인데, Odysseus는 일부러 "파일 그대로 서빙"을 골랐다. 셀프호스팅 사용자가 코드를 열어 고치기 쉽고(트랜스파일 불필요), 컨테이너가 단순해지며, "내가 통제하는 소프트웨어"라는 철학과도 맞는다. 단점은 대규모 상태관리가 번거로워진다는 것 — 그래서 프런트가 전체 코드의 상당 부분(JS 40%)을 차지할 만큼 손으로 많이 짜야 했다.
핵심은 docker compose up -d --build 하나로 앱 + 부속 서비스 3개가 한꺼번에 뜨는 구조다.
| 서비스 | 이미지/포트 | 역할 |
|---|---|---|
| odysseus | 자체 빌드 · :7000 | FastAPI 본체. data/·logs/·SSH키·HF캐시를 호스트에 볼륨 마운트 |
| chromadb | chromadb/chroma · :8100→8000 | 벡터 메모리 저장소(텔레메트리 끔) |
| searxng | searxng/searxng · 127.0.0.1:8080 | 자체 메타 검색 엔진(웹/딥리서치용). 기본 LAN 미노출 |
| ntfy | binwiederhier/ntfy · :8091 | 푸시 알림(노트 핑·작업 알림 채널) |
data/ 폴더에 root 소유 파일을 써서, 나중에 일반 사용자가 못 고치는 EPERM 사고가 난다. Odysseus의 엔트리포인트는 gosu로 PUID/PGID(기본 1000:1000)로 권한을 떨군 뒤 uvicorn을 실행하고, 마운트된 폴더의 소유권을 맞춰준다. 셀프호스팅에서 흔히 데는 함정을 미리 막은 설계.이미지는 python:3.14-slim 기반에 build-essential·cmake·git(Cookbook이 첫 실행 때 llama.cpp를 빌드), tmux(백그라운드 다운로드/서빙), openssh-client(원격 서버 서빙), nodejs/npm(브라우저 MCP용 npx)을 깐다. GPU는 docker/gpu.nvidia.yml · gpu.amd.yml 오버레이를 COMPOSE_FILE에 추가해 켠다.
코드가 3층으로 깔끔히 나뉜다. routes/는 HTTP 입출력(얇은 컨트롤러), src/는 에이전트 루프·LLM 호출 같은 코어 로직, services/는 검색·메모리·하드웨어적합도 같은 도메인 기능을 캡슐화한다. 덕분에 "검색 제공자를 바꾸기"나 "메모리 백엔드 교체" 같은 변경이 한 폴더 안에 갇힌다.
54개 라우트 파일이 도메인별로 쪼개져 있어(email_routes.py·cookbook_routes.py…), 한 파일이 비대해지지 않는다. FastAPI의 APIRouter로 모듈을 합치는 전형적 모범 사례 — 중대형 FastAPI 앱 구조를 공부하기에 좋은 표본이다.
에이전트의 도구는 MCP(Model Context Protocol)로 표준화돼 붙는다. Odysseus는 외부 MCP를 등록할 뿐 아니라, mcp_servers/에 이메일·이미지생성·메모리·RAG 서버를 직접 내장한다. 브라우저 제어(페이지 이동·스크린샷·비전)는 @playwright/mcp를 npx 캐시에 있을 때만 자동 등록 — 없으면 건너뛰고 로그만 남겨, 신규 설치가 수 분짜리 npm 다운로드에 멈추지 않게 했다.
벡터 메모리(ChromaDB/fastembed)가 없으면 키워드 검색으로 자동 강등되고, 브라우저 MCP 패키지가 없으면 그 도구만 빠진 채 나머지가 정상 동작한다. "의존성 하나 빠졌다고 앱 전체가 죽지 않는다"는 셀프호스팅 친화적 견고함이 곳곳에 박혀 있다.
Odysseus는 셸 접근·파일 업로드·웹 리서치·메일/캘린더·API 토큰을 모두 가진다. 그래서 AUTH_ENABLED=true 유지, 공개 인터넷 직노출 금지(HTTPS 리버스 프록시 필수), 비관리자는 셸/파이썬/파일 권한 기본 차단, MCP관리·토큰·웹훅·백업은 admin 전용 게이팅 — 권한 모델이 촘촘하다. 셀프호스팅 시 가장 먼저 읽어야 할 부분이다.
app.db(세션·메시지·문서) · memory.json · presets.json · settings.json · uploads/ · personal_docs/ · chroma/가 전부 이 한 폴더에 모인다. 백업은 이 폴더만 챙기면 되고, .gitignore로 막혀 있어 포크를 공개해도 개인 데이터가 새지 않는다. "내 데이터는 내 디스크에" 원칙의 물리적 구현.54개 라우트를 APIRouter로 모듈화하고, core/에 인증·DB·미들웨어를 모은 구조는 "FastAPI 프로젝트를 어떻게 키우는가"의 살아있는 교과서다.
실습 아이디어: routes/note_routes.py 하나를 골라 요청 → src 로직 → services 호출 → 응답까지 한 흐름을 따라가며 호출 그래프를 그려보기.
src/llm_core.py + endpoint_resolver.py + model_discovery.py가 vLLM·llama.cpp·Ollama·OpenAI·OpenRouter를 하나의 인터페이스로 묶는다. OpenAI 호환 API를 공통분모로 삼아 어떻게 추상화하는지가 핵심.
실습 아이디어: 새 프로바이더(예: 로컬 LM Studio)를 추가해보며 추상화의 확장 지점을 체득.
agent_loop.py · agent_tools.py · mcp_manager.py 삼총사로 "도구를 쥔 에이전트가 작업을 끝까지 굴리는" 패턴을 학습한다. MCP로 도구를 표준화하는 현대적 방식의 좋은 예시.
실습 아이디어: mcp_servers/memory_server.py를 참고해 나만의 간단한 MCP 서버(예: 날씨 조회)를 추가.
fastembed(ONNX) + ChromaDB 조합으로 외부 API 없이 벡터 검색을 구현. rag_vector.py · memory_vector.py에서 "벡터 + 키워드 하이브리드 검색"과 강등 로직을 볼 수 있다.
실습 아이디어: ChromaDB를 잠시 꺼서 키워드 폴백이 어떻게 작동하는지 직접 확인.
services/hwfit/는 "VRAM을 보고 양자화별 fit 점수를 매겨 모델을 추천"하는 드문 기능이다. 로컬 LLM 운영의 실전 노하우(GGUF vs FP8 vs AWQ, 서빙 엔진 선택)가 코드로 정리돼 있다.
실습 아이디어: fit.py의 점수 공식을 읽고, 내 GPU에서 추천 결과가 합리적인지 검증.
Dockerfile의 PUID/PGID·gosu, atomic_io.py의 원자적 쓰기, SearXNG의 127.0.0.1 바인딩, Caddy 리버스 프록시 가이드 — "서비스를 안전하게 띄운다"의 실무 감각을 통째로 배운다.
실습 아이디어: Caddy로 HTTPS를 입혀 LAN의 다른 기기에서 접속해보기.
| 항목 | 내용 |
|---|---|
| 핵심 런타임 | Python 3.11+ (도커 이미지는 3.14-slim) |
| 설치 방식 | Docker Compose(권장) / 네이티브 Linux·macOS·Windows |
| 기본 포트 | 앱 7000 (macOS 네이티브는 7860, AirPlay 충돌 회피) |
| 코어 앱(채팅·에이전트·메모리·문서·메일·캘린더·리서치) | GPU 불필요 — 일반 PC/홈서버에서 동작. 모델은 API로 붙이면 됨 |
| Cookbook 백그라운드 다운로드/서빙 | tmux 필요(Windows는 Git for Windows의 bash) |
| 로컬 GPU 서빙(vLLM/SGLang) | Linux/WSL2 + NVIDIA(CUDA) 또는 AMD(ROCm) |
| Apple Silicon | 도커는 Metal GPU 사용 불가 → 네이티브 실행(start-macos.sh)로 llama.cpp/Ollama(Metal) |
| Windows 로컬 모델 | Ollama가 가장 쉬움(localhost:11434/v1 연결) |
| 브라우저 MCP(선택) | npx @playwright/mcp + Playwright(~300MB) |
아무 PC + 도커. 로컬 GPU 없이 OpenAI·OpenRouter·Anthropic 키만 넣으면 모든 워크스페이스 기능(에이전트·메일·캘린더·리서치)이 돈다. GPU 고민은 나중에.
NVIDIA GPU(8~24GB) + Linux/WSL2. Cookbook으로 카드에 맞는 양자화 모델을 추천받아 llama.cpp/vLLM로 서빙. 데이터까지 완전 로컬.
Linux 미니PC/NAS + 도커 + Tailscale + Caddy(HTTPS). PWA로 폰에 설치해 외부에서도 안전하게 접속하는 "개인 AI 서버".
git clone → cp .env.example .env → docker compose up -d --build → localhost:7000 접속. Settings에서 OpenRouter/OpenAI 키를 넣고 첫 채팅을 돌린다.
배우는 것: Compose 멀티서비스 부팅 흐름과 data/ 영속화, 헬스체크가 통과하는 순서(searxng → odysseus).
Agent 모드에서 "이 폴더의 CSV를 읽고 요약 리포트를 문서로 만들어줘" 같은 멀티스텝 작업을 던진다. 셸/파일/웹 도구가 어떻게 연쇄 호출되는지 로그로 관찰.
배우는 것: 에이전트 루프 + 도구 호출의 실제 동작, opencode 기반 코어의 감각.
로컬 GPU가 있다면 Cookbook이 스캔한 fit 점수를 보고 모델을 받아 서빙한다. GPU가 없으면 services/hwfit/fit.py를 읽고 점수 공식을 직접 분석.
배우는 것: VRAM↔양자화↔모델 크기의 트레이드오프, 하드웨어 인식 서빙의 의사결정.
mcp_servers/memory_server.py를 본떠 새 MCP 서버(예: 사내 위키 검색)를 만들고 mcp_manager에 등록. 에이전트가 새 도구를 인식하는지 확인.
배우는 것: MCP 서버 작성·등록·수명주기, 에이전트 도구 확장 패턴.
Caddy + Tailscale로 TLS를 입히고, AUTH_ENABLED·per-user 권한·2FA·API 토큰을 점검한 뒤 안전하게 LAN/원격에 노출. data/auth.json로 오픈 가입을 닫는다.
배우는 것: 셀프호스팅 보안 모델 전반 — 리버스 프록시, 권한 게이팅, 토큰 위생.
FastAPI 공식 튜토리얼 → APIRouter 모듈화 → SQLAlchemy + pydantic-settings. Odysseus의 app.py·core/·routes/를 대조하며 "라우트→로직→서비스" 3층 구조를 모사한 미니 앱 작성.
OpenAI 호환 API 규약 → 멀티 프로바이더 추상화 → 도구 호출(tool/function calling) → MCP 사양. llm_core.py·agent_loop.py·mcp_manager.py 정독 후 간단한 도구 에이전트 구현.
임베딩 개념 → fastembed(ONNX) 로컬 추론 → ChromaDB 컬렉션/쿼리 → 벡터+키워드 하이브리드 검색. rag_vector.py를 참고해 문서 Q&A 파이프라인을 손수 작성.
Docker Compose 멀티서비스 → 볼륨/권한(PUID·gosu) → 리버스 프록시(Caddy)·Tailscale → 인증/2FA/권한 모델. 직접 띄운 Odysseus를 HTTPS로 하드닝하며 운영 감각 완성.
| 용어 | 뜻 |
|---|---|
| Self-hosting | 내가 관리하는 컴퓨터에 소프트웨어를 직접 올려 쓰는 방식. 데이터 주권·프라이버시가 장점 |
| Local-first | 데이터·연산을 우선 로컬에 두고, 클라우드는 선택적으로만 쓰는 설계 철학 |
| FastAPI | 파이썬 비동기 웹 프레임워크. 타입 힌트 기반 검증·자동 문서화가 강점 |
| uvicorn | FastAPI를 구동하는 ASGI 서버 |
| MCP (Model Context Protocol) | LLM/에이전트가 외부 도구·데이터에 붙는 표준 프로토콜 |
| Agent loop | 관찰→계획→도구 호출→결과 반영을 반복하며 작업을 끝까지 수행하는 실행 루프 |
| RAG | 검색 증강 생성. 외부 문서를 찾아 컨텍스트로 넣어 답변 품질을 높임 |
| 임베딩(Embedding) | 텍스트를 의미 벡터로 변환한 것. 의미 기반 검색의 토대 |
| fastembed | 외부 API 없이 로컬 ONNX로 임베딩을 계산하는 라이브러리 |
| ChromaDB | 오픈소스 벡터 데이터베이스. 의미 메모리/RAG 저장소로 사용 |
| SearXNG | 프라이버시 중심 메타 검색 엔진. 여러 검색엔진 결과를 모아줌(추적 없음) |
| ntfy | 간단한 HTTP 기반 푸시 알림 서비스 |
| CalDAV | 캘린더 동기화 표준 프로토콜(Nextcloud·Apple·Fastmail 등과 연동) |
| IMAP / SMTP | 이메일 수신(IMAP)·발신(SMTP) 표준 프로토콜 |
| vLLM / llama.cpp / Ollama | 로컬 LLM 추론·서빙 엔진들(고성능 GPU 서빙 / 경량 CPU·GPU / 간편 로컬) |
| 양자화(GGUF·FP8·AWQ) | 모델 가중치를 저비트로 압축해 메모리·속도를 절약하는 기법들 |
| Cookbook / llmfit | 하드웨어(VRAM)를 스캔해 적합 모델을 추천·다운로드·서빙하는 기능/라이브러리 |
| PWA | 설치 가능한 웹앱. 모바일에서 네이티브 앱처럼 동작 |
| PUID/PGID + gosu | 컨테이너가 지정한 사용자 권한으로 떨어져 실행 → 호스트 파일 권한 사고 방지 |
| Graceful Degradation | 의존성 일부가 빠져도 핵심 기능이 유지되도록 단계적으로 강등하는 설계 |
| Reverse Proxy (Caddy) | 앞단에서 TLS를 종료하고 요청을 내부 서비스로 전달. HTTPS·인증 보강 |
| 2FA / TOTP | 비밀번호 외 추가 인증. 시간 기반 일회용 코드(pyotp·QR) |
| opencode | Odysseus 에이전트 코어가 기반으로 삼은 오픈소스 코딩 에이전트 |
| Tongyi DeepResearch | 알리바바의 다단계 딥리서치 프로젝트. Odysseus의 리서치 기능이 각색 |
| Antithesis (bombadil) | 결정론적 시뮬레이션으로 버그를 재현·탐지하는 테스트 플랫폼/툴 |