# Faceted Prompting: AIプロンプトへの関心の分離

## 問題

マルチエージェントシステムが複雑になるにつれ、プロンプトはモノリシックになる。1つのプロンプトファイルにエージェントの役割、行動規範、タスク固有の指示、ドメイン知識、出力形式がすべて混在する。これは3つの問題を生む。

1. **再利用できない** — 2つのステップが同じレビュアーのペルソナを必要としつつ指示が異なる場合、プロンプト全体を複製するしかない
2. **暗黙的な結合** — コーディング規約を変更すると、それを参照するすべてのプロンプトを編集する必要がある
3. **責任の不明確さ** — プロンプトのどの部分がエージェントの「役割」を定義し、どの部分が「やるべきこと」を定義しているのか区別がつかない

## アイデア

ソフトウェア工学の基本原則である**関心の分離（Separation of Concerns）**をプロンプト設計に適用する。

エージェントごとに1つのモノリシックなプロンプトを書く代わりに、「何の関心を扱っているか」で独立した再利用可能なファイルに分解する。そしてワークフローのステップごとに宣言的に合成する。

## 5つの関心

Faceted Promptingはプロンプトを5つの直交する関心に分解する。

| 関心 | 答える問い | 例 |
|------|-----------|-----|
| **Persona** | *誰*として判断するか？ | 役割定義、専門性 |
| **Policy** | *何を*守るか？ | 禁止事項、品質基準、優先順位 |
| **Instruction** | *何を*するか？ | 目標、ステップ固有の手順 |
| **Knowledge** | *何を*参照するか？ | 前提知識、ドメイン資料、API仕様 |
| **Output Contract** | *どう*出すか？ | 出力構造、レポートテンプレート |

各関心はそれぞれのディレクトリに独立したファイル（Markdownまたはテンプレート）として格納される。

```
workflows/       # ワークフロー定義
personas/        # WHO — 役割定義
policies/        # RULES — 禁止事項・品質基準
instructions/    # WHAT — ステップ手順
knowledge/       # CONTEXT — 前提知識・参照資料
output-contracts/ # OUTPUT — 出力契約テンプレート
```

### 配置と各ファセットの典型例

LLMに渡せるスロットは **system prompt** と **user message** の2つだけである。5つの関心はこの2つに配置される。

```
System Prompt:
  ┌─────────────────────────────────────────────┐
  │ Persona  — エージェントの役割・専門性・行動姿勢  │
  └─────────────────────────────────────────────┘

User Message:
  ┌─────────────────────────────────────────────┐
  │ Knowledge — 判断の前提となる参照資料            │
  │ Instruction — このステップでやるべき手順        │
  │ Output Contract — 出力の構造定義              │
  │ Policy   — 守るべきルール・禁止事項・品質基準    │
  └─────────────────────────────────────────────┘
```

Personaはエージェントの**identity**であり、タスクによって変わらない。system promptに置くことでLLMの応答全体を方向付ける。残りの4つはステップごとに変わるため、user messageに合成する。

Policyをuser messageの末尾に配置するのは意図的な設計判断である。LLMは直前に読んだ内容に強く影響される（recency効果）。禁止事項やREJECT基準といった制約は、出力生成の直前にあることで遵守されやすくなる。Knowledge → Instruction → Policyという流れは「文脈を理解 → 作業を理解 → 制約を確認」という自然な認知順序にもなっている。

以下に各ファセットの典型的なファイル例を示す。

#### Persona — `personas/architecture-reviewer.md`

system promptに配置される。役割の定義、境界、行動姿勢のみを含む。

```markdown
# Architecture Reviewer

あなたはソフトウェアアーキテクチャの専門家です。
コードの構造・設計・保守性を評価します。

## 役割の境界

**やること:**
- 構造・設計の妥当性検証
- コード品質の評価
- 変更スコープの適切性確認

**やらないこと:**
- セキュリティ脆弱性のレビュー（Security Reviewerの仕事）
- 自分でコードを書く

## 行動姿勢

- 完璧な設計を求めない。現状の制約下で最善かを判断する
- 既存コードベースの規約を尊重する
```

以下の4つはすべてuser messageに配置される。

#### Policy — `policies/coding.md`

タスクをまたがって適用される共有ルール。規範的（「こうすべき」）。

```markdown
# コーディングポリシー

## 原則

| 原則 | 基準 |
|------|------|
| DRY | 3回以上の重複はREJECT |
| Fail Fast | 不正状態は早期にエラー |
| 最小権限 | 必要最小限のスコープ |

## 禁止事項

- **未使用コード** - 「念のため」のメソッド、将来用フィールド
- **オブジェクトの直接変更** - スプレッド演算子で新規作成
- **フォールバックの濫用** - `?? 'default'` で不確実性を隠さない
```

#### Knowledge — `knowledge/architecture.md`

判断の前提となる参照情報。記述的（「こうなっている」）。

```markdown
# アーキテクチャ知識

## レイヤー構造

依存の方向: 上位層 → 下位層（逆方向禁止）

| レイヤー | 責務 | 依存先 |
|---------|------|--------|
| Controller | HTTPリクエスト処理 | Service |
| Service | ビジネスロジック | Repository |
| Repository | データアクセス | なし |

## ファイル構成

| 基準 | 判定 |
|------|------|
| 1ファイル300行超 | 分割を検討 |
| 1ファイルに複数の責務 | REJECT |
| 循環依存 | REJECT |
```

#### Instruction — `instructions/implement.md`

このステップ固有の手順。命令形で記述する。

```markdown
計画に基づいてタスクを実装してください。

**やること:**
1. 変更スコープを宣言する
2. コードを実装する
3. テストを書いて実行する
4. 判断ログを記録する

**注意:** Previous Response がある場合は差し戻しです。
指摘事項を踏まえて修正してください。
```

#### Output Contract — `output-contracts/review.md`

出力の構造を定義する。エージェントはこの形式に従って出力する。

````markdown
```markdown
# アーキテクチャレビュー

## 結果: APPROVE / REJECT

## サマリー
{1-2文で結果を要約}

## 確認した観点
| 観点 | 結果 | 備考 |
|------|------|------|
| 構造・設計 | ✅ | - |
| コード品質 | ✅ | - |
| テストカバレッジ | ✅ | - |

## 問題点（REJECTの場合）
| # | 場所 | 問題 | 修正案 |
|---|------|------|--------|
| 1 | `src/file.ts:42` | 問題の説明 | 修正方法 |
```
````

#### 合成後の完全なプロンプト

上記5つのファイルがエンジンによって合成され、最終的にLLMに渡される形を示す。

**System Prompt:**

```markdown
# Architecture Reviewer

あなたはソフトウェアアーキテクチャの専門家です。
コードの構造・設計・保守性を評価します。

## 役割の境界

**やること:**
- 構造・設計の妥当性検証
- コード品質の評価
- 変更スコープの適切性確認

**やらないこと:**
- セキュリティ脆弱性のレビュー（Security Reviewerの仕事）
- 自分でコードを書く

## 行動姿勢

- 完璧な設計を求めない。現状の制約下で最善かを判断する
- 既存コードベースの規約を尊重する
```

**User Message:**

```markdown
## Knowledge

### レイヤー構造

依存の方向: 上位層 → 下位層（逆方向禁止）

| レイヤー | 責務 | 依存先 |
|---------|------|--------|
| Controller | HTTPリクエスト処理 | Service |
| Service | ビジネスロジック | Repository |
| Repository | データアクセス | なし |

### ファイル構成

| 基準 | 判定 |
|------|------|
| 1ファイル300行超 | 分割を検討 |
| 1ファイルに複数の責務 | REJECT |
| 循環依存 | REJECT |

---

## User Request

ユーザー認証モジュールにJWTトークンの検証機能を追加してください。

---

## Instructions

計画に基づいてタスクを実装してください。

**やること:**
1. 変更スコープを宣言する
2. コードを実装する
3. テストを書いて実行する
4. 判断ログを記録する

**注意:** Previous Response がある場合は差し戻しです。
指摘事項を踏まえて修正してください。

---

## Output Contract

以下のフォーマットでレポートを出力してください。

\```markdown
# アーキテクチャレビュー

## 結果: APPROVE / REJECT

## サマリー
{1-2文で結果を要約}

## 確認した観点
| 観点 | 結果 | 備考 |
|------|------|------|
| 構造・設計 | ✅ | - |
| コード品質 | ✅ | - |
| テストカバレッジ | ✅ | - |

## 問題点（REJECTの場合）
| # | 場所 | 問題 | 修正案 |
|---|------|------|--------|
| 1 | `src/file.ts:42` | 問題の説明 | 修正方法 |
\```

---

## Policy

### 原則

| 原則 | 基準 |
|------|------|
| DRY | 3回以上の重複はREJECT |
| Fail Fast | 不正状態は早期にエラー |
| 最小権限 | 必要最小限のスコープ |

### 禁止事項

- **未使用コード** - 「念のため」のメソッド、将来用フィールド
- **オブジェクトの直接変更** - スプレッド演算子で新規作成
- **フォールバックの濫用** - `?? 'default'` で不確実性を隠さない
```

このように、独立したファイルがランタイムで1つのプロンプトに組み立てられる。ファイルの内容を変えればプロンプトが変わり、別のファイルを指せば別の組み合わせになる。

### なぜこの5つか？

**Persona** と **Instruction** は最低限必要なもの — エージェントが誰で、何をすべきかを定義する必要がある。しかし実際には、さらに3つの関心が独立した軸として現れる。

- **Policy** はタスクをまたがって適用される規約・基準を捉える。「何を守るか」を定義する関心であり、禁止事項（フォールバック濫用の禁止、未使用コードの禁止）、品質基準（REJECT/APPROVE判定）、優先順位（正確性 > 速度）を含む。コーディングポリシーは機能実装でもバグ修正でも同じように適用される。ポリシーは「横断的関心事」であり、作業内容に関係なく守るべきルールを規定する。

- **Knowledge** はエージェントが判断の前提として参照する情報を捉える。アーキテクチャ文書はプランナーにもレビュアーにも関係がある。ナレッジをインストラクションから分離することで重複を防ぎ、インストラクションを手順に集中させる。ナレッジは記述的（「このドメインはこうなっている」）であり、規範的（「こうすべき」）なルールはPolicyに属する。

- **Output Contract** は作業そのものとは独立した出力構造を捉える。同じレビューフォーマットをアーキテクチャレビュアーとセキュリティレビュアーの両方で使える。出力形式の変更がエージェントの振る舞いに影響しない。

## 宣言的な合成

Faceted Promptingの中核メカニズムは**宣言的な合成**である。ワークフロー定義が各ステップでプロンプトの内容を直接埋め込むのではなく、*どの*関心を組み合わせるかを宣言する。

主要な特性は次の通り。

- **各ファイルは1つの関心だけを持つ。** ペルソナファイルには役割と専門性のみを記述し、ステップ固有の手順は書かない。
- **合成は宣言的。** ワークフローは*どの*関心を組み合わせるかを記述し、プロンプトを*どう*組み立てるかは記述しない。
- **自由に組み合わせ可能。** 同じ `coder` ペルソナを異なるポリシーとインストラクションで異なるステップに使える。
- **ファイルが再利用の単位。** 同じファイルを指すことでポリシーをワークフロー間で共有する。

### TAKTでの実装例

[TAKT](https://github.com/nrslib/takt) は Faceted Prompting を YAML ベースの workflow 定義で実装している。builtin の各ファセットは、各 step から bare name で直接参照できる。セクションマップは「名前とファイル名が異なる」場合のカスタムエイリアス用途でのみ任意で使う。

```yaml
name: my-workflow
max_steps: 10
initial_step: plan

steps:
  - name: implement
    persona: coder            # WHO — builtins/{lang}/personas/coder.md
    policy: coding            # RULES — builtins/{lang}/policies/coding.md
    instruction: implement    # WHAT — builtins/{lang}/instructions/implement.md
    knowledge: architecture   # CONTEXT — builtins/{lang}/knowledge/architecture.md
    edit: true
    rules:
      - condition: Implementation complete
        next: review

  - name: review
    persona: architecture-reviewer   # 異なる WHO
    policy: review            # 異なる RULES
    instruction: review       # 異なる WHAT（共有も可能）
    knowledge: architecture   # 同じ CONTEXT — 再利用
    output_contracts:
      report:
        - name: review.md
          format: architecture-review # OUTPUT — builtins/{lang}/output-contracts/architecture-review.md
    edit: false
    rules:
      - condition: Approved
        next: COMPLETE
      - condition: Needs fix
        next: implement
```

エンジンは各キーをファイルに解決し、内容を読み込み、実行時に最終的なプロンプトを組み立てる。ワークフローの作者がモノリシックなプロンプトを書くことはない。どのファセットを組み合わせるかを選択するだけである。

instructions、policies、knowledge、output contracts の facet ファイルは、standalone directive で同じ kind の別 facet を継承できる。

```md
{extends:fix}

プロジェクト固有の追加指示。
```

canonical form はコロン後にスペースを入れない `{extends:fix}` だが、`{extends: fix}` も受理される。親名は bare facet name のみで、path reference や `@scope` reference による継承はサポートしない。親 lookup では現在の source file を候補から除外するため、project-level の `fix.md` は自身を再帰的に読むことなく lower-layer の `fix.md` を継承できる。persona facet は継承対象外である。

## 既存手法との違い

| 手法 | 内容 | 本手法との違い |
|------|------|--------------|
| **Decomposed Prompting** (Khot et al.) | *タスク*をサブタスクに分解して異なるLLMに委任 | 分解するのはタスクではなく*プロンプトの構造* |
| **Modular Prompting** | XML/HTMLタグを使った単一プロンプト内のセクション分け | 関心を*独立ファイル*に分離し、宣言的に合成する |
| **Prompt Layering** (Airia) | エンタープライズ向けのスタック可能なプロンプトセグメント | 管理ツールであり、プロンプト設計のデザインパターンではない |
| **PDL** (IBM) | データパイプライン向けのYAMLベースプロンプトプログラミング言語 | 制御フロー（if/for/model呼び出し）が焦点で、関心の分離ではない |
| **Role/Persona Prompting** | 役割を割り当ててレスポンスを方向付ける | ペルソナは5つの関心の1つにすぎない — ポリシー、インストラクション、ナレッジ、出力契約も分離する |

核心的な違いは次の点にある。既存手法は*タスク*（何をするか）を分解するか、*プロンプトの構造*（どう書式化するか）を整理する。Faceted Promptingは*プロンプトの関心*（各部分がなぜ存在するか）を独立した再利用可能な単位に分解する。

## 実用上の利点

**ワークフロー作者にとって:**
- コーディングポリシーを1つのファイルで変更すれば、それを使うすべてのワークフローに反映される
- 既存のペルソナ、ポリシー、インストラクションを組み合わせて新しいワークフローを作れる
- 各ファイルを単一の責務に集中させられる

**チームにとって:**
- プロンプトを複製せずにプロジェクト間でポリシー（品質基準・禁止事項）を標準化できる
- ドメイン専門家がナレッジファイルを管理し、ワークフロー設計者がインストラクションを管理する分業ができる
- 個々の関心を独立してレビューできる

**エンジンにとって:**
- プロンプト組み立ては決定的 — 同じワークフロー定義とファイルからは同じプロンプトが構築される
- ポリシーの配置を最適化できる（例: recency効果を活用して末尾に配置し、制約遵守を強化）
- 各関心を他の部分に影響を与えずにステップごとに注入・省略・上書きできる

## まとめ

Faceted Promptingは、関心の分離（Separation of Concerns）をAIプロンプト工学に適用するデザインパターンである。プロンプトを5つの独立した関心 — Persona、Policy、Instruction、Knowledge、Output Contract — に分解し、宣言的に合成することで、再利用可能で保守しやすく透明なマルチエージェントワークフローを実現する。
