アプリ開発プロセスにおけるAIと人間の協働：ワークフロー設計ガイド

# はじめに

SIer業界において、AIの活用は新たなパラダイムシフトをもたらしています。AIと人間（SI技術者）の効果的な協働が不可欠となっています。本記事では、SIerのアプリ開発プロセスにおいて、AIと人間がどのように協力し合い、高品質なソリューションを提供できるかについて解説します。

## 本書の目的

AIと人間の協働ワークフローを効果的に設計・実装するための具体的なガイドラインを提供することです。

# AIと人間の協働ワークフロー設計のTIPS

## 自動化の本質

自動化とは、できるだけ人間の手をかけずに品質を担保できることを目指すことです。

## 自動化のジレンマ

- 品質の担保のために人間のチェックは必要です。
  - 人間のチェックをできる限り少なく、簡単に行えるフローを目指します。
- AIが単独で修正不能な問題に対しAI修正ループが発生すると、LLMのAPIコストのみが嵩むことになります。
  - これは避けるべき状態です。
  - ループのブレイクポイントを設計することが重要です。

## AIによるチェックと人間によるチェックの2段階を行う

品質を確保しつつ、効率的なワークフローを実現するために、AIによるチェックと人間によるチェックの2段階アプローチを採用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/e465127f-e022-76d7-2c61-4c87be355c9d.png)

## 人間が確認しやすい「チェックのための中間成果物」をAIに出力させる

- 人間が品質評価を行いやすい形の「チェックのための中間成果物」をAIに出力させます。
  - AIと人間の最適なやりとりの形（インターフェース）を定義します。
  - これらの形（インターフェース）はサブタスクによって異なります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/fa849b3d-9167-377e-674c-b2e286595ff8.png)



## AIの出力を修正するための2つの手法

AIの出力の再修正は必ず発生します。成果物そのもので直接やりとりすべき修正と、集約された中間成果物でやりとりすべき修正とを分けて考えます。

- **成果物そのもので直接やりとりすべき修正**：修正対象が1ファイルに限定される修正/AIへの要求コストが高い修正
- **集約された中間成果物でやりとりすべき修正**：修正対象が複数ファイルに波及し、整合性が必要な修正

https://qiita.com/ymgc3/items/04af1d8a27db94c47512


# 自動化ワークフローの段階的実現

## ワークフローの複雑度を測る指標

ワークフローの複雑度を測る指標としては以下があります：

| 指標 | 説明 |
|------|------|
| サイクルタイム | ワークフローの開始から完了までにかかる総時間 |
| 手順数 | ワークフロー内の総ステップ数 |
| 分岐の複雑さ | 条件分岐やループの数と深さ |
| ボトルネック | ワークフロー内で最も遅延が発生する箇所 |
| リソース利用率 | 人員や設備の稼働率 |
| エラー率 | プロセス中に発生するエラーの頻度 |
| 再作業率 | やり直しが必要になるタスクの割合 |

## ワークフローの複雑度を段階的に上げる

- 複雑性をコントロールすることが設計者に求められます。
- いきなり大きなフローを作らず、出力の価値を担保できる小さなサブプロセスを見出し、段階的な実現をしていくことが、大きな価値実現のための肝となります。

## アウトプット品質を向上させるためにフィードバックループを活用する

- AIのアウトプットをAIに評価させ、再修正させます。
- フィードバック構造は、出力信号が再び入力としてシステムに戻される構造です。
  - これにより、システムは自己調整を行い、望ましい動作を維持することができます。

```mermaid
graph LR
    D[入力] --> E[処理]
    E --> F[出力]
    F -->|フィードバック| D
```

- フィードフォワードでは、システムの挙動は比較的予測しやすいです。
- 一方、フィードバックでは、要素間の相互作用が非可換であることが多く、システムの挙動はより複雑で予測が難しくなります。扱いが難しい一方、複雑性を攻略するために活用が必要となります。
  - LangChainがLangGraphに進化していることは、グラフ構造によるループ設計を可能とし、より複雑なタスクに対応するためです。

#### ループのブレイクポイントを設定する
- AIが単独で修正不能な問題に対しAI修正ループが発生すると、LLMのAPIコストのみが嵩むことになります。
  - これは避けるべき状態です。
  - ループのブレイクポイントを設計することが重要です。

## AIに考えさせることと、AIに考えさせないことを明確にする

- AIに考えさせないことを増やすことは、出力の揺らぎを減らすことになり、安定性と効率につながります。
  - そのため、AIに考えさせない領域を増やすことは自動化のために重要です。
- AIに考えさせないこと
  - 例：使用する言語やライブラリ、ディレクトリ構成、方針設計、テストの分離方針など
      - SIerを主語とした場合、これらは最適解が一意に収斂されていく領域
      - 人間が予め決定する方が、品質、出力の安定性を向上させます

### 例.プロジェクトセットアッププロセスをワークフローにしてみると

- ワークフロー上は役割をAIとしていますが、大体コマンドライン実行のみで終わるタスクです
- 使用する言語やライブラリ、ディレクトリ構成が定まっていれば、AI(LLM)へのリクエストは少なくなることのイメージが持てるでしょう

<img width="400" alt="a4a612bc-10df-f012-a1d8-de146ab794ab.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/a4a612bc-10df-f012-a1d8-de146ab794ab.png">


## AIに考えさせないことを環境条件として定義

- AIに考えさせないことは環境条件として、ツール内にテキストで組み込みます。
  - AIが内的に常に参照することとなります。

セットアップ時の環境条件の読み込みイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/9570b6d4-1e64-e093-cfd0-97ab74c78b75.png)

# AIの記憶領域

## AIの記憶領域の分類

AIの記憶領域を便宜的に以下のように分類します：

| 分類 | 記憶内容 | 記憶の継続範囲 | 例 |
|------|----------|----------------|-----|
| 基盤モデルLLM | 一般的な開発用語辞書、ソフトウェア工学用語集 | 永続的 | - |
| 初期記憶 | 会社標準的な仕様書テンプレート | PJ単位 | 業界標準の仕様書テンプレート、ディレクトリ構造のテンプレート |
| 長期記憶 I類 | プロジェクトの非機能要件、企業固有のガイドライン、ドメイン特有の専門知識 | PJ単位 | セキュリティ要件、パフォーマンス基準、社内コーディング規約、業界固有の規制 |
| 長期記憶 II類 | プロジェクトの機能仕様、プロジェクトのPGM、プロジェクトのDBモデル | PJ単位 | 画面一覧、画面UI、API一覧、TBL一覧、ドメイン定義 |
| 長期記憶 Ⅲ類 | 要件間の潜在的な依存関係、過去のプロジェクトとの類似点、ドメイン固有の暗黙的な制約 | PJ単位 | - |
| 中期記憶 | 形式化された要件リスト、現在の仕様書ドラフトの状態、仕様書生成タスクの進捗状況 | チャットスレッド単位 | 機能要件リスト、優先順位、コミットのマイルストーン |
| コンテキスト記憶 | 直前のユーザー入力、現在生成中の仕様書セクションの内容、直近の修正や補足の指示 | チャットスレッド単位 | 特定の要件に関する質問、仕様書の特定部分の修正指示、追加の説明要求 |
| 手続き的記憶 | 仕様書生成のワークフロー、要件から仕様への変換ルール、仕様書の一貫性チェックプロセス | システム全体 | 要件分析→設計→実装の流れ、EARS（Easy Approach to Requirements Syntax） |

## AIにおいての中期記憶=コンテキスト

- LLMに与えるコンテキストは中期記憶として読み替えられます
- コンテキストで扱う文字数は少なく保つことがAIの出力精度を高めます。
  - 現在のLLMはロングコンテキストが入力可能になってきていますが、コンテキスト量が多くても全てを確実に読み取ることはできません。
  - コンテキストとして渡す文字量を少なく保つために、タスクに対し重要ではないコンテキストは渡さない制御を行うことは設計の重要な点です。
  - 例えば、非機能要件は長期記憶としての扱いですが、タスクによって呼び出される/呼び出されないの2通りを制御します。

## AIの記憶領域とトリガーの設計

| 分類 | 例 | 記憶の書き込みトリガー |
|------|-----|------------------------|
| 基盤モデルLLM |- 一般的な開発用語辞書<br>- ソフトウェア工学用語集 | - モデルの学習時に組み込まれる<br>- 定期的な更新やファインチューニング |
| 初期記憶 | - 会社標準的な仕様書テンプレート<br>- ディレクトリ構造のテンプレート | - システム管理者による手動設定 |
| 長期記憶 I類 |　- プロジェクトの非機能要件<br>- 企業固有のガイドライン<br>- セキュリティ要件<br>- パフォーマンス基準 | - プロジェクト計画段階での入力<br>- 重要な方針変更時 |
| 長期記憶 II類 | - プロジェクトの機能仕様<br>- 画面一覧、画面UI<br>- API一覧<br>- DBモデル | - 要件定義フェーズでの入力<br>- 設計文書のコミット時 |
| 長期記憶 Ⅲ類 | - 要件間の潜在的な依存関係<br>- 過去のプロジェクトとの類似点<br>- ドメイン固有の暗黙的な制約 | - AIの推論プロセス中<br>- 人間のフィードバックに基づく学習 |
| 中期記憶 | - 形式化された要件リスト<br>- 現在の仕様書ドラフトの状態<br>- タスクの進捗状況 | - ユーザーとの対話中<br>- タスク実行中の定期的な更新 |
| コンテキスト記憶 | - 直前のユーザー入力<br>- 現在生成中のセクションの内容<br>- 直近の修正指示 | - ユーザーの各入力時<br>- AIの各応答生成時 |
| 手続き的記憶 | - 仕様書生成のワークフロー<br>- 要件から仕様への変換ルール | -(あらかじめ設計される) |


## 生成タスクごとに呼び出す記憶

## 生成タスクごとの記憶呼び出し
- タスクと呼び出される記憶のセットを予め定義します。
- 例：コード生成タスク → 長期記憶I類（非機能要件）、長期記憶II類（機能仕様）

- タスクの性質に応じて、必要な記憶を効率的に組み合わせます
    - 手続き的記憶領域にタスクと記憶のマッピングを保存し、自動的に適用されるようにします
  - このタスクと呼び出される記憶とのセットを予め定義しておきます（手続き的記憶領域）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/f45b47c1-37e2-ec01-be37-708dc8f2c8b7.png)



## コンテキストを限定しながら作業させる

- LLMへの１リクエストで品質を保って生成可能なコードは、100行~300行程度です(主観)
- それ以上のコードボリュームでの自動化を実現させる場合には、ワークフローを組む必要があります
    - サブプロセスを定義し、コンテキストサイズを限定します
    - コンテキストウインドウをずらしながら、せまいコンテキストを保ち作業を連続させます
        - 既出のチャットAIツールの扱いが上手い方は、これを人力でやっています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348593/ae31454f-656c-b39a-8673-9b64ad056276.png)

# まとめ

SIer業界におけるAIと人間の協働は、効率的で高品質なソリューション提供の鍵となります。本ガイドでは、以下の重要なポイントを提示しました。

1. **自動化の本質理解**: 
   - 人間の介入を最小限に抑えつつ、品質を担保することが自動化の目標
   - AIと人間のチェックを組み合わせた2段階アプローチが効果的

2. **効果的なワークフロー設計**:
   - 中間成果物を活用し、人間による効率的なレビューを可能とする
   - ワークフローの複雑度を段階的に上げ、安定した自動化プロセスを構築

3. **フィードバックループの活用**:
   - AIの出力を自己評価・修正する仕組みを導入し、品質向上を図る
   - 複雑なタスクに対応するため、フィードバック構造を活用する

4. **AIと人間の役割分担の明確化**:
   - AIに考えさせる領域と人間が決定する領域を明確に区分
   - 環境条件としてAIに考えさせない要素を定義し、出力の安定性を向上させる

5. **AIの記憶システムの設計**:
   - 基盤モデルLLMから手続き的記憶まで、多様な記憶領域の設計が重要
   - 各記憶タイプに適した書き込みトリガーを設定し、適切なタイミングで情報を更新させる

6. **コンテキスト管理の最適化**:
   - AIの記憶をコンテキストとして扱い、効率的な情報処理を実現する
   - タスクに応じて必要なコンテキストのみを選択的に活用する設計とする

これらの原則を適切に実装することで、AIと人間の強みを最大限に活かし、革新的かつ高品質なソリューションを提供します。常に進化するAI技術と人間の専門知識を融合させ、継続的な改善を行うことが、今後のSIer業界の成功の鍵となるでしょう。