TrendShift 딥다이브 · 2026-07-17 · Daily #6

HKUDS/DeepTutor 딥다이브
나를 기억하는 평생 개인화 AI 튜터

DeepTutor는 홍콩대 데이터지능연구실(HKUDS)이 만든 에이전트-네이티브(agent-native) 학습 워크스페이스다. 채팅·문제풀이·퀴즈생성·딥리서치·시각화·숙달연습(Mastery)이라는 여섯 가지 모드가 전부 하나의 에이전트 루프(agent loop) 위에서 돌고, 파일로 남는 3계층 메모리가 학습자를 기억해 개인화한다. 저장소 스스로의 소개는 "다중 에이전트 협업과 RAG를 갖춘 에이전트-네이티브 지능형 학습 동반자". 중요한 구분부터 — 논문 읽기 도우미로 알려진 상업용 deeptutor.ai와는 완전히 다른 프로젝트다. 이 문서가 다루는 건 오픈소스 자가호스팅(self-hosted) 플랫폼 HKUDS의 DeepTutor(deeptutor.info)다. LightRAG·AutoAgent를 만든 바로 그 연구실의 후속작이며, 이 문서는 저장소를 소스까지 클론해 "여기서 무엇을 배울 수 있는가"를 한국어로 정리한다. (저장소: HKUDS/DeepTutor · 라이선스 Apache-2.0 · v1.5.1 · 최신 커밋 3e3b9a6, 2026-07-09 · Python 백엔드 + Next.js 프론트 풀스택 · 한국어 README 없음 · TrendShift Daily #6 · #AI agent #RAG)
목차
  1. 프로젝트 한 줄 요약
  2. 왜 지금 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석 — 하나의 루프, 3계층 메모리
  5. 디렉토리 구조 해부
  6. 학습 포인트
  7. 시스템 · 실행 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한 줄 요약

정체부터 명확히 — 이건 챗봇 하나가 아니라 "나를 기억하는 학습 조교"를 통째로 셀프호스팅하는 플랫폼이다

DeepTutor공부와 관련된 여러 작업을 한 지붕 아래에서, 그것도 "나를 기억하는" 상태로 처리해 주는 자가호스팅 학습 플랫폼이다. 흔한 "질문하면 답하는 챗봇"과 다른 점이 둘 있다. 첫째, 채팅·문제풀이(Solve)·퀴즈생성(Quiz)·딥리서치(Research)·시각화(Visualize)·숙달연습(Mastery Path)이 각각 별도 앱이 아니라 같은 에이전트 루프 위의 서로 다른 "능력(capability)"으로 구현돼 있다. 둘째, 대화·노트·퀴즈·지식베이스에서 벌어진 일이 파일로 남는 3계층 메모리에 쌓여, 다음에 만났을 때 나를 기억하고 수준·취향에 맞춰 준다. 이름 그대로 "평생(lifelong) 개인화 튜터"를 지향한다.

가장 먼저 · 동명이인 주의
deeptutor.ai(상업용 논문 리더) ≠ HKUDS/DeepTutor(이 문서)

웹에 "DeepTutor"로 검색하면 PDF·논문 읽기를 돕는 상업용 스타트업 서비스(deeptutor.ai)가 먼저 나온다. 이 문서가 다루는 건 그게 아니라, 홍콩대 HKUDS가 공개한 오픈소스 자가호스팅 학습 플랫폼(deeptutor.info)이다. 같은 이름의 다른 프로젝트이니, 자료를 찾을 때 반드시 github.com/HKUDS/DeepTutor 저장소 기준으로 확인하자. (저장소 내부엔 과거 이름의 흔적도 남아 있다 — 프론트엔드 패키지명이 opentutor-web, 초기 챗봇 엔진이 "TutorBot"이었다가 "Partners"로 리브랜딩됨.)

핵심 용어
에이전트-네이티브(agent-native) · "기능을 붙인 챗봇"이 아니라 "에이전트가 곧 뼈대"
보통의 학습 앱은 "미리 짜 둔 화면·버튼"이 주인공이고 AI는 그 위에 얹은 부품이다. 에이전트-네이티브는 반대다 — 시스템의 중심에 "생각하고 도구를 골라 쓰는 에이전트 루프"가 있고, 채팅·퀴즈·리서치 같은 기능은 그 루프가 상황에 맞게 실행하는 시나리오일 뿐이다. DeepTutor에서 모든 모드가 하나의 ChatOrchestrator(대화 지휘자)를 거쳐 같은 루프로 처리되는 게 그 증거다. 덕분에 "채팅하다가 그대로 리서치로, 다시 퀴즈로" 문맥을 잃지 않고 이어진다.
핵심 용어
HKUDS · 이 저장소의 계보(LightRAG·AutoAgent를 만든 곳)
HKUDS는 홍콩대학교(HKU) Data Intelligence Lab로, RAG 분야에서 유명한 LightRAG(그래프 기반 경량 RAG), 자율 에이전트 프레임워크 AutoAgent, 연구 자동화 AI-Researcher 같은 화제작을 연달아 낸 그룹이다. DeepTutor는 그 연구실의 "학습" 도메인 후속작으로, 자기네가 만든 RAG·에이전트 기술을 교육이라는 실전 제품에 녹여낸 성격이 강하다. 리드 개발자는 Bingxi Zhao, 공식 사이트는 deeptutor.info다. (별점 수치는 시점마다 바뀌므로 이 문서에선 인용하지 않는다.)
한 문장 비유

"내 방에 들인 전속 조교 한 명 — 나를 기억하고, 필요하면 다른 전문가(서브에이전트)를 불러오고, 메모까지 파일로 남긴다"

DeepTutor는 "검색해서 답 주는 봇"이 아니라, 내 책상 옆에 상주하는 조교에 가깝다. 오늘 무엇을 헷갈렸는지 기억하고(3계층 메모리), 어려운 코딩 질문이 나오면 옆방의 전문가(로컬 Claude Code·Codex)를 불러와 상의하고(subagent), 자료가 필요하면 내 지식베이스를 뒤진다(RAG). 심지어 이 조교는 텔레그램·슬랙 같은 메신저로도 붙어("Partners") 늘 곁에 있을 수 있다.

그리고 이 조교의 특이점은 "머릿속을 열어 볼 수 있다"는 것이다. 나를 어떻게 기억하는지가 벡터 블랙박스가 아니라 읽을 수 있는 마크다운·로그 파일로 남아, "왜 나에 대해 이렇게 판단했는가"를 근거까지 되짚을 수 있다(§4-3).

2왜 지금 주목받는가

TrendShift Daily #6 · #AI agent #RAG — "에이전트·스킬 홍수 속에서, 완결된 자가호스팅 학습 '제품'으로 승부"

2026년 GitHub 트렌딩은 사실상 "에이전트 스킬 백화점"이다. Claude Code 스킬 팩, 코딩 CLI, MCP 서버가 끝없이 쏟아진다. 그 사이에서 DeepTutorDaily #6으로 올라온 이유는 결이 다르기 때문이다 — "부품(스킬 하나)"이 아니라, 여섯 가지 학습 모드를 한 몸에 담고 바로 띄워 쓰는 "완제품 플랫폼"이다. 게다가 그 완제품의 내부가 HKUDS의 RAG·에이전트 연구를 실전 배선한 결과라, "학습 앱"이자 동시에 "에이전트 아키텍처 교보재"로 읽힌다. README는 자체적으로 "111일 만에 별 2만 개 돌파"를 내세우는데, 수치의 진위와 무관하게 짧은 기간에 폭발적으로 트렌딩한 것은 분명하다(별점 수치 자체는 이 문서에서 인용하지 않는다).

포인트내용
정체HKUDS의 에이전트-네이티브 학습 플랫폼(자가호스팅). 채팅·Solve·Quiz·Research·Visualize·Mastery를 한 런타임에.
중심 차별점"한 루프, 모든 모드" + "검사 가능한 3계층 메모리". 개인화의 근거를 파일로 되짚는다.
RAG하나의 지식베이스를 LlamaIndex·PageIndex·GraphRAG·LightRAG·Obsidian 중 골라 바인딩. 재색인 중에도 기존 인덱스 보존(버전드 인덱스).
상호운용로컬 Claude Code·Codex를 대화 중 live로 호출(subagent), CLI를 --format json NDJSON 스트림으로 열어 다른 LLM이 DeepTutor를 도구로 운전.
배포Docker 한 방(단일 포트 3782). PocketBase·샌드박스 런너까지 docker-compose로. GPU 불필요(faiss-cpu).

주목 포인트 1 — "한 루프, 모든 모드": 문맥을 잃지 않는 설계

대부분의 학습 도구는 "요약 탭", "퀴즈 탭", "검색 탭"이 각자 논다. DeepTutor는 여섯 모드가 전부 같은 에이전트 루프의 '능력(capability)'이라, 채팅하다 딥리서치로, 다시 문제풀이로 넘어가도 같은 컨텍스트와 같은 기억을 공유한다. 사용자는 엔진을 바꾸는 게 아니라 목표만 바꾸고, 컨텍스트가 나를 따라다닌다.

주목 포인트 2 — "머릿속을 열 수 있는" 3계층 메모리

개인화를 내세우는 도구는 많지만, 대개 "숨은 벡터스토어"에 기록해 왜 그렇게 기억하는지 알 수 없다. DeepTutor의 메모리는 L1(원시 이벤트 로그) → L2(주제별 요약) → L3(교차 종합)파일 기반이고, L2가 L1을, L3가 L2를 인용한다. 즉 "너는 미적분을 어려워한다"는 판단의 근거를 원시 대화까지 역추적할 수 있다. NotebookLM류·일반 RAG 튜터와 결정적으로 갈리는 지점이다.

주목 포인트 3 — 에이전트가 "운전할 수 있는" 도구

DeepTutor는 사람만 쓰는 앱이 아니다. deeptutor run <능력> --format jsonNDJSON 이벤트 스트림을 뱉어, 다른 LLM/스크립트가 DeepTutor를 하나의 도구처럼 호출할 수 있다. 반대로 DeepTutor는 로컬 Claude Code·Codex를 대화 턴 중간에 불러 상의하고(subagent), MCP 클라이언트로 외부 도구도 붙인다. "에이전트가 에이전트를 부리는" 상호운용이 처음부터 설계에 들어 있다.

중요 · 오해 방지
라이브러리가 아니라 "앱" · 코드 실행 샌드박스는 기본이 subprocess

① 이건 import 해서 쓰는 라이브러리라기보다 띄워서 쓰는 애플리케이션이다(파이썬 SDK 파사드도 있지만 본체는 웹앱). ② 오피스 문서(docx/pdf/pptx/xlsx)를 다루는 스킬은 모델이 생성한 파이썬을 실제로 실행하는데, 기본 설정(sandbox_allow_subprocess)이 호스트에서 그대로 실행이다. 안전을 원하면 docker-compose 배포의 샌드박스 런너 사이드카로 격리하는 걸 권한다(§7). ③ 트렌딩 순위·지표는 시간마다 바뀐다.

3기술 스택 전체 지도

두 겹으로 읽어라 — ① 에이전트-네이티브 파이썬 백엔드, ② Next.js 16 프론트. 의존성 진실원은 pyproject.toml

DeepTutor의 스택은 파이썬 백엔드(코드량 최대) + Next.js/React 프론트의 풀스택이다. 실측하면 파이썬이 약 19만 줄(903개 .py), TypeScript/React가 약 9만 줄로 백엔드가 뼈대다. 한 가지 함정 — 루트 requirements.txt는 사실상 비어 있고(-r requirements/partners.txt 한 줄), 진짜 의존성 목록은 pyproject.toml에 있다. 이걸 모르면 스택 전체를 오판한다.

겉면 ① — 서버 · CLI (파이썬 3.11+)

요소내용
웹서버FastAPI ≥0.100 + Uvicorn[standard] + websockets ≥12 — 실시간 스트리밍은 WebSocket(/api/v1/ws) 기반.
CLITyper[all] + Rich + prompt_toolkit. 흥미로운 디테일: pyte(인메모리 터미널 에뮬레이터)로 로컬 Claude Code의 /model TUI를 스크래핑해 모델 목록을 읽는다.
LLM SDK네이티브 SDK 직결openai·anthropic·dashscope(Qwen)·perplexityai·oauth-cli-kit(Codex OAuth)·tiktoken. ※ 초기 베타에서 litellm을 제거하고 프로바이더별 네이티브로 전환했다.

겉면 ② — RAG · 문서처리 · 저장

요소내용
RAG 엔진(기본)llama-index ≥0.14 + llama-index-retrievers-bm25 + FAISS(faiss-cpu, 대형 KB용 ANN, 없으면 SimpleVectorStore로 폴백) + PyMuPDF.
선택 RAG 엔진extras로 갈아끼움 — [graphrag](Microsoft GraphRAG), [rag-lightrag](RAG-Anything→MinerU), 그리고 PageIndex·Obsidian 볼트 바인딩.
문서 파싱python-docx·openpyxl·python-pptx·pypdf·pdfplumber·reportlab·defusedxml + 선택 markitdown/docling/pymupdf4llm.
인증·저장bcrypt·python-jose(JWT)·pocketbase(선택, 단일유저 통합)·aiosqlite. 검색 기본값은 키가 필요 없는 ddgs(DuckDuckGo).

겉면 ③ — 프론트엔드 (web/, 패키지명 opentutor-web)

요소내용
프레임워크Next.js ^16 + React 19 + TypeScript 5 + TailwindCSS 3.4. App Router의 라우트 그룹으로 (workspace)/(utility)/(admin)/(auth) 분리.
시각화chart.js 4.5 + mermaid 11(다이어그램) + cytoscape(개념 그래프) + framer-motion 12. 수식은 rehype-katex+remark-math.
문서 프리뷰·i18ndocx-preview·exceljs·jspdf·html2canvas + i18next(다국어). 테스트는 Playwright.

겉면 ④ — 인프라 · 배포

요소내용
컨테이너Dockerfile(풀앱 단일 컨테이너) + Dockerfile.runner(하드닝된 코드실행 사이드카).
composedocker-compose.yml 3서비스 — pocketbase + deeptutor + sandbox-runner(코드실행 격리, 호스트 미노출). compose.yaml은 podman/rootless 변형.
네트워킹유일 노출 포트 3782(프론트). Next.js 미들웨어 web/proxy.ts/api/*·/ws/*를 백엔드 8001로 서버사이드 포워딩.
핵심 용어 · 왜 "33개 프로바이더"가 가능한가
OpenAI 호환 엔드포인트 · 하나의 추상화로 온갖 모델
DeepTutor는 프로바이더 레지스트리(services/provider_registry.py)로 약 33종의 모델 제공사를 추상화한다 — OpenAI·Anthropic·Gemini·DashScope(Qwen)·DeepSeek·Perplexity·OpenRouter 같은 클라우드부터, Ollama·vLLM·LM Studio·llama.cpp·NVIDIA NIM 같은 로컬 서버까지. 비결은 이들 대부분이 "OpenAI와 같은 API 형식"을 지원하기 때문이다. 코드가 바꾸는 건 base_url·키·모델명뿐이라, "클라우드로 시작해 나중에 내 GPU의 로컬 모델로 이사"가 설정 한 줄로 가능하다. 벤더 종속을 피하는 실전 패턴의 살아있는 예다.
한눈에 — "학원 하나를 통째로 컨테이너에 담았다"

스택이 넓어 보여도 구조는 단순하다. 프론트(Next.js)는 "교실", 백엔드(FastAPI+에이전트)는 "조교실", PocketBase는 "출석부·사물함", 샌드박스 런너는 "위험한 실험을 격리한 실습실"이다. 이 네 칸이 docker-compose 한 파일로 묶여 있어, 명령 한 줄이면 "학원 하나"가 통째로 뜬다. 무거운 GPU 없이(faiss-cpu) 노트북에서도 돌아가고, 모델은 클라우드 키 하나만 꽂으면 된다.

4아키텍처 심화 분석 — 하나의 루프, 3계층 메모리

핵심은 "2계층 플러그인(도구/능력) + 3진입점 + 라벨 기반 루프", 그리고 그 위에 얹힌 파일 기반 메모리

4-1. 전체 배선도 — 진입점 셋이 한 지휘자로 모인다

DeepTutor의 골격은 의외로 단정하다. CLI든 웹소켓이든 파이썬 SDK든, 모든 입력은 하나의 ChatOrchestrator(대화 지휘자)로 모인다. 지휘자는 UnifiedContext(통합 컨텍스트)를 조립하고 어떤 "능력(capability)"을 쓸지 고른 뒤(기본값 chat), 그 아래 라벨 기반 에이전트 루프를 돌린다. 루프가 도구를 쓸지, 파이프라인을 더 진행할지, 끝낼지를 매 라운드 결정한다.

진입점: CLI (Typer) │ WebSocket /api/v1/ws │ Python SDK (app/facade.py) \ │ / v v v ┌──────────────────────────────────────────────────────────┐ │ ChatOrchestrator (runtime/orchestrator.py) │ │ UnifiedContext(core/context.py) 조립 → 능력(capability) │ │ 선택 (기본값 = chat) │ └──────────┬──────────────────────────────┬────────────────┘ │ │ ┌────────v────────┐ ┌──────────v───────────┐ │ ToolRegistry │ │ CapabilityRegistry │ │ = Level 1 도구 │ │ = Level 2 파이프라인 │ │ (즉석 단발 도구)│ │ (턴을 통째로 점유) │ └────────┬────────┘ └──────────┬───────────┘ └──────────────┬───────────────┘ v core/agentic/loop.py ← 라벨 기반 반복 스케줄러 (THINK / TOOL / FINISH / REPLAN / PAUSE ...) │ 모든 이벤트 → StreamBus로 fan-out v tool_dispatch.py (도구 병렬 실행) │ ┌─────────────────────────┴─────────────────────────┐ v v v 3계층 메모리 멀티엔진 RAG subagent / MCP (services/memory) (services/rag) (Claude Code · Codex)
핵심 용어 · DeepTutor의 심장
2계층 플러그인 — Level 1 "도구" vs Level 2 "능력"
DeepTutor는 확장 지점을 두 층으로 나눈다. Level 1 도구(Tool)는 LLM이 대화 중 즉석에서 골라 쓰는 단발 기능이다 — 사용자가 토글하는 web_search·paper_search·reason·brainstorm, 상황에 따라 열리는 rag·read_memory·write_memory·exec(코드실행)·consult_subagent 등. 반면 Level 2 능력(Capability)턴을 통째로 점유하는 다단계 파이프라인이다 — 예컨대 deep_research는 "질문 재구성 → 분해 → 조사 → 보고"의 여러 단계를 밟는다. 요약하면 도구 = 한 번의 손동작, 능력 = 여러 단계를 밟는 시나리오. 이 분리 덕에 새 기능을 "가벼운 도구"로도, "무거운 파이프라인"으로도 꽂을 수 있다.

Level 2 능력(capability) 파이프라인 예시 (deeptutor/capabilities/)

능력단계 흐름
chatexploring → responding (기본 대화)
deep_solveplanning → reasoning → writing (문제풀이)
deep_questionideation → generation (퀴즈 생성)
deep_researchrephrasing → decomposing → researching → reporting
visualizeanalyzing → generating → reviewing (차트·도식)
math_animatorconcept_analysis → design → code_gen → retry → render (Manim 영상)
mastery_path주제 유형별 "숙달 게이트"를 통과해야 다음으로

4-2. 라벨 기반 에이전트 루프 — "다음 줄의 라벨"이 곧 명령

DeepTutor의 루프(core/agentic/loop.py)는 영리하다. 모델이 매 라운드 응답의 첫 줄에 라벨을 방출하게 하고(예: THINK, TOOL, FINISH, REPLAN, PAUSE), 스케줄러는 그 라벨만 보고 다음 행동을 정한다. 종료 라벨이 뜨면 루프를 끝낸다. 핵심은 이 루프가 특정 능력에 종속되지 않게(capability-agnostic) 설계됐다는 점 — 능력별 구체 로직은 LoopHost라는 프로토콜에 위임한다. 덕분에 "채팅"이든 "딥리서치"든 같은 루프 엔진을 공유한다.

한 라운드의 흐름 (라벨 기반) 모델 응답 첫 줄 라벨을 읽는다 │ ├─ THINK → 생각만. 컨텍스트에 남기고 다음 라운드로 ├─ TOOL → tool_dispatch로 도구 실행(병렬 가능) → 결과를 되먹임 ├─ REPLAN → 지금까지를 요약하고 계획을 다시 세움 ├─ PAUSE → ask_user 등으로 사용자 입력 대기(헤드리스면 자동 해소) └─ FINISH → 종료 라벨. 최종 응답을 확정하고 루프 탈출 │ └────────► (종료 라벨이 아니면) 다음 라운드로 반복
핵심 용어
StreamBus · "모든 이벤트를 실시간 중계"
루프가 도는 동안 생기는 모든 사건(생각·도구 시작/끝·부분 응답)은 StreamBus라는 이벤트 버스로 여러 구독자에게 동시에 뿌려진다(fan-out). 그래서 웹 UI는 토큰이 생성되는 즉시 스트리밍으로 보여줄 수 있고, CLI는 같은 이벤트를 --format jsonNDJSON(줄 단위 JSON) 스트림으로 내보내 다른 프로그램이 파싱하게 한다. "한 번 실행에 여러 관객"을 가능케 하는 배관이다.

4-3. "머릿속을 열 수 있는" 3계층 메모리 — DeepTutor의 정체성

이 프로젝트의 가장 큰 차별점. 개인화 기억을 벡터 블랙박스가 아니라 사람이 읽을 수 있는 파일로 남긴다(deeptutor/services/memory/). 세 층으로 승격하며, 위 층이 아래 층을 인용해 모든 개인화 주장을 근거까지 역추적할 수 있다.

3계층 메모리 (파일 기반 · 위로 갈수록 압축·종합) ┌─ L3 ─────────────────────────────────────────────┐ │ L3/{profile | recent | scope | preferences}.md │ 교차 표면 종합 │ "이 학습자는 누구인가"의 전체 그림 │ (모든 surface 통합) └───────────────▲───────────────────────────────────┘ │ 인용(cite) ┌─ L2 ─────────┴───────────────────────────────────┐ │ L2/<surface>.md (표면별 큐레이션된 팩트) │ 주제/표면별 요약 │ 예: L2/chat.md, L2/quiz.md, L2/kb.md ... │ └───────────────▲───────────────────────────────────┘ │ 인용(cite) ┌─ L1 ─────────┴───────────────────────────────────┐ │ trace/<surface>/<날짜>.jsonl (append-only 원시로그)│ 원시 이벤트 │ 실제 벌어진 대화·행동을 그대로 적재 │ (지우지 않고 쌓음) └───────────────────────────────────────────────────┘ 추적 표면(surface): chat · notebook · quiz · kb · book · partner · cowriter consolidator 가 Update/Audit/Dedup 예산으로 L1→L2→L3 승격·중복제거
비유 — "일기(L1) → 주간 정리(L2) → 자기소개서(L3)"

L1은 매일 쓰는 날것의 일기다(지우지 않고 계속 쌓음). L2는 그 일기를 주제별로 간추린 정리 노트고("이 사람은 채팅에서 이런 걸 자주 물었다"), L3는 그 정리들을 모아 만든 한 장의 자기소개서다("이 학습자의 목표·수준·취향은 이렇다"). 핵심은 자기소개서(L3)의 한 문장이 어느 정리 노트(L2)에서, 그게 다시 어느 날 일기(L1)에서 왔는지 발자국을 따라갈 수 있다는 것. "왜 나를 이렇게 파악했지?"에 근거로 답할 수 있는 기억이다.

여기에 consolidator(정리자)가 붙어, 무한정 커지지 않도록 "갱신·감사·중복제거" 예산 안에서 사실을 승격·병합한다. 또 하나 영리한 격리 — 메신저 동반자 Partners는 주인의 메모리를 읽되 자기 것만 쓴다(경로 오버라이드). 그래서 여러 채널이 같은 사람을 공유하되 서로의 기억을 오염시키지 않는다.

4-4. 멀티엔진 RAG — 지식베이스는 하나, 검색 엔진은 교체식

DeepTutor는 지식베이스(KB) 하나를 여러 RAG 엔진 중 하나에 바인딩한다 — 기본 LlamaIndex, 그리고 PageIndex·GraphRAG·LightRAG·LightRAG Server·Obsidian 볼트. 공통 인터페이스(pipelines/base.py) 뒤에서 엔진을 lazy-import로 갈아끼우므로, 무거운 GraphRAG를 안 쓰면 아예 로드하지 않는다. 재색인할 때도 version-N 형태의 버전드 인덱스로 기존 인덱스를 보존해, 색인 도중에도 검색이 멈추지 않는다.

기본 파이프라인의 검색은 하이브리드다 — 밀집(벡터) + 희소(BM25)를 LlamaIndex의 QueryFusionRetriever로 융합하고, SmartRetriever가 쿼리 변형 3개를 만들어 병렬로 검색·집계한다. 대형 KB는 FAISS로 가속하되, 없으면 조용히 단순 벡터스토어로 폴백한다.

한눈 정리 · 아키텍처가 주는 4가지 골격
한 지휘자 · 2계층 플러그인 · 라벨 루프 · 열어볼 수 있는 기억

ChatOrchestrator 단일 관문 — 모든 진입점(CLI/WS/SDK)이 한 지휘자로 모여 컨텍스트를 잃지 않는다. ② 도구(Level 1) / 능력(Level 2)의 2계층 — 가벼운 단발 기능과 무거운 파이프라인을 분리해 확장. ③ 라벨 기반 루프 — 능력에 종속되지 않는 루프 엔진 + StreamBus로 실시간 중계. ④ 파일 기반 3계층 메모리 — 인용으로 근거를 되짚는 개인화. 이 네 골격은 "학습 앱"을 넘어 어떤 에이전트 제품에도 이식 가능한 설계 교본이다.

5디렉토리 구조 해부

"어느 폴더가 무엇을 담는가" — 백엔드 deeptutor/가 핵심, 그중 services/가 가장 크다

저장소를 열면 크게 백엔드 파이썬 패키지 deeptutor/, CLI deeptutor_cli/, 프론트 web/ 세 덩어리가 보인다. 코드의 심장은 deeptutor/이고, 그 안에서도 services/(RAG·메모리·LLM·MCP·샌드박스·Partners…)가 압도적으로 크다. 총 파일 약 1,667개.

DeepTutor/ ├── deeptutor/ ← 백엔드 파이썬 패키지 (핵심) │ ├── core/ agentic/(loop·labeled_step·tool_dispatch), context, stream_bus │ ├── agents/ chat · research · question · visualize · math_animator · notebook │ ├── capabilities/ solve · mastery · obsidian · subagent + registry (Level 2) │ ├── tools/ rag · web_search · reason · exec · github · ask_user … (Level 1 구현) │ ├── services/ ★가장 큼 rag/(5개 엔진) · memory/(3계층+consolidator) · llm/(33 provider) │ │ embedding · search · mcp · sandbox · skill · persona · partners · voice │ ├── runtime/ orchestrator.py(ChatOrchestrator) · launcher · registry/(tool·capability) │ ├── api/ main.py(FastAPI) · routers/(chat·knowledge·partners·memory·ws 30+) │ ├── book/ "리빙북" 엔진 (blocks · agents · prompts) │ ├── co_writer/ 선택 인식 마크다운 편집기 │ ├── app/facade.py Python SDK 파사드 (DeepTutorApp) │ └── __version__.py "1.5.1" ← 단일 버전 진실원 ├── deeptutor_cli/ Typer CLI (main · chat · kb · skill · init_wizard …) ├── deeptutor_web/ 릴리스 시 Next.js standalone 빌드가 담기는 자리(소스엔 __init__.py만) ├── web/ 프론트엔드 소스 (Next.js App Router: (workspace)/(utility)/(admin)/(auth)) ├── packaging/deeptutor-cli/ CLI 전용 배포 프로젝트 (소스 설치) ├── tests/ scripts/ requirements/ assets/ ├── Dockerfile · Dockerfile.runner · docker-compose*.yml · compose.yaml ├── pyproject.toml ★의존성 단일 진실원 SKILL.md · AGENTS.md · CONTAINERIZATION.md · LICENSE
위치무엇을 담나
deeptutor/services/가장 큰 심장부. RAG 5개 엔진, 3계층 메모리+정리자, 33개 LLM 프로바이더, MCP·샌드박스·Partners·음성·이미지/영상 생성까지.
deeptutor/core/agentic/라벨 기반 루프(loop.py), 라벨 스텝, 도구 병렬 디스패치. §4의 "심장" 코드.
deeptutor/capabilities/Level 2 능력 파이프라인 + 레지스트리. Solve·Mastery·Obsidian·Subagent 등.
deeptutor/api/routers/FastAPI 라우터 30여 개 — chat·knowledge·partners·memory·통합 WebSocket 등.
web/Next.js 16 프론트. 라우트 그룹으로 워크스페이스/유틸/관리자/인증 분리.
주의 · "빈 폴더"에 속지 말 것
deeptutor_web/ 와 tools/builtin/ 은 비어 보여도 정상

deeptutor_web/는 소스 체크아웃에선 __init__.py만 있는 빈 껍데기다 — Next.js standalone 빌드는 릴리스 시 채워지고, 소스로 돌릴 땐 web/를 dev 모드로 띄운다. "프론트가 없다"고 오판 금지. ② 실제 도구 구현은 deeptutor/tools/*.py에 있고 tools/builtin/은 등록부/래퍼다. ③ 의존성은 루트 requirements.txt가 아니라 pyproject.toml에 있다(§3). 이 세 가지가 저장소를 처음 볼 때 가장 헷갈리는 지점이다.

6학습 포인트

"학습 앱"을 넘어 — 이 저장소에서 실제로 훔쳐 배울 6가지 설계

배울 것 1 — 라벨 기반 에이전트 루프 설계

가장 값진 학습. core/agentic/loop.py모델이 방출한 라벨(THINK/TOOL/FINISH…)로 제어 흐름을 정하는 깔끔한 루프다. 특정 기능에 종속되지 않게(LoopHost 위임) 만들어, 채팅·리서치·문제풀이가 같은 엔진을 공유한다. "에이전트 루프를 어떻게 능력-불가지론적으로 추상화하는가"의 실전 답안이다.

배울 것 2 — 투명한 파일 기반 메모리

벡터 블랙박스 대신 L1/L2/L3 마크다운+JSONL로 개인화를 구현하고, 위 층이 아래 층을 인용해 감사 가능하게 만든 아키텍처(services/memory/). "AI가 나를 왜 이렇게 기억하는가"를 설명할 수 있어야 하는 모든 제품에 이식할 가치가 있다. consolidator의 예산 기반 승격·중복제거도 좋은 참고.

배울 것 3 — 멀티엔진 RAG 추상화

같은 인터페이스(pipelines/base.py) 뒤에 LlamaIndex·GraphRAG·LightRAG·PageIndex를 lazy-import로 갈아끼우고, version-N 버전드 인덱스로 무중단 재색인. "엔진 교체 가능한 RAG"를 어떻게 배선하는지 그대로 보여준다. 하이브리드 검색(QueryFusionRetriever)과 FAISS 폴백 전략도 함께.

배울 것 4 — 에이전트 상호운용(interop)

CLI를 NDJSON 스트림으로 열어 다른 LLM이 운전하게 하고, MCP 클라이언트로 외부 도구를 붙이고, 로컬 Claude Code·Codex를 대화 중 live로 호출(consult_subagent)한다. "에이전트가 에이전트를 부리는" 상호운용 설계의 교본.

배울 것 5 — 스키마 기반 멀티채널(IM) 레이어

Partners는 텔레그램·슬랙·디스코드·Feishu·Teams·Matrix 등 15개 이상 메신저를 공통 파이프라인으로 추상화한다(partners/channels/). "여러 플랫폼에 같은 봇을 붙이되 코드 중복 없이" 하는 법을 배울 수 있다. 별도 봇 엔진이 아니라 같은 ChatOrchestrator 턴으로 처리한다는 점이 특히 영리하다.

배울 것 6 — 배포 다형성(deployment polymorphism)

로컬 subprocess 샌드박스 vs docker-compose 런너 사이드카, rootless podman, 단일 포트 리버스 프록시(web/proxy.ts)까지 — CONTAINERIZATION.md"같은 앱을 환경별로 다르게 배포"하는 실전 패턴이 정리돼 있다. 패키징도 deeptutor(풀앱)/deeptutor-cli(CLI만)로 이원화하고 무거운 엔진은 extras로 opt-in한다.

한 줄 정리 · 이 저장소의 학습 가치
"학습 앱"이라 쓰고 "에이전트 아키텍처 교본"이라 읽는다

DeepTutor에서 가져갈 것은 "튜터링 기능"이 아니라 에이전트 제품을 실제로 굴리는 골격이다 — 라벨 기반 루프, 열어볼 수 있는 3계층 메모리, 교체식 RAG, NDJSON·MCP·subagent 상호운용, 멀티채널 추상화, 배포 다형성. 이 골격은 도메인이 교육이 아니어도(고객지원·연구·업무비서 무엇이든) 그대로 재사용된다. 한국어 자료가 없다는 장벽만 이 문서로 넘으면, 가성비 높은 실전 레퍼런스다.

7시스템 · 실행 요구사항

"노트북 + 모델 이용권" 정도면 충분 — GPU는 필수 아님(faiss-cpu), 대신 코드실행 격리엔 신경 쓸 것

DeepTutor는 무거운 하드웨어를 강요하지 않는다. 핵심 의존성에 torch·CUDA·tensorflow가 전혀 없고, 벡터스토어는 faiss-cpu다. 대부분은 노트북에서 파이썬과 LLM 키 하나로 돌아간다.

항목요구/방법
런타임Python ≥3.11(3.11~3.14 타깃). Node.js — PyPI 설치는 20+, 소스/Docker는 22 LTS 권장(Next.js standalone 서버 spawn용).
GPU불필요. 코어·서버는 CPU로 충분(faiss-cpu). 단, 선택 엔진 [rag-lightrag]의 MinerU 문서파싱이나 로컬 임베딩/LLM은 별도 서비스로 돌리며 GPU 이점이 있다.
API 키최소 LLM 프로바이더 1개 — OpenAI·Anthropic·Gemini·DashScope·DeepSeek·Perplexity·OpenRouter 등 33종 중 택1, 또는 Ollama·vLLM·LM Studio·llama.cpp·NVIDIA NIM 로컬. 웹검색은 기본 ddgs(DuckDuckGo, 키 불필요).
선택 서비스PocketBase(단일유저 통합 시). 코드실행 스킬엔 샌드박스(기본 subprocess 또는 compose 런너). math_animator는 시스템 LaTeX·ffmpeg·cairo·pkg-config·cmake 필요.
설정 위치루트 .env아니라 data/user/settings/*.json(JSON/YAML). 포트 기본값 백엔드 8001 / 프론트 3782.
가장 쉬운 시작docker-compose up — PocketBase+앱+샌드박스 런너가 함께 뜨고 localhost:3782로 접속. 코드실행이 자동 격리돼 가장 안전한 경로.
한눈 요약 — "학원 개원 준비물은 가볍다"

값비싼 GPU 서버를 살 필요 없다. 컴퓨터 한 대 + 모델 이용권(API 키) 하나면 "학원(DeepTutor)"이 문을 연다. 가장 편한 개원 방법은 docker-compose up — 교실·조교실·사물함·격리실습실이 한꺼번에 켜진다. 단 하나 신경 쓸 것은 "실습실 격리": 문서 스킬이 AI가 짠 코드를 실제로 돌리므로, compose의 샌드박스 런너로 격리하는 배포를 권한다(직접 실행은 편하지만 호스트에서 코드가 도는 위험이 있다).

8직접 해볼 수 있는 실습 과제

난이도별 — "띄우기 → KB 만들기 → 메모리 열어보기 → RAG 엔진 갈아끼우기 → CLI로 운전하기"

가장 안전하고 빠른 시작은 Docker다.

# 저장소 클론 후 docker-compose로 한 번에 (PocketBase+앱+샌드박스 런너)
git clone --depth 1 https://github.com/HKUDS/DeepTutor.git
cd DeepTutor
docker compose up          # localhost:3782 접속
# 설정 화면에서 LLM 프로바이더 키 1개 입력 (예: OpenAI / OpenRouter / Ollama)
실습 1 · 난이도 ★☆☆☆☆

띄우고 여섯 모드 한 바퀴 — 제품 감 잡기

docker compose up으로 띄운 뒤, 채팅 → 문제풀이(Solve) → 퀴즈(Quiz) → 딥리서치 → 시각화 → 숙달연습을 각각 한 번씩 돌려 본다. 같은 대화 문맥이 모드를 넘나들며 유지되는지 관찰 — §4-1의 "한 지휘자, 여러 능력"을 눈으로 확인하는 단계다.

실습 2 · 난이도 ★★☆☆☆

내 자료로 지식베이스(KB) 만들고 RAG 질문 — 멀티엔진 체험

PDF·마크다운 몇 개를 올려 KB를 만들고 질문해 본다. 답변이 어느 문서의 어느 대목을 근거로 삼는지 확인한다. 기본 LlamaIndex 하이브리드(벡터+BM25) 검색이 어떻게 출처를 붙이는지 관찰하는 게 목표.

실습 3 · 난이도 ★★★☆☆

메모리 파일 열어보기 — L1/L2/L3 역추적

몇 차례 대화·퀴즈를 한 뒤 data/ 아래 메모리 폴더를 연다. L1의 원시 로그(trace/<surface>/<날짜>.jsonl), L2의 표면별 요약(L2/<surface>.md), L3의 종합(L3/profile.md)을 나란히 보며 "AI가 나를 어떻게 기억하는지"와 그 근거 인용을 직접 추적한다. DeepTutor의 정체성을 체감하는 실습.

실습 4 · 난이도 ★★★★☆

RAG 엔진 갈아끼우기 — LlamaIndex → LightRAG / GraphRAG

같은 KB를 다른 엔진에 바인딩해 본다([rag-lightrag] 또는 [graphrag] extras 설치). 같은 질문에 대해 벡터 검색 vs 그래프 기반 검색의 답이 어떻게 달라지는지 비교. 공통 인터페이스 뒤에서 엔진이 교체되는 lazy-import 설계(§4-4)를 코드로 확인한다.

실습 5 · 난이도 ★★★★★

CLI를 NDJSON으로 "운전"하거나 Partner 채널 붙이기 — 상호운용의 끝

deeptutor run <능력> --format json으로 NDJSON 이벤트 스트림을 다른 스크립트에서 파싱해, DeepTutor를 하나의 도구처럼 호출하는 파이프라인을 짜 본다. 여유가 되면 [partners] extras로 텔레그램/슬랙 봇 채널을 붙여, 같은 에이전트를 메신저에서 부려 본다. "에이전트를 도구로 쓰는" 최고 난도의 학습.

9관련 기술 심화 학습 로드맵

DeepTutor를 교보재 삼아 "에이전트 제품 엔지니어"를 목표로 한 6주 커리큘럼
주차주제 · 목표 (대응 코드)
1주차에이전트 루프 기본기. 라벨 기반 제어 흐름(core/agentic/loop.py), tool_dispatch 병렬 실행, StreamBus. 목표: "능력에 종속되지 않는 루프"의 개념을 손에.
2주차도구/능력 2계층 설계. Level 1 도구 vs Level 2 파이프라인(tools/ · capabilities/registry.py). 새 도구 하나를 직접 등록해 보기.
3주차RAG 엔진 아키텍처. 하이브리드 검색(QueryFusionRetriever), SmartRetriever 쿼리 확장, FAISS, 버전드 인덱스. 엔진 교체식 RAG를 밑바닥부터 이해.
4주차메모리 시스템. 3계층(L1/L2/L3) 승격·인용, consolidator 예산, Partner 격리. "설명 가능한 개인화"를 설계하는 법.
5주차상호운용. MCP 클라이언트, subagent(Claude Code/Codex live 호출), CLI의 NDJSON 스트림. 에이전트를 도구로 노출·소비하는 양방향 설계.
6주차멀티채널 · 배포. Partners의 IM 채널 추상화(partners/channels/), CONTAINERIZATION.md의 배포 다형성, 샌드박스 격리. 에이전트를 "제품"으로 굳히기.
병행 학습 팁
"DeepTutor 소스 + HKUDS 형제 프로젝트 + 표준 문서"를 함께
DeepTutor의 RAG를 파고들 땐 같은 연구실의 LightRAG를, 에이전트 루프를 볼 땐 AutoAgent를 곁들이면 "이 팀의 설계 취향"이 보인다. 상호운용 파트에선 Model Context Protocol 공식 문서로 "DeepTutor의 손구현 ↔ 업계 표준"을 잇는다. 또 §인덱스의 다른 에이전트·RAG 딥다이브(cat-agents · cat-data-rag · cat-llm-infra)와 "같은 문제를 어떻게 다르게 풀었나"를 비교하면 학습이 배가된다.

10핵심 키워드 사전

DeepTutor 소스에서 반복되는 용어 빠른 참조
용어
에이전트-네이티브(agent-native)기능을 얹은 챗봇이 아니라, "생각하고 도구를 고르는 에이전트 루프"가 시스템의 중심 뼈대인 설계. 모든 모드가 그 루프의 시나리오.
ChatOrchestrator모든 진입점(CLI/WebSocket/SDK)이 모이는 단일 지휘자. 컨텍스트를 조립하고 어떤 능력을 쓸지 정한다(runtime/orchestrator.py).
Level 1 도구 / Level 2 능력도구=대화 중 즉석에 쓰는 단발 기능(rag·web_search·exec…), 능력=턴을 통째로 점유하는 다단계 파이프라인(deep_research·mastery_path…).
라벨 기반 루프모델이 응답 첫 줄에 라벨(THINK/TOOL/FINISH/REPLAN/PAUSE)을 방출하면, 스케줄러가 그 라벨로 다음 행동을 정하는 제어 방식.
3계층 메모리(L1/L2/L3)L1=원시 이벤트 로그(jsonl), L2=표면별 요약(md), L3=교차 종합(md). 위 층이 아래 층을 인용해 개인화 근거를 역추적.
표면(surface)기억이 추적되는 활동 영역 — chat·notebook·quiz·kb·book·partner·cowriter. 표면별로 L1/L2가 나뉜다.
consolidator메모리가 무한정 커지지 않게 "갱신·감사·중복제거" 예산 안에서 사실을 L1→L2→L3로 승격·병합하는 정리자.
멀티엔진 RAG지식베이스 하나를 LlamaIndex·PageIndex·GraphRAG·LightRAG·Obsidian 중 골라 바인딩. lazy-import로 교체, 버전드 인덱스로 무중단 재색인.
QueryFusionRetriever / 하이브리드밀집(벡터)+희소(BM25) 검색을 융합하는 LlamaIndex 리트리버. SmartRetriever가 쿼리 변형 3개로 병렬 검색.
Partners텔레그램·슬랙 등 15+ 메신저에 붙는 영속 동반자. 별도 봇 엔진이 아니라 같은 ChatOrchestrator 턴으로 처리, 주인 메모리는 읽되 자기 것만 씀.
subagent로컬 Claude Code·Codex를 대화 턴 중간에 live로 불러 상의하는 도구(consult_subagent). "에이전트가 에이전트를 부린다".
EduHub / Agent-SkillsDeepTutor의 스킬 포맷(SKILL.md)과 허브. 보안 게이트(zip-slip/bomb 방어)를 통과해야 설치. ClawHub 호환.
샌드박스 런너모델이 생성한 코드를 격리 실행하는 사이드카(Dockerfile.runner). 호스트에 노출되지 않음. 안전 배포의 핵심.

11참고 링크

공식 소스 우선 — 버전·수치는 클론한 소스(v1.5.1, 커밋 3e3b9a6, 2026-07-09) 기준

공식
· GitHub 저장소: github.com/HKUDS/DeepTutor (Apache-2.0 · v1.5.1)
· 공식 사이트/문서: deeptutor.info (CLI Agent Handoff 문서 포함)
· TrendShift 카드: trendshift.io/repositories/17099 (Daily #6 · #AI agent · #RAG)
· 스킬 허브: EduHub · 커뮤니티 Discord

저장소 안에서 먼저 열 곳
· AGENTS.md — 아키텍처 요약(능력·도구 표)의 단일 진실원
· deeptutor/core/agentic/loop.py — 라벨 기반 에이전트 루프(§4-2)
· deeptutor/services/memory/ — 3계층 메모리 + consolidator(§4-3)
· deeptutor/services/rag/pipelines/ — 멀티엔진 RAG + 하이브리드 검색(§4-4)
· SKILL.md · deeptutor_cli/main.py — CLI 표면과 에이전트 핸드오프
· pyproject.toml — 의존성 단일 진실원 / CONTAINERIZATION.md — 배포 다형성

곁들여 학습(형제·표준)
· HKUDS LightRAG · AutoAgent — 같은 연구실의 RAG·에이전트 원류
· MCP 공식: modelcontextprotocol.io — 상호운용 파트의 표준
· §인덱스의 다른 에이전트·RAG 딥다이브와 비교(cat-agents · cat-data-rag · cat-llm-infra)

참고 · 소스 정독으로 확인한 주의점
동명이인 · 빈 껍데기 · 미검증 링크 등 7가지 함정

동명이인 — 상업용 deeptutor.ai(논문 리더)와 혼동 금지. 이 문서는 HKUDS의 deeptutor.info. ② 프론트 web/package.json의 이름(opentutor-web)·버전(1.0.0)은 레거시 값 — 진짜 버전은 deeptutor/__version__.py1.5.1. ③ README·CITATION의 arXiv:2604.26962는 미래형 ID(외부 검증 불가) — "저자 주장 링크"로만 취급. ④ 의존성 진실원은 pyproject.toml, 루트 requirements.txt는 사실상 비어 있음. ⑤ deeptutor_web/·tools/builtin/은 비어 보여도 정상(§5). ⑥ 코드실행 샌드박스 기본값이 subprocess(호스트 실행) — 안전엔 compose 런너 격리 권장. ⑦ 한국어 README 없음(번역 11종에 미포함) — 이 문서가 사실상 첫 한국어 정리. 트렌딩 순위·지표는 계속 바뀐다.