# 機能設計書 20-PM Agent

## 概要

本ドキュメントは、プロジェクトマネジメント支援を行う「PM Agent」サブグラフの設計を記述する。

### 本機能の処理概要

**業務上の目的・背景**：データベース設計においてユーザーの要件を正確に把握し、構造化されたビジネス要件ドキュメント（BRD）として整理することは重要である。本機能は、PM（プロジェクトマネージャー）の役割をAIが担い、曖昧な要件を明確化し、DB AgentやQA Agentが利用可能な形式に整理する。

**機能の利用シーン**：
- Deep Modelingワークフローからのサブグラフ呼び出し
- ユーザーの自然言語による要件からの構造化要件抽出
- テストケースを含むBRDの自動生成

**主要な処理内容**：
1. analyzeRequirementsノードでユーザー要件を分析
2. 要件をgoalとtestcasesの構造化形式に変換
3. processAnalyzedRequirementsToolで要件を保存
4. ストリーミングでリアルタイムにフロントエンドに送信

**関連システム・外部連携**：
- OpenAI API（GPT-5）
- YAML出力（No.15）でスキーマを文字列化

**権限による制御**：デザインセッションへのアクセス権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | デザインセッション詳細画面 | 主機能 | 要件分析と構造化 |

## 機能種別

AIサブグラフ（要件分析エージェント）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| messages | BaseMessage[] | Yes | 対話履歴 | 空でないこと |
| schemaData | Schema | Yes | 現在のスキーマ情報 | Schema型に準拠 |
| designSessionId | string | Yes | デザインセッションID | 有効なUUID |
| analyzedRequirements | AnalyzedRequirements | No | 既存の分析済み要件 | デフォルト空 |
| analyzedRequirementsRetryCount | number | No | リトライ回数 | デフォルト0 |

### 入力データソース

- 親グラフ（Deep Modelingワークフロー）からの状態引き継ぎ
- ユーザーとの対話メッセージ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| messages | BaseMessage[] | 更新された対話履歴 |
| analyzedRequirements | AnalyzedRequirements | 構造化された要件情報 |
| artifactSaveSuccessful | boolean | 要件保存成功フラグ |

### 出力フォーマット（AnalyzedRequirements）

```typescript
{
  goal: string;  // セッション全体の目的（1-2文）
  testcases: {
    [category: string]: {
      id: string;        // UUID
      title: string;     // テストケースタイトル
      type: string;      // SQL操作タイプ（INSERT, UPDATE, DELETE, SELECT）
      sql: string;       // SQL文（初期は空）
      testResults: any[]; // テスト結果（初期は空配列）
    }[]
  }
}
```

### 出力先

- 親グラフへの状態返却
- ストリーミング応答（SSE_EVENTS.ANALYZED_REQUIREMENTS）としてフロントエンドに送信

## 処理フロー

### 処理シーケンス

```
1. analyzeRequirementsノード実行
   └─ LLMに要件分析を依頼
      └─ 現在のスキーマをYAMLで渡す
      └─ PM分析プロンプトを適用
2. ルーティング判定（routeAfterAnalyzeRequirements）
   └─ 要件が保存済み → END
   └─ リトライ上限超過 → エラー
   └─ ツール呼び出しあり → invokeSaveArtifactToolへ
   └─ ツール呼び出しなし → analyzeRequirementsへ（再分析）
3. invokeSaveArtifactToolノード実行
   └─ processAnalyzedRequirementsToolを実行
      └─ 入力を正規化（ID付与、空フィールド追加）
      └─ ストリーミングイベント発信
      └─ Commandで状態更新
4. 成功判定
   └─ artifactSaveSuccessful → END
   └─ 失敗 → analyzeRequirementsへ（リトライ）
```

### フローチャート

```mermaid
flowchart TD
    A[START] --> B[analyzeRequirementsノード]
    B --> C{要件保存済み?}
    C -->|Yes| D[END]
    C -->|No| E{リトライ上限?}
    E -->|超過| F[WorkflowTerminationError]
    E -->|未達| G{ツール呼び出しあり?}
    G -->|Yes| H[invokeSaveArtifactToolノード]
    G -->|No| B
    H --> I{保存成功?}
    I -->|Yes| D
    I -->|No| B
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 自律的分析 | ユーザー対話なしで要件を自律的に分析 | 常に適用 |
| BR-02 | 業界標準仮定 | 曖昧な要件は業界標準で補完 | 要件不明確時 |
| BR-03 | リトライ上限 | 最大3回のリトライ後にエラー | 分析失敗時 |
| BR-04 | 必須フィールド | goalとtestcasesは必ず出力 | 常に適用 |

### テストケース仕様

| 項目 | 説明 |
|-----|------|
| title | ビジネス・ユーザー視点でのテストシナリオ |
| type | SQL操作タイプ（INSERT, UPDATE, DELETE, SELECT） |
| カテゴリ | 論理的なグルーピング |
| 正常・異常 | 両シナリオを含む |

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベースを直接操作しない。要件は親グラフの状態として管理される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------
| - | WorkflowTerminationError | 設定取得失敗 | エラーをスローしてワークフロー終了 |
| - | WorkflowTerminationError | リトライ上限超過（3回） | エラーをスローしてワークフロー終了 |
| - | Valibotバリデーションエラー | ツール入力不正 | エラーをスローしてリトライ |

### リトライ仕様

- RETRY_POLICY適用
- initialInterval: 1秒
- backoffFactor: 2
- maxAttempts: 3
- 分析レベルのリトライ上限: 3回（MAX_ANALYSIS_RETRY_COUNT）

## トランザクション仕様

該当なし（状態管理のみ）

## パフォーマンス要件

- 要件分析：30秒以内
- ストリーミング応答によるリアルタイムフィードバック

## セキュリティ考慮事項

- LLM出力はValibotでスキーマ検証
- 要件情報はセッション状態として管理（永続化は親グラフが担当）

## 備考

- GPT-5モデルをreasoningモード（effort: medium, summary: detailed）で使用
- tool_choice: requiredでツール使用を必須化
- parallel_tool_calls: falseで順次実行
- strictモードでツールスキーマを厳格に適用

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | pmAgentAnnotations.ts | `frontend/internal-packages/agent/src/pm-agent/pmAgentAnnotations.ts` | サブグラフの状態定義 |

**読解のコツ**: Annotation.Root()でサブグラフ固有の状態（analyzedRequirements, artifactSaveSuccessful, analyzedRequirementsRetryCount等）を定義している。

#### Step 2: グラフ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | createPmAgentGraph.ts | `frontend/internal-packages/agent/src/pm-agent/createPmAgentGraph.ts` | サブグラフの構築 |

**主要処理フロー**:
- **16-17行目**: StateGraphの初期化とpmAgentStateAnnotationの適用
- **19-25行目**: analyzeRequirementsとinvokeSaveArtifactToolノードの追加（リトライポリシー付き）
- **27-32行目**: START→analyzeRequirementsエッジと条件付きエッジの定義
- **33-42行目**: invokeSaveArtifactTool後の条件付きエッジ（成功時END、失敗時リトライ）
- **44行目**: グラフのコンパイル

#### Step 3: 分析ノードを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | analyzeRequirementsNode.ts | `frontend/internal-packages/agent/src/pm-agent/nodes/analyzeRequirementsNode.ts` | 要件分析ノード |

**主要処理フロー**:
- **17-27行目**: 設定取得とスキーマのYAML変換
- **31-35行目**: invokePmAnalysisAgentでLLM呼び出し
- **46-49行目**: レスポンスを状態に追加、リトライカウントをインクリメント

#### Step 4: LLM呼び出しを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | invokePmAnalysisAgent.ts | `frontend/internal-packages/agent/src/pm-agent/invokePmAnalysisAgent.ts` | LLMストリーム呼び出し |

**主要処理フロー**:
- **24-33行目**: GPT-5モデルの設定（reasoning, tool_choice等）
- **49行目**: reasoningフィールドの除去
- **51-59行目**: プロンプトフォーマットとストリーム実行
- **68-82行目**: ResultAsyncチェーンでエラーハンドリング

#### Step 5: 要件保存ツールを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | processAnalyzedRequirementsTool.ts | `frontend/internal-packages/agent/src/pm-agent/tools/processAnalyzedRequirementsTool.ts` | 要件保存と状態更新 |

**主要処理フロー**:
- **53-71行目**: ツール本体の定義、入力の正規化（ID・空フィールド追加）
- **83-94行目**: ToolMessageとストリーミングイベントの発信
- **96-102行目**: Commandで状態更新（analyzedRequirements, artifactSaveSuccessful）

#### Step 6: プロンプトを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | pmAnalysisPrompts.ts | `frontend/internal-packages/agent/src/pm-agent/prompts/pmAnalysisPrompts.ts` | システムプロンプト定義 |

**読解のコツ**: PM_ANALYSIS_SYSTEM_MESSAGEで役割、指示、ワークフロー、出力フォーマットを定義。

### プログラム呼び出し階層図

```
createPmAgentGraph()
    │
    └─ StateGraph(pmAgentStateAnnotation)
           │
           ├─ analyzeRequirementsNode
           │      │
           │      ├─ getConfigurable(config)
           │      │
           │      ├─ yamlSchemaDeparser(schemaData)
           │      │
           │      └─ invokePmAnalysisAgent(variables, messages, configurable)
           │             │
           │             ├─ removeReasoningFromMessages()
           │             │
           │             ├─ pmAnalysisPrompt.format()
           │             │
           │             ├─ model.stream() [GPT-5]
           │             │      └─ SystemMessage(pmAnalysisPrompt)
           │             │      └─ cleanedMessages
           │             │
           │             └─ streamLLMResponse()
           │
           ├─ routeAfterAnalyzeRequirements
           │      ├─ 要件保存済み → 'END'
           │      ├─ リトライ上限 → WorkflowTerminationError
           │      ├─ hasToolCalls() → 'invokeSaveArtifactTool'
           │      └─ else → 'analyzeRequirements'
           │
           └─ invokeSaveArtifactToolNode
                  │
                  ├─ ToolNode([processAnalyzedRequirementsTool])
                  │
                  └─ processAnalyzedRequirementsTool
                         │
                         ├─ v.parse(analyzedRequirementsInputSchema, input)
                         │
                         ├─ 入力の正規化（ID付与、空フィールド追加）
                         │
                         ├─ dispatchCustomEvent(SSE_EVENTS.MESSAGES)
                         │
                         ├─ dispatchCustomEvent(SSE_EVENTS.ANALYZED_REQUIREMENTS)
                         │
                         └─ Command({ update: { analyzedRequirements, artifactSaveSuccessful } })
```

### データフロー図

```
[入力]                    [処理]                         [出力]

schemaData ──▶ yamlSchemaDeparser() ──▶ schemaText
     │                                      │
     │                    ┌─────────────────┘
     │                    ▼
     │         pmAnalysisPrompt.format() ──▶ systemPrompt
     │                                      │
     │                    ┌─────────────────┘
     │                    ▼
messages ────▶ invokePmAnalysisAgent() ──▶ AIMessage
     │                │                         │
     │                │          ┌──────────────┴──────────────┐
     │                │          │                             │
     │                │   ツール呼び出しなし           ツール呼び出しあり
     │                │          │                             │
     │                │          ▼                             ▼
     │                │   再分析ループ           invokeSaveArtifactTool
     │                │                                       │
     │                │                                       ▼
     │                │                      processAnalyzedRequirementsTool
     │                │                                       │
     │                │                    ┌──────────────────┘
     │                │                    ▼
     │                │           正規化されたAnalyzedRequirements
     │                │                    │
     │                │          ┌─────────┴─────────┐
     │                │          ▼                   ▼
     │                │   SSE_EVENTS.MESSAGES   SSE_EVENTS.ANALYZED_REQUIREMENTS
     │                │          │                   │
     │                │          └─────────┬─────────┘
     │                │                    ▼
     └────────────────│──────────▶ フロントエンドへストリーミング
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| createPmAgentGraph.ts | `frontend/internal-packages/agent/src/pm-agent/createPmAgentGraph.ts` | ソース | サブグラフ構築 |
| pmAgentAnnotations.ts | `frontend/internal-packages/agent/src/pm-agent/pmAgentAnnotations.ts` | ソース | 状態定義 |
| analyzeRequirementsNode.ts | `frontend/internal-packages/agent/src/pm-agent/nodes/analyzeRequirementsNode.ts` | ソース | 分析ノード |
| invokeSaveArtifactToolNode.ts | `frontend/internal-packages/agent/src/pm-agent/nodes/invokeSaveArtifactToolNode.ts` | ソース | ツール実行ノード |
| processAnalyzedRequirementsTool.ts | `frontend/internal-packages/agent/src/pm-agent/tools/processAnalyzedRequirementsTool.ts` | ソース | 要件保存ツール |
| routeAfterAnalyzeRequirements.ts | `frontend/internal-packages/agent/src/pm-agent/routing/routeAfterAnalyzeRequirements.ts` | ソース | ルーティング |
| invokePmAnalysisAgent.ts | `frontend/internal-packages/agent/src/pm-agent/invokePmAnalysisAgent.ts` | ソース | LLM呼び出し |
| pmAnalysisPrompts.ts | `frontend/internal-packages/agent/src/pm-agent/prompts/pmAnalysisPrompts.ts` | ソース | プロンプトテンプレート |
| createPmAgentGraph.test.ts | `frontend/internal-packages/agent/src/pm-agent/createPmAgentGraph.test.ts` | テスト | ユニットテスト |
| createPmAgentGraph.integration.test.ts | `frontend/internal-packages/agent/src/pm-agent/createPmAgentGraph.integration.test.ts` | テスト | 統合テスト |
