recording-to-obsidian は何をしますか?
1つの会議または1つの講義を、Obsidianボールト内の自己完結型かつ完全にリンクされた部分に変換します。両方のモードはパイプライン、規約、検証手順を共有しますが、抽出する内容とノートの形状が異なります。
| 会議モード | 講義モード | |
|---|---|---|
| 目的 | 決定されたこと、誰が何をいつまでに行うかを記憶する | アイデアをいつでも素早く再学習する |
| ハブ | セッションごとに1つの会議ハブ + 会議ごとに1エントリのシリーズMOC | 講義ごとに1つのMOC |
| 本文ノート | ADR形式の意思決定記録、永続的な知識のためのトピックノート | アンカーノート(高密度)+ アトミックノート(1アイデアごと) |
| トレーサビリティ | 決定事項とToDoに文字起こしタイムスタンプ [00:12:34] | PDF++スライドリンク [[deck.pdf#page=5]]、音声のみのコンテンツにはタイムスタンプ |
| リファレンス | references/meeting-mode.md | references/lecture-mode.md |
<skill> はこのファイルが置かれているフォルダを意味します。
1. パイプライン
資料 ──► 1 セットアップ ──► 2 文字起こし ──► 3 モード選択 ──► 4 ノート作成 ──► 5 検証 ──► 6 レポート
設定, scripts/ 会議か ノートを書く check_vault
Python transcribe.py 講義か (1つのサブエージェント) scan_secrets
1.1 セットアップ
まず開始時刻を記録します: date +%s を実行し、数字を保持します。検証では、その後に書かれたノートのみをチェックします。
<skill>/config.toml を読み込みます。文字起こしのバックエンド/モデル/言語、話者分離、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 と呼びます — これは表記上のものです。コマンドでは、インタープリタとスクリプトの完全なリテラルパスを1コマンドにつき1回、シェル変数や 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(セグメントごとに1行[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 モードの選択
ユーザーからの明示的なモード(または notes.default_mode が auto 以外)が優先されます。それ以外の場合:
- 資料にスライド、ノートブック、ラボコード、または配布資料がある → 講義。
- それ以外の場合、文字起こしの最初の約5分を読み、残りをスキミング:
| 会議のシグナル | 講義のシグナル |
|---|---|
| 複数の話者が同程度の時間発言 | 1人の支配的な話者が説明 |
| アジェンダ、ステータス更新、「〜の進捗は?」 | 「今日は〜をカバーします」、「前回は〜を見ました」 |
| 提案、トレードオフの議論、「〜でいきましょう」、「同意しました」 | 定義、導出、実例、演習 |
| 所有者と日付:「金曜までにやってもらえますか?」 | 理解するための質問(決定するためではない) |
| プロジェクト、顧客、期限、リスク | コース/講義番号、課題、宿題 |
- 混合ケースは目的に基づく: デザインレビュー、計画、レトロ、報告会、1on1は会議。録画されたテックトーク、トレーニング、セミナー、チュートリアルは、多少の議論があっても講義。
選択と、それを導いた2〜3のシグナルを記録します(レポートに含めます)。本当に同程度の場合はユーザーに尋ねます。それ以外は選択し、理由を述べます。
1.4 実行モデル: オーケストレーター + 1つのノート作成
文字起こし全体、スライドをページごと、ノートブックを読み、数十のファイルを書くのはすぐにコンテキストウィンドウを満たすため、役割を分割します:
- オーケストレーター — リクエストを受け取ったセッション。1.1〜1.3を実行し(文字起こし出力はディスクに保存、モード選択に十分な文字起こしのみを読み取る)、ノート作成を1つのノート作成サブエージェントに委任し、次に1.5の検証を実行してレポートします。
- ノート作成 — 選択されたモードの全作成作業を自身のコンテキストで実行する1つのサブエージェント: すべての資料を読み、計画し、書き、自己チェックします。1つの会議または1つの講義は1つのコンテキストに快適に収まります。ページや文字起こしチャンクをエージェント間で分割しないでください(相互参照が失われ、ノートが重複します)。
サブエージェントツールが利用できない場合、サブエージェントが必要な処理を実行できない場合(画像の確認、スクリプトの実行、ファイルの書き込みなど)は、委任せずに自分で作業を行います。会議モードでは、ブリーフが作業自体と同じくらい長くなるほど短い会議(スライドやドキュメントのない約15分未満の録音)の場合は、直接作成しても構いません。講義モードは常にノート作成を使用します(サブエージェントが利用できない、またはジョブを実行できない場合を除く): デッキはページごとに読み取る必要があり、それは作成者のコンテキストに属し、あなたのコンテキストには属しません。レポートでどちらを選択したかを述べてください。検証(1.5)は決してスキップしません。複数のセッションの場合は、セッションごとに1つのノート作成を使用し、同じMOCに追加する場合は順次実行します。
ノート作成へのブリーフ — コンテキストなしで開始するため、すべてを与えます:
- このスキルの絶対パス、モード、従うファイル:
references/meeting-mode.mdまたはreferences/lecture-mode.md、さらにreferences/note-templates.md、references/transcript-processing.md、references/mermaid-style.md; - ボールトパス、スクラッチフォルダ、
$PY、出力言語、タイトル/シリーズ/日付(または「導出」)、設定からのフォルダ名; - すべての資料の絶対パスと文字起こしファイルの絶対パス、文字起こしサマリー(言語、モデル、話者);
- 既存のシリーズ/コースMOCと前のセッションのハブ/MOC(ある場合)、ユーザーが特に要求したものすべて;
- ルール: ボールト内にのみ書き込む、文書化された追加を除き既存のノートを変更しない、シークレットなし;
- 戻り値: セクション3のレポートブロックと解決できなかったもの。
1.5 検証(オーケストレーター)
ノート作成が戻ってきたら、そのサマリーを信頼せずに独立して作業を確認します:
$PY <skill>/scripts/check_vault.py <vault> --since <ジョブ開始時のエポック秒>
$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の「次へ」リンク)以外に、既存のノートは変更されていないこと;
- 会議モード: すべての決定にレコードがあるか、明示的に重要でないとされていること。すべてのToDoに所有者(または
TBD)、期限(またはTBD)、タイムスタンプがあること; - 講義モード: MOCがすべての新しいノートを正確に1回リストしていること。講義の自己チェックの粒度とアンカーターゲットが満たされていること。
小さな問題は直接修正し、大きな問題は正確なリストとともにノート作成に戻します。check_vault.py を問題が0になるまで再実行します。ユーザーが希望しない限り、スクラッチフォルダを削除します(wavとページ画像が含まれています)。
2. 共有規約
ボールトレイアウト — ノートはフラット。ナビゲーションはMOCとハブから行います。
vault/
├── notes/ # アトミック、アンカー、決定、トピックノート(フラット)
├── meetings/<series>/ # 会議ハブ: "YYYY-MM-DD <title>.md"
├── moc/<series or course>/ # シリーズMOC(会議)/ 講義ごとに1つの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なし(会議ハブは例外: ソートのために日付で始めます)。/ \ : * ? " < > | # ^ [ ] は避け、: の代わりに — を使用します。タイトルは単独で意味が通じるほど具体的に: レート制限にはAPIキーごとにトークンバケットを使用する.md、レート制限.md ではありません。
フロントマター — すべてのノートは少なくとも title、type、date_created を含むYAMLフロントマターで始まります。type は moc、meeting、decision、topic(会議モード)および moc、anchor、atomic(講義モード)です。モード固有のフィールドは references/note-templates.md にあります。タグは小文字の英語ケバブケース: 1つのシリーズ/コースタグ、2〜4つのトピックタグ、1つのタイプタグ。新しいタグを発明する前に、ボールトに既存のタグを再利用します。
言語 — 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"]]。
タイムスタンプ — すべての決定、ToDo、音声からのみ得られる主張について、文字起こしの [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: 1つのMOC、通常の30ページ以上のデッキで8〜15のアンカーノート、コンテンツスライドあたり平均して少なくとも1つのアトミックノート、スライド/ノートブック/文字起こしを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, …)
MOC: moc/<course>/<Lecture_Topic>.md
Unresolved: <…>
4. インストールと依存関係
必要なツール
- Python 3.10+ — 文字起こしスクリプトと検証スクリプトを実行します。
- ffmpeg — 音声抽出用(システムパスにあること)。
- whisper.cpp または mlx — 高速なローカル文字起こし用(
install.shがセットアップします)。
インストール
cd <このスキルフォルダ>
bash install.sh
話者分離を有効にする場合:
bash install.sh --diarize
これにより、専用のPython仮想環境が作成され、必要な依存関係がすべてインストールされます。話者分離にはHugging Faceトークンが環境変数として必要です。
設定
config.toml で以下の設定をカスタマイズできます:
| キー | デフォルト | 説明 |
|---|---|---|
transcription.backend | mlx | 使用する文字起こしバックエンド (mlx または whisper.cpp) |
transcription.model | whisper-large-v3-turbo | Whisperモデルサイズ |
transcription.language | auto | 文字起こし言語(自動検出) |
diarize.enabled | false | 話者分離を有効にする |
diarize.hf_token_env | HF_TOKEN | Hugging Faceトークンの環境変数名 |
notes.output_language | auto | ノートの出力言語(自動は資料の言語) |
notes.default_mode | auto | デフォルトモード (auto, meeting, lecture) |
runtime.python | (仮想環境) | Pythonインタープリタのパス |
5. トラブルシューティング
| 問題 | 解決策 |
|---|---|
$PY が見つからない | install.sh を実行して仮想環境を作成します |
| 文字起こしが遅い | より小さいモデル (--model small) を試すか、GPUアクセラレーションを確認します |
| 話者ラベルがない | install.sh --diarize を実行し、Hugging Faceトークンが環境変数に設定されていることを確認します |
| リンクが壊れている | scripts/check_vault.py を実行し、報告されたエラーを修正します |
| Mermaid図がレンダリングされない | 構文を references/mermaid-style.md で確認します |
このスキルは、会議や講義からの知識を構造化された相互リンクされたObsidianノートに変換することで、情報を整理し、後で簡単に検索・再利用できるようにします。