1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ObsidianをSSoTにしたマルチAIエージェント設計──チャット脳からオーケストレーション脳へ

1
Posted at

※この記事は Zenn(https://zenn.dev/kimshoshi/articles/obsidian-multi-agent-orchestration)からの転載です。


はじめに:「AIに聞く」と「AIを動かす」は別物

ChatGPTやClaudeに質問して答えをもらう。それは「チャット」であり、AIを入力→出力の関数として使っている状態だ。

しかし実際の業務には、次のような課題がある。

  • 会話が終わると文脈が消える(ステートレス
  • 一つのモデルにすべてを任せると、得意・不得意の壁にぶつかる
  • 「AIが出した答え」を次のAIに渡す橋渡しを、人間が手作業でやっている
  • 自動化しようとすると「どこに何が書いてあるか」の管理が崩壊する

これらを解決するのがマルチエージェントオーケストレーションだ。本稿では、ObsidianというMarkdownベースのノートアプリをSSoT(Single Source of Truth)として使い、複数のAIを役割分担させる設計を技術的に解説する。


全体アーキテクチャ

┌─────────────────────────────────────────┐
│         Obsidian Vault(SSoT)           │
│  ┌──────────────────────────────────┐   │
│  │  YAML frontmatter(構造化メタデータ)│   │
│  │  Markdownボディ(非構造化テキスト) │   │
│  └──────────────────────────────────┘   │
│            ↑ 読み書き ↓                   │
│  ┌───────┬────────┬────────┬─────────┐  │
│  │Claude │ Codex  │ Gemini │launchd  │  │
│  │Sonnet │  CLI   │  CLI   │(スケジュ)│  │
│  └───────┴────────┴────────┴─────────┘  │
└─────────────────────────────────────────┘
             ↓ API呼び出し
    ┌─────────────────────┐
    │ X API / WP REST API │
    └─────────────────────┘

ポイント:各AIは直接通信しない。全員がObsidian vaultを経由してやり取りする。これがファイルベースIPCの核心だ。


技術コンセプト1:マルチエージェントオーケストレーション

定義

複数のLLMエージェントが、それぞれ異なる役割・権限・コンテキストを持ち、協調して一つのワークフローを実行する設計パターン。

なぜ単一モデルで全部やらないのか

懸念点 単一モデル マルチエージェント
コンテキストウィンドウ 長大な会話で枯渇する タスク単位で分割するため各エージェントのコンテキストが小さい
コスト 重いモデルをすべてのタスクに使う タスク重要度に応じてモデルを使い分け(Opus/Sonnet/Haiku)
専門性 汎用だが深さに限界がある 役割特化でプロンプトを最適化できる
並列処理 逐次実行しかできない 依存関係がないタスクは並列で走らせられる

本構成のエージェント分担

Claude Opus  ── 企画・判断・最終承認(司令塔)
Claude Sonnet── 文章生成・整形・SNS文(実行層)
Codex CLI   ── コード実装・ファイル一括処理(実装層)
Gemini CLI  ── PDF読取・長文資料・ファクトチェック(読取層)
launchd     ── スケジューリング・イベントトリガー(インフラ層)

技術コンセプト2:ファイルベースIPC(Inter-Process Communication)

IPCとは

異なるプロセス間でデータを受け渡す仕組みの総称。通常はソケット通信やメッセージキュー(RabbitMQなど)が使われるが、本構成ではMarkdownファイルがメッセージキューの役割を担う

なぜMarkdownファイルなのか

  • 人間とAIの両方が読み書きできる
  • バージョン管理(iCloud同期)が標準で使える
  • Obsidianがリアルタイムにレンダリングするため、人間がモニタリングしやすい
  • APIが不要(ファイルI/Oだけで完結する)

実装例:AIタスクファイルの構造

---
作成日: 2026-06-27
依頼先: Sonnet
種別: 実装
状態: 未着手          ← 有限状態機械のstate
次のアクション: Sonnetが記事ドラフトを作成する
---

## 依頼内容
...

## 受入条件
...

## 作業ログ
<!-- Sonnetがここに追記する -->

状態 フィールドが有限状態機械(FSM: Finite State Machine) のstateとして機能する。

未着手 → 進行中 → 確認待ち → 完了
                 ↓
               保留 / 却下

各エージェントは自分が担当するstateのファイルだけを処理する。これによりレースコンディション(競合書き込み)を防ぎながら疎結合を保つことができる。


技術コンセプト3:SSoT(Single Source of Truth)

問題:情報の散乱

AIを複数使い始めると、「どのAIが最新の指示を持っているか」が分からなくなる。ChatGPTの会話、Claudeの会話、Notionのページ、Slackのメッセージ──情報が分散し、矛盾が生じる。

解決:vaultを唯一の権威にする

ルールはObsidianにある → AIはvaultを読んで動く → 更新もvaultに書く

具体的には:

  • 運用ルールAI会話ログ/Claude/memory/ 以下のmdファイル
  • タスク管理🏠1.home/AIタスク/ 以下のmdファイル
  • 制作物📋2.実務/ 以下の各フォルダ

どのAIも、会話を始める前にvaultの関連ファイルを読むという規約を守ることで、全エージェントが同一の文脈を持つ。


技術コンセプト4:イベント駆動自動化(launchd)

構成

macOSのlaunchdをスケジューラーとして使い、定期実行でAIワークフローをトリガーする。

<!-- ~/Library/LaunchAgents/com.businesshub.x-post.plist -->
<key>StartInterval</key>
<integer>900</integer>  <!-- 15分ごとに実行 -->
<key>ProgramArguments</key>
<array>
  <string>/usr/local/bin/node</string>
  <string>/path/to/x_post.js</string>
  <string>--mode</string>
  <string>post</string>
</array>
<key>EnvironmentVariables</key>
<dict>
  <key>X_MAX_CHARS</key>
  <string>2000</string>
</dict>

x_post.jsの処理フロー

1. SNS運営/X投稿/ をreaddirSync()でスキャン
2. /^\d{4}-\d{2}-\d{2}_.+\.md$/ にマッチするファイルを抽出
3. frontmatterをパースして 状態: 承認済 のみ対象に絞る
4. 予約時刻 があれば ISO 8601 でパース → 現在時刻と比較
5. X API(OAuth 2.0 PKCE)で投稿
6. 投稿IDをfrontmatterに書き戻し → 状態: 投稿済(X)に更新

ポイント:AIはファイルを書くだけでよい。「いつ実行するか」の判断をlaunchdに委ねることで、AIのコンテキストにスケジューリングロジックを持ち込まなくて済む(関心の分離)。


技術コンセプト5:YAMLフロントマターを構造化プロトコルとして使う

Markdownは本来、人間が読む文書フォーマットだ。しかしYAML frontmatterを使うことで、機械可読なメタデータ層をMarkdownに重ねられる。

---
状態: 承認済          # FSMのstate
依頼先: Sonnet        # ルーティングキー
種別: ブログドラフト   # タスクタイプ
予約時刻: 2026-06-28T07:05:00+09:00  # ISO 8601
要User対応: true      # 人間介入フラグ
---

これはRESTのHTTPヘッダー、メッセージキューのメタデータ、gRPCのメッセージ定義と同じ役割を果たしている。Markdownボディがペイロード、frontmatterがエンベロープだ。


「チャットするだけ」との本質的な違い

観点 チャット 本構成
状態管理 ステートレス(会話が終われば消える) ステートフル(ファイルに永続化)
スケーラビリティ 人間がボトルネック launchdが自律実行するため人間なしで回る
モデル選択 一つのモデルに依存 タスク特性に応じてモデルを動的選択
エラー回復 人間が気づいて再実行 失敗ログをファイルに記録、次の実行で拾い直す
監査可能性 会話ログが散在 vault内のmdファイルに全履歴が集約
コンテキスト共有 同一会話内のみ 全エージェントがvaultを通じて同一コンテキストを参照
人間の介入点 全ステップ 状態: 承認済 を押すだけ(ゲート制御)

実装に必要な技術スタック

必須

技術 用途
YAML frontmatter パース js-yaml(Node.js)/ yaml(Ruby)
ファイルウォッチ / ポーリング fs.readdirSync + launchd
OAuth 2.0 PKCE X API認証
REST API クライアント fetch(Node.js 18+)
ISO 8601 日時パース new Date() / Date.parse()

推奨

技術 用途
launchd(macOS) or systemd(Linux) イベントドリブンなスケジューリング
iCloud Drive / Dropbox vault同期(マルチデバイス対応)
WP REST API WordPressへのdraft投稿自動化

不要なもの

  • Docker(ローカルスクリプトで完結するため)
  • データベース(frontmatterがKVストアの代替になる)
  • Webサーバー(プッシュではなくポーリング設計のため)

設計上のトレードオフ

メリット

  • 参入障壁が低い:MarkdownとYAMLの知識だけで始められる
  • 観察可能性が高い:Obsidianを開けば全エージェントの状態が一目でわかる
  • 変更コストが低い:ルール変更はmdファイルの編集だけで済む

デメリット

  • ポーリングのレイテンシ:15分ごとのスキャンなので即時性がない(手動実行で回避可)
  • 同時書き込みの競合:複数エージェントが同一ファイルに同時書き込みすると壊れる(FSMで防ぐが完全ではない)
  • スキーマ管理の難しさ:YAMLの構造をコードで強制できないため、フィールド名のtypoが静かに壊れる

まとめ

ObsidianをSSoTに据えたマルチエージェント構成は、「AIに聞く」から「AIを動かす」への移行を最小コストで実現する一つのアーキテクチャだ。

核心は3点:

  1. Markdownファイルをメッセージキュー(IPC)として使う
  2. YAML frontmatterのstateフィールドで有限状態機械を実装する
  3. launchdでエージェントをイベントドリブンに起動する

RAGやベクターDBを使わなくても、適切に設計されたファイル構造とポーリングループだけで、驚くほど複雑なマルチエージェントワークフローを動かせる。

オーケストレーションフレームワーク(LangChain、AutoGenなど)を使えばより高度なことができるが、まずこの「ファイルとYAMLだけ」の設計から始めると、エージェント間通信の本質が理解しやすい。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?