* 目次 [#pa1c4fb4] #contents * Obsidianは「メモ帳」ではなく「圧縮帳」である [#main] ** はじめに [#introduction] Obsidianはしばしば「メモ帳」「ナレッジベース」「第二の脳」と表現される。しかし、設計書や技術文書を扱っていると、これらの表現には違和感が残る。 自分の感覚では、Obsidianは「書き溜める場所」ではない。 むしろ、''文章を圧縮し、分解し、再利用可能な形に整えるための帳面''に近い。 本記事では、Obsidianを「圧縮帳」と捉える視点と、なぜ設計書において特にこの使い方が有効なのかを整理する。 ** 問題意識:AIは文章を生成しっぱなしで圧縮しない [#problem] 生成AIは非常に便利だが、現状は「文章を増やす方向」に強く偏っている。 - 丁寧に説明する - 前提をすべて書く - 補足を重ねる その結果、文章は読みやすいようでいて、''責務が混ざり合った塊''になりがちである。 これはコードで言えば、 - God Class - SRP違反 - 責務の混在 に相当する状態だ。 ** 設計書とコードは同型であるべき [#isomorphism] 設計書の最終的な成果物は「コード」である。 そしてコードは、クラスやモジュールといった''役割を持った部品の組み合わせ''として表現される。 にもかかわらず、設計書だけが - 長文の説明 - 時系列の文章 - 前提と本題の混在 という未圧縮状態のままだと、次の工程で歪みが生じる。 設計書が未圧縮だと、コードを書く段階で誰かが「圧縮」することになる。 これはバグや認識ズレの温床になる。 ** 文章にもSRP(単一責務原則)を適用する [#srp] ここで重要になるのが、''文章のSRP(単一責務原則)''という考え方である。 - 1つの文章は、1つの責務だけを持つ - 説明が増え始めたら、責務が肥大化しているサイン - 肥大化した部分は、別の単位に切り出す これはコード設計では当たり前の感覚だが、自然言語ではあまり意識されてこなかった。 ** Obsidianのリンクは「文章のクラス化」 [#link-as-class] Obsidianのリンクは、単なる関連付けではない。 文章中で、 - 用語の説明が始まったとき - 前提条件を詳しく書きたくなったとき - 概念を一般化したくなったとき それは「この部分は独立した責務を持ち始めている」という合図である。 その内容を丸ごとリンク先ノートに移し、元の文章にはリンクだけを残す。 これは、 - クラスを外だしする - 実装詳細を隠蔽する - 名前で意味を圧縮する という行為と本質的に同じである。 ** 知識の直積を防ぎ、圧縮する [#compression] 文章をインラインで書き続けると、知識は直積的に増殖する。 - 本題 × 用語説明 - 本題 × 前提条件 - 本題 × 補足知識 これをObsidianのリンクによって分解すると、 - 本題(圧縮) - 用語定義(別ノート) - 前提条件(別ノート) という形に分離できる。 結果として、''情報量は減るが、意味量は減らない''。 これは可逆圧縮に近い。 ** なぜ利用者は不便を感じにくいのか [#usability] 文章を強く圧縮すると、通常は「読みにくさ」が問題になる。 しかしObsidianでは、 - クリック一つで展開できる - ホバーで中身を確認できる - バックリンクですぐ戻れる つまり、''展開コストが極端に低い''。 これはIDEで - クラス定義にジャンプする - 実装を必要なときだけ読む 体験とよく似ている。 ** Obsidianは自然言語のIDEである [#ide-for-natural-language] プログラマーは長年、IDEを通して次の知恵を身につけてきた。 - 分割する - 名前を付ける - 圧縮する - 必要なときだけ展開する Obsidianは、この設計思想を''自然言語の世界に持ち込んだツール''だと考えられる。 つまり、 |ノート|クラス| |リンク|参照| |グラフ|構造図| |AI|リファクタリング補助| という対応関係が成立する。 ** まとめ [#summary] Obsidianは、メモを溜める場所ではない。 - 思考を圧縮する - 設計を正規化する - コードと同型な構造を作る そのための「圧縮帳」である。 生成AIと組み合わせることで、 - 人間は考える(圧縮の判断) - AIは展開する(生成・補足) という分業が可能になる。 ーーーーーーーーーーーーー * 圧縮処理システムの設計 [#compression-system] ** ドキュメントの格納場所とステータス管理 [#storage-and-status] ** 基本的な考え方 [#basic-concept] 圧縮処理をシステム化するには、ドキュメントのライフサイクルを管理する必要がある。 - Obsidianを「ドキュメント指向DB」として扱う - 文章の圧縮 = 概念の外出し + リンク化 - 構造化により、AIのコンテキスト消費を最小化 *** フォルダ構造案 [#folder-structure] ** フォルダ構造案 [#folder-structure] vault/ ├── 00_inbox/ # 圧縮前の生ドキュメント(投入口) ├── 01_processing/ # 圧縮処理中 ├── 00_inbox/ # 圧縮前の生ドキュメント ├── 10_concepts/ # 用語・概念(クラス相当) │ ├── terms/ # 用語定義 │ ├── patterns/ # パターン・原則 │ └── domains/ # ドメイン知識 ├── 20_docs/ # 圧縮済みドキュメント(本体) │ ├── design/ # 設計書 │ ├── specs/ # 仕様書 │ └── notes/ # 考察・メモ └── 90_archive/ # オリジナル保存(参照用) ├── 20_docs/ # 圧縮済みドキュメント └── 90_archive/ # オリジナル保存 *** ステータス管理(frontmatter) [#status-management] ** 人間とエージェントの役割分担 [#role-division] --- status: raw | processing | compressed | archived source: "90_archive/original_filename.md" compressed_at: 2025-01-17 extracted_concepts: - "[[SRP]]" - "[[God Class]]" compression_ratio: 0.6 --- |処理|担当|h |ファイル投入・承認|人間| |パターン検出・置換|エージェント| |概念の粒度・命名判断|人間| *** 処理フロー [#processing-flow] ** TBD/TODO管理 [#tbd-management] + inbox監視 → 新規ファイル検出 + 分析フェーズ → セグメント分割、責務判定、切り出し候補抽出 + 抽出フェーズ → 既存ノート確認、新規概念ノート作成、リンク置換 + 格納フェーズ → 圧縮済み文章を適切な場所へ、オリジナルをarchiveへ + レポート出力 → 何を抽出しどこにリンクしたかのサマリー *** 方針 [#tbd-policy] ** アーキテクチャ:人間とエージェントの役割分担 [#architecture] 複雑な独自システムは作らない。既存ツールを活用する。 *** 全体像 [#overall-architecture] - TBD/TODOの管理 → '''Forgejo Issue'''(#番号で参照) - 未管理TBDの検出 → '''grep''' - 会議アジェンダ → Issueのマイルストーン機能 ┌─────────────────────────────────────────────────────────┐ │ Human Layer │ │ ┌─────────────────────────────────────────────────┐ │ │ │ Obsidian UI + Plugins │ │ │ │ - Dataview(ステータス一覧、未処理件数) │ │ │ │ - Templater(承認・却下のワークフロー) │ │ │ │ - Graph View(概念の関係可視化) │ │ │ │ - Hover Preview(リンク先の即時確認) │ │ │ └─────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ │ Vault (共有層) │ ┌─────────────────────────────────────────────────────────┐ │ Agent Layer │ │ ┌─────────────────────────────────────────────────┐ │ │ │ Claude Code Custom Agent │ │ │ │ - inbox監視、圧縮処理、概念抽出・ノート生成 │ │ │ └──────────────────────┬──────────────────────────┘ │ │ ┌──────────────────────▼──────────────────────────┐ │ │ │ MCP (Obsidian連携) │ │ │ │ - ファイル操作、検索、frontmatter操作 │ │ │ └─────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ *** 運用フロー [#tbd-flow] *** 役割分担 [#role-division] |処理|担当|理由|h |ファイル投入|人間|何を圧縮対象にするかは人間判断| |抽出候補の提示|エージェント|パターン検出は機械が得意| |抽出の承認|人間|概念の粒度・命名は人間判断| |圧縮実行|エージェント|機械的な置換処理| |概念の再利用判断|人間|文脈依存の判断| |リンク先ホバー確認|人間|読み手としての体験| ** Dataviewプラグインの活用 [#dataview] *** Dataviewとは [#what-is-dataview] Obsidian内のノートをデータベースのように検索・集計・表示できるプラグイン。SQLやExcelのフィルタに近い感覚で、vault内の情報を動的に抽出できる。 *** 基本的な使い方 [#dataview-basics] リスト表示: ```dataview LIST FROM "00_inbox" WHERE status = "raw" ``` テーブル表示: ```dataview TABLE status, file.mtime as "更新日" FROM "20_docs" SORT file.mtime DESC LIMIT 10 ``` *** クエリで使える情報源 [#dataview-sources] |情報|例|h |frontmatter|status, tags, created など自由に定義| |ファイル情報|file.name, file.mtime, file.size| |インラインフィールド|本文中の key:: value 形式| |タグ|#tag| |リンク|<nowiki>[[link]]</nowiki>| *** AIエージェントからの利用 [#dataview-from-agent] MCP経由でDataview DQLを実行できる: const result = await mcp.search_vault({ query: 'LIST FROM "00_inbox" WHERE status = "raw"', queryType: "dataview" }); 人間もエージェントも''同じDataviewクエリ言語''で情報にアクセスできる。 ** 設計書スキーマの設計 [#design-doc-schema] *** ユースケースから逆算する [#usecase-driven] 「こんな検索がしたい」から逆算してスキーマを決める。 *** 想定ユースケース [#usecases] + 進捗管理:未完了の設計書を期限順に + 影響範囲の把握:特定モジュールに依存している設計書は? + レビュー状況:レビュー待ちの設計書一覧 + バージョン・変更追跡:特定システムの設計書を版順に + 概念の利用箇所:特定概念を参照している設計書は? *** 設計書のfrontmatterスキーマ [#frontmatter-schema] --- # === 識別 === type: design_doc doc_type: 基本設計 | 詳細設計 | IF設計 | DB設計 target_system: "決済システム" domain: 金融 | 公共 | 社内 1. 未管理TBD検出 grep -rn "%%TBD%%" docs/ | grep -v "TBD-#" # === バージョン === version: "1.2" created: 2025-01-10 changed_at: 2025-01-17 change_summary: "エラーハンドリング追加" 2. Issue登録(Forgejo) → #123 が発行される # === ワークフロー === status: draft | review | approved | done assignee: "[[田中]]" due_date: 2025-01-31 3. ファイル更新 %%TBD%% → %%TBD-#123%% # === レビュー === reviewer: "[[鈴木]]" review_status: none | pending | done review_date: 4. 会議でIssueを確認・決定 # === 依存関係 === depends_on: - "[[認証モジュール]]" - "[[共通エラー処理]]" 5. コード/設計書を更新、PR作成 Fixes #123 でコミット # === 圧縮管理 === compression_status: raw | normalized | compressed extracted_concepts: - "[[SRP]]" - "[[冪等性]]" --- 6. マージ → Issue自動クローズ ** TBDから議事録、設計書更新、PRまでのワークフロー [#tbd-workflow] ** コンテキスト効率 [#context-efficiency] *** 全体フロー [#tbd-overall-flow] |方式|消費トークン|h |全文読み込み|26,000| |構造化(ピンポイント)|500| + 設計書に未決定事項(TBD)を記載 + TBDをもとに会議アジェンダ生成(エージェント) + 会議実施 → 議事録作成 + 議事録をエージェントが解析、決定事項を抽出 + 設計書を更新(ブランチ上で) + PRを作成(変更差分+根拠としての議事録リンク) + レビュー・承認・マージ(人間) 構造化により、AIの'''継戦能力'''が向上する。 *** 設計書のTBD管理 [#tbd-in-design-doc] *** 効率化のポイント [#efficiency-points] frontmatterでの管理: open_issues: - id: TBD-001 question: "タイムアウト値は何秒にするか" context: "外部API呼び出し時" raised_at: 2025-01-10 status: open | discussing | resolved resolved_by: "[[MTG-2025-01-17]]" - grepで位置特定 → AIは該当箇所のみ読む - Issue番号で参照 → 全文検索不要 - 概念のリンク化 → 重複説明を排除 本文中のマーカー: 外部API呼び出し時のタイムアウトは %%TBD-001%% 秒とする。 ** まとめ [#summary] *** 議事録スキーマ [#meeting-note-schema] --- type: meeting_note meeting_id: MTG-2025-01-17 date: 2025-01-17 participants: - "[[田中]]" - "[[鈴木]]" agenda_source: - "[[決済システム詳細設計]]" decisions: - tbd_id: TBD-001 source_doc: "[[決済システム詳細設計]]" question: "タイムアウト値は何秒にするか" decision: "30秒とする" rationale: "外部APIのSLAが20秒のため、余裕を持たせて30秒" decided_by: "田中" new_issues: - question: "リトライ間隔の初期値" target_doc: "[[決済システム詳細設計]]" --- *** PRテンプレート [#pr-template] ## 概要 設計書の未決定事項(TBD)を会議決定に基づき更新 ## 変更内容 | TBD-ID | 変更前 | 変更後 | 根拠 | |--------|--------|--------|------| | TBD-001 | 未定 | 30秒 | SLA+余裕 | ## 根拠となる議事録 - [[MTG-2025-01-17]] ** コンテキスト効率:構造化による節約 [#context-efficiency] *** 従来のアプローチ vs 構造化アプローチ [#comparison] |方式|処理|消費トークン|h |従来(全文読み込み)|議事録+設計書3件を全部読む|26,000| |構造化(ピンポイント)|decisionsフィールド+該当行のみ|500| *** 設計思想としての「参照渡し」 [#pass-by-reference] |プログラミング|ドキュメント処理|h |値渡し(オブジェクト全体コピー)|全文読み込み| |参照渡し(ポインタだけ)|TBD-IDで「どこを見ればいいか」だけ渡す| 構造化により、AIの''継戦能力''(長時間の自律処理)が向上する。 ** ソースコードとの連携 [#code-integration] *** コード内TODO/TBDの構造化 [#structured-todo] /** * @dataview type: service * @dataview domain: 決済 * @dataview tbd: TBD-001 */ public class PaymentService { // TODO(TBD-001): タイムアウト値は設計確定待ち // source: docs/決済システム詳細設計.md private static final int TIMEOUT = 0; } *** 統合管理のアーキテクチャ [#unified-architecture] Obsidian (設計書) TBD-001: resolved, decision: 30秒 │ │ 同期エージェント ▼ ソースコード TODO(TBD-001) → 解決済みならコード更新+TODO削除 │ ▼ GitHub Issue #123 → 自動クローズ ** Dataviewの拡張:コードファイル対応 [#dataview-extension] *** 現状の制約 [#current-limitation] Dataviewは .md ファイルのみが対象。.java, .py などは読み取れない。 *** 改造案 [#modification-plan] Dataviewはオープンソース(MIT License)なので改造可能。 // 改造後のイメージ getSupportedExtensions(): string[] { return ['.md', '.java', '.py', '.ts', '.go']; } extractFromCode(file: TFile): Metadata { // @dataview key: value 形式をパース } *** コード側の記法案 [#code-annotation] /** * @dataview type: service * @dataview domain: 決済 * @dataview status: implementing * @dataview depends: [[認証モジュール]] * @dataview tbd: TBD-001 */ public class PaymentService { *** 実現後のクエリ例 [#extended-query] ```dataview TABLE file.name as "クラス", domain, status FROM "src" WHERE type = "service" ``` 設計書とコードを''横断検索''できるようになる。 *** 実装の選択肢 [#implementation-options] |方法|メリット|デメリット|h |Dataview本体をフォーク|完全な自由度|本家追従のメンテコスト| |Dataview拡張プラグイン|本家と独立、軽量|APIの制約を受ける| |本家にPR|メンテ不要、コミュニティ貢献|マージされるか不明| ** まとめ [#system-summary] - Obsidianを''ドキュメント指向DB''として扱う - エージェントは''ETLパイプライン''として機能する - 構造化・正規化は人間のためだけでなく、''AIとの協業の基盤'' - Dataview拡張により、設計書とコードの統合管理が視野に入る - 複雑なシステムより'''運用ルール''' - 既存ツール(Forgejo Issue、grep)を活用 - AIには最小限のコンテキストを渡す