recording-to-obsidian은(는) 무엇을 하나요?
하나의 회의 또는 하나의 강의를 Obsidian 볼트의 자체 포함된 완전히 연결된 부분으로 변환합니다. 두 모드는 파이프라인, 규칙 및 검증 단계를 공유하며, 추출하는 내용과 노트를 구성하는 방식에서 차이가 있습니다.
| 회의 모드 | 강의 모드 | |
|---|---|---|
| 목적 | 결정된 사항과 누가 무엇을 언제까지 하는지 기억 | 언제든지 아이디어를 빠르게 재학습 |
| 허브 | 세션당 하나의 회의 허브 + 회의별 하나의 항목이 있는 시리즈 MOC | 강의당 하나의 MOC |
| 본문 노트 | ADR 스타일 의사 결정 기록; 지속 가능한 지식을 위한 주제 노트 | 앵커 노트(밀집) + 원자 노트(아이디어당 하나) |
| 추적성 | 결정 및 실행 항목에 대한 대본 타임스탬프 [00:12:34] | PDF++ 슬라이드 링크 [[deck.pdf#page=5]]; 음성 전용 콘텐츠의 타임스탬프 |
| 참고 | references/meeting-mode.md | references/lecture-mode.md |
<skill>는 이 파일이 있는 폴더를 의미합니다.
1. 파이프라인
자료 ──► 1 설정 ──► 2 전사 ──► 3 모드 선택 ──► 4 노트 작성 ──► 5 검증 ──► 6 보고
config, scripts/ 회의 또는 노트 작성 check_vault
python transcribe.py 강의 (하위 에이전트) scan_secrets
1.1 설정
먼저 시작 시간을 기록합니다: date +%s를 실행하고 숫자를 유지하세요. 검증은 그 이후에 작성된 노트만 확인합니다.
<skill>/config.toml을 읽습니다. 전사 백엔드/모델/언어, 화자 분리(diarization), notes.output_language, notes.default_mode, 볼트 폴더 이름(notes_dir, moc_dir, meetings_dir, sources_dir; 아래 기본값 사용)을 설정합니다. 스크립트의 인터프리터는 runtime.python입니다. 비어 있으면 ~/.local/share/recording-to-obsidian/venv/bin/python을 사용합니다. 이를 $PY라고 부르세요. 명령에는 인터프리터 및 스크립트의 전체 리터럴 경로를 작성하고, 셸 변수나 cd … && 체인 없이 호출당 하나의 명령으로 작성하세요(에이전트 권한 규칙이 리터럴 명령과 일치하며, 변수는 확인 불가능하게 만듭니다). 존재하지 않으면 사용자에게 install.sh(README)를 실행하라고 알리세요. 사용자의 Python 환경에 pip 설치하지 마세요.
다른 어떤 것보다 먼저 다음 사실을 확인하세요(추론할 수 없는 것만 물어보세요):
- vault — 사용자 경로, 그렇지 않으면
.obsidian/를 포함하거나 사용자가 "이 볼트"라고 말한 경우 현재 작업 디렉토리. 볼트 내부에만 작성하세요. - materials — 모든 파일의 절대 경로; 확장자별로 분류: 오디오/비디오, 자막(
.srt/.vtt), 슬라이드(.pdf/.pptx), 노트북/코드, 이미지/사진, 문서. - title, series/course, date — 사용자, 파일 이름 또는 자료에서 가져옵니다. 날짜나 참석자 목록을 절대 만들어내지 마세요(
TBD로 작성하고 그렇게 말하세요). - output language — 사용자가 요청하지 않은 경우
notes.output_language.
1.2 전사
일치하는 자막 파일(같은 스템)이 없는 모든 녹음에 대해 다음을 실행합니다:
$PY <skill>/scripts/transcribe.py <recording> -o <scratch>/transcripts
<scratch>는 볼트 외부의 임시 폴더입니다(예:$TMPDIR/recording-to-obsidian-<date>-<slug>). 모든 중간 파일에 사용됩니다.- 필요한 경우 옵션:
--model small(더 빠르고 거침),--language en(감지 건너뜀),--diarize(화자 레이블;install.sh --diarize및diarize.hf_token_env로 명명된 환경 변수의 Hugging Face 토큰 필요). 첫 번째 실행은 모델을 다운로드하며, 몇 분이 소요될 수 있습니다. stderr에 진행 상황을 출력합니다. 완료될 때까지 기다리세요. <stem>.srt및<stem>.txt(세그먼트당[HH:MM:SS] Speaker N: text한 줄)를 작성하고 JSON 요약 줄(언어, 모델, 지속 시간, 화자, 정리 통계, 파일 경로)을 출력합니다. 그 요약을 유지하세요: 언어, 모델 및 화자 분리는 노트의 Source 섹션에 들어갑니다.- 모든 도구에서 가져온 기존 자막도 같은 방식으로 정규화할 수 있습니다:
$PY <skill>/scripts/transcribe.py talk.vtt -o <scratch>/transcripts(모델 없음. 반복 루프는 접히고 타임스탬프가 있는.txt가 작성됨). - 긴 녹음도 괜찮습니다: 스크립트는 몇 시간 분량의 오디오를 처리합니다. 파일을 분할하지 마세요.
전사가 실패하면 오류 줄을 보고하세요. $PY <skill>/scripts/transcribe.py --check는 누락된 것을 보여줍니다.
1.3 모드 선택
사용자의 명시적 모드(또는 auto가 아닌 notes.default_mode)가 우선합니다. 그렇지 않으면:
- 자료 중 슬라이드, 노트북, 실습 코드 또는 유인물이 있으면 → 강의.
- 그렇지 않으면 대본의 처음 ~5분을 읽고 나머지를 훑어보세요:
| 회의 신호 | 강의 신호 |
|---|---|
| 비슷한 발언 시간을 가진 여러 화자 | 설명하는 한 명의 주요 화자 |
| 안건, 상태 업데이트, "어디까지 왔나요…" | "오늘은 …을 다룰 것입니다", "지난주에 …을 보았습니다" |
| 제안, 논의된 트레이드오프, "…로 가겠습니다", "동의" | 정의, 유도, 작업 예제, 연습 문제 |
| 소유자 및 날짜: "금요일까지 해주실 수 있나요?" | 이해를 위한 청중 질문, 결정을 위한 것이 아님 |
| 프로젝트, 고객, 마감일, 위험 | 과정/강의 번호 매기기, 읽을거리, 숙제 |
- 혼합된 경우는 목적에 따라 결정됩니다: 디자인 리뷰, 기획, 회고, 디브리핑 및 1:1은 회의입니다. 녹음된 기술 강연, 교육, 세미나 및 튜토리얼은 약간의 토론이 있더라도 강의입니다.
선택과 이를 이끈 두세 가지 신호를 기록합니다(보고서에 포함). 정말 애매하고 물어볼 수 있다면 물어보세요. 그렇지 않으면 선택하고 이유를 말하세요.
1.4 실행 모델: 오케스트레이터 + 하나의 노트 작성자
전체 대본, 페이지별 덱 및 노트북을 읽고 수십 개의 파일을 작성하면 컨텍스트 창이 빠르게 채워지므로 역할을 분할하세요:
- 오케스트레이터 — 요청을 받은 세션입니다. 1.1~1.3을 수행하고(전사 출력은 디스크에 남음. 모드를 선택하기에 충분한 대본만 읽음), 작성을 하나의 노트 작성자 하위 에이전트에 위임한 다음 1.5의 검증을 실행하고 보고합니다.
- 노트 작성자 — 선택한 모드에 대한 전체 작성 작업을 자체 컨텍스트에서 수행하는 하나의 하위 에이전트: 모든 자료 읽기, 계획, 작성, 자체 점검. 하나의 회의 또는 하나의 강의는 하나의 컨텍스트에 편안하게 들어갑니다. 페이지나 대본 청크를 에이전트 간에 분할하지 마세요(상호 참조가 손실되고 노트가 중복됨).
하위 에이전트 도구를 사용할 수 없거나 하위 에이전트가 작업에 필요한 작업(이미지 보기, 스크립트 실행, 파일 쓰기 등)을 수행할 수 없는 경우 직접 작업을 수행하세요. 회의 모드에서는 회의가 충분히 짧아 브리핑이 작업만큼 길어질 경우(슬라이드나 문서가 없는 약 15분 미만 녹음) 직접 작성할 수도 있습니다. 강의 모드는 항상 노트 작성자를 사용합니다. 단, 하위 에이전트를 사용할 수 없거나 작업을 수행할 수 없는 경우는 예외입니다. 덱은 페이지별로 읽어야 하며, 이는 작성자의 컨텍스트에 속합니다. 보고서에서 어떤 것을 선택했는지 말하세요. 검증(1.5)은 절대 건너뛰지 않습니다. 여러 세션의 경우, 동일한 MOC에 추가할 때 순차적으로 세션당 하나의 노트 작성자를 사용하세요.
노트 작성자용 브리핑 — 컨텍스트가 없으므로 모든 것을 제공하세요:
- 이 스킬의 절대 경로; 모드; 따라야 할 파일:
references/meeting-mode.md또는references/lecture-mode.md, 그리고references/note-templates.md,references/transcript-processing.md,references/mermaid-style.md; - 볼트 경로, 스크래치 폴더,
$PY, 출력 언어, 제목/시리즈/날짜(또는 "유도"), config의 폴더 이름; - 모든 자료 및 대본 파일의 절대 경로, 전사 요약(언어, 모델, 화자);
- 기존 시리즈/과정 MOC 및 이전 세션의 허브/MOC(있는 경우); 사용자가 특별히 요청한 모든 것;
- 규칙: 볼트 내부에만 작성; 문서화된 추가 사항을 제외하고 기존 노트를 절대 수정하지 않음. 비밀 정보 없음;
- 반환해야 할 것: 3절의 보고 블록 및 해결할 수 없는 모든 것.
1.5 검증 (오케스트레이터)
노트 작성자가 반환되면, 요약을 신뢰하지 말고 독립적으로 작업을 확인하세요:
$PY <skill>/scripts/check_vault.py <vault> --since <작업 시작 시의 epoch 초>
$PY <skill>/scripts/scan_secrets.py <vault>/sources
check_vault.py는 **issues: 0**으로 끝나야 합니다. 이유가 없는 한(말하세요) 경고도 수정하세요. Obsidian이 링크를 확인하는 방식(파일 이름 또는 부분 경로, 대소문자 구분 안 함, #heading/|alias 무시, 코드 블록 건너뜀)으로 링크를 확인하므로, 보고된 끊어진 링크는 Obsidian에서도 끊어집니다. 다음을 확인합니다: 끊어진 [[links]]/임베드/마크다운 링크, .pdf 없는 PDF++ 링크, 프론트매터(title, type, date_created), 허브 범위(모든 새 노트가 MOC 또는 회의 허브에서 연결됨; 모든 회의 허브가 MOC에서 연결됨), 비밀 정보. 연결되지 않은 노트, 스타일이 지정되지 않은 Mermaid 및 모호한 링크에 대한 경고.
그런 다음 스크립트가 확인할 수 없는 것을 확인하세요:
- 문서화된 추가 사항(시리즈 MOC 항목, 대체된 결정 상태, 이전 강의 MOC의 "다음" 링크)을 제외하고 기존 노트가 변경되지 않음.
- 회의 모드: 모든 결정에 기록이 있거나 명시적으로 사소함. 모든 실행 항목에 소유자(또는
TBD), 마감일(또는TBD) 및 타임스탬프가 있음. - 강의 모드: MOC가 모든 새 노트를 정확히 한 번 나열함. 강의 자체 점검의 세분성 및 앵커 목표가 충족됨.
작은 문제는 직접 수정하세요. 큰 문제는 정확한 목록과 함께 노트 작성자에게 다시 보내세요. check_vault.py가 0 문제를 보고할 때까지 다시 실행하세요. 사용자가 원하지 않는 한 스크래치 폴더(wav 및 페이지 이미지 포함)를 삭제하세요.
2. 공통 규칙
볼트 레이아웃 — 노트는 평면입니다. 탐색은 MOC와 허브에서 제공되며 폴더가 아닙니다.
vault/
├── notes/ # 원자, 앵커, 결정 및 주제 노트 (평면)
├── meetings/<series>/ # 회의 허브: "YYYY-MM-DD <title>.md"
├── moc/<series or course>/ # 시리즈 MOC (회의) / 강의당 하나의 MOC
└── sources/<series or course>/<YYYY-MM-DD or Lecture_NN>/
├── <prefix>_transcript.srt / .txt
├── <prefix>.pdf # 슬라이드, PDF++ 링크용
├── slide_images/ whiteboard_photos/ notebooks/
└── structured_slides.json # 선택적 페이지별 읽기 기록
sources/에 복사된 모든 파일에 시리즈/과정 + 세션 접두사를 지정하세요(Atlas_2026-11-12_transcript.srt, Optics101_L03.pdf, Optics101_L03_p08.jpg). Obsidian은 파일 이름으로 링크를 확인하므로, 두 세션 모두 transcript.srt 또는 page-08.jpg를 포함하면 상호 연결됩니다. 폴더 이름은 시리즈/과정 이름을 사용하고 공백은 -로 대체합니다.
파일 이름 — 사람이 읽을 수 있는 제목, ID 없음(회의 허브는 예외: 정렬을 위해 날짜로 시작). / \ : * ? " < > | # ^ [ ]를 피하고 : 대신 —를 사용하세요. 제목은 독립적으로 충분히 구체적이어야 함: Rate limits use a token bucket per API key.md, Rate limiting.md가 아님.
프론트매터 — 모든 노트는 최소한 title, type 및 date_created가 있는 YAML 프론트매터로 시작합니다. type은 moc, meeting, decision 또는 topic(회의 모드)이고 moc, anchor 또는 atomic(강의 모드)입니다. 모드별 필드는 references/note-templates.md에 있습니다. 태그는 소문자 영어 케밥-케이스입니다: 하나의 시리즈/과정 태그, 2~4개의 주제 태그, 하나의 유형 태그. 새 태그를 만들기 전에 볼트에 이미 있는 태그를 재사용하세요.
언어 — output_language = "auto"는 자료의 언어(대본의 감지된 언어 또는 슬라이드 언어)로 작성한다는 의미입니다. 출력 언어가 자료의 언어와 다른 경우, 기술 용어는 원래 언어로 유지하고 처음 나올 때 각 용어를 주석 처리하세요. 영어 회의의 중국어 노트: 功能开关 (feature flag); 독일어 강의의 영어 노트: error propagation (Fehlerfortpflanzung). 그런 다음 자연스럽게 읽히는 형태를 사용하세요. 코드, 명령, 경로, 제품 및 도구 이름은 절대 번역하지 않습니다. 제목은 출력 언어를 따릅니다.
링크 — 모든 [[wikilink]]는 볼트 내의 노트 또는 파일로 확인되어야 합니다. 중복을 작성하는 대신 기존 노트에 링크하세요. 단순한 이름이 모호할 수 있는 경우 경로([[sources/Atlas/2026-11-12/Atlas_2026-11-12_transcript.srt|transcript]])를 사용하세요. PDF++ 페이지 링크는 항상 .pdf를 유지합니다: [[Optics101_L03.pdf#page=5|Slide p.5 "Snell's law"]].
타임스탬프 — 모든 결정, 실행 항목 및 음성에서만 나오는 주장에 대해 대본의 [HH:MM:SS]를 인용하세요. 이는 녹음으로 돌아가는 감사 추적입니다.
비밀 정보 — 볼트에 자격 증명을 절대 작성하지 마세요. 노트북이나 코드를 sources/에 복사하기 전에 복사본에 대해 $PY <skill>/scripts/scan_secrets.py --redact <copy>를 실행하세요(값은 <REDACTED>가 되고 변수 이름은 유지). 회의에서 말로 전달된 비밀번호, 카드 번호 또는 민감한 개인 데이터도 기록하지 마세요. "자격 증명이 구두로 공유되었습니다(여기에 기록되지 않음)"라고 작성하세요.
시각 자료 — Mermaid 다이어그램을 작성하기 전에 references/mermaid-style.md를 읽으세요. 팔레트와 다이어그램 렌더링을 유지하는 규칙이 있습니다. 잘못된 구문은 다이어그램이 없는 것보다 나쁩니다.
모드 출력
- 회의 →
references/meeting-mode.md: 허브 1개, 주요 결정당 결정 기록 1개, 유지할 가치가 있는 지식에 대한 0~N개의 주제 노트, 시리즈 MOC(처음 사용 시 생성)에 추가된 항목 1개, 대본이sources/에 복사됨. - 강의 →
references/lecture-mode.md: MOC 1개, 일반적인 30페이지 이상 덱에 대해 8~15개의 앵커 노트, 콘텐츠 슬라이드당 평균 하나 이상의 원자 노트, 슬라이드/노트북/대본이sources/에 복사됨.
3. 보고
회의 모드:
Meeting 2026-11-12 — <title> (series: <series>) mode: meeting (signals: …)
Transcript: 00:41:07, mlx:whisper-large-v3-turbo, 3 speakers, en → notes en
Hub: meetings/<series>/2026-11-12 <title>.md
Decisions: 3 (records: 3) Action items: 7 (owner TBD: 1, due TBD: 2)
Topic notes: 2 Open questions: 2 Risks: 1
Series MOC: moc/<series>/MOC — <series>.md (entry appended)
check_vault: issues 0, warnings 0
Unresolved: <speakers not matched to names, unclear passages, …>
강의 모드:
Lecture NN — <topic> mode: lecture (signals: …)
Slides: 45 pages (content 37) Knowledge points: 68
Notes: 56 atomic + 12 anchor archetypes: concept=34, practice-demo=6, …
Notes per content slide: 1.5 Anchors with >=2 rich elements: 12/12
Mermaid: 14 (types: sequence, mindmap, flowchart, …) Valid syntax: 14
MOC: moc/<course>/<Lecture> <topic>.md
Sources: sources/<course>/<Lecture NN>/
check_vault: issues 0, warnings 0
Unresolved: <clipped equations, illegible whiteboard, …>