Engineering agent-design 27 min read

Synapse の責任者エージェント設計 — {domain}-director パターン

Claude Code 上に業務横断エージェント組織を組む設計。{domain}-director パターン・スキル委譲・`.claude/agents/` 構造を全開示。AI エージェントのハーネス設計を実装する senior engineer 向け。

公開 2026-05-22 森本 拓見

本記事に登場する HUMAN_INPUT マーカーとは、AI 執筆 skill が記事本文に残す「ここは人間が後で確定値を埋めるべき」を示すプレースホルダー(形式例: <!-- HUMAN_INPUT: 数値を記入 -->)。

Synapse の責任者エージェント設計をシニアエンジニア向けに公開する。{domain}-director パターンで責任者エージェントを立て、.claude/skills/ にスキルを切り出してスキル委譲する構造 — .claude/agents/ の定義ファイル実物を含めて、Yakumo が実際に動かしている設計を開示する。

エージェント組織を業務横断で設計する方法を探しているなら、この記事が実装例になる。Synapse(Claude Code 上に組んだ業務横断エージェント組織)のブログ運用部分を切り出し、@blog-director / @editor-in-chief / @seo-director の設計と、それらが呼び出す /blog-* スキル群の実装パターンを開示する。

なぜ Synapse を作ったか、そして AI エージェント組織を事業にどう組み込むかという business 視点は、事業判断を扱う記事 AI エージェント組織の立ち上げ方 に委ねている。本記事は engineer 向けの実装詳細を扱う。


Synapse の全体構造 — 業務横断エージェント組織の設計

.claude/agents/.claude/skills/ のディレクトリ構造

Claude Code はプロジェクトルートの .claude/ 配下にエージェント定義とスキル定義を置く慣習を持つ。Yakumo の Synapse はこれを次の構造で使っている:

.claude/
├── README.md              # エージェント組織の全体ガイド
├── agents/                # 責任者エージェント定義(Tier 1)
│   ├── blog-director.md
│   ├── editor-in-chief.md
│   └── seo-director.md
└── skills/                # 決定論スキル(全 15 個のうちブログ運用主要 7 本を抜粋)
    ├── README.md
    ├── blog-audit/
    │   └── SKILL.md
    ├── blog-classify/
    │   └── SKILL.md
    ├── blog-tech-write/
    │   └── SKILL.md
    ├── blog-review/
    │   └── SKILL.md
    ├── blog-meta/
    │   └── SKILL.md
    ├── blog-translate/
    │   └── SKILL.md
    └── blog-publish/
        └── SKILL.md

エージェント定義は Markdown ファイルで、frontmatter に name / description / model / tools を持つ。スキルは SKILL.md に手順書(シェルスクリプト + プロンプト)を書く形式だ。

担当ドメイン別の責任者エージェント

Synapse のブログ運用部分は 3 つの責任者エージェント(Tier 1)で構成する:

エージェント担当ドメイン主な判断
@blog-directorブログ事業全体トラック振り分け・優先順位・横断判断
@editor-in-chief編集方針・トーン読者層判定・NG 表現チェック・パイプライン計画
@seo-directorSEO 戦略キーワード設計・メタ最適化・カニバリ回避

「作業エージェント」を作らないのが設計の核だ。理由は次のセクションで詳述する。

エージェント間の委譲フロー

Synapse の委譲フローは 2 層で動く:

ユーザー(main-thread)

  ├── @blog-director に相談
  │     → 実行計画を main-thread に返す

  ├── main-thread が計画を見て /blog-* スキルを直接起動

  └── スキルが LLM を内部呼び出し(判断連鎖を吸収)

@blog-director は実行者ではなく アドバイザ だ。main-thread に実行計画を返し、スキルの実際の起動は main-thread が行う。


{domain}-director パターン — 責任者エージェントの定義

{domain}-director パターンの概念

{domain}-director パターン とは、業務ドメインごとに「その領域 (area) の責任者エージェント」を {domain}-director.md として立てる設計だ。実装例: blog-director.md / sales-director.md / dev-director.md / seo-director.md / editor-in-chief.md

{domain}-director パターンは、担当ドメイン × 権限 × 委譲先の 3 要素でエージェントを定義する設計だ。

要素意味
担当ドメインエージェントが責任を持つ業務範囲
権限エージェントが判断できる事項の上限
委譲先自分の権限を超えた判断をどこに渡すか

「担当エージェントを作る」のではなく「責任者エージェントを立てる」思想だ。後者は判断の責任の所在を明確にする。前者は「担当があるが責任はあいまい」という状態を生む。

Claude Code 上でこのパターンを実装すると、各エージェントの Markdown ファイルに以下の情報を持たせることになる:

  • 担当領域セクション: そのエージェントが自分で判断できる事項の列挙
  • 委任先セクション: 権限外の事項をどのエージェントに渡すか
  • 参照ドキュメントセクション: 判断根拠となる設定ファイルの一覧

責任者エージェント定義ファイルの構造

実際の @blog-director 定義ファイルの構造を見ると、パターンの実装が分かる:

---
name: blog-director
description: ブログ事業全体の責任者。横断判断・トラック振り分け・優先順位を決め、
             @seo-director / @editor-in-chief に方針を渡すアドバイザ
model: claude-sonnet-4-6
tools: Read, Glob, Grep, Bash
---

> **[Claude Code runtime 制約]**
>
> sub-agent は更に sub-agent / skill を spawn できない。
> このため blog-director は「実行計画を構築して main-thread に返す」アドバイザ役に徹する。
> 実際のスキル / 他エージェント呼び出しは main-thread が行う。

# ブログ事業責任者エージェント (Blog Director)

## 担当領域
- **トラック戦略**: tech と case の本数バランス・優先順位
- **読者層判定**: 新規記事・既存記事をどちらに振るか

## 委任先
- **SEO・流入観点**`@seo-director`
- **編集方針・トーン・読者層判定の詳細**`@editor-in-chief`

model: claude-sonnet-4-6tools: Read, Glob, Grep, Bash がある。tools に AgentSkill を追加しても Claude Code runtime には注入されない — これが次のセクションで詳述する「判断連鎖をスキル内で吸収する」設計の理由になる。

@editor-in-chief の定義も同じ構造を持つ:

---
name: editor-in-chief
description: 編集方針・読者層判定・トーン・固有名詞の扱いを統括する編集長。
             `rewrite-tech` / `rewrite-case` パイプラインのオーナー
model: claude-sonnet-4-6
tools: Read, Glob, Grep, Bash
---

## 担当領域

### 編集方針レイヤー
- **読者層判定**: 記事が tech / case どちらの読者に書かれているかを精査
- **トーン統制**: `src/_docs/BRAND.md` の語り口・NG 表現の遵守を保証
- **固有名詞の扱い**: Synapse / montage / medallion の紹介粒度を管理
- **パイプライン管理**: `rewrite-tech` / `rewrite-case` の各 stage 起動指示を構築

@seo-director は SEO という専門ドメインを持ち、キーワード戦略とカニバリ(同一キーワード競合)回避を担う:

---
name: seo-director
description: SEO・キーワード戦略・タイトル/description 最適化・流入観点の責任者。
             `/blog-meta` の起動指示を main-thread に返すアドバイザ
model: claude-sonnet-4-6
tools: Read, Glob, Grep, Bash
---

## 担当領域(抜粋)
- cluster SEO マップの保守: pillar の primary_keyword ↔ spoke の secondary_keyword の対応図を維持し、
  クラスター内のカニバリを回避する

3 エージェントの共通点は「アドバイザに徹する」という動作仕様だ。各エージェントの定義ファイルの冒頭に [Claude Code runtime 制約] として明記してある。

CLAUDE.md によるハーネスの宣言と呼び出し規約

.claude/ のエージェント・スキルを使うためのルールは CLAUDE.md に宣言する。Yakumo の CLAUDE.md には次の規約が記されている:

## 不変規約

- **実装の委譲**: コード・config・skill / agent 定義・YAML の構造化編集は
  原則 `web-developer` / `system-developer` / 該当ディレクター agent に委譲。
  メインは要件整理・指示文作成・diff レビュー・コミット
- **ブログ運用**: 業務として記事を扱う場合は必ず責任者エージェント経由
`@blog-director` / `@seo-director` / `@editor-in-chief`

呼び出し規約を CLAUDE.md に書くことで、Claude Code が会話のコンテキストを保持している間、エージェントの起動フローが一貫する。


スキル委譲 — .claude/skills/ の設計

Claude Code でなぜスキルが必要か — sub-agent 制約への対処

{domain}-director パターンで重要な設計判断が 1 つある。Claude Code では sub-agent(Agent ツール経由で起動したエージェント)が、さらに sub-agent / skill を spawn できない という runtime 制約だ。

この制約が意味すること:

  • @blog-director から @editor-in-chief を起動 → @editor-in-chief の中から /blog-tech-write を呼べない
  • 「エージェントが別エージェントを呼んで、そのエージェントがスキルを呼ぶ」という 3 層の呼び出しチェーンは動かない

この制約への対処として Synapse が選んだのが 「判断連鎖をスキル内で吸収する」 設計だ。

❌ 動かない構造:
main-thread → @blog-director → @editor-in-chief → /blog-tech-write

✅ 動く構造:
main-thread → @blog-director(実行計画を返す)
main-thread → /blog-tech-write(直接起動)

         スキル内部で LLM 呼び出し(判断・執筆)

スキルは「決定論的な手順書」であり、その手順書の中で LLM を呼ぶ。これにより、エージェント間の判断連鎖が必要な場面でも、スキル内に判断ロジックを押し込める。

スキルとエージェントの責任分担の判断基準

この制約を踏まえると、「何をエージェントに持たせ、何をスキルにするか」の判断基準が明確になる:

判断エージェントスキル
持たせる情報ドメイン知識・参照ドキュメント・委譲先I/O contract・手順・LLM プロンプト
実行タイミングmain-thread からの相談時main-thread の直接起動
LLM 呼び出し相談への回答(実行計画の構築)成果物の生成(draft・分類結果等)
判断の主体どの手順を踏むべきかその手順を実行してどう出力するか
@blog-director が担うもの:
  「この記事は tech トラック → @editor-in-chief に渡す
   → rewrite-tech パイプラインの phase 1 から /blog-classify を起動してほしい」

/blog-tech-write が担うもの:
  「ブリーフを読み、audience-tracks.json を参照し、
   BRAND.md の制約の中で tech 構造の本文を LLM で生成し、
   draft_v{n}.md に書き出す」

スキルの I/O contract 設計

スキルには 3 要素の I/O contract を必ず持たせる:

要素意味
入力(Input)スキルが読むファイル・引数・前提条件
出力(Output)スキルが書き出すファイル・変数
前提条件(Precondition)スキルが期待する状態(例: draft が存在する / review が pass している)

/blog-tech-write の I/O contract:

Input:
  - slug(引数)
  - blog-ops/articles/{slug}.yaml(ブリーフ)
  - src/_docs/BRAND.md(語り口・NG 表現)
  - src/config/brand.ts(禁則語)
  - blog-ops/config/audience-tracks.json(tech 構造)

Output:
  - blog-ops/output/rewrite/{slug}/draft_v{n}.md(本文 Markdown)

Precondition:
  - ブリーフ YAML が存在すること
  - cluster: tech が明示されていること

I/O contract を SKILL.md に明記することで、パイプライン DAG(blog-ops/config/pipelines/new-article-pillar.json)との整合を保てる。

決定論スキル vs 判断型エージェントの使い分け

もう 1 つの分岐点は「決定論スキル」か「判断型エージェント」かだ:

分類特徴
決定論スキル手順が固定。入力が同じなら出力が安定/blog-audit(全記事を CSV に書き出す)/ /blog-meta(frontmatter を整備する)
判断型エージェントドメイン知識を持ち、状況に応じて異なる判断を返す@blog-director(記事をどのトラックに振るか)/ @seo-director(キーワードカニバリの有無)

判断型エージェントも、最終的に出力するのは「main-thread への指示文」だ。実際の成果物(ファイル)を生成するのはスキルの仕事になる。


実装の全開示 — Synapse の代表的な {domain}-director

@blog-director の定義と委譲先スキル

@blog-director はブログ事業全体の責任者として 2 つのモードを持つ:

監査モード(@blog-director audit):

## 監査時の動き(`@blog-director audit`

1. `blog-ops/config/pipelines/audit.json` を Read して実行計画を構築
2. main-thread に以下の指示を返す:
   [phase 1] /blog-audit を実行
   [phase 2] 結果を読んで blog-director に再呼び出し
3. 結果を受け取ったら、優先リライト候補トップ 5 を選定し
   `blog-ops/output/audit/plan_{date}.md` に出力する指示を返す

リライト振り分けモード(@blog-director rewrite <slug>):

## リライト振り分け(`@blog-director rewrite <slug>`

1. 対象記事を Read
2. `blog-ops/specs/audience-tracks.md` の判定フローに従い tech / case / 分割推奨 を判定
3. main-thread に以下のいずれかを返す:
   - tech 振り → `@editor-in-chief rewrite-tech <slug>` を起動(指示として返す)
   - case 振り → `@editor-in-chief rewrite-case <slug>` を起動(指示として返す)
   - 分割推奨 → ユーザー確認を求める

@blog-director が起動できるのは指示文の返却のみ。実際の /blog-audit 起動、@editor-in-chief 起動はすべて main-thread の役割だ。これが runtime 制約に対する誠実な実装だ。

@editor-in-chief の定義と委譲先スキル

@editor-in-chief は tech リライトパイプラインのオーナーとして、6 フェーズの実行計画を main-thread に返す:

## tech リライト時の動き(`@editor-in-chief rewrite-tech <slug>`

1. `blog-ops/config/pipelines/rewrite-tech.json` を Read して DAG を確認
2. `src/content/magazine/{track}/{category}/{slug}.md` を Read して現状記事を把握
3. `blog-ops/specs/audience-tracks.md` の tech トラック構造を確認
4. `src/_docs/BRAND.md` の tech トラック向けトーン要件を確認
5. main-thread に以下の順で起動指示を返す:
   [phase 1] /blog-classify {slug}
   [phase 2] /blog-pattern {slug}
   [phase 3] /blog-tech-write {slug}
   [phase 4] /blog-review {slug} track=tech
             → pass の場合のみ次へ。fail はユーザー確認を求める
   [phase 5] /blog-meta {slug} track=tech
   [phase 6] /blog-publish {slug}(ユーザー最終確認後)

注目すべきは phase 4 の → pass の場合のみ次へ だ。@editor-in-chief がパイプラインのどこで「人間に確認を返す」かを明示している。ノンストップ自動実行はしない — 判断の節目で main-thread に決定権を返すのが設計方針だ。

参照ドキュメントの宣言も重要だ:

## 参照設定

編集判断は必ず以下を参照してから行う。ハードコードしない。

| ドキュメント | 参照タイミング |
|---|---|
| `blog-ops/specs/audience-tracks.md` | 読者層判定フロー・構造・評価軸 |
| `src/_docs/BRAND.md` | トーン・NG 表現・推奨表現・プロダクト紹介の流儀 |
| `src/config/brand.ts` | 固有名詞の enum・禁則語リスト(機械可読) |
| `blog-ops/config/audience-tracks.json` | トラック定義の機械可読版 |

「判断根拠はハードコードせず、必ずファイルを参照してから行う」というルールをエージェント定義内に宣言することで、SSOT(Single Source of Truth)の整合を保つ。

@seo-director の定義と委譲先スキル

@seo-director は SEO という専門ドメインを持ち、/blog-meta の起動指示を返す役割だ:

## メタ最適化時の動き(`@seo-director meta <slug>`

1. `src/content/magazine/{cluster}/{category}/{slug}.md` を Read して現状の frontmatter と本文を確認
2. `blog-ops/config/sites/corporate.json` でカテゴリ・タグ数制限を確認
3. `blog-ops/config/audience-tracks.json` で記事のトラックに対応するキーワード傾向を把握
4. main-thread に以下を返す:
   /blog-meta を以下のパラメータで起動してください:
   - slug: {slug}
   - track: {tech|case}(判定根拠を添える)
   - site_config: blog-ops/config/sites/corporate.json

@seo-director の特徴は cluster SEO マップの保守 だ。business cluster / tech cluster の 2 cluster 設計を維持し、各 cluster 内で pillar の primary_keyword を頂点として spoke が降りてくる構造を守る:

## 2 cluster 設計の運用

- **business cluster**: primary_keyword は経営判断・投資判断クエリを対象
- **tech cluster**: primary_keyword は設計パターン・実装パターン・ツールクエリを対象
- **2 cluster 間で primary_keyword の重複を避ける**(カニバリ回避)

@seo-director keyword <slug> モードは、記事 brief の seo: セクション素案を YAML 形式で返す。main-thread がそれをファイルに書き出し、次のスキル(/blog-plan)への入力にする:

seo:
  primary_keyword: "AI エージェント 組織設計 Claude Code"
  secondary_keywords:
    - "Claude Code エージェント 設計 実装"
    - "{domain}-director パターン エージェント"
  longtail_clusters:
    - "Claude Code で業務横断エージェント組織を設計する方法"
  search_intent: "informational"
  serp_title_finalized: "Synapse の責任者エージェント設計 — {domain}-director パターン"
  cluster_position: "tech cluster pillar(synapse-org シリーズの tech 軸)"

フォールバック設計

エージェント失敗時の責任の流れ

Synapse のフォールバック設計は 3 層になっている:

スキル内部での処理失敗
  → HUMAN_INPUT マーカーを付与して draft を返す
  → main-thread に「人間の確認が必要」と明示する

@blog-review の fail 判定
  → pipeline を中断し、ユーザーに確認を求める
  → fail の理由を 04_review.md に構造化して出力する

エージェントが判断できない(分割推奨等)
  → ユーザー確認を求めてフロー停止
  → 判断材料(判定根拠・複数の選択肢)を提示する

/blog-tech-write スキルの HUMAN_INPUT マーカーはフォールバックの典型例だ。AI が確認できない情報(具体的な数値・失敗事例・採用しなかった案の具体名)にマーカーを埋め込み、人間が後から補う形にする:

{{HUMAN_INPUT: 運用開始時期(いつから Synapse を本番運用しているか)}}
<!-- 現在 .claude/skills/ には 15 個のスキルが定義されている(blog-audit / blog-case / blog-case-write / blog-classify / blog-fill-ssot / blog-fact-check / blog-meta / blog-pattern / blog-plan / blog-publish / blog-retro / blog-review / blog-tech-write / blog-translate / ui-ux-pro-max) -->

スキルが HUMAN_INPUT マーカー数の最低基準(tech: 5 個以上)を下回ると、自動で再生成ループを回す。2 回リトライしても下回る場合は _state.jsonblockers に記録し、人間に報告する。

人間エスカレーションのトリガー設計

Synapse の人間エスカレーションは以下の条件でトリガーする:

トリガー動作
/blog-review が fail を返したpipeline を中断し、fail 理由と一緒にユーザーへ確認
/blog-publish 直前必ずユーザー最終確認を求める
記事の分割推奨(tech と case が混在)@blog-director に差し戻し、ユーザーに選択を求める
HUMAN_INPUT マーカーが最低数以下自動リトライ後、人間確認を求める

@editor-in-chief の定義ファイルには次の宣言がある:

ノンストップ自動実行はしない。`/blog-review` で fail が出たとき・`/blog-publish` の直前は
必ずユーザーに確認を求める。

この 1 行をエージェント定義に書くことで、Claude Code が @editor-in-chief を呼ぶたびに、この制約がコンテキストに含まれる。


設計の判断記録 — なぜこの構造にしたか

フラット構造にしなかった理由

最初に「全部 main-thread から直接スキルを呼べばいい」という設計を試みた。

フラット構造の問題は、判断のドメイン知識が main-thread に集約されること。「この記事は tech トラックか case トラックか」「SEO キーワードが被っていないか」という判断を、エージェントに責任を持たせずにすべて main-thread が行うと:

  • main-thread のコンテキストが肥大化する
  • 同じ判断をするたびに参照ドキュメントを毎回渡す必要がある
  • 「このドメインの知識は誰が持っているか」が分からなくなる

{domain}-director パターンを導入した理由は、ドメイン知識とその参照先を責任者エージェントに固定するためだ。@seo-director に聞けば SEO の判断が返ってくる。@editor-in-chief に聞けば編集方針が返ってくる。知識の所在が明確になる。

スキルを agents/ に混ぜなかった理由

.claude/agents/ に実行手順を書いてしまう実装も考えられる。しかし Synapse ではエージェントとスキルを分離した。

理由は再利用性だ。スキル(/blog-tech-write 等)は:

  • main-thread から直接呼べる
  • パイプライン DAG(JSON)から参照できる
  • エージェントの実行計画の中で「次のアクション」として列挙できる

エージェント定義に手順を混ぜると、スキルを複数のパイプラインで共有できなくなる。/blog-tech-writenew-article-pillar パイプラインでも rewrite-tech パイプラインでも使う。分離しておいたから再利用できた。

CLAUDE.md は委譲規約だけに留める — 詳細を書くと SSOT が崩れる

CLAUDE.md に書く委譲ルールは「起動ルートの宣言」にとどめる。

## 不変規約(CLAUDE.md)

- ブログ運用: 業務として記事を扱う場合は必ず責任者エージェント経由

各エージェントの内部ルール(参照ドキュメント・モード別動作・フォールバック)は agents/*.md に書く。CLAUDE.md に詳細を書きすぎると、ルールの更新場所が増えて SSOT が崩れる。

分離の基準:

内容書く場所
「どのエージェントを通して呼ぶか」の宣言CLAUDE.md
「そのエージェントがどう動くか」の仕様agents/*.md
「スキルの入出力と手順」skills/*/SKILL.md
「パイプライン DAG」blog-ops/config/pipelines/*.json

ルールの更新頻度も分離の根拠になる。起動ルートはほぼ変わらないが、スキルの手順は頻繁に改良する。変更頻度の異なるものを同じファイルに書かない — それが CLAUDE.md を最小に保つ理由だ。


Synapse ハーネスの設計チェックリスト — まとめ

Claude Code 上に業務横断エージェント組織を組む際、Synapse の設計から抽出できる原則をまとめる。

{domain}-director パターンの導入チェック

  • 担当ドメイン × 権限 × 委譲先の 3 要素でエージェントを定義しているか
  • 各エージェントが「アドバイザ」に徹し、実行計画を main-thread に返す構造になっているか
  • 「作業エージェント」を作っていないか(Claude Code の sub-agent 制約に違反する)
  • CLAUDE.md に「どのエージェント経由で起動するか」の起動ルートを宣言しているか

.claude/agents/ の定義品質チェック

  • frontmatter に name / description / model / tools が揃っているか
  • 担当領域セクション(自分が判断できる事項)が明示されているか
  • 委任先セクション(権限外の事項をどこに渡すか)が明示されているか
  • 参照ドキュメントセクションがあり、判断根拠のファイルパスを列挙しているか
  • 「ノンストップ自動実行しない」「判断の節目で main-thread に返す」が宣言されているか

.claude/skills/ の I/O contract チェック

  • 入力(読むファイル・引数)が SKILL.md に明記されているか
  • 出力(書き出すファイル)が SKILL.md に明記されているか
  • 前提条件(スキルが期待する状態)が明記されているか
  • パイプライン DAG(blog-ops/config/pipelines/*.json)との整合が取れているか

フォールバック設計チェック

  • 各スキルが「人間の確認が必要な情報」を HUMAN_INPUT マーカーで明示しているか
  • review fail 時に pipeline が停止し、ユーザーに確認を求める設計になっているか
  • publish 直前に必ず人間確認のステップが入っているか

Synapse は Claude Code のエージェント機能を使い倒しているが、仕組みそのものは .claude/agents/.claude/skills/ に Markdown ファイルを置くだけだ。複雑に見えるエージェント組織も、{domain}-director パターンとスキル分離の 2 つの原則から導ける。

Synapse がどのように事業運営に組み込まれているか、エンジニア組織をどう構成してエージェントと協働するかの business 観点は AI エージェント組織の立ち上げ方 を参照してほしい。

SHARE X でシェア B! はてブ