텔레그램으로 던진 링크/문서/키워드를 스크랩 → Gemini로 구조화 → 팔란티어식 타입 온톨로지 그래프로 적재하고, 새 자료를 기존에 쌓인 그래프와 연결하며, 나중에 키워드로 검색 → LLM 정리해 보여주는 개인용 지식베이스.
v1 파이프라인 완성 + 개인용 컨테이너 운영 구조. 단일 사용자 전용이며 멀티테넌시는 범위 밖이다(GOALS.md 참조). 자동복구·헬스·circuit breaker·능동 알림을 제공한다.
문서 목록과 온톨로지 그래프를 함께 보며 전체 지식 구조를 탐색한다.
키워드로 노드를 찾고 관찰·출처 문서·연결 관계를 한 화면에서 확인한다.
그래프의 출처 문서를 요약과 본문으로 크게 읽고 글자 크기를 조절한다.
두 노드 사이의 관계 경로를 계산해 그래프와 단계별 결과로 표시한다.
URL이나 메모 텍스트를 붙여 넣어 새 자료와 관련 링크를 지식 그래프에 적재한다.
여러 노드를 종합 목록에 모아 공통 맥락을 분석할 준비를 한다.
uv sync # 의존성 설치
cp .env.example .env # 로컬 개발 설정 준비(기본 provider는 mock)
uv run claire doctor # 환경/벡터백엔드/임베딩 점검
uv run claire health # 시스템 건강 상태(JSON): DB·schema·큐·inbox
uv run claire ingest "https://example.com/article" # 단건 적재
uv run claire search "키워드" # 하이브리드 검색 + LLM 정리
uv run claire bot # 텔레그램 봇 (long-polling)uv run claire ...는 현재 checkout과 가상환경을 사용하는 로컬 개발·테스트 경로다.
배포된 컨테이너의 데이터를 조회하거나 변경할 때는 이 경로와 섞지 않고
./cb-manuscript app ...을 사용한다.
claire는 컨테이너 내부 프로세스와 로컬 개발이 공유하는 애플리케이션 진입점이다.
로컬 checkout에서는 uv run claire ...로, 배포 환경의 one-off 작업은 호스트에서
./cb-manuscript app ...으로 실행한다.
| 명령 | 설명 |
|---|---|
doctor / health / status / stats |
환경 점검 / 건강 JSON / 현황 / 그래프 카운트 |
migrate / liveness |
명시적 DB migration / 읽기 전용 DB·schema 생존 확인 |
ingest <payload> [--expand] |
단건 적재(URL/텍스트/파일) |
search <q> [--no-summary] |
FTS+벡터 하이브리드 검색 + Gemini 정리(인용) |
bot / serve-api |
텔레그램 봇 / Starlette·Uvicorn 웹 서비스 |
recover-run / recover-loop |
error inbox 자동 재적재(게이팅·지수백오프·영구실패 구분) |
refresh-mark / refresh-run / refresh-loop |
빈약/구버전 문서 재스크랩(복원) |
replay-failed |
error inbox 수동 전량 재적재 |
배포된 인스턴스의 호스트 수명주기는 루트의 cb-manuscript로만 조작한다.
cb-manuscript는 .env, 설치·업데이트와 Compose를 담당하고,
cb-manuscript app은 같은 배포 설정과 데이터로 claire one-off 명령을 실행한다.
영속 서비스의 컨테이너 내부 명령은 Compose가 직접 claire를 호출한다. 세부 경계와
health 종료 코드 차이는 운영 명령 경계를 참고한다.
cb-manuscript는 준비된 Linux 호스트에서 설정 검증·이미지 build·DB
migration·서비스 기동을 일관된 순서로 수행한다.
Linux 호스트가 기준이다. Windows에서는 WSL Ubuntu의 Linux 파일시스템에 checkout을 두고 실행한다. 다음 항목이 필요하다.
- Bash와 Python 3.10 이상(
fcntl,sqlite3표준 모듈 포함) - Git
- 실행 중인 Docker Engine과 Docker CLI
docker compose형태의 Docker Compose plugin- 현재 사용자 계정의 Docker daemon 접근 권한
- checkout,
data/,vault/,.cb-manuscript/를 읽고 쓸 권한 - 최초 image build를 위한 container registry·OS package repository·Python package index의 DNS/HTTPS 접근
sudo apt update
sudo apt install -y bash ca-certificates curl git python3Docker Engine, Docker CLI와 Compose plugin은 Docker 공식 Ubuntu 설치 안내에 따라 준비한다. 설치 후 현재 계정에 Docker daemon 접근 권한을 적용하고 버전을 확인한다.
python3 --version # 3.10 이상
python3 -c 'import fcntl, sqlite3'
git --version
docker --version
docker compose version
docker info --format '{{.ServerVersion}}'저장소를 clone한 뒤 루트로 이동한다. private repository는 credential manager 또는 SSH 인증을 사용한다.
git clone https://github.com/fofwisdom/claire-bible.git
cd claire-bible컨테이너 image build가 Python 3.11, uv, Chromium과 애플리케이션 Python 패키지를
설치한다. 호스트 uv는 로컬 소스 개발과 기본 원격 배포 CI에서
사용한다.
저장소 루트에서 init을 먼저 실행한다.
./cb-manuscript init이 명령은 다음 작업을 수행한다.
.env.example을.env로,.env.dev.example을.env.dev로 복사- 기존 환경 파일과 비어 있지 않은 설정 유지
- production/development selector와
CLAIRE_ANONYMOUS_READONLY=0보충 - 비어 있는
CLAIRE_INJECT_TOKEN을 URL-safe owner token으로 생성 - 환경 파일을 mode
0600으로 설정 - 기본
data/,vault/디렉터리 생성
설치할 profile에 따라 설정 파일과 명령을 선택한다.
| 목적 | 적용 설정 | 명령 형태 |
|---|---|---|
| 같은 호스트에서 격리된 시험 | .env 다음 .env.dev overlay |
./cb-manuscript dev <command> |
| production 운영 | .env |
./cb-manuscript <command> |
development의 기본값은 127.0.0.1:8766, mock provider, Telegram bot 비활성화다. 같은
호스트에서 시험한다면 init 직후 사용할 수 있다. 다른 개발 장치에서 접속할 때는
.env.dev의 CB_API_BIND와 CLAIRE_PUBLIC_URL을 실제 고정 LAN IPv4 기준으로 함께
변경한다.
production에서는 .env의 예시 hostname을 포함한 다음 값을 실제 환경에 맞게
변경한다.
CLAIRE_ENVIRONMENT=production
CB_API_BIND=192.168.10.25
CB_API_PORT=8765
CLAIRE_PUBLIC_URL=https://kb.example.net/
CLAIRE_CORS_ALLOWED_ORIGINS=
CLAIRE_ANONYMOUS_READONLY=0CB_API_BIND는 Claire 호스트에 실제 할당된 단일 IPv4여야 한다.CB_API_PORT는 사용 가능한 port여야 한다.CLAIRE_PUBLIC_URL은 실제 DNS hostname의 root HTTPS URL이어야 한다.- production HTTPS와 인증서는 별도 reverse proxy가 담당한다.
- production host의 API source 제한은 reverse proxy IP를 기준으로
DOCKER-USERchain에 설정한다. CB_DATA_DIR·CB_VAULT_DIR을 바꾸면 해당 host 디렉터리를 미리 만들고 Docker bind mount와 쓰기 권한을 확인한다.
DNS, reverse proxy, TLS, Host 전달과 방화벽 구성은 외부 접속과 reverse proxy를 따른다.
최초 기동은 기본 mock provider와 비활성 Telegram 구성으로 확인할 수 있다.
CLAIRE_PROVIDER=mock
GEMINI_API_KEY=
TELEGRAM_BOT_TOKEN=실제 Gemini를 사용하려면 provider와 API key를 모두 설정한다.
CLAIRE_PROVIDER=gemini
GEMINI_API_KEY=replace-with-gemini-api-keyTelegram bot을 활성화할 때 TELEGRAM_BOT_TOKEN과 CLAIRE_ALLOWED_USERS의 허용할
숫자 user ID를 설정한다.
CLAIRE_ANONYMOUS_READONLY=1은 숨김 문서를 포함한 전체 지식베이스의 읽기 API를
자격증명 없이 공개한다. 최초 설치는 기본값 0을 유지하고, 방화벽과 rate limit을
검증한 뒤 필요한 profile에서만 명시적으로 활성화한다.
doctor와 install은 별도 명령이다. 선택한 profile에서 다음 순서로 실행한다.
# production
./cb-manuscript doctor
./cb-manuscript install
# development
./cb-manuscript dev doctor
./cb-manuscript dev installdoctor는 Docker CLI·Compose·daemon, Git, 환경 파일과 Compose 문법을 확인한다.
설치 전에 다음 운영 조건도 확인한다.
CB_API_BIND가 실제 host interface에 존재하는지CB_API_PORT가 비어 있는지- Docker build와 데이터 증가에 필요한 디스크 공간
- custom data/vault 경로의 mount·쓰기 권한
- registry·APT·Python package index 접근
- production DNS·reverse proxy·TLS·방화벽
- Gemini와 Telegram 자격증명의 실제 유효성
설치가 끝나면 같은 profile에서 상태와 두 단계 health를 확인한다. development는 각
명령 앞에 dev를 붙인다.
./cb-manuscript status
./cb-manuscript health
./cb-manuscript app health
./cb-manuscript app doctor
./cb-manuscript logs --tail 100 apiinstall의 마지막 검증 범위는 API 컨테이너의 DB·schema liveness다. 설치 후 실제
환경에서 Gemini 호출, Telegram 메시지, scraping, reverse proxy와 브라우저 접속을
각각 확인한다.
./cb-manuscript update # fast-forward source → build → stop → migrate → up
./cb-manuscript update --no-fetch # 이미 동기화된 소스로 재배치
./cb-manuscript up
./cb-manuscript down
./cb-manuscript restart
./cb-manuscript backup # backups/cb-YYYYMMDD/
./cb-manuscript backup --format archive # backups/cb-YYYYMMDD.tar.gz
./cb-manuscript restore backups/cb-YYYYMMDD --yes
./cb-manuscript health
./cb-manuscript logs -f api
./cb-manuscript shell
./cb-manuscript app --help # 배포 이미지의 전체 앱 명령 확인
./cb-manuscript app status # 배포된 앱의 one-off 상태 조회
./cb-manuscript app health # degraded까지 평가하는 전체 health
./cb-manuscript compose -- ps # 고급 Compose 탈출구CLAIRE_ENVIRONMENT는 development 또는 production 중 하나가 반드시 필요하다.
bare 명령의 환경 선택은 프로세스 값을 먼저 본다. 다만 설정 파일의 역할까지 바꾸지는
않으므로 .env는 production, .env.dev는 development를 선언해야 한다.
development가 선택되면 .env 다음에 .env.dev와 개발 Compose overlay를 적용한다.
기존 dev prefix는 development 별칭으로 유지하지만 프로세스 환경이 production이면
충돌로 중단한다. CLAIRE_PUBLIC_URL과 CORS 목록은 선택된 env 파일의 값을 검사하고
그대로 컨테이너에 전달한다.
기존 설치를 처음 이 구조로 올릴 때는 lifecycle 명령 전에 ./cb-manuscript init을 한
번 다시 실행한다. 기존 secret과 명시된 값을 유지하면서 누락된 환경 selector와
CLAIRE_ANONYMOUS_READONLY=0을 production/development 파일에 각각 보충한다. 그 뒤
production .env에는 실제 외부 hostname의
CLAIRE_PUBLIC_URL=https://.../을 반드시 설정하고, 필요할 때만 exact HTTPS origin을
CLAIRE_CORS_ALLOWED_ORIGINS에 넣는다.
웹 읽기는 기본적으로 인증이 필요하다. exact CLAIRE_ANONYMOUS_READONLY=1은 canonical
same-origin 또는 Origin 헤더가 없는 요청에서 자격증명 없는 읽기를 허용하는 명시적
opt-in이다. 이는 owner 인증이나 쓰기 기능을 끄는 설정이 아니며, 그래프·문서
상세·숨김 문서를 포함한 지식베이스 전체가 API를 통해 공개된다. hidden은 화면
정리용 표시이지 접근 제어가 아니다. 공개 전에 외부 접속과 reverse
proxy의 방화벽·rate limit 경계를 적용한다.
app, shell, 고급 compose one-off는 인스턴스 잠금을 잡아 lifecycle 및 백업·복원과
동시에 실행되지 않는다. migration, Compose 관리 daemon과 파괴적 유지보수는 실수로
실행되지 않도록 기본 차단된다. app --advanced ...는 전문가용 raw passthrough이며
서비스 정지, migration 순서, 백업 또는 복구 가능성을 보장하지 않는다.
백업은 현재 profile의 data와 vault를 writer 정지 상태에서 함께 캡처하고,
SQLite snapshot·quick_check·foreign-key 검사·SHA-256 manifest를 검증한 뒤에만
공개한다. 기본은 폴더이고 --format archive는 .tar.gz 파일을 만든다.
--component data 또는 --component vault로 일부만 선택할 수 있다. 같은 날짜 산출물은
묵시적으로 덮어쓰지 않으며 새 상태로 교체하려면 --replace가 필요하다. .env의
secret과 호스트 topology는 v1 backup에 포함하지 않는다.
복원은 파일 또는 폴더를 자동 판별하며 profile·project·hash·SQLite를 서비스 정지 전에
검증한다. --yes가 필요하고, 선택한 component를 교체한 뒤 migration과 liveness까지
성공해야 완료한다. 실패하면 직전 data/vault를 되돌리고 원래 실행 중이던 컨테이너만
재개한다.
./cb-manuscript health는 실행 중인 API 컨테이너의 DB·schema liveness를 확인한다.
주의 항목이 누적된 degraded 상태도 출력하지만 liveness가 정상이면 성공한다.
./cb-manuscript app health는 전체 애플리케이션 상태를 평가하므로 degraded이면
종료 코드 1을 반환한다.
update는 dirty worktree와 non-fast-forward 갱신을 거부한다. 새 이미지 build가 성공한
뒤 현재 project와 이전 고정 이름 컨테이너를 중지하고 migration을 한 번만 실행한다.
SQLite migration 중에는 짧은 쓰기 중단이 발생한다. migration 전에 실패하면 직전에
실행 중이던 컨테이너만 다시 시작한다. 새 스택 기동 이후 실패는 진단을 위해 그 상태를
유지하며 자동 rollback으로 오인하지 않는다. 이 update 실패 정책은 별도의
cb-manuscript restore component rollback과 구분한다.
환경 파일:
| 파일 | 역할 |
|---|---|
.env |
production 기본 runtime·Compose 설정과 secret |
.env.dev |
development project·포트·데이터 경로 override |
.env.deploy |
production SSH/rsync 접속 설정. 컨테이너에는 전달하지 않음 |
Compose project 이름은 CB_PROJECT_NAME으로 고정한다. 운영은 기본 claire-bible,
개발은 claire-bible-dev이며 고정 container_name을 사용하지 않는다. 설치 후 이름이
바뀌면 중복 writer 방지를 위해 명령이 거부된다. 이전 이름으로 down을 완료한 뒤 표시된
상태 파일을 제거해야 이름을 전환할 수 있다.
5개 서비스는 같은 이미지와 data·vault를 공유한다.
| 서비스 | 역할 |
|---|---|
bot |
선택적 Telegram long-polling |
api |
ASGI API·웹 UI. 컨테이너는 전체 interface에서 듣고 호스트는 CB_API_BIND의 정확한 IPv4에만 게시 |
refresh |
갱신 큐 처리 |
recover |
error inbox 자동 재적재 |
expand |
1홉 자동확장 큐 처리 |
워크스테이션에서 원격 호스트로 전송해야 하면 접속 설정을 runtime .env와 분리한다.
워크스테이션에는 Bash, Python 3.10 이상, Docker Compose, SSH, rsync와 기본 CI
실행용 uv가 필요하다. 원격 호스트에는 Bash, Python 3.10 이상, rsync, 실행 중인
Docker Engine과 Compose, 배포 경로 쓰기·Docker daemon 접근 권한, image build용
외부 네트워크가 필요하다.
Ubuntu 워크스테이션의 원격 전송 도구는 APT로 설치한다. 기본 CI용 uv는
공식 standalone installer로
준비한다.
# 배포 워크스테이션
sudo apt update
sudo apt install -y openssh-client rsync
curl -LsSf https://astral.sh/uv/install.sh | sh설치 후 새 shell session에서 uv --version을 확인한다.
원격 Ubuntu 호스트는 위의 Docker·Python 준비에 SSH server와 rsync를
추가한다.
# 원격 대상 호스트
sudo apt update
sudo apt install -y openssh-server rsync
sudo systemctl enable --now ssh./cb-manuscript init
# production .env를 실제 bind, URL, provider 설정으로 편집
cp .env.deploy.example .env.deploy
# DEPLOY_REMOTE, DEPLOY_PATH, DEPLOY_ENV_SYNC 입력
./cb-manuscript remote install
./cb-manuscript remote update원격 전송은 deploy.sh 호환 계층을 사용하지만 실제 컨테이너 lifecycle은 원격의
cb-manuscript가 수행한다. DEPLOY_ENV_SYNC=if-missing|always|never로 원격 runtime
.env 동기화 정책을 정한다. 원격 install/update는 production 전용이며 로컬과 원격
명령 모두 CLAIRE_ENVIRONMENT=production으로 고정된다.
기본 DEPLOY_ENV_SYNC=if-missing은 원격 .env가 없을 때만 로컬 production .env를
전송한다. 최초 설치에는 유효한 로컬 .env 또는 이미 준비된 원격 .env 중 하나가
반드시 필요하다. remote install 전에 원격 호스트의 Python·Docker·Compose 버전,
daemon 접근, 배포 경로 권한과 build 네트워크를 확인한다.
웹 접속은 외부 접속과 reverse proxy를 따른다. development는 고정 IPv4로 직접 HTTP 접속하고, production은 별도 LAN reverse proxy가 hostname과 클라이언트 TLS를 담당한 뒤 Claire의 HTTP upstream으로 전달한다. production HTTPS와 인증서 발급·갱신은 LAN reverse proxy에서 관리한다.
- 추출 실패(Gemini 429/quota/크레딧 소진): 원본은
raw_inboxerror 로 보관(유실 0).recover가 지수백오프로 자동 재적재. 영구실패(failed) 누적 시 텔레그램으로 소유자 경보. 크레딧 충전 등으로 회복되면 due 항목이 자동 복구된다. - 기동 여부 확인:
./cb-manuscript health로 API 컨테이너의 liveness를 확인한다. - 주의 상태 진단:
./cb-manuscript app health의degraded,attention필드를 확인한다.degraded이면 명령도 실패로 종료한다.
src/claire/
config.py 설정(.env)
cli.py CLI 진입점
telegram_bot.py 텔레그램 진입점
api/ ASGI API와 웹 UI
health.py 건강 상태 산출(/health · CLI 공유)
notify.py 텔레그램 소유자 경보
ingest/ fetcher 라우터 + normalize + dedup + IngestService(공유 통로) + 자동복구
ontology/ 타입 온톨로지(코드 인터페이스) + registry(domain/range)
extract/ Gemini structured 추출 + provider 어댑터(mock/gemini) + resolver(약어 동의어 수렴) + circuit breaker
store/ SQLite(graph+FTS+vec) + 마이그레이션 + vault(.md) export
expand/ 1홉 자동 확장
retrieval/ 하이브리드 검색 + LLM 정리