Skip to content

Repository files navigation

학습 점검 퀴즈 도구 — v0

내가 정리한 노트(Word/Markdown/노션)로 자기 점검 퀴즈를 만들고 푸는 로컬 도구.

핵심은 퀴즈가 아니라 근거 인용입니다. 모든 문항은 내 노트의 특정 구간에서 나오고, evidence가 원문에 실제로 존재하는지 서버가 검증합니다. 없으면 그 문항은 버려집니다. 그래서 할루시네이션이 구조적으로 차단되고, 동시에 정리가 빈 곳이 드러납니다 — 퀴즈를 못 만드는 구간은 "정리 갭 카드"로 표시됩니다.


왜 써야 하나

  • 할루시네이션이 구조적으로 막힘 — 프롬프트로 "노트에서만 내라"고 말하는 게 아니라, evidence가 원문에 실제로 있는지 코드가 검증. 없으면 그 문항 자체가 안 만들어짐
  • 정리가 부실한 곳을 스스로 알려줌 — 퀴즈를 못 만든 구간이 "정리 갭 카드"로 뜸. 복습 도구이자 동시에 노트 정리 상태를 점검하는 도구
  • 설치 마찰이 거의 없음 — 아래 "시작하기 A"처럼, 스킬만 쓸 거면 git clone + 스크립트 한 줄로 끝. venv도 pip install도 API 키도 필요 없음
  • API 비용 0원 (스킬 경로)/quiz-add는 Claude Code가 직접 생성하고 검증 스크립트만 돌리는 구조라 LLM 호출 자체가 없음
  • 반복 사용 비용도 0 — 문항을 미리 만들어 SQLite에 저장해두는 구조라 풀기·채점·복습·오답노트가 전부 LLM 호출 없이 동작
  • 복습 타이밍을 안 챙겨도 됨 — 간격 반복(Leitner)이 "곧 잊어버릴 문항"만 알아서 골라서 다시 띄워줌
  • 노트 소스가 다양함.md / .docx / .txt는 물론 노션 페이지도 그대로 연동. 정리하던 도구를 안 바꿔도 됨
  • 알림이 안 질림 — 하루 한 번만 뜨도록 설계돼서, 매번 뜨는 알림형 도구처럼 며칠 안에 꺼버리게 되는 일이 적음
  • 완전 로컬 — 문항 생성 시 API 호출 한 번 빼면 전부 내 컴퓨터 안에서 도는 개인용 도구. 노트 내용이 서버에 안 쌓임

필요한 것 (시작 전에)

처음 써보는 분들을 위한 체크리스트입니다. 컴퓨터에 뭐가 깔려 있어야 하는지 잘 모르겠다면 여기부터 확인하세요.

필요한 것 왜 필요한가 확인 방법
터미널(명령줄) 사용 아래 명령어들을 복사해서 붙여넣고 실행할 줄 알면 충분합니다. macOS는 "터미널" 앱, Windows는 아래 참고
Git 이 저장소를 내려받기 위해 필요 (또는 GitHub에서 zip으로 다운로드해도 됨) git --version
Python 3.10 이상 이 도구 자체가 파이썬 스크립트(quiz.py)로 되어 있음 python3 --version
Claude Code (A 경로에만 필요) /quiz-add, /quiz-review 스킬이 Claude Code 위에서 동작함. 아직 없다면 먼저 설치·로그인부터 하세요 Claude Code 실행해서 채팅 되는지 확인
노션 계정 + Integration (선택) 노트를 노션에 정리해뒀고 그걸 그대로 연동하고 싶을 때만 필요. 안 쓰면 몰라도 됨 아래 "노션 연동" 참고
Anthropic API 키 (B 경로에만, 선택) Claude Code 없이 터미널만으로 문항을 생성하고 싶을 때만 필요 아래 "시작하기 B" 참고

Windows 사용자라면: install.sh는 macOS/Linux용 셸 스크립트라 Windows 기본 명령 프롬프트(cmd)에서는 안 돌아갑니다. Git Bash(Git 설치 시 같이 깔림)나 **WSL(Windows용 Linux)**을 열어서 그 안에서 아래 명령어들을 실행하세요.

또한 python3 --version이 버전 번호 없이 Python만 찍고 끝나거나 아무 반응이 없다면, Python을 python.org에서 설치했는데 python3가 Microsoft Store의 빈 스텁으로 잡혀 있는 경우입니다. 이럴 땐 이 문서의 모든 python3python으로 바꿔서 실행하세요.

macOS/Linux는 터미널을 그냥 열어서 그대로 따라 하면 됩니다.


시작하기

두 가지 방법이 있습니다. 뭘 쓸지 모르겠으면 A로 시작하세요 — 제일 빠르고, 나중에 언제든 B로 확장할 수 있습니다.

A. 스킬만 쓰기 (제일 쉬움, 권장)

노트로 퀴즈를 만들고 푸는 것까지 전부 채팅 안에서 끝납니다. venv도, pip install도, API 키도 필요 없습니다. Claude Code, Codex CLI 둘 다 지원하며 아래에서 골라 쓰면 됩니다.

A-1. Claude Code

git clone https://github.com/dokwon33/knowledge-recall.git
cd knowledge-recall
./claude-setup/install.sh              # 이 폴더에서만 쓰려면
./claude-setup/install.sh --global     # 어느 폴더에서든 쓰려면

설치하면 세 가지가 생깁니다.

설명
/quiz-add 노트로 퀴즈 생성. Claude Code가 직접 생성하므로 API 비용 0원
/quiz-review 오늘 복습할 문항을 대화로 출제·채점
SessionStart 훅 하루 첫 실행에만 오늘 복습할 문항 3개를 컨텍스트에 주입

Claude Code가 노트를 읽고 문항을 만든 뒤 validate.py로 검증만 돌리는 구조라, span 검증이라는 보증은 그대로 유지하면서 비용만 사라집니다.

실제로 이렇게 씁니다 (설치 후 매일의 흐름)

1) 노트 정리하고 나서 → 퀴즈 만들기

Claude Code 채팅창에 노트 파일을 가리키면서 이렇게 말하면 됩니다.

/quiz-add notes/spring-ai.docx --subject "Spring AI"

또는 그냥 "이 노트로 퀴즈 만들어줘"처럼 자연어로 말하고 파일 경로만 알려줘도 스킬이 알아서 반응합니다. Claude가

  1. 노트를 청크로 나눠서 미리보기 (--dry-run)
  2. 직접 문항을 만들고 (LLM API 호출 없음 — Claude Code 자신이 생성)
  3. validate.py로 "원문에 실제로 있는 문장인가"만 검증
  4. 저장된 문항 수 / 탈락한 문항 수 / 정리 갭을 채팅으로 보고합니다.

정리가 부실해서 문항을 못 만든 부분은 "정리 갭"으로 알려주는데, 이게 이 도구를 쓰는 진짜 이유입니다 — 노트 정리 상태를 점검하는 부수 효과.

2) 복습할 때 → 대화로 풀기

/quiz-review

또는 그냥 "복습하자", "오늘 복습할 거 있어?"라고 말해도 됩니다. 그러면:

  1. 오늘 간격 반복 스케줄에 걸린 문항(기본 5개)을 한 문항씩 채팅으로 냅니다
  2. 다 답할 때까지 정답을 먼저 보여주지 않습니다
  3. 전부 답하면 한 번에 채점하고, 문항마다 내 노트 원문 인용 + 해설을 보여줍니다
  4. 틀린 문항은 내일 다시 나옵니다 (간격 반복 박스가 0으로 리셋)

대화보다 브라우저가 편하면 /quiz-review에게 "웹으로 풀래"라고 말하세요. 스킬이 알아서 flask만 (venv나 requirements.txt 전체 없이) 한 번 설치하고 quiz.py serve를 백그라운드로 띄운 뒤 http://127.0.0.1:5000/due 주소를 줍니다.

직접 터미널에서 하고 싶으면 아래처럼도 가능합니다:

python quiz.py due          # 터미널에서 바로 (표준 라이브러리만 있으면 됨)
python quiz.py serve        # 브라우저 UI (flask 설치 필요 — pip install flask)

훅 동작 확인 (Claude Code SessionStart 훅 — 하루 첫 실행에만 복습 알림):

echo '{"source":"startup"}' | python3 hooks/session_start.py
rm .last_review    # 하루 한 번 제한 해제 (다시 테스트할 때)

A-2. Codex CLI

/quiz-add, /quiz-review와 동일한 스킬이 .agents/skills/ 에 Codex의 Skills 포맷(SKILL.md)으로도 들어 있습니다. 이 경로는 Codex가 저장소를 열면 자동으로 스캔하므로 설치 스크립트가 필요 없습니다 (claude-setup/install.sh는 Claude Code 전용).

git clone https://github.com/dokwon33/knowledge-recall.git
cd knowledge-recall
codex   # 이 폴더에서 그대로 실행

Codex 채팅에서 $quiz-add, $quiz-review로 명시 호출하거나, "노트로 퀴즈 만들어줘"처럼 자연어로 말해도 자동으로 인식합니다(암묵 호출). 동작 방식과 절대 규칙(노트에 없는 내용 금지, span 검증 등)은 Claude Code 스킬과 완전히 동일합니다 — Claude Code용 SessionStart 훅(하루 첫 복습 알림)만 Codex에는 없습니다.

왜 "매번"이 아니라 "하루 한 번"인가

VS Code는 하루에 10~20번 엽니다. 매번 퀴즈가 뜨면 며칠 안에 꺼버리게 됩니다. 알림형 학습 도구가 죽는 가장 흔한 패턴이라, .last_review에 날짜를 남겨 하루 한 번으로 제한했습니다. /clear·리줌·컴팩션에도 뜨지 않습니다.

B. 로컬 UI·API까지 전부 쓰기

브라우저 UI(serve)로 풀고 싶거나, Claude Code 없이 Anthropic API로 직접 생성하고 싶다면:

cd knowledge-recall
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

cp .env.example .env      # ANTHROPIC_API_KEY 채우기 (노션 쓰려면 NOTION_API_KEY도)
# 1) 파싱 결과만 미리보기 (API 호출 없음, 무료)
python quiz.py add samples/spring-ai.docx --dry-run

# 2) 퀴즈 생성 (Anthropic API 사용)
python quiz.py add notes/spring-ai.docx --subject "Spring AI" -n 10

# 3) 브라우저에서 풀기
python quiz.py serve          # → http://127.0.0.1:5000

API 키 없이 전체 흐름만 먼저 보고 싶다면:

python quiz.py add samples/spring-ai.docx --subject "Spring AI" \
       --mock samples/mock-response.json
python quiz.py serve

samples/mock-response.json에는 정상 문항 3개 + 할루시네이션 2개 + 중복 1개 + 정답 오류 1개가 섞여 있습니다. 7개 중 3개만 통과하는 걸 확인해보세요.

개발 / 테스트

pip install -r requirements-dev.txt
pytest                # 55개
pytest -k validate    # span 검증만

CLI 레퍼런스

python quiz.py add <경로 또는 노션 URL/ID> [옵션]   # 문서 등록 + 퀴즈 생성
python quiz.py notion-list <노션 페이지 URL/ID>     # 하위 페이지/DB 행 목록
python quiz.py list                                # 문서 목록 (문항/오답/갭 수)
python quiz.py due [-n N] [--json]                  # 오늘 복습할 문항
python quiz.py stats                                # 누적 통계 + span 통과율 + 박스 분포
python quiz.py serve [--port PORT] [--debug]        # 브라우저에서 풀기 (기본 :5000)

add의 주요 옵션:

옵션 설명
--subject "이름" 과목 태그
-n N 요청 문항 수 (기본 config.DEFAULT_ITEM_COUNT)
--dry-run 파싱/청킹 결과만 미리보기, API 호출 없음, 저장 안 함
--force 이미 등록된 문서(동일 content_hash)라도 문항 재생성
--mock <json경로> LLM 대신 저장된 JSON 응답 사용 (테스트·Claude Code 스킬용)
--prompt-ver v2 prompts/v2.txt로 생성 (A/B 비교)
--no-retry 통과율이 낮아도 1회 재생성을 시도하지 않음

노션 연동

(1) 액세스 토큰이 없다면 처음 발급 (추후에는 바로 3번 단계로 넘어가면 됩니다)

스크린샷 2026-08-03 오후 1 44 17

(2) 액세스 토큰 복사+붙여넣기 하여 .env에 NOTION_API_KEY={your_access_token} 추가

image

(3) 해당 페이지(하단 페이지 자동 사용하고싶다면 상위 페이지)에서 ⋯ 클릭 후 Integration 공유

image

로컬 파일 대신 노션 페이지를 바로 넣을 수 있습니다 (A/B 두 경로 모두 사용 가능). 새 의존성은 없습니다 (urllib 표준 라이브러리만 사용).

# .env 에 NOTION_API_KEY=ntn_... 추가
# (https://app.notion.com/developers/connections 에서 발급, 대상 페이지에
#  ⋯ → 연결 추가 로 그 Integration을 공유해야 함)

python quiz.py add "https://notion.so/내-노트-abcdef..." --subject "통계"

페이지 안에 하위 페이지나 데이터베이스가 있으면(예: 강의 노트가 데이터베이스의 행 하나씩인 경우) 자동으로 따라 들어가지 않습니다 — 이 도구는 "노트 하나 = 문서 하나"가 기본 단위라, 무작정 합치면 서로 다른 노트가 뒤섞이고 span 위치도 꼬입니다. 대신 목록만 보여줍니다:

python quiz.py notion-list "https://notion.so/메인-페이지-abcdef..."
# → 하위 페이지/데이터베이스 행 목록 + id
python quiz.py add <원하는 id> --subject "<과목>"

보충형 문항 (예외 모드)

기본은 항상 "노트에 없으면 갭으로 보고"입니다. 다만 /quiz-add로 만들다가 특정 갭을 콕 집어 "그냥 보충해서 내줘"처럼 명시적으로 요청하면, 그 갭에 한해 LLM 지식으로 보충한 문항을 만들 수 있습니다.

  • 그 문항은 grounding: "llm_supplement"로 저장되고, evidence를 원문에서 찾지 않는 대신 관련 청크 위치를 span으로 씁니다.
  • 화면(풀기 화면·채점 결과)에는 항상 "[보충됨]" 배지가 붙어서 일반 문항과 섞이지 않습니다.
  • 사용자가 요청하지 않은 갭까지 알아서 보충하지는 않습니다 — 매 갭 단위로 명시적 승인이 전제입니다. 자세한 규칙은 claude-setup/skills/quiz-add/SKILL.md 참고.

간격 반복 (Leitner)

랜덤 복습 대신, 곧 잊어버릴 문항만 골라서 다시 띄웁니다.

박스 다음 복습까지 이동
0 1일 맞히면 ↑ / 틀리면 0으로
1 3일
2 7일
3 21일
4 60일 사실상 졸업

새로 만든 문항은 당일 복습 대상입니다. python quiz.py stats로 박스 분포를 볼 수 있어요.

문서를 --force로 재생성하면 문항이 새로 만들어지므로 박스 진행도가 초기화됩니다. 노트를 크게 고쳤을 때만 쓰세요.


동작

.docx / .md / 노션 페이지
     │
     ▼
[ingest]   제목 경계로 청킹 → heading_path 보존 → 품질 판정
     │       · ok         → 출제 대상
     │       · thin       → 정리 갭 카드
     │       · image_only → 정리 갭 카드
     ▼
[generate] 문서 전체를 프롬프트에 넣고 1회 호출 (RAG 없음)
     │
     ▼
[validate] ★ evidence가 원문에 실제로 있는지 확인
     │       없으면 문항 폐기 · 통과율 60% 미만이면 1회 재생성
     ▼
[db]       SQLite 저장 — 이후 풀기/채점/해설은 LLM 호출 0회
     │
     ▼
[app]      Flask 로컬 UI: 풀기 → 채점 → 원문 인용 + 해설 → 오답 복습

왜 이 구조인가

결정 이유
퀴즈 사전 생성 풀기·채점·해설·재풀이가 전부 LLM 호출 0회. 문서 1개당 약 32원으로 끝
RAG / 임베딩 없음 노트 하나가 5~10k 토큰. 통째로 넣는 게 더 싸고 정확
span 검증 프롬프트로 "문서에서만 내라"고 말하는 것만으론 안 됨. 구조로 강제
갭 카드 퀴즈를 못 만드는 건 실패가 아니라 알려줘야 할 정보

파일

파일 역할
quiz.py CLI 엔트리 (add / notion-list / list / due / stats / serve)
ingest.py docx·md 파싱, 청킹, 품질 판정
notion_ingest.py 노션 페이지 → ingest.Block (표준 라이브러리만 사용)
generate.py 프롬프트 조립, Anthropic 호출, JSON 파싱
validate.py span 검증 — 이 프로젝트의 핵심
srs.py 간격 반복 스케줄 (Leitner 박스)
db.py SQLite 스키마 + 쿼리
app.py Flask 라우트
hooks/session_start.py 하루 첫 실행 복습 알림
claude-setup/ Claude Code 스킬 2종 + 훅 설정 + install.sh
.agents/skills/ 같은 스킬 2종의 Codex CLI 버전 (설치 스크립트 불필요, 자동 스캔)
prompts/v1.txt 시스템 프롬프트 (API 경로용)
templates/ 화면
config.py 임계값·단가·모델. 튜닝은 여기서만

튜닝 포인트

config.py에서:

기본 언제 바꾸나
THIN_CHARS 80 멀쩡한 정리가 자꾸 thin으로 걸리면 낮추기
MIN_SENTENCE_RATIO 0.3 개조식 노트가 자꾸 thin으로 걸리면 낮추기
MERGE_TARGET_CHARS 1200 문항이 지엽적이면 올리기 (맥락이 늘어남)
FUZZY_THRESHOLD 0.92 span 탈락이 너무 많으면 0.88까지 낮춰보기
MIN_PASS_RATIO 0.6 재생성 트리거 기준
MODEL claude-sonnet-5 Haiku로 내리면 싸지지만 span 통과율이 떨어질 것

프롬프트를 고칠 때는 prompts/v2.txt를 새로 만들고 --prompt-ver v2로 돌리세요. gen_logs 테이블에 버전별 통과율이 쌓여서 비교할 수 있습니다.

SELECT prompt_ver, model,
       SUM(generated) AS 통과, SUM(rejected) AS 탈락,
       ROUND(100.0*SUM(generated)/(SUM(generated)+SUM(rejected)),1) AS 통과율,
       ROUND(SUM(cost_usd),4) AS 비용
FROM gen_logs GROUP BY prompt_ver, model;

이 쿼리 하나가 나중에 오픈소스 LLM 비교 실험(SPEC §9.1)의 결과표가 됩니다.


지금 확인해야 할 것

v0를 만든 목적은 가설 하나를 검증하는 겁니다.

내가 정리한 문서로 만든 퀴즈가 실제로 풀 만한가?

노트 3개(잘 쓴 것 / 보통 것 / 부실한 것)로 30문항을 만들어 직접 채점해보세요.

  • 실제로 풀 만한가? → 목표 20/30 이상
  • evidence가 진짜 내 문장인가? → 목표 27/30 이상
  • 부실한 노트에서 억지 출제했나, 갭으로 보고했나?

기준을 못 넘기면 prompts/v2.txt를 만들어 2~3회 고쳐서 재시도하세요. 여기서 품질이 안 나오면 나머지를 아무리 잘 만들어도 안 쓰게 됩니다.


알려진 제약 (v0 의도된 범위)

  • 이미지/캡처는 처리하지 않습니다. 캡처만 있는 구간은 image_only 갭 카드로 표시만.
  • PDF 미지원. .docx / .md / .txt / 노션 페이지만.
  • 노션 하위 페이지·데이터베이스는 자동으로 안 따라 들어갑니다. notion-list로 목록을 보고 원하는 걸 개별 문서로 추가하세요 (위 "노션 연동" 참고).
  • 인증 없음. 내 컴퓨터에서만 도는 단일 사용자용입니다.
  • 네트워크 드라이브나 동기화 폴더에서 SQLite 잠금 오류가 나면 export QUIZ_DB=~/quiz.sqlite 로 로컬 경로를 지정하세요.

다음 단계(Spring + Vue 포팅, 배포)는 docs/SPEC.md 참고. 단, v0를 2주 이상 실제로 써본 뒤에 시작하세요.

About

No description, website, or topics provided.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages