"내 서버 안에서 도는 LLM에 Claude API와 똑같은 껍데기를 씌워, 회사 데이터로 동작하는 AI 앱을 바로 만들 수 있게 해주는 도구"입니다. 보통 우리가 Ollama나 vLLM을 띄우면 "모델은 돌아가지만 그뿐"입니다. 문서를 넣어 답하게 하려면 RAG 파이프라인을, 웹 검색·코드 실행을 붙이려면 툴 시스템을, 여러 앱이 붙게 하려면 표준 API를 직접 다 만들어야 합니다. PrivateGPT는 이 "앱이 되기 위한 모든 배관"을 한 겹의 API로 미리 깔아 둔 것입니다.
이름은 'Private(사적인) + GPT'입니다. 데이터가 내 인프라 밖으로 나가지 않는다는 프라이버시·온프레미스 정체성이 핵심입니다. 결정적으로 v1.0부터는 이 API가 Anthropic의 Claude API 스펙을 레퍼런스로 그대로 따릅니다. 그래서 Claude Desktop, Claude Code, VS Code 확장, n8n 같은 "OpenAI/Anthropic 호환 백엔드를 쓰는 도구"를 내 로컬 PrivateGPT로 그냥 연결할 수 있습니다. 모델 실행(Ollama)과 앱 기능(PrivateGPT)을 분리한 발상이 이 프로젝트의 정체성입니다.
발전기(LLM 추론 서버)는 전기를 만들어 냅니다. 하지만 발전기만으로는 집에서 살 수 없습니다. 콘센트 규격, 벽 속 배선, 두꺼비집, 가전제품을 연결하는 표준이 있어야 비로소 "쓸 수 있는 집"이 됩니다.
PrivateGPT는 바로 그 전기 설비 일체입니다. 발전기(Ollama·vLLM)가 만든 전기(토큰)를 받아, 표준 콘센트(Claude 호환 API), 배선(RAG·툴·MCP), 가전 연결(Claude Code·n8n)을 제공합니다. 발전기를 바꿔 끼워도(모델 교체) 집의 배선은 그대로입니다. "모델은 갈아끼우고 앱 기능은 유지"가 가능한 이유입니다.
PrivateGPT는 초기 PoC가 GitHub에서 5만 스타를 넘기며 "그 해 가장 화제가 된 로컬 AI 레포" 중 하나였습니다. 그런데 2026년 다시 트렌딩에 오른 이유는 따로 있습니다. v1.0 대규모 개편(revamp) 때문입니다. 옛날의 "오프라인으로 내 PDF와 채팅하는 스크립트"에서 → "Claude API 스펙을 그대로 미러링하는 로컬 백엔드"로 정체성을 갈아엎었습니다. Claude Code·Claude Desktop·Cowork 같은 도구가 폭발적으로 늘면서, "그 도구들을 내 로컬 모델로 돌리는 표준 백엔드" 수요가 정확히 PrivateGPT와 맞아떨어졌습니다.
| 도구 | 무엇을 푸는가 | PrivateGPT와의 관계 |
|---|---|---|
| Ollama / vLLM / llama.cpp | "모델을 어떻게 실행하나" (추론 레이어) | PrivateGPT가 그 위에 올라탐 — 함께 씀 |
| Open WebUI / Onyx | 채팅·엔터프라이즈 검색 완제품 (app-first) | 그 제품들 밑에 깔리는 표준 백엔드가 PrivateGPT |
| LangChain / LlamaIndex | RAG·에이전트를 코드로 조립하는 라이브러리 | PrivateGPT는 그걸 'API 서버 제품'으로 완성해 줌 |
| PrivateGPT | "로컬 모델 위에 유용한 AI 앱 API를 어떻게 얹나" (API-first) | — |
핵심은 "API-first"라는 포지션입니다. Open WebUI가 "사람이 쓰는 채팅 화면"을 준다면, PrivateGPT는 "다른 앱·에이전트가 호출하는 표준 API"를 줍니다. 그래서 PrivateGPT의 /ui 워크벤치는 데모(demonstrator)일 뿐, 진짜 제품은 API라고 README가 못 박습니다.
README는 자신이 Claude API의 어떤 기능을 구현했는지 표로 공개합니다. 실제로 상당 부분이 ✅ 지원입니다.
| 기능 | 지원 | 설명 |
|---|---|---|
| Messages / Streaming | ✅ | 표준 메시지 API + 실시간 스트리밍(SSE) |
| Retrieval + 인용 | ✅ | 문서 검색 결과에 출처(citation)를 달아 반환 |
| Tool use (내장) | ✅ | 웹 검색·웹 fetch·코드 실행·DB 질의·표 분석 내장 |
| Files / PDF 인제스천 | ✅ | PDF·오피스·마크업 등 멀티포맷 업로드 |
| MCP / Custom tools | ✅ | MCP 커넥터 + 사용자 정의 툴 |
| Embeddings | ✅ | 임베딩 자동 발견·생성 |
| Skills | ⚙️ 기본 | Agent Skills 기초 지원(부분) |
| Token-based auth | ✅ | 토큰 기반 인증 지원 |
| OAuth / organizations | ❌ | 조직 인증(OAuth)은 미지원 |
| Extended thinking | ⚙️ 모델 의존 | 모델이 지원하면 사용 가능 |
| Vision | ⚙️ 모델 의존 | 모델이 지원하면 이미지 입력 가능 |
앱은 Claude API 형태로 한 번만 짜두면, 뒤에서 도는 모델은 Ollama든 vLLM이든 자유롭게 갈아끼울 수 있습니다. 클라우드 비용 없이, 데이터 유출 걱정 없이, 그러면서도 Claude 생태계 도구들을 그대로 씁니다. "프라이버시 + 표준 호환"이라는 두 마리 토끼가 트렌딩의 동력입니다.
v0.x 시절의 settings-ollama.yaml·settings-openai.yaml 같은 모드별 프로파일과 Chroma 벡터스토어, Poetry, Gradio UI는 v1.0에서 제거됐습니다. 지금은 LLM 연결을 OPENAI_API_BASE 환경변수로 통일하고, 벡터스토어는 Qdrant 단일, 빌드는 uv, UI는 정적 HTML입니다. 인터넷의 옛 튜토리얼을 따라 하면 동작하지 않으니, 반드시 현재 버전 문서를 기준으로 삼아야 합니다.
PrivateGPT는 FastAPI 웹 서버 + llama-index RAG 코어 + injector 의존성 주입(DI)을 뼈대로 합니다. 가장 인상적인 설계는 의존성을 잘게 쪼갠 'extras(선택 설치 그룹)'입니다. 필요한 기능만 골라 설치하도록 수십 개의 그룹으로 나뉘어 있어, "가벼운 RAG만" 쓸 수도, "DB·미디어·분산 큐까지" 다 켤 수도 있습니다. 빌드는 Poetry가 아니라 uv(Astral) + hatchling을 씁니다.
| 항목 | 내용 |
|---|---|
| 언어 | Python 3.11 고정 (>=3.11, <3.12) |
| 웹 프레임워크 | FastAPI [all] + python-multipart (파일 업로드) |
| 의존성 주입 | injector — 모든 컴포넌트를 @singleton @inject로 배선 |
| RAG 프레임워크 | llama-index-core (0.14.x) — 인덱싱·검색·노드의 뼈대 |
| CLI | typer — private-gpt serve / worker / run |
| 설정 | pydantic 모델 + settings*.yaml + ${ENV:default} 환경변수 치환 |
| 코드 품질 | ruff(상대 임포트 전면 금지) · black · mypy strict · pytest(asyncio) |
PrivateGPT는 모델을 직접 실행하지 않으므로, LLM/임베딩을 "어떤 OpenAI 호환 서버에 연결할지"로 다룹니다. auto_discover_models 옵션이 켜져 있으면 연결된 서버의 /v1/models를 긁어 모델을 자동 등록합니다.
| extras 그룹 | 역할 |
|---|---|
| llm-openai-compatible | Ollama·vLLM·LM Studio·llama.cpp 등 OpenAI 호환 서버 연결 |
| llm-anthropic / sdk-openai | Anthropic SDK·OpenAI SDK(+ openai-harmony, gpt-oss용) |
| tokenizer-local | transformers·huggingface-hub로 로컬 토크나이저(토큰 수 계산) |
| embedding-openai-compatible | 임베딩 모델도 OpenAI 호환 엔드포인트로 |
| 구성요소 | 기본값 / 선택지 |
|---|---|
| 벡터스토어 | Qdrant (hnsw·hybrid search·cosine, embed_dim 1024, 논리적 멀티테넌시) |
| 노드/인덱스 스토어 | simple(파일) 또는 PostgreSQL(docstore·index-store) |
| 오브젝트 스토리지 | 로컬 / S3(boto3) / SMB(smbprotocol) |
| 분산 큐 | Celery + RabbitMQ(대량 인제스천), Redis(스트림·세마포어) |
| DB 프로바이더 | Postgres·MySQL·MSSQL·DB2 — SQL 질의 툴용 |
| 영역 | 구성 |
|---|---|
| 문서 파싱 | markitdown(docx/pdf/pptx/xlsx) · docling(OCR·표 추출) · pptx2md(슬라이드) |
| 내장 툴 | 웹 검색(Brave) · 웹 fetch · 코드 실행 샌드박스 · DB 질의 · 표 분석(pandasai) |
| 웹 스크래핑 | Playwright(tool-web-scraping) |
| 확장 | MCP 커넥터(mcp>=1.27) · Agent Skills(sqlite 저장) |
| 미디어 | torch·torchvision·torchaudio·opencv·ffmpeg (이미지/오디오/영상) |
| 관측성 | Arize Phoenix(OpenInference + OTLP) · Opik |
injector 라이브러리로 LLMComponent·VectorStoreComponent 같은 부품을 @singleton(앱 전체에 하나만)으로 만들어 생성자에 꽂아 줍니다. 덕분에 "Qdrant를 Postgres로 바꾸기" 같은 교체가 설정 한 줄로 끝납니다.PrivateGPT의 구조를 한 문장으로 줄이면 이렇습니다. "FastAPI 라우터가 요청을 받고 → 서비스가 DI로 주입된 컴포넌트들을 오케스트레이션하고 → 요청이 '인터셉터 체인'을 거치며 단계별로 가공된 뒤 → 에이전트 루프가 LLM과 툴을 오가며 답을 만들고 → SSE로 스트리밍한다." 핵심 키워드는 DI · 인터셉터 체인 · 에이전트 루프 · 트리 인제스천 넷입니다.
여기서 eager_loading이 중요합니다. 무거운 컴포넌트(모델 클라이언트·벡터스토어 연결)를 서버가 뜰 때 미리 만들어 두어, 첫 요청이 느려지는 '콜드 스타트'를 막습니다. 모든 컴포넌트가 @singleton이라 앱 전체에서 단 하나만 존재합니다.
채팅 요청은 곧장 LLM으로 가지 않습니다. 여러 개의 '인터셉터(interceptor)'를 순서대로 통과하며 단계별로 가공됩니다. 미들웨어를 줄줄이 엮은 파이프라인이라고 보면 됩니다. server/chat/interceptors/ 안에 20여 개가 있습니다.
이 패턴의 장점은 관심사 분리입니다. "인용 달기"와 "히스토리 압축"이 서로를 모른 채 각자의 인터셉터로 존재합니다. 새 기능은 인터셉터 하나를 추가하면 끝이라, 거대한 함수가 비대해지지 않습니다.
가공된 요청은 ChatLoopEngine으로 들어가 "LLM 호출 → 툴이 필요하면 실행 → 결과를 다시 LLM에" 를 반복(agentic loop)합니다. 한편 문서 인제스천은 단순 청킹이 아니라 문서를 계층적 '트리'로 변환합니다(섹션→표→이미지→문단→조각 노드). 검색 시에는 이 트리를 위아래로 확장(tree expansion)해 인용 품질과 문맥을 높입니다.
DI로 부품을 갈아끼우고, 인터셉터로 기능을 더하고, extras로 의존성을 켜고 끕니다. 덕분에 같은 코드베이스가 "노트북에서 도는 가벼운 RAG"부터 "K8s 위 분산 엔터프라이즈 백엔드(상용 Zylon)"까지 커버합니다. 확장성과 교체 가능성을 동시에 잡은, 잘 설계된 모듈 아키텍처의 교과서적 사례입니다.
코드의 거의 전부는 private_gpt/ 패키지 아래에 있습니다. 크게 server/(HTTP 레이어) · components/(도메인 로직) · settings/(설정) · events/(스트리밍)로 나뉘며, 각 도메인이 라우터 ↔ 서비스 ↔ 컴포넌트 3층으로 일관되게 분리돼 있습니다.
주목할 점 셋. 첫째, server/의 모든 도메인이 router(HTTP) → service(로직) → component(부품)로 똑같이 나뉘어 예측 가능합니다. 둘째, events/는 Anthropic API의 스트리밍 이벤트 구조(content block·delta)를 그대로 재현해 Claude 호환을 떠받칩니다. 셋째, ui/index.html은 React 빌드 없이 인라인 스타일·스크립트로 된 단일 정적 파일입니다 — "UI는 어디까지나 데모"라는 철학의 표현입니다.
튜토리얼의 RAG는 보통 "청크 나누고 임베딩하고 검색"에서 끝납니다. PrivateGPT는 문서를 계층 트리로 만들고, 검색 결과를 트리로 확장하고, 인용을 추출하는 프로덕션급 파이프라인을 보여줍니다. components/ingest/transformations/를 읽는 것만으로 "현업 RAG가 단순 청킹과 무엇이 다른가"를 배울 수 있습니다.
transformations/의 단계 이름들(markdown_to_tree, remove_header_and_footer, describe_image)을 나열하고, 각 단계가 "왜 검색 품질을 높이는지"를 한 줄씩 설명해 보세요.injector의 @singleton @inject 패턴은 Spring(자바)·NestJS(노드)의 DI와 같은 원리입니다. "Qdrant를 다른 벡터스토어로 바꾸기"가 왜 설정 한 줄인지를 components/vector_store/의 팩토리 패턴에서 직접 확인하세요. 프레임워크 없이 순수 파이썬으로 DI를 구현한 좋은 예제입니다.
VectorStoreComponent가 어떻게 settings.vectorstore.database 값을 읽어 팩토리를 고르는지 추적하고, "새 벡터스토어를 추가하려면 어디에 무엇을 더해야 하는가"를 정리해 보세요.server/chat/interceptors/는 "하나의 요청을 여러 단계가 순차 가공"하는 체인 패턴의 교본입니다. Express 미들웨어, Django 미들웨어, gRPC 인터셉터와 같은 사고방식이라 한 번 익히면 널리 전이됩니다.
citation)를 골라 입력·출력이 무엇인지 적고, "이 단계를 빼면 무엇이 깨지는가"를 추론해 보세요.PrivateGPT는 Anthropic API 스펙을 미러링합니다. server/와 events/를 보면 메시지·스트리밍·툴 사용을 어떻게 표준 스펙에 맞춰 설계하는지가 드러납니다. "남의 API와 호환되는 서버"를 만드는 일은 실무에서 자주 마주치는 과제입니다.
make api-docs로 OpenAPI 스펙을 뽑아, PrivateGPT가 노출하는 엔드포인트 목록을 정리하고 Claude API 문서와 형태를 비교해 보세요.대량 문서를 넣을 때 동기 처리로는 한계가 있습니다. PrivateGPT는 celery/에서 인제스천을 백그라운드 태스크로 분리합니다. 메시지 큐(RabbitMQ)·결과 백엔드·세마포어(Redis) 같은 분산 시스템 기본기를 구체적 맥락으로 익힐 수 있습니다.
settings-test.yaml의 celery.use_workers:false(동기 실행)와 운영 모드(비동기)의 차이를 비교하고, 워커를 켜고 끄는 트레이드오프를 적어 보세요.핵심 원칙: PrivateGPT 자체는 모델을 실행하지 않으므로 가볍습니다. 무거운 건 따로 띄우는 추론 서버(Ollama 등)이며, GPU·메모리 요구는 거기서 고른 모델이 결정합니다.
| 항목 | 요구사항 |
|---|---|
| Python | 3.11 고정 (3.12 이상 미지원) |
| PrivateGPT 본체 | 가벼움 — API 서버라 CPU·메모리 부담 적음 |
| 추론 서버(별도) | 예: Ollama로 중형 모델 구동 시 VRAM 16~24GB+(모델 크기 의존) |
| 임베딩 모델 | 소형(수백 MB~) — CPU로도 가능하나 GPU면 인제스천이 빠름 |
| 벡터스토어 | Qdrant — 로컬 임베디드 모드면 추가 서버 불필요 |
| OS | Linux·macOS·Windows. 운영은 Docker 권장 |
| 선택 의존성 | documents extras면 libreoffice·poppler, media면 ffmpeg, 웹스크래핑이면 chromium 등 자동 설치 |
PrivateGPT를 노트북에 깔아도, 뒤에 붙일 LLM이 24GB VRAM을 요구하면 결국 그 모델을 돌릴 머신이 필요합니다. "로컬에서 무료로 돈다"는 말의 실제 비용은 추론 인프라(GPU)에 있습니다. 가벼운 모델(예: 소형 양자화 모델)로 시작하고, 품질이 필요하면 추론 서버만 더 좋은 머신으로 옮기는 식으로 분리해 접근하세요.
Ollama로 소형 모델과 임베딩 모델을 띄운 뒤, OPENAI_API_BASE=http://localhost:11434/v1 private-gpt serve로 서버를 올립니다. 브라우저에서 localhost:8080/ui 워크벤치에 접속해 모델을 고르고 첫 메시지를 보내 보세요. "모델 실행과 앱이 분리된다"는 감각을 잡는 것이 목표입니다.
워크벤치에서 PDF 몇 개를 업로드해 인제스천한 뒤, 문서 내용을 묻고 답에 달린 인용(citation)이 실제 원문 위치를 가리키는지 확인합니다. 같은 질문을 문서 없이 물었을 때와 답이 어떻게 달라지는지 비교해 보세요.
settings.yaml의 주요 블록(retrieval.top_k, vectorstore, chat)을 바꿔 가며 검색 개수·동작이 어떻게 달라지는지 실험합니다. PGPT_PROFILES=mock으로 LLM 없이 임베딩만 테스트하는 모드도 띄워 보세요. 설정 한 줄이 동작을 바꾸는 '교체 가능 아키텍처'를 체감합니다.
Brave API 키를 넣어 웹 검색 툴을, 로컬 샌드박스로 코드 실행 툴을 활성화합니다. 그런 다음 "오늘 환율을 검색해 표로 정리해줘"처럼 여러 툴을 연쇄로 쓰는 요청을 보내, ChatLoopEngine의 에이전트 루프가 툴을 어떻게 호출하는지 로그로 관찰해 보세요.
PrivateGPT를 OpenAI/Anthropic 호환 프로바이더로 설정하고, Claude Code(또는 VS Code 확장·n8n)가 이 로컬 엔드포인트를 바라보게 연결합니다. 클라우드 API 없이 완전히 내 인프라 안에서 도는 에이전틱 코딩 환경을 구성하고, Docker로 묶어 재현 가능하게 만들어 보세요.
| 주차 | 주제 | 학습 내용 |
|---|---|---|
| 1주차 | 로컬 LLM + RAG 기초 | Ollama·vLLM로 추론 서버 띄우기, 임베딩·벡터스토어 개념, llama-index의 인덱싱·검색 흐름 |
| 2주차 | FastAPI + DI 설계 | FastAPI 라우터·의존성, injector로 @singleton 컴포넌트 배선, 설정(pydantic + yaml) 패턴 |
| 3주차 | 에이전트 · 툴 · 인터셉터 | 인터셉터 체인, ChatLoopEngine의 툴 호출 루프, MCP·Agent Skills, 코드 실행 샌드박스 |
| 4주차 | 프로덕션 · 분산 | Celery+RabbitMQ 분산 인제스천, Qdrant 운영, Docker 멀티스테이지 빌드, 관측성(Phoenix) |
처음부터 Celery·분산으로 가지 마세요. "추론 서버 + PrivateGPT 연결 → 내 문서로 RAG"가 손에 붙는 1주차가 가장 중요합니다. 이 구조가 보이면 나머지(DI·툴·분산)는 "이미 아는 RAG에 모듈을 더하는" 응용일 뿐입니다. 코드를 읽을 땐 launcher.py → server/chat/ → components/ 순으로 따라가면 전체 그림이 잡힙니다.
/v1/chat/completions·/v1/models 같은 OpenAI의 엔드포인트 규격을 그대로 따르는 서버. Ollama·vLLM·LM Studio가 모두 이 규격을 지원해, PrivateGPT는 주소(OPENAI_API_BASE)만 바꿔 어떤 추론 서버든 연결한다. "표준 콘센트" 역할.ChatLoopEngine이 이 루프를 돌려, 웹 검색·코드 실행·DB 질의 같은 툴을 필요한 만큼 연쇄로 사용한다.uv.lock으로 의존성을 고정하고 extras(선택 그룹)를 uv sync --extra ...로 골라 설치한다.공식 — 깃허브 zylon-ai/private-gpt · 문서 docs.privategpt.dev(Quickstart·providers·integrations·API reference) · 상용 플랫폼 zylon.ai
시작하기 — macOS는 brew install private-gpt, Linux/Windows는 uv tool install --python 3.11 "private-gpt[core]". 실행은 OPENAI_API_BASE=http://localhost:<port>/v1 private-gpt serve 후 localhost:8080/ui 접속. 별도 추론 서버(Ollama 등)가 먼저 떠 있어야 합니다.
함께 보면 좋은 것 — Ollama·vLLM(추론 서버), llama-index(RAG 프레임워크), Qdrant(벡터스토어), Anthropic Claude API 문서(호환 스펙의 원본). 통합 가이드의 Claude Code·Claude Desktop·OpenCode·n8n 연동 예제가 실전 출발점입니다.