Skip to content

greenheadHQ/awesome-anki

Repository files navigation

Awesome Anki

Awesome Anki 메인 화면

Awesome Anki는 **Anki 노트를 학습 효율이 높은 원자 카드(Atomic Card)**로 분할하고, 검증하고, 필요 시 복구(롤백)할 수 있는 로컬 우선 웹 애플리케이션입니다.

목차

1. 프로젝트 소개

기존 Anki 카드에 정보가 과도하게 밀집되면 복습 효율이 떨어질 수 있습니다. Awesome Anki는 다음 흐름으로 이 문제를 해결합니다.

  1. 카드 구조를 분석해 분할 가능 여부를 판단합니다.
  2. AI(Gemini/OpenAI)로 카드를 의미 단위로 분리합니다.
  3. 분할 전 백업을 생성하고, 적용 실패 시 자동 롤백합니다.
  4. 팩트/최신성/유사성/문맥 검증으로 결과 품질을 점검합니다.

2. 핵심 기능

2.1 카드 분할

  • AI Split: Gemini 또는 OpenAI를 사용해 비정형 텍스트를 의미 단위로 분할
  • 멀티 프로바이더: 웹 UI에서 프로바이더/모델 선택, 모델별 결과 비교 가능
  • 비용 가시화: 분석 전 비용 추정, 분석 후 실측 비용 + 토큰 사용량 표시
  • 예산 가드레일: 서버 사이드 예산 상한으로 과도한 비용 방지
  • Preview / Apply 분리: 적용 전 미리보기로 결과 확인 가능
  • 학습 데이터 복제: 분할 후 카드에 스케줄링 정보 복제 시도

2.2 검증

  • Fact Check: 카드 내용의 사실성 점검
  • Freshness: 최신성 점검(기준 날짜 기반)
  • Similarity: Jaccard + 임베딩 기반 유사 카드 탐지
  • Context: nid 링크 기반 문맥 일관성 점검
  • All-in-one 검증: 단일 요청으로 통합 검증 실행

2.3 안정성

  • 분할 전 백업(preBackup) 필수 생성
  • 적용 실패 시 자동 롤백
  • 손상 백업 파일 자동 격리(.corrupt-*)
  • 원클릭 수동 롤백 API 제공

2.4 프롬프트 운영

  • 프롬프트 버전 생성/수정/활성화/삭제
  • 시스템 프롬프트 원격 SoT 저장 (awesomeAnki.prompts.system)
  • expectedRevision 기반 CAS 충돌 제어 (409 반환)
  • systemPrompt 저장 성공 시 즉시 Anki sync() 실행
  • 분할 히스토리 저장/조회
  • 실패 패턴 분석
  • A/B 실험(Experiment) 생성 및 완료 처리

2.5 보안

  • /api/health를 제외한 API는 ANKI_SPLITTER_API_KEY 인증 필요

3. 기술 스택

영역 기술
런타임 Bun
언어 TypeScript
서버 Hono
React 19 + Vite
상태 관리 TanStack Query
스타일링 Tailwind CSS v4
렌더링 markdown-it + KaTeX
LLM Google Gemini + OpenAI
연동 AnkiConnect

4. 모노레포 구조

awesome-anki/
├── src/                      # 루트 CLI 엔트리
├── packages/
│   ├── core/                 # 도메인 로직(분할/검증/백업)
│   ├── server/               # Hono REST API
│   └── web/                  # React + Vite 웹 UI
├── output/                   # 런타임 산출물(백업, 임베딩 캐시, 프롬프트 버전/legacy 기록)
├── docs/                     # 아키텍처/기능/트러블슈팅 문서
└── templates/                # 카드 템플릿 리소스

5. 빠른 시작

5.1 사전 요구사항

5.2 설치

git clone https://github.com/greenheadHQ/awesome-anki.git
cd awesome-anki
bun install

5.3 환경 설정

cp .env.example .env

실제 운영값은 이 저장소 기준으로 .envrc에서 export 관리하며, 비밀값은 secrets/*.age로 암호화 관리합니다.

6. 실행 방법

6.1 웹 GUI (권장)

# 서버 + 웹 동시 실행
bun run dev

# 서버만 실행 (기본: 3000)
bun run dev:server

# 웹만 실행 (기본: 5173)
bun run dev:web

6.2 CLI

# 연결 상태 확인
bun run cli:status

# 덱 분할 미리보기
bun run cli:split

# 덱 분할 적용
bun run cli:split -- --apply

# 특정 노트 분할
bun run cli split --note <noteId>

# 분석 명령 (내부용)
bun run cli analyze <deckName> [noteId]

# 백업 목록/롤백
bun run cli backups
bun run cli rollback <backupId>

7. 환경 변수

7.1 핵심 서버/도메인 변수

변수 설명
GEMINI_API_KEY Gemini API 키 (split/validation에서 Gemini 사용 시 필요)
OPENAI_API_KEY OpenAI API 키 (임베딩 필수, split/validation에서 OpenAI 사용 시 필요)
ANKI_SPLITTER_API_KEY 서버 API 인증 키
ANKI_CONNECT_URL AnkiConnect URL
ANKI_CONNECT_VERSION AnkiConnect 버전(기본 6)
TARGET_DECK 기본 대상 덱
SPLIT_HISTORY_DB_PATH 분할 이력 SQLite 파일 경로 (기본 data/split-history.db)
HISTORY_SYNC_MODE 히스토리 동기화 모드 (local / remote)
ANKI_SPLITTER_DEFAULT_LLM_PROVIDER 기본 LLM 프로바이더 (gemini / openai, 기본 gemini)
ANKI_SPLITTER_DEFAULT_LLM_MODEL 기본 LLM 모델 (기본 gemini-3-flash-preview)
ANKI_SPLITTER_BUDGET_CAP_USD 서버 사이드 예산 상한 USD (기본 1.0)

7.2 웹/개발 변수

변수 설명
VITE_API_URL 웹에서 직접 호출할 API 베이스 URL
VITE_API_PROXY_TARGET Vite dev 프록시 타깃(기본 http://localhost:3000)
VITE_LOCATOR_TARGET Locator 에디터 타깃 (cursor/vscode)
VITE_DISABLE_LOCATOR Locator 강제 비활성화

8. 개발 DX 도구

이 섹션은 LocatorJS를 실제로 어떻게 켜고 끄는지, 어떤 설정값이 영향을 주는지를 정리합니다.

8.1 공통 동작 원칙

  1. LocatorJS는 packages/web/src/main.tsx에서 import.meta.env.DEV 조건으로만 초기화됩니다.
  2. 즉, bun run dev일 때만 동작하고 bun run build 산출물에서는 실행되지 않습니다.
  3. 비활성화는 아래 환경변수로 즉시 제어할 수 있습니다.
    • VITE_DISABLE_LOCATOR=true

8.2 LocatorJS (브라우저 → 에디터 점프)

설정 방법

  1. 런타임 패키지 설치
    • @locator/runtime
  2. Vite Babel 체인에 data-id 플러그인 연결
    • @locator/babel-jsx/dist
    • 개발 모드에서만 적용 (mode === "development")
  3. 런타임 초기화
    • setupLocatorUI({ targets, showIntro: false })
    • showIntro: false로 온보딩 팝업 비활성화
  4. 에디터 타깃 선택
    • 기본: VITE_LOCATOR_TARGET=cursor
    • 전환: VITE_LOCATOR_TARGET=vscode

사용 방법

  1. bun run dev 실행
  2. 브라우저에서 점프하려는 컴포넌트 위에 마우스를 올림
  3. macOS 기준 Option + Click 실행
  4. 설정된 에디터(Cursor/VS Code)에서 해당 파일+라인으로 이동

점검 포인트

  1. 점프가 안 되면 먼저 VITE_DISABLE_LOCATORtrue인지 확인
  2. 반드시 Vite 개발 서버(bun run dev 또는 bun run dev:web)에서 테스트
  3. 소스 메타가 누락되면 packages/web/vite.config.ts의 Babel 플러그인 설정 확인

8.3 권장 운영 시나리오

  1. 평소: Locator 활용 (기본 활성)
  2. 불필요 시: VITE_DISABLE_LOCATOR=true로 비활성화

9. API 레퍼런스

9.1 인증

  • /api/health를 제외한 API는 인증 필요
  • 인증 방법:
    • X-API-Key: <ANKI_SPLITTER_API_KEY>
    • Authorization: Bearer <ANKI_SPLITTER_API_KEY>

9.2 공통

메서드 경로 설명
GET /api/health 서버 헬스 체크

9.3 Deck / Card

메서드 경로 설명
GET /api/decks 덱 목록
GET /api/decks/:name/stats 덱 통계
GET /api/cards/deck/:name 덱 카드 목록
GET /api/cards/deck/:name/difficult 어려운 카드 목록
GET /api/cards/:noteId 단일 카드 상세

9.4 Split / History / Backup / Media

메서드 경로 설명
GET /api/llm/models 사용 가능 LLM 모델/가격 조회
POST /api/split/preview 분할 미리보기 (provider/model/budgetUsdCap 선택 가능, 예산 초과 시 HTTP 402)
POST /api/split/apply 분할 적용
POST /api/split/reject 분할 반려 처리
GET /api/history 분할 이력 목록 조회
GET /api/history/:sessionId 분할 이력 상세 조회
GET /api/history/sync/health 히스토리 동기화 상태
GET /api/backup 백업 목록
GET /api/backup/latest 최신 백업 ID
POST /api/backup/:id/rollback 롤백 실행
GET /api/media/:filename Anki 미디어 프록시

9.5 Validation

메서드 경로 설명
POST /api/validate/fact-check 팩트 체크
POST /api/validate/freshness 최신성 검사
POST /api/validate/similarity 유사성 검사
POST /api/validate/context 문맥 검사
POST /api/validate/all 통합 검증

9.6 Embedding

메서드 경로 설명
POST /api/embedding/generate 덱 임베딩 생성/갱신
GET /api/embedding/status/:deckName 임베딩 캐시 상태
DELETE /api/embedding/cache/:deckName 캐시 삭제
POST /api/embedding/single 단일 텍스트 임베딩(디버그용)

임베딩 API 응답은 공통 envelope를 사용합니다:

  • 성공: ok=true, schemaVersion, requestId, timestamp(ISO 8601), data
  • 실패: ok=false, schemaVersion, requestId, timestamp(ISO 8601), error.code/message/retryable
  • POST /api/embedding/generate는 부분 실패 시에도 HTTP 200을 유지하고 data.status=completed_with_errorsdata.failures[]로 상세를 반환합니다.

9.7 Prompt Ops

메서드 경로 설명
GET /api/prompts/system 원격 systemPrompt + revision 조회
POST /api/prompts/system CAS 기반 systemPrompt 저장 + sync
GET /api/prompts/versions 프롬프트 버전 목록
GET /api/prompts/versions/:id 버전 상세
POST /api/prompts/versions 버전 생성
PUT /api/prompts/versions/:id 버전 수정 (systemPrompt 수정 불가)
DELETE /api/prompts/versions/:id 버전 삭제
POST /api/prompts/versions/:id/activate 버전 활성화
GET /api/prompts/active 현재 활성 버전 조회
GET /api/prompts/versions/:id/failure-patterns 실패 패턴 분석
GET /api/prompts/experiments 실험 목록
GET /api/prompts/experiments/:id 실험 상세
POST /api/prompts/experiments 실험 생성
POST /api/prompts/experiments/:id/complete 실험 완료

추가 정책:

  • systemPrompt SoT는 Git tracked file이 아닌 miniPC AnkiConnect config다.
  • 로컬 파일 fallback 저장은 금지되며, sync 실패 시 저장 요청은 실패 처리된다.

10. 품질 검증

루트 디렉터리에서 실행합니다.

# 빠른 검증 (PR 최소 기준)
bun run check:quick

# 전체 검증 (권장)
bun run check

세부 검증:

bun run lint
bun run typecheck
bun run test
bun run build

CI에서는 .github/workflows/ci.ymlquality-gatebun run check를 실행합니다.

11. 운영/트러블슈팅 체크

문제 발생 시 아래 순서 권장:

  1. bun run check:quick
  2. bun run check
  3. ANKI_SPLITTER_API_KEY 및 API 헤더 확인
  4. ANKI_CONNECT_URL 연결 확인

상세 트러블슈팅 문서: docs/TROUBLESHOOTING.md

12. 자가 호스팅 (Self-Host)

12.1 사전 작업

# 호스트에 데이터 디렉토리 생성 및 권한 설정 (UID 1001 = 컨테이너 내부 anki 사용자)
sudo mkdir -p /srv/awesome-anki/{data,output}
sudo chown -R 1001:1001 /srv/awesome-anki

12.2 최소 실행

podman run -d --name awesome-anki \
  --network=host \
  -e GEMINI_API_KEY=<your-key> \
  -e ANKI_CONNECT_URL=http://100.79.80.95:8765 \
  -e ANKI_SPLITTER_REQUIRE_API_KEY=false \
  -v /srv/awesome-anki/data:/app/data \
  -v /srv/awesome-anki/output:/app/output \
  ghcr.io/greenheadhq/awesome-anki:latest

ANKI_SPLITTER_REQUIRE_API_KEY=false: Tailscale/VPN 등 네트워크 격리 환경에서만 사용하세요. 공개 네트워크에 노출되는 경우 reverse proxy 단에서 인증(basic auth 등)을 반드시 설정해야 합니다.

12.3 환경변수 파일 사용

# /etc/awesome-anki/env 예시
GEMINI_API_KEY=...
OPENAI_API_KEY=...
ANKI_CONNECT_URL=http://100.79.80.95:8765
ANKI_SPLITTER_REQUIRE_API_KEY=false
PORT=3100
podman run -d --name awesome-anki \
  --network=host \
  --env-file /etc/awesome-anki/env \
  -v /srv/awesome-anki/data:/app/data \
  -v /srv/awesome-anki/output:/app/output \
  ghcr.io/greenheadhq/awesome-anki:latest

12.4 Caddy reverse proxy 연계

Caddy 사이트블록 예시 (NixOS 등에서 관리):

anki.greenhead.dev {
  reverse_proxy localhost:3100
}

상세 인프라 구성은 greenheadHQ/nixos-config#75를 참고하세요.

13. 참고 링크

13.1 내부 문서

13.2 외부 레퍼런스

14. 라이선스

MIT

About

Anki 덱 관리용

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors