Skip to content

Repository files navigation

PaperVoca (논문보까)

PaperVoca는 영어 논문 PDF를 읽기 전에 사용자의 장기 어휘 메모리와 논문 문맥을 함께 분석해, 모를 가능성이 높고 논문 이해에 중요한 어휘를 제안하는 논문 읽기 중심 어휘 학습 앱입니다.

핵심 흐름은 다음과 같습니다.

온보딩으로 초기 어휘 메모리 생성
  -> PDF 업로드와 본문 추출
  -> LangGraph 기반 핵심 어휘 추천
  -> 읽기 중 known / unknown / confused 태깅
  -> 어휘 메모리 갱신
  -> 메모리 기반 cloze 퀴즈 생성과 채점

데이터는 브라우저의 IndexedDB에 저장하고, LLM 호출은 Next.js Route Handler(/api/agent/generate)를 통해 OpenAI 또는 OpenAI-compatible self-hosted endpoint로 전달합니다. 기본 데모 경로는 LM Studio, Ollama, vLLM 같은 로컬 self-hosted LLM입니다.

주요 기능

  • 연구 분야, 논문 독해 경험, 어휘 자신감을 바탕으로 초기 known 어휘 메모리 생성
  • PDF 업로드, 페이지별 텍스트 추출, 원본 PDF blob과 추출 텍스트의 IndexedDB 저장
  • 논문 전체 범위를 page-balanced context로 압축해 핵심 어휘 후보 생성
  • 후보별 한국어 뜻, 원문 문장, 문맥 설명, 중요도 근거, source page 표시
  • 추천어 또는 PDF에서 직접 선택한 표현을 known, unknown, confused로 태깅
  • /memory에서 어휘 메모리 검색, 상태 수정, 삭제
  • /cloze에서 메모리 기반 빈칸 퀴즈 생성, 정답/오답에 따른 메모리 상태 갱신
  • agent monitor, LangGraph diagram rendering, LangSmith 평가 스크립트 제공

기술 스택

  • Next.js 16 App Router, React 19, TypeScript
  • Tailwind CSS 4, ESLint 9, Vitest, Playwright
  • Dexie / IndexedDB for local persistence
  • pdfjs-dist for PDF rendering and text extraction
  • LangGraph for workflow orchestration
  • LangChain OpenAI adapter for OpenAI-compatible chat endpoints
  • Zod-based structured output parsing and coercion

초기 셋업

요구 사항:

  • Node.js >=20.9.0
  • npm >=10 권장
  • LLM provider 1개: OpenAI API key 또는 로컬 OpenAI-compatible server

설치와 실행:

npm install
npm run dev

브라우저에서 http://localhost:3000을 엽니다.

첫 실행 순서:

  1. LLM 공급자 설정 다이얼로그에서 provider를 저장합니다.
  2. 온보딩 화면에서 연구 분야와 독해 수준을 입력합니다.
  3. 초기 어휘 메모리 생성이 끝나면 PDF를 업로드합니다.
  4. /paper?paperId=...에서 추천 어휘를 확인하고 태깅합니다.
  5. /memory/cloze에서 메모리와 퀴즈 흐름을 확인합니다.

이 README의 명령 예시는 npm 기준입니다. 현재 저장소에는 package-lock.jsonpnpm-lock.yaml이 함께 있으므로, 재현성을 위해 한 작업 환경에서는 하나의 package manager만 사용하세요.

LLM 공급자 설정

Self-hosted 권장 경로

셀프 호스팅 탭에서 Base URL과 모델명을 입력합니다. 대부분의 로컬 서버는 API key를 비워도 됩니다.

예시:

LM Studio: http://localhost:1234/v1
Ollama:    http://localhost:11434/v1
vLLM:      http://localhost:8000/v1

주의 사항:

  • 현재 LLM 호출은 /api/agent/generate 서버 라우트를 경유하므로 일반적인 브라우저 CORS 설정은 필요하지 않습니다. 단, 로컬 LLM 서버 자체가 origin/client 제한을 두는 경우에는 PaperVoca 개발 서버의 요청을 허용해야 합니다.
  • 서버 라우트는 기본적으로 localhost, 127.0.0.1, ::1, 0.0.0.0 self-hosted endpoint만 허용합니다.
  • 원격 self-hosted endpoint를 명시적으로 허용하려면 실행 환경에 PAPERVOCAB_ALLOW_REMOTE_SELF_HOST=true를 설정해야 합니다.
  • 공개 인터넷의 임의 endpoint를 넣으면 논문 본문과 어휘 메모리 일부가 그 서버로 전송됩니다.

OpenAI API

OpenAI API 탭에서 sk-... 형식의 API key와 모델명을 저장합니다. 모델명을 비우면 UI는 gpt-4o-mini를 기본값으로 사용합니다.

보안 경계:

  • provider 설정은 브라우저 localStorage에 저장됩니다.
  • LLM 호출 시 provider 설정은 /api/agent/generate 요청 본문으로 전달됩니다. 로컬 개발에서는 같은 머신의 Next 서버가 이를 처리합니다.
  • 논문, PDF 파일, 후보, 어휘 메모리, 퀴즈 세션은 브라우저 IndexedDB에 저장됩니다.
  • 외부 공유 PC에서는 사용하지 마세요.
  • 외부 데모나 다중 사용자 배포에서는 개인 API key를 브라우저에 저장하는 방식 대신 서버 환경변수 또는 gateway 기반 구성을 별도로 설계하세요.

자주 쓰는 명령

npm run dev                  # 개발 서버
npm run build                # production build
npm start                    # build 결과 실행
npm run lint                 # ESLint
npm test                     # Vitest 전체 테스트
npm run monitor:agent        # local agent workflow event monitor
npm run graph:agent          # vocabulary LangGraph diagram asset 생성
npx tsx scripts/render-quiz-langgraph.ts

선택 실행:

node scripts/e2e-lmstudio.mjs
node scripts/e2e-paper-layout.mjs
npm run langsmith:vocab:dataset
npm run langsmith:vocab:experiment

LM Studio E2E와 LangSmith 평가는 별도 로컬 LLM 또는 LangSmith 환경변수가 필요합니다.

프로젝트 구조

app/
  page.tsx                  # 홈, 온보딩 상태 확인, PDF 업로드 진입
  onboarding/page.tsx       # 초기 사용자 프로필과 어휘 메모리 생성
  paper/page.tsx            # PDF reader, 추천 어휘, 직접 선택 태깅
  memory/page.tsx           # 어휘 메모리 조회/수정/삭제
  cloze/page.tsx            # 메모리 기반 빈칸 퀴즈
  review/page.tsx           # /cloze redirect
  api/agent/generate/route.ts
                            # LLM prompt execution server boundary

components/
  ApiKeyDialog.tsx          # provider 설정 입력
  Header.tsx                # provider 상태와 reset/data 관리 진입점
  UploadCard.tsx            # PDF 업로드와 텍스트 추출
  PdfViewer.tsx             # PDF 렌더링과 텍스트 선택
  CandidateList.tsx         # 추천 어휘 리스트와 태깅 UI
  ReviewControls.tsx        # 퀴즈/복습 상태 컨트롤

lib/
  db.ts                     # Dexie schema: papers, vocabMemory, feedback, quizSessions 등
  storage.ts                # localStorage provider config와 memoryVersion
  pdf.ts                    # PDF text extraction
  vocab.ts                  # 후보 캐시, 태깅, 직접 선택 후보 생성
  memory.ts                 # 어휘 메모리 CRUD와 status update
  review.ts                 # review seed와 cloze item formatting
  reviewPipeline.ts         # quiz content LangGraph workflow
  quizSessions.ts           # quiz session 생성, 채점, status 반영
  llm/                      # provider, server/client boundary, self-hosted compatibility
  agent/                    # prompts, schemas, parsing, tools, workflows, quality policy

scripts/
  agent-monitor.mjs         # workflow event monitor
  render-agent-graph.ts     # vocabulary workflow diagram generation
  render-quiz-langgraph.ts  # quiz workflow diagram generation
  e2e-*.mjs                 # Playwright 기반 smoke/E2E helpers
  langsmith/                # vocabulary evaluation dataset/experiment scripts

__tests__/ and tests/
  Vitest unit/integration tests for storage, memory, agent workflow, review, route, parsing

docs/
  agentic-architecture.md
  papervoca-memory-centered-learning-prd.md
  papervoca-final-demo-guide.md
  test-and-evaluation-report.md
  assets/

Agentic Workflow 구조

1. Prompt execution boundary

브라우저 UI는 provider 설정과 task input을 /api/agent/generate로 보냅니다. 서버 라우트는 task id를 검증하고, task별 PromptSpec과 Zod schema를 사용해 structured output을 생성합니다.

지원 task:

  • onboarding_memory
  • vocabulary_suggestions
  • vocabulary_reflection_judge
  • manual_selection_candidate
  • cloze_review_content

2. Vocabulary planning graph

사전 읽기 어휘 추천은 lib/agent/vocabularyGraph.tslib/agent/workflows/에 있는 LangGraph workflow가 담당합니다.

START
  -> loadPaperContext
  -> proposeVocabulary
     -> validate_vocabulary_candidates tool call attempt
  -> reflectVocabulary
     -> repairVocabulary? -> judgeVocabulary?
  -> persistSuggestions
END

주요 특징:

  • PDF 전체를 page-balanced excerpts로 구성해 첫 페이지만 과대표집하지 않습니다.
  • known, unknown, confused 메모리를 분리해 prompt에 주입합니다.
  • LLM-bound validation tool call을 먼저 시도하고, provider가 tool calling을 지원하지 않으면 direct JSON 경로로 fallback합니다.
  • reflection은 이미 known인 단어 포함, 임의 단어열 후보 등 명확한 문제만 repair trigger로 봅니다.
  • repair가 실패하거나 judge를 사용할 수 없으면 deterministic fallback으로 initial/repaired 후보 중 더 나은 쪽을 선택합니다.
  • 최종 후보는 IndexedDB candidatesextractionCache에 저장됩니다.

자세한 설명은 docs/agentic-architecture.md를 참고하세요.

3. Review / cloze quiz graph

복습 콘텐츠는 lib/reviewPipeline.ts의 LangGraph workflow로 생성합니다.

START
  -> loadReviewSeeds
  -> planReviewContent
  -> generateReviewContent
  -> persistReviewContent
END

unknownconfused 메모리를 우선 복습 대상으로 삼고, LLM이 생성한 cloze 문항을 reviewContent에 저장합니다. 사용자의 정답은 해당 단어를 known으로, 오답은 confused로 갱신하며 memoryVersion을 올려 이후 추천 캐시가 stale 상태가 되게 합니다.

4. Monitoring and evaluation

개발 중에는 다음 명령으로 workflow event를 터미널에서 볼 수 있습니다.

npm run monitor:agent

평가와 검증 계획은 다음 문서에 정리되어 있습니다.

데이터 모델 요약

주요 IndexedDB 테이블:

  • userProfile: 온보딩 프로필과 초기 메모리 생성 상태
  • papers: 업로드 논문 metadata와 페이지별 추출 텍스트
  • paperFiles: 원본 PDF blob
  • candidates: 논문별 추천 어휘 후보
  • vocabMemory: 장기 어휘 메모리와 현재 status
  • feedback: 태깅과 메모리 변경 이벤트
  • extractionCache: text hash, memory version, prompt/schema version 기반 추천 캐시
  • reviewContent: 생성된 cloze 복습 콘텐츠
  • quizSessions: 퀴즈 세션, 답안, 정답/오답 결과

검증 상태

현재 테스트 표면:

  • npm test: storage, memory, vocabulary workflow, parsing, review, quiz session, API route 테스트
  • npm run lint: Next.js/TypeScript ESLint
  • npm run build: production build
  • node scripts/e2e-lmstudio.mjs: LM Studio 기반 주요 사용자 흐름 E2E

최근 문서화된 결과는 docs/test-and-evaluation-report.md에 있습니다.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages