Obsidian × Claude Code 연구보조 시스템
(a) 본인의 프로젝트 파일로부터 스스로 구축되고, (b) 작업하는 동안 갱신되며, (c) 구조화된 질의에 답하는("X의 PI는 누구지?", "Y는 어떤 방법론을 쓰지?", "이번 주에 뭐가 바뀌었지?") 영구 지식 그래프 하나를 원하는 학술 연구자를 위한 재현 가능한 셋업입니다. 이 시스템은 로컬에서 돌아가고, agent로 Claude Code(또는 Codex)를, vault UI로 Obsidian을, 저렴한 LLM 판단용으로 OpenRouter(Gemini Flash)를 사용합니다.
왜 이게 필요한가 — 연구자는 수십 개의 폴더에 걸쳐 단편적인 컨텍스트(프로젝트 초안, 회의 노트, 방법론 결정, 그랜트 마감, 지도학생 상태)를 쌓아갑니다. vault 자체는 그냥 저장만 합니다. 이 레이어가 그것을 자기조직적이고 질의 가능하게 만듭니다. 단일 진입점 페이지가 매일 반복되는 "내가 어디까지 했더라?" 검색을 대체합니다.
1. 무엇을 얻는가
- 단일 진입점 페이지(
wiki/Today.md) — 모든 세션이 여기서 시작됩니다. 라우팅 치트시트, 현재 마감, 프로젝트 우선순위 티어, 자동 갱신되는 "최근 활동" 블록이 있습니다. - 지식 온톨로지(197+ 노드 / 2200+ 엣지) — frontmatter + 위키링크에서 자동 추출되어 JSON-LD + 인터랙티브 D3 그래프로 export됩니다. 엔티티("MyProject"), 술어("hasPI"), 또는 타입("Grant")으로 질의합니다.
- 자동 세션 디제스트 — 모든 Claude Code 또는 Codex 세션이
wiki/sources/Sessions YYYY-MM-DD.md에 구조화된 노트(목표 · 결과 · 핵심 결정 · 손댄 파일 · 다음 단계)로 끝납니다. - 연구 노트 워처 — 2시간마다 새 노트/소스 파일을 스캔하고, 무엇이 바뀌었는지 LLM이 판단하여 vault 업데이트(마감, 상태, 새 협업자)를
wiki/situation/YYYY-MM-DD.md에 제안합니다. 높은 confidence 변경은 자동 적용됩니다. - 데스크탑 정리기 — Desktop 루트의 흩어진 파일을 LLM이 판단하여 구조화된 폴더로 분류하고,
--undo를 지원하는 manifestDesktop\_organize_log\<run-id>.txt를 남깁니다. - /slides 워크플로 —
/slides <topic>이 캐시된 open-design 스킬 템플릿 + 본인 vault 콘텐츠를 사용해 단일 파일 HTML 슬라이드덱을 생성합니다. - 영구 메모리 —
~\.claude\projects\<machine>\memory\가 모든 세션에서 자동 로드됩니다. 향후 세션은 본인의 프로젝트, 지도학생, 방법론, 취향을 다시 설명하지 않아도 압니다.
모두 로컬에서 돌아갑니다. LLM 비용 ~$0.02-0.05/일.
2. 아키텍처
┌──────────────────────────────────────────────────────┐
│ Obsidian vault (wiki/) │
│ │
│ entities/ projects · people · grants · labs │
│ concepts/ methodology · theory · patterns │
│ sources/ manuscripts · digests · session logs │
│ activity/ daily auto-aggregated activity │
│ situation/ LLM-judged change proposals │
│ │
│ Today.md ← single entry point │
│ _ontology.json + _ontology_graph.html │
└──────────────────────────────────────────────────────┘
▲
│
┌───────────────────────────────────┼───────────────────────────────────┐
│ │ │
▼ ▼ ▼
Session digests Daily tracker (every 2h) On-demand commands
(Claude Stop hook + ───────────────────────── /slides · /recall
codex_digest.ps1) • file activity scan query_ontology.py
• git commits apply_situation.py
• GitHub events organize_desktop.py
• calendar / notes
• ontology rebuild
• situation watch (LLM)
• desktop organizer (LLM)
세 개의 영속성 레이어:
| 레이어 | 위치 | 목적 |
|---|---|---|
| 프로젝트 지식 | wiki/ |
프로젝트/방법론/사람에 대한 인용·질의 가능한 사실. frontmatter(type:, deadline:, status:)를 가진 엔티티 페이지. |
| 활동 / 집계 | wiki/activity/ + wiki/situation/ + wiki/sources/Sessions YYYY-MM-DD.md |
트래커와 세션 훅이 자동으로 기록하는 시계열 스냅샷. |
| 자동 메모리 | ~\.claude\projects\<machine>\memory\ |
Claude가 시작 시 읽는 세션 간 포인터. 인덱스 파일 MEMORY.md는 항상 컨텍스트에 있음. |
프라이버시 자세: 모든 것이 로컬 우선입니다. vault는 순수 마크다운입니다. 외부 호출은 (a) 선택적 OpenRouter LLM completion과 (b) 선택적 GitHub 활동용 gh CLI뿐입니다. 민감한 소스는 vault 밖에 둡니다 — § 8 참고.
3. 사전 요구사항
- Obsidian(v1.9.10+ 권장)
- Claude Code CLI 설치 및 인증
- Python 3.11+(스크립트용)
- PowerShell(Windows) — macOS/Linux의 Bash도 경로만 약간 바꾸면 비슷하게 동작
- 인증된
ghCLI(선택 — GitHub 활동용) _secrets/openrouter.txt또는$env:OPENROUTER_API_KEY에 저장된 OpenRouter API key(선택 — LLM 판단용. 없으면 시스템이 우아하게 degrade)- 소스 파일 텍스트 추출용
pdfplumber,python-docx,openpyxl,python-pptx가 설치된 Python venv 또는 시스템 설치
4. 셋업 워크스루
4.1 Vault 부트스트랩
claude-obsidian seed에서 시작하거나, 빈 Obsidian vault 아무거나에서 시작하세요. 이 가이드가 가정하는 폴더 레이아웃:
ObsidianVault/
├── CLAUDE.md ← vault-level Claude Code instructions
├── wiki/
│ ├── Today.md ← single entry point (write the template once)
│ ├── index.md ← table of contents
│ ├── overview.md ← project-portfolio narrative
│ ├── log.md ← append-only event log
│ ├── entities/
│ ├── concepts/
│ ├── sources/
│ ├── activity/ ← created automatically
│ ├── situation/ ← created automatically
│ ├── _ontology.json ← generated
│ ├── _ontology_summary.md
│ └── _ontology_graph.html
└── scripts/ ← all automation lives here
시스템을 seed하기 위해 엔티티 페이지 몇 개를 손으로 작성하세요 — 주요 프로젝트/그랜트/방법론마다 wiki/entities/<Name>.md를 다음 frontmatter로 생성합니다:
---
type: project # or grant | concept | person | course | manuscript | lab | tool
title: "MyProject"
status: active
tier: 2
deadline: 2026-05-20
related:
- "<span class="wikilink">Jane Researcher</span>"
- "<span class="wikilink">Bayesian Causal Forest</span>"
---
# MyProject
[narrative body — methodology, status, decisions, links to other entities]
크로스링크(본문의 <span class="wikilink">...</span> 위키링크)가 풍부할수록 온톨로지가 관계를 더 잘 재구성합니다.
4.2 User-level CLAUDE.md("항상 로드" 지침)
C:\Users\<you>\CLAUDE.md(또는 ~/CLAUDE.md)에 CLAUDE.md를 둡니다. Claude Code는 부모 체인을 거슬러 올라가 어떤 작업 디렉토리에서든 이걸 자동 로드합니다. 이것이 "기억해봐 / tell me about X"를 즉시 grounding되게 만듭니다.
핵심 내용:
# User-level Claude Code instructions
## On every session start
1. Read `<vault>/wiki/Today.md` — single entry point.
2. Auto-memory at `~\.claude\projects\<machine>\memory\MEMORY.md` is already loaded.
3. Prefer existing knowledge bases over reasoning from scratch.
## Knowledge bases (in priority order)
| Source | What | How to query |
|---|---|---|
| wiki/Today.md | deadlines, priorities, recent | Read |
| wiki/_ontology.json | structured: 12 entity types + 14 relations | Read or query_ontology.py |
| wiki/entities/<Name>.md | per-entity narrative | Read directly |
| wiki/concepts/ | methodology pages | Read |
| wiki/situation/<date>.md | latest LLM-judged changes | Read |
| wiki/sources/Sessions <date>.md | session logs | Read for "what did I do" |
## On "make a slide deck / PT 만들어"
Invoke /slides <topic> — see ~/.claude/commands/slides.md.
4.3 슬래시 커맨드
~/.claude/commands/recall.md:
---
description: Recall context for a topic from vault + ontology + memory
argument-hint: "[topic or question]"
---
Read wiki/Today.md first. If $ARGUMENTS names a topic, drill: entity page → ontology query → daily situation note. Cite via <span class="wikilink">wikilinks</span>. Korean reply OK.
~/.claude/commands/slides.md — 전체 스펙은 § 6 참고.
4.4 스크립트
이것들을 <vault>/scripts/에 둡니다(전체 내용은 동반 코드 레포에 있음). 각각의 간략한 목적:
| 스크립트 | 트리거 | 하는 일 |
|---|---|---|
update_today.ps1 |
Stop 훅 + 수동 | Today.md § Recent 블록 갱신(최근 7일 vault 편집, frontmatter의 마감) |
save_session.ps1 |
Stop 훅 | transcript로 digest_session.py 호출, 그다음 update_today.ps1 |
digest_session.py |
save_session이 호출 | Claude/Codex JSONL transcript를 파싱, LLM 요약, wiki/sources/Sessions YYYY-MM-DD.md에 추가 |
codex_digest.ps1 |
Codex 세션 후 수동 | 최신 Codex rollout을 찾아 digest_session.py 실행 |
daily_tracker.ps1 |
2시간마다 예약 작업 | 오케스트레이터 — 아래 모든 collector 호출 |
build_ontology.py |
트래커 §8 | wiki/를 순회, frontmatter + 위키링크 파싱, _ontology.json + summary + D3 그래프 생성 |
situation_watch.py |
트래커 §9 | 지난 실행 이후 vault에 추가된 새 연구 노트/소스 파일 스캔, 변화를 LLM이 판단, wiki/situation/<date>.md 작성 |
apply_situation.py |
수동 | situation 노트의 AUTO 블록 → 엔티티 페이지 + 온톨로지 재빌드에 적용 |
organize_desktop.py |
트래커 §10 | Desktop 루트의 흩어진 파일을 LLM이 구조화된 폴더로 분류, _organize_log/<run>.txt 작성 |
query_ontology.py |
수동 / /recall에서 | _ontology.json에 대한 빠른 조회(--type Grant, --predicate hasPI, <pattern>) |
collect_github.ps1 |
트래커 | PR/이슈/푸시용 gh CLI |
collect_calendar.ps1 |
트래커 | Outlook 캘린더 오늘+내일 |
collect_notes.ps1 |
트래커 | Sticky Notes(UWP plum.sqlite) + Outlook Notes 폴더 |
collect_social.ps1 |
트래커 | 사용자가 토큰을 연결하면 LinkedIn/X/Notion용 스텁 |
4.5 Claude Code Stop 훅
~\.claude\settings.json을 편집:
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File \"<vault>\\scripts\\save_session.ps1\" -Source claude"
}
]
}
]
}
}
이후, 종료되는 모든 Claude Code 세션이 wiki/sources/Sessions YYYY-MM-DD.md에 구조화된 디제스트를 자동 기록합니다.
4.6 Windows 예약 작업(2시간마다)
schtasks.exe /Create /TN "ResearchAssistantTracker" /SC DAILY /ST 00:00 /RI 120 /DU 23:59 /TR "powershell.exe -NoProfile -ExecutionPolicy Bypass -File <vault>\scripts\daily_tracker.ps1" /F
# Allow run-when-missed (catch-up after computer was off):
$task = Get-ScheduledTask -TaskName ResearchAssistantTracker
$task.Settings.StartWhenAvailable = $true
$task.Settings.DisallowStartIfOnBatteries = $false
$task.Settings.StopIfGoingOnBatteries = $false
Set-ScheduledTask -TaskName ResearchAssistantTracker -Settings $task.Settings
이 작업은 하루 12회(00:00, 02:00, …, 22:00) 실행됩니다. 슬롯 시점에 컴퓨터가 꺼져 있으면 Windows가 깬 직후 가능한 한 빨리 실행합니다. 트래커의 동적 윈도우 로직은 .tracker_state.json을 사용해 "마지막 성공 실행 이후 경과 시간"을 계산하고 그에 따라 스캔 윈도우를 넓힙니다(최대 7일로 제한).
5. 컴포넌트 상세
5.1 vault 온톨로지
스키마는 wiki/concepts/Vault Ontology.md에 있습니다 — 12개 엔티티 타입과 14개 관계의 사람이 읽을 수 있는 스펙. 빌드 스크립트 build_ontology.py:
- 모든
wiki/**/*.md를 순회하고, frontmatter에서type:을 파싱합니다. - 각 페이지를
vault:<type>/<slug>를 키로 하는 노드로 등록합니다. - 본문의 각
<span class="wikilink">wikilink</span>에 대해, 링크 주변 ±100자 윈도우를 보고 관계 cue를 매칭하려 시도합니다: - "PI" / "Principal Investigator" →hasPI- "advisee of" / "supervised by" →advisedBy- "uses" / "applies" / "method" →usesMethod- "funded by" / "$" →fundedBy- … 총 14개 관계. - 타입-도메인 강제 — subject 타입이 관계의 선언된 도메인과 맞지 않으면(예:
hasPI는Project|Grant → Person), subject/object를 교체합니다. 이는 사람의 페이지가 "MyProject (PI)"를 언급하는 흔한 패턴을 처리합니다 → 역방향이 아니라MyProject hasPI <Person>을 생성합니다. _ontology.json(foaf/schema/skos/vault 네임스페이스를 가진 JSON-LD),_ontology_summary.md(개수 + 허브 + 고아 노드),_ontology_triples.tsv(grep용 flat),_ontology_graph.html(D3 force-directed, 타입별 색상 노드, 타입 필터 체크박스)을 생성합니다.
질의:
python query_ontology.py "MyProject" # show entity + outbound + inbound
python query_ontology.py --predicate hasPI # all PI relationships
python query_ontology.py --type Grant # all grants with email_count etc.
python query_ontology.py --orphans # degree-0 nodes (likely stubs)
Person 노드의 샘플 출력 — 그 사람이 PI인 그랜트(hasPI), 그 사람의 지도학생(advisedBy), 협업자를 보여줍니다.
5.2 진입점으로서의 Today.md
Today.md는 엄격한 구조를 갖습니다:
- § 1 라우팅 치트시트 — "X를 물으면 Y를 보라" 표
- § 2 활성 마감 — frontmatter에
deadline: YYYY-MM-DD가 있는 모든 엔티티 페이지에서 자동 수집 - § 3 프로젝트 우선순위 티어 — 수동 편집(사용자가 정기적으로 손대는 유일한 섹션)
- § 4 최근 활동(자동) — 최근 7일 vault 편집 + 새로 추가된 소스 파일(
<!-- BEGIN AUTO RECENT -->마커 사이,update_today.ps1이 재생성) - § 5 미해결 후속 작업 — 수동 큐
- § 6 세션 / 자동화 상태 — 모든 훅/작업과 그 내용 + 트리거 표
- § 7 빠른 명령 — 가장 많이 쓰는 PowerShell 명령 5-6개
Stop 훅이 모든 Claude Code 세션 후 § 4를 재생성하므로, 절대 stale해지지 않습니다.
5.3 세션 디제스트
Claude Code 세션이 끝나면, Stop 훅이 stdin JSON으로 transcript_path를 받습니다. digest_session.py:
- JSONL을 파싱합니다 — Claude Code의 경우:
message.content블록을 가진type=user|assistant. Codex의 경우: 중첩된payload.type=message|function_call|custom_tool_call을 가진type=response_item. - 개수를 셉니다: 사용자 메시지, Edit/Write/Read한 파일, Bash 명령.
- 상위 30개 사용자 메시지 + 마지막 assistant 텍스트 + 도구 신호를 OpenRouter Gemini Flash에 프롬프트와 함께 보냅니다: "JSON
{topic, goal, outcome, key_decisions, next, tags}로 요약하라." ## HH:MM-HH:MM [source] <topic> (sid: 8char)섹션을wiki/sources/Sessions YYYY-MM-DD.md에 추가합니다.wiki/log.md에 한 줄 항목.
사용자 메시지가 3개 미만인 세션은 건너뜁니다. 세션당 비용: ~$0.001.
Codex(Stop 훅 없음)의 경우, 사용자가 각 세션 후 pwsh codex_digest.ps1을 실행합니다 — 최신 ~/.codex/sessions/*.jsonl을 찾아 같은 디제스트를 실행합니다.
5.4 Situation watch(연구 노트 트래커)
가장 LLM을 많이 쓰는 컴포넌트입니다. 2시간마다:
- vault
wiki/sources/와wiki/.raw/에서situation_eval의 마지막 확인 timestamp 이후 새로 추가되거나 수정된 파일을 스캔합니다(작은 SQLite 테이블 또는 JSON 파일에 추적). - Triage: 각 새 노트를 (a) 온톨로지 vocab(149개 엔티티)에 대한 엔티티 매칭, (b) 중요도 키워드("deadline", "decision", "submitted", "rejected", "approved", "Co-PI", "defense", "R&R", "IRB approval", + 한국어 대응어), (c) 첨부 개수로 점수화합니다.
- 상위 N개(기본 10개) → 엄격한 프롬프트로 OpenRouter에: 상황 변화를 JSON
{entity_label, change_type, new_value, evidence_quote, confidence, auto_applicable, reasoning}으로 식별. [AUTO]와[REVIEW]블록 + triage 표와 함께wiki/situation/YYYY-MM-DD.md에 출력.- 평가된 모든 노트 ID를
situation_eval에 표시하여 다음 실행에서 다시 LLM에 보내지 않게 합니다.
자동 적용 정책은 보수적입니다: confidence ≥ 0.85 AND change_type ∈ {deadline_update, status_update, progress_update}. 그 외 모든 것(역할 변경, 새 협업자, 새 방법론)은 사용자 검토를 기다립니다.
apply_situation.py는 일별 노트를 읽고, [AUTO] 블록을 찾고, 대상 엔티티 페이지를 조회하여 frontmatter(deadline: / status:)를 upsert하고, evidence quote와 함께 ## Recent situation updates 본문 줄을 추가하고, wiki/log.md에 로깅하고, 마지막으로 온톨로지를 재빌드합니다. 결과: 네트워크 그래프가 몇 분 안에 새 상태를 반영합니다.
5.5 데스크탑 정리기
데스크탑에 임의의 파일을 저장하면, organize_desktop.py(2시간마다, --apply와 함께):
- Desktop 루트 파일만 나열합니다 — 구조화된 폴더로는 절대 재귀하지 않습니다.
- 건너뛰는 것:
credential.txt및 기타 시크릿;~$*Word/Excel 잠금 파일;desktop.ini; 최근 60분 내 수정된 파일(아마 활발히 편집 중); 점 파일;*.lnk/*.crdownload/*.tmp. - 각 후보에 대해: 텍스트 미리보기 추출(PDF는 pdfplumber, docx는 python-docx 등), 목적지 화이트리스트(
_archive,_projects,_writing,22_Grants,20_Advising,27_Media/_screenshots…)와 온톨로지 엔티티 카탈로그와 함께 LLM에 전송. - LLM이
{action, destination, destination_subpath, confidence, reason}을 반환합니다. - confidence ≥ 0.90에서만 자동 이동 AND 목적지가 화이트리스트에 있을 때. 그 외 모든 것은 manifest에 REVIEW로 남습니다.
- Manifest:
Desktop\_organize_log\YYYY-MM-DD_HHmm.txt. 일반 텍스트, 세 섹션(이동된 파일 / 제안 / 검토 필요), 모든 이동을 FROM → TO + 이유 + confidence와 함께. - 모든 이동은
--undo <run-id>되돌리기를 위해Desktop\_organize_log\.history.jsonl에 추가됩니다.
금지된 목적지: _secrets. LLM이 파일을 거기로 라우팅하라고 제안하면, 스크립트는 review_needed로 다운그레이드합니다.
5.6 /slides 워크플로
사용자가 /slides <topic>(또는 자연어 "PT 만들어 줘 / make a deck about X")을 입력합니다. ~/.claude/commands/slides.md의 슬래시 커맨드가 agent에게 다음을 지시합니다:
Desktop\_tools\open-design-cache\skills\의 캐시된 템플릿에서 스킬을 선택합니다.nexu-io/open-design에서 캐시됨: -magazine-web-ppt(기본, 에디토리얼 매거진) -html-ppt-knowledge-arch-blueprint(연구 방법론 / 시스템 아키텍처) -html-ppt-course-module(교육 / 워크샵) -html-ppt-pitch-deck(그랜트 제안 / 펀드레이징) -html-ppt-product-launch(도구/기능 공개)SKILL.md+references/*.md+assets/template.html(또는example.html)을 읽습니다 — 이것들은 비활성 마크다운/HTML 스펙이며 코드 실행이 없습니다.- 토픽에 대한 vault 콘텐츠를 끌어옵니다:
wiki/entities/<topic>.md→wiki/concepts/→query_ontology.py "<topic>"→ vault가 부실할 때 선택적 웹 리서치. - 먼저 8-15장 슬라이드 outline을 제안합니다; 사용자가 OK.
Desktop\_PTs\<YYYY-MM-DD>_<topic-slug>\index.html에 단일 파일 self-contained HTML을 생성합니다 — 모든 CSS/JS는 inline, 폰트는 CDN에서.wiki/sources/Decks <year>.md에 항목을 추가합니다.
비용: ~3-5분 생성, 길이에 따라 덱당 $0.005-0.02.
6. 일상 흐름(실제로 어떻게 보이는가)
아침 — vault를 열고 Today.md를 봅니다. § 2는 현재 마감(D-카운터)을, § 3은 프로젝트 우선순위 티어를, § 4는 지난 7일간 무엇이 바뀌었는지(그리고 밤새 어떤 새 연구 노트 / 소스 파일이 추가됐는지)를 보여줍니다.
작업 중 — 본인의 머신 어디서든 Claude Code 세션을 시작합니다. CLAUDE.md가 자동 로드되고, MEMORY.md가 자동 로드되며, 즉시 "X 상태가 어때?"나 "Y에 대한 슬라이드덱 만들어"라고 물을 수 있습니다. agent는 재설명 없이 전체 컨텍스트를 갖습니다.
2시간마다(백그라운드) — 트래커가 발동합니다. wiki/sources/의 새 소스 파일이 스캔되고, 중요한 변화가 wiki/situation/<date>.md에 제안되고, 온톨로지가 재빌드되고, Today.md가 갱신되고, Desktop의 흩어진 파일이 분류됩니다.
세션 종료 — Stop 훅이 digest_session.py를 실행하여 wiki/sources/Sessions <date>.md에 구조화된 항목을 추가합니다. 다음에 여는 세션이 그것을 Read하여 본인이 무엇을 결정했는지 기억할 수 있습니다.
주말 — 제안된 변경을 위해 wiki/situation/<date>.md 파일들을 검토하고, apply_situation.py로 적용하고, 본인이 실제로 무엇을 만들었는지 기록을 위해 wiki/sources/Sessions <date>.md를 훑어봅니다.
7. 비용 & 성능
| 컴포넌트 | 빈도 | 비용 |
|---|---|---|
| 일별 트래커(collector만, LLM 없음) | 2시간마다 | ~무료, ~30초 wall time |
| 온톨로지 재빌드 | 2시간마다 | ~무료, ~3초 |
| Situation watch(LLM) | 2시간마다, 새 노트 상위 10개 | ~$0.001-0.005/실행 |
| 세션 디제스트(LLM) | 매 세션 종료 | ~$0.001/세션 |
| 데스크탑 정리기(LLM) | 2시간마다, ~5-15개 흩어진 파일/일 | ~$0.001/일 |
| /slides 생성(Claude Code 자체를 통한 LLM) | 온디맨드 | ~$0.005-0.02/덱 |
| 합계 | OpenRouter를 통한 Gemini Flash로 ~$0.02-0.05/일 |
~10배 품질을 ~10배 비용에 원하면 anthropic/claude-3.5-haiku로 전환하세요(여전히 $0.50/일 미만).
8. 프라이버시와 안전성
- vault는 집계만 담습니다, 원본 민감 콘텐츠가 아닙니다. 이메일 본문, IRB 참가자 데이터, credential 파일은 절대 vault에 들어가지 않습니다. 본인이 추가한 소스 노트는 situation_watch 요약 중 LLM에 보이므로, 자동 처리하고 싶은 연구 노트에 민감한 PII를 붙여넣지 마세요 — 그런 것은 워처에서 제외된 별도 폴더에 두세요.
- 데스크탑 정리기는 명시적인
_secrets금지를 갖습니다(LLM 추천 시크릿 라우팅은 수동 검토로 다운그레이드). 또한 최근 60분 내 수정된 파일(아마 활발히 편집 중), Word/Excel 잠금 파일, 모든desktop.ini/thumbs.db를 건너뜁니다. - Undo 지원 — 모든 데스크탑 이동은
_organize_log/.history.jsonl에 로깅됩니다;python organize_desktop.py --undo <run-id>가 전체 실행을 되돌립니다. - situation_watch의 적용 정책은 보수적입니다 — confidence ≥ 0.85인
deadline_update / status_update / progress_update만 자동 적용됩니다. 역할 변경, 새 협업자, 펀딩 결정은 모두 REVIEW로 남습니다. - 로컬 우선 — vault는 순수 마크다운, 온톨로지는 순수 JSON-LD입니다. 독점 포맷 없음, 동기화 요구 없음. 오프라인에서 동작(네트워크 없으면 LLM 단계가 우아하게 건너뛰어짐).
- OpenRouter key는 vault 밖
_secrets/에만 저장되어 런타임에 읽힙니다. 절대 커밋되지 않음.
9. 커스터마이징
새 엔티티 타입 추가
wiki/concepts/Vault Ontology.md§ 1(Entity types)에 행을 추가합니다.build_ontology.py의infer_type()에 타입 감지 규칙을 추가합니다(경로 기반 fallback 또는type:frontmatter).--type조회를 원하면query_ontology.py의 타입 필터에 추가합니다.
새 관계 추가
- cue 구절과 함께
wiki/concepts/Vault Ontology.md§ 2(Relation types)에 행을 추가합니다. - cue 정규식 + subject_types + object_types와 함께
build_ontology.py의RELATION_RULESdict에 항목을 추가합니다. - 향후 온톨로지 재빌드가 자동으로 이를 인식합니다.
새 슬라이드 스킬 추가
gh api "repos/nexu-io/open-design/contents/skills/<skill-id>/SKILL.md" --jq '.content' | base64 -d > Desktop\_tools\open-design-cache\skills\<skill-id>\SKILL.md
gh api "repos/nexu-io/open-design/contents/skills/<skill-id>/example.html" --jq '.content' | base64 -d > Desktop\_tools\open-design-cache\skills\<skill-id>\example.html
그다음 ~/.claude/commands/slides.md § 2에 라우팅 규칙을 추가합니다.
일별 트래커에 새 collector 추가
기존 § 1-10 블록 뒤에 daily_tracker.ps1에 새 섹션을 추가합니다. 패턴:
$lines += ''
$lines += '## My new collector'
$lines += ''
$out = & <command> 2>$null
if ($out) { $lines += $out } else { $lines += '- (no new <thing>)' }
OpenRouter를 다른 LLM 제공자로 교체
모든 스크립트는 상단에서 OPENROUTER_URL과 MODEL 상수를 읽습니다. https://api.anthropic.com/v1/messages(헤더 변경 포함) 또는 로컬 Ollama(http://localhost:11434/api/chat)로 바꾸세요 — response_format JSON 계약은 동일하게 유지하세요.
10. 트러블슈팅
| 증상 | 가능한 원인 | 해결 |
|---|---|---|
Today.md § Recent가 갱신 안 됨 |
Stop 훅 미설정 또는 PowerShell 경로 오류 | ~\.claude\settings.json 확인; powershell -File save_session.ps1 수동 실행 |
트래커는 발동하는데 activity/<date>.md 없음 |
예약 작업이 잘못된 사용자 / 프로필 없이 실행 | schtasks /Query /TN ResearchAssistantTracker /V /FO LIST, Logon Mode 확인 |
query_ontology.py가 "no matches" 반환 |
레이블 대소문자 불일치 또는 페이지에 frontmatter type: 없음 |
엔티티를 grep하고, frontmatter에 type: project 추가, 온톨로지 재빌드 |
Situation watch가 (LLM error) 출력 |
OpenRouter key 누락/만료 또는 rate-limit | cat _secrets/openrouter.txt, curl ...models로 테스트 |
| organize_desktop이 잘못된 파일 이동 | 과신한 LLM 판단 | manifest에서 python organize_desktop.py --undo <run-id>, AUTO_THRESHOLD 상향 |
| 슬라이드 스킬 누락 | 로컬에 캐시 안 됨 | gh api repos/nexu-io/open-design/contents/skills/<id>/SKILL.md ... |
11. 이벤트 허브로서의 온톨로지(통합 척추)
위 컴포넌트 대부분은 일별 마크다운 파일(activity/<date>.md, situation/<date>.md, sources/Sessions <date>.md)을 생성합니다. 각각은 질의 가능하지만, 별도의 폴더에 삽니다. "지난 7일간 MyProject에 관한 모든 것을 보여줘"를 한 번의 질의로 답할 수 있게 하려면, 온톨로지가 선택된 이벤트를 일급 노드로 흡수합니다.
무엇이 노드가 되고 무엇이 속성으로 남는가
| 이벤트 | 사는 위치 | 온톨로지 노드가 되는가? |
|---|---|---|
| 일별 활동 로그 | wiki/activity/<date>.md |
아니오 — 너무 noisy, 파일 쓰기 churn이 지배적일 것 |
| Situation 변화 | wiki/situation/<date>.md |
아니오 — 적용된 변경이 대상 엔티티의 frontmatter(deadline:, status:)를 변형하고 그것이 이미 인식됨 |
| 데스크탑 파일 이동 | Desktop\_organize_log\<run>.txt |
아니오 — 순수 파일시스템 동작, 의미 관계 없음 |
| 세션 디제스트 | wiki/sources/Sessions <date>.md |
예 — Session 노드 + aboutEntity 엣지 |
| 슬라이드덱 생성 | wiki/sources/Decks <year>.md |
예 — Deck 노드 + aboutEntity 엣지 |
세션과 덱은 연구자가 역사적으로 가장 질의하고 싶어 하는 이벤트입니다: "지난 학기 CSCL에 관한 모든 세션", "AERA-NSF 제안에 대해 내가 만든 모든 덱". 활동 로그와 organize 실행은 운영상의 일시적 데이터입니다; 그 가치는 시간 교차 조인이 아니라 일별 파일에 있습니다.
세 가지 새 엔티티 타입
- Session —
vault:session/<YYYY-MM-DD>-<HHMM>-<source>-<sid8>. 속성:date,ts_start,ts_end,source(claude/codex),sid(8자),topic.wiki/sources/Sessions YYYY-MM-DD.md의##헤딩당 하나. - Deck —
vault:deck/<YYYY-MM-DD>-<topic-slug>. 속성:date,skill(open-design 스킬 id),topic,summary.wiki/sources/Decks YYYY.md의 행당 하나. - Fold —
vault:fold/<sessions|decks>-<YYYY-MM>. 임계값(기본 30일)보다 오래된 모든 Session/Deck 항목을 담는 월별 압축 노드. 멤버는partOfFold엣지를 받습니다. 시각화는 기본적으로 기반 노드를 숨길 수 있습니다.
세 가지 새 관계
aboutEntity— Session/Deck → Project/Grant/Concept/Course/Manuscript/Person/Lab. 섹션 본문의<span class="wikilink">wikilinks</span>와 온톨로지 레이블에 대한 단어 경계 매칭에서 자동 추출.producedBy— Session/Deck → Person. 사용자(또는 다른 기여자). 현재는 vault 소유자로 추론됨.partOfFold— Session/Deck → Fold. 연령 기반 압축 패스 중 설정됨.
fold 압축이 왜 중요한가
retention 없이는, 매 2시간 tick마다 Session 노드가 무한히 추가됩니다. 1년 후면 세션 디제스트만으로 1500-3000개 노드가 되어, 200개의 실질적 엔티티를 압도합니다. Fold 압축:
- 메인 추출 후, 모든 Session과 Deck 노드를 스캔합니다.
- 연-월로 그룹화합니다. 30일보다 오래된 것은
vault:fold/<sessions|decks>-<YYYY-MM>로 가는partOfFold엣지를 받습니다. - 원본 노드에
properties.folded = true를 표시하여 D3 viz가 기본적으로 필터링할 수 있게 합니다. - Fold 노드 자체는 통계용으로
member_count를 운반합니다.
효과: 시스템이 얼마나 오래 돌든 라이브 그래프는 크기가 대략 안정적으로 유지되고(200-300 노드), 전체 이력은 fold된 노드를 숨김 해제하여 질의 가능하게 남습니다.
이벤트 허브 질의하기
# All sessions about MyProject in the last month
python query_ontology.py "MyProject" | grep -A 40 "<-aboutEntity"
# All decks (any topic, any time)
python query_ontology.py --type Deck
# Everything that touched Bayesian Causal Forest (sessions + decks + projects)
python query_ontology.py "Bayesian Causal Forest"
# Total work artifacts about a project: count of aboutEntity edges
python query_ontology.py --predicate aboutEntity | grep MyProject | wc -l
vault-텍스트-as-스냅샷 모델은 엔티티에 대해 여전히 동작하지만, Session/Deck은 온톨로지가 이제 "X에 대해 무엇을, 언제 만들었는가?"에 답하는 시간 레이어를 추가합니다 — flat한 vault 구조로는 닿을 수 없던 질문입니다.
가이드 채택자를 위한 트레이드오프
새로 시작한다면, 결정하세요: - Light(이 가이드의 기본값): Session + Deck을 노드로, 30일 fold. 그래프를 navigable하게 유지하고, 추적할 가치가 가장 큰 두 가지 artifact 타입에 대한 역사적 질의를 지원합니다. - Heavy: SituationChange, OrganizedFile, dailyActivitySummary도 노드화. 1년이면 그래프 triple이 ~50K에 달합니다. 진짜 triple store(예: Apache Jena, Neo4j)가 필요하고 D3 viz는 부적합해집니다. 진정으로 이벤트 교차 SPARQL("어떤 프로젝트가 같은 주에 deadline-update AND 세션을 가졌는가?")이 필요할 때만 유용합니다. 대부분의 연구자는 그렇지 않습니다. - None: 원래의 스냅샷 전용 온톨로지를 유지. 가장 단순하지만, 통합 이력 질의를 잃습니다.
Light 설정이 이 가이드가 겨냥하는 청중에 가장 잘 맞습니다: RDF 스택을 세우지 않고 역사적 작업을 검색하고 싶은 단독 연구자.
12. 왜 이게 동작하는가(디자인 노트)
- 단일 진입점이 검색을 없앤다. 연구자는 컨텍스트를 다시 찾느라 하루 30분 이상을 낭비합니다.
Today.md는 보편적 랜딩입니다 — 모든 세션, 모든 agent, 모든 "내가 어디였지?" 질문이 여기서 시작됩니다. - 영구 메모리가 프롬프트 엔지니어링을 이긴다. 본인의 프로젝트에 대한 사실을
~\.claude\projects\<machine>\memory\에 두면 모든 세션이 자동으로 그것들을 로드합니다; "나는 …에 대해 작업하는 학술 연구자입니다"를 다시 설명할 필요가 없습니다. - flat 태그보다 온톨로지. 타입과 관계 그래프(Project hasPI Person, Project usesMethod Concept, Person advises Person)는 flat 태그가 할 수 없는 방식으로 질의 가능합니다.
내가 참여한 모든 그랜트의 PI는 누구지?는 한 번의 SPARQL/CLI 질의입니다. - LLM은 중심이 아니라 가장자리에. 오케스트레이터는 순수 Python/PowerShell입니다. LLM은 결정 포인트(situation 판단, 파일 라우팅, 슬라이드 생성)에서만 호출됩니다. 시스템 대부분이 무료로 돌아가고, LLM 비용은 triage 필터로 제한됩니다.
- 보수적 자동 적용. 모든 LLM 제안 변경은 confidence 점수와
[REVIEW]fallback을 갖습니다. 지루한 경우(날짜 업데이트, 상태 전환)만 자동 적용합니다. 시스템은 본인의 해석적 콘텐츠를 절대 조용히 재작성하지 않습니다. - 되돌릴 수 있는 작업. 데스크탑 이동은 undo가 있습니다. frontmatter 업데이트는
wiki/log.md에 audit trail을 남깁니다. 온톨로지는 편집되지 않고 재생성됩니다 — 언제나 소스에서 재빌드할 수 있습니다. - 조합 가능. 모든 스크립트는 단일 파일입니다. 각각 한 가지 일을 합니다. 트래커는 200줄 오케스트레이터입니다. 나머지를 건드리지 않고 어떤 조각이든 fork할 수 있습니다.
13. 레포 레이아웃(제안)
research-assistant-system/
├── README.md ← this guide
├── ObsidianVault/
│ ├── CLAUDE.md
│ ├── wiki/
│ │ ├── Today.md (template)
│ │ ├── concepts/
│ │ │ └── Vault Ontology.md
│ │ └── ...
│ └── scripts/
│ ├── daily_tracker.ps1
│ ├── build_ontology.py
│ ├── query_ontology.py
│ ├── digest_session.py
│ ├── situation_watch.py
│ ├── apply_situation.py
│ ├── organize_desktop.py
│ ├── update_today.ps1
│ ├── save_session.ps1
│ ├── codex_digest.ps1
│ ├── collect_github.ps1
│ ├── collect_calendar.ps1
│ ├── collect_notes.ps1
│ └── collect_social.ps1
├── claude-config/
│ ├── settings.json (Stop hook excerpt)
│ └── commands/
│ ├── slides.md
│ └── recall.md
└── examples/
├── entity-page-template.md
├── concept-page-template.md
└── sample-ontology-graph.html
14. 감사의 말
- claude-obsidian — seed vault 구조와 LLM Wiki Pattern.
- nexu-io/open-design — 슬라이드덱 스킬 스펙(magazine / pitch / blueprint / course / launch). 캐시된 SKILL.md + 템플릿 HTML을 읽기 전용으로 참조; 이 시스템에서 open-design의 코드는 실행되지 않습니다.
- BERTopic, sentence-transformers — 범주형 분석이 필요할 때 온톨로지를 보완하는 토픽 클러스터링 레이어용.
15. 설계 근거와 근거 기반(evidence base)
아래 결정들은 모두 의도된 선택입니다. 이 섹션은 각 선택을 출판된 연구와 연결해, 그냥 믿고 따르는 대신 직접 평가하고 — 또는 반박할 — 수 있도록 합니다. 초심자 튜토리얼은 실행 가능성에 집중하느라 이 레이어를 생략했고, 그 내용이 바로 여기에 있습니다.
검색 대신 단일 진입점. Today.md가 존재하는 이유는 중단된 작업으로 복귀하는 비용이 크기 때문입니다. Mark, Gudith, Klocke(2008)의 지식노동자 현장연구에서, 방해받은 사람들은 더 빠르게 일하는 것으로 보상했지만 측정 가능한 수준으로 더 높은 스트레스·좌절·노력을 감수했습니다. 같은 연구 프로그램의 관련 연구는 중단된 작업으로 완전히 복귀하는 데 약 20분 이상이 걸린다고 보고합니다. 고정된 랜딩 페이지는 컨텍스트 전환마다 반복되는 "어디까지 했더라?" 검색을 없앱니다.
재프롬프트 대신 영속 메모리. 영속적인 사실을 ~\.claude\projects\<machine>\memory\에 두는 것은 MemGPT에서 정식화한 메모리 계층화 아이디어와 같습니다. MemGPT는 작은 인-컨텍스트 윈도우와 더 큰 외부 저장소 사이로 정보를 페이징해 에이전트가 세션을 넘어 지식을 유지하게 합니다(Packer et al., 2023). situation-watch 루프 — 새 노트를 관찰하고, 판단된 변화를 합성하고, 다시 기록 — 는 Park et al.(2023)의 에이전트가 긴 시간 동안 일관성을 유지하게 한 관찰 → 성찰 → 회수 사이클입니다.
플랫 태그 대신 온톨로지. 타입이 부여된 엔티티–관계 그래프(Project hasPI Person, Person advisedBy Person)는 플랫 태그로는 답할 수 없는 질의("내가 속한 모든 그랜트의 PI는 누구지?")에 답합니다. 이것이 Hogan et al.(2021)이 정리한 지식그래프 데이터 모델의 결정적 장점이며, 익스포트가 자체 포맷 대신 표준 어휘 — JSON-LD(W3C, 2020)에 FOAF·SKOS 용어와 schema.org 타입 — 를 쓰는 이유입니다. 인터랙티브 그래프는 D3로 그립니다(Bostock, Ogievetsky, & Heer, 2011).
중심이 아니라 가장자리의 LLM. 오케스트레이터는 순수 Python/PowerShell이고, 모델은 판단 지점(상황 분류, 파일 라우팅)에서만 호출됩니다. 후보를 점수화·분류하는 데 강한 모델을 쓰는 것은 LLM-as-judge 패턴으로, Zheng et al.(2023)은 개방형 과제에서 이것이 인간 선호와 80% 넘게 일치함을 발견했습니다 — "이게 마감 변경인가?" 판단에는 충분하면서도, 분류 필터로 비용이 저렴하고 한정됩니다. 같은 논문은 위치·장황함·자기-강화 편향도 기록하는데, 자동 적용을 보수적으로 유지하는 이유입니다(§5.4, §8).
본인 코퍼스에 생성을 그라운딩. /slides는 생성 전에 vault 엔티티와 온톨로지 사실을 끌어와, 덱이 모델의 파라미터 메모리만이 아니라 회수된·출처가 분명한 콘텐츠에 조건화되게 합니다 — Lewis et al.(2020)의 retrieval-augmented generation 접근으로, 사실성을 높이고 산출물이 주장하는 내용에 출처를 제공합니다.
기반으로서의 노트. 손으로 쓴 엔티티 페이지는 본인의 언어로 작성된, 원자적이고 촘촘히 교차링크된 노트입니다 — Ahrens(2017)가 현대 도구에 맞게 체계화한 Zettelkasten 실천입니다. <span class="wikilink">위키링크</span> 교차참조가 풍부할수록 온톨로지가 관계를 더 잘 재구성합니다(§5.1). 온톨로지를 넘어 범주형 구조가 필요할 때, 토픽 클러스터링은 Sentence-BERT 임베딩(Reimers & Gurevych, 2019)과 BERTopic(Grootendorst, 2022)을 씁니다.
16. 레퍼런스 및 더 읽을거리
1차 문헌
- Mark, G., Gudith, D., & Klocke, U. (2008). The cost of interrupted work: More speed and stress. Proceedings of CHI 2008, 107–110. https://ics.uci.edu/~gmark/chi08-mark.pdf
- Packer, C., Fang, V., Patil, S. G., Lin, K., Wooders, S., & Gonzalez, J. E. (2023). MemGPT: Towards LLMs as operating systems. arXiv:2310.08560. https://arxiv.org/abs/2310.08560
- Park, J. S., O'Brien, J., Cai, C. J., Morris, M. R., Liang, P., & Bernstein, M. S. (2023). Generative agents: Interactive simulacra of human behavior. Proceedings of UIST 2023. https://arxiv.org/abs/2304.03442
- Hogan, A., Blomqvist, E., Cochez, M., et al. (2021). Knowledge graphs. ACM Computing Surveys, 54(4), Article 71. https://doi.org/10.1145/3447772
- Zheng, L., Chiang, W.-L., Sheng, Y., et al. (2023). Judging LLM-as-a-judge with MT-Bench and Chatbot Arena. Advances in Neural Information Processing Systems 36 (NeurIPS 2023). https://arxiv.org/abs/2306.05685
- Lewis, P., Perez, E., Piktus, A., et al. (2020). Retrieval-augmented generation for knowledge-intensive NLP tasks. Advances in Neural Information Processing Systems 33 (NeurIPS 2020). https://ai.meta.com/research/publications/retrieval-augmented-generation-for-knowledge-intensive-nlp-tasks/
- Reimers, N., & Gurevych, I. (2019). Sentence-BERT: Sentence embeddings using Siamese BERT-networks. Proceedings of EMNLP-IJCNLP 2019, 3982–3992. https://aclanthology.org/D19-1410/
- Grootendorst, M. (2022). BERTopic: Neural topic modeling with a class-based TF-IDF procedure. arXiv:2203.05794. https://arxiv.org/abs/2203.05794
- Bostock, M., Ogievetsky, V., & Heer, J. (2011). D³: Data-driven documents. IEEE Transactions on Visualization and Computer Graphics, 17(12), 2301–2309. https://doi.org/10.1109/TVCG.2011.185
- Ahrens, S. (2017). How to take smart notes. Sönke Ahrens. https://www.soenkeahrens.de/en/takesmartnotes
도구 및 표준
- Claude Code 문서. https://code.claude.com/docs/en/overview
- Obsidian. https://obsidian.md
- OpenRouter API 문서. https://openrouter.ai/docs
- W3C (2020). JSON-LD 1.1: A JSON-based serialization for linked data. https://www.w3.org/TR/json-ld11/
- W3C (2009). SKOS Simple Knowledge Organization System reference. https://www.w3.org/TR/skos-reference/
- FOAF vocabulary specification. http://xmlns.com/foaf/spec/
- schema.org vocabulary. https://schema.org/
이 가이드는 단독 연구자의 portfolio(수십 개의 프로젝트와 그랜트)를 위해 프로덕션에서 동작하는 시스템을 기술합니다. 보고된 수치(~197 온톨로지 노드, 2200+ 엣지, ~$0.02-0.05/일 LLM 비용)는 2026-05-02 기준 실제 측정값입니다. 임계값과 스킬 선택을 본인의 규모에 맞게 조정하세요.