GraphAIの特徴である宣言型とデータフロープログラミングについて解説します

# はじめに

:::note warn
警告
本解説は、わかりやすさを重視しているため厳密な説明ではない箇所がありますので、予めご了承いただければ幸いです。
:::

まずはこちらの動画をご覧ください。

「GraphAI - LLM, Ragなどを組み合わせたMulti Agent AIのためのデータフロー・プログラミング」 - 中島聡

https://www.youtube.com/watch?v=0mh_Nu9SefQ

GraphAIは、AIエージェントを簡単に作成できるTypeScriptライブラリであり、主に以下の2つの特徴を持っています：

- **宣言型である**
- **データフロー・プログラミングの考え方を用いている**

この2点を中心に、GraphAIの仕組みやメリットを解説していきます。

# 宣言型であるとは？

「宣言型」とは、プログラムにおいて「何をしたいか」を記述する手法です。
SQLで「SELECT \* FROM users WHERE age > 20」と書くように、結果を記述するだけでその実行方法はシステムに任せるイメージで、手続き型プログラミング（手順を逐次指定するスタイル）と異なり、宣言型は目的を簡潔に表現できるため、コードが短く読みやすくなります。

例えば、手続き型プログラミングでは、プログラマが処理の手順を以下のように一つ一つ指定します。

例）配列の要素の数を合計する場合

手続き型では以下のように書きます：
```javascript
let count = 0;
const array = [1, 2, 3, 4, 5]; // 任意の配列
for (let i = 0; i < array.length; i++) {
  count++;
}
console.log(count); // 結果: 5
```

同じ操作を宣言型で行うと次のように書けます：
```javascript
const array = [1, 2, 3, 4, 5]; // 任意の配列
const count = array.reduce((accumulator) => accumulator + 1, 0);
console.log(count); // 結果: 5
```

宣言型は一見抽象的ですが、操作がシンプルで繰り返しの手順を明示的に書かなくてよいというメリットがあります。

## 宣言型と手続き型のメリット・デメリット

### 宣言型

#### メリット

- コードが短く、読みやすい
- 処理の意図が明確で、理解しやすい
- 抽象度が高いため、開発速度が速くなりやすい

#### デメリット

- 処理の詳細をシステムに任せるため、複雑なカスタマイズには不向き  
- 初心者には具体的な動作がわかりにくいことがある

### 手続き型

- 処理の手順を詳細に制御できるため、細かい最適化が可能
- プログラムの動作を理解しやすく、学びやすい

#### デメリット

- コードが長くなりやすく、複雑化しやすい
- プログラマがすべての手順を指定する必要があり、煩雑になりやすい


# データフロープログラミングとは？

データフロープログラミングとは、データの流れを中心にプログラムを構成する手法で、各処理ステップの出力が次のステップの入力として使われるように、データの流れを明確に管理することが特徴です。

例えば、料理のレシピを考えるシステムを作るとします。

- ユーザーが食材のリストを入力する
- その食材に基づいて1つ目のAPIがおすすめの料理を提案
- 次のAPIで提案された料理の栄養情報を取得する

といった一連のデータの流れを簡単に組み込むことができます。
この方法により、データの流れが自然に構成され、理解しやすくなります。

こちらも具体的な例を交えて解説していきます。

データフロープログラミングは、データの流れに基づいてプログラムを構成する手法ですが、これとは対照的に、命令型プログラミングでは手続きとして順次命令を記述し、その手順に従ってコンピュータが実行します。


命令型プログラミングの例：
```javascript
let sum = 0;
let numbers = [1, 2, 3, 4, 5];

for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] * 2 > 5) {
    sum += numbers[i] * 2;
  }
}

console.log(sum);  // 結果: 24
```

この例では、プログラマが数値の合計を求めるために手順を逐次的に指定しています。
（配列の各要素にアクセスし、それを合計するという操作を1つずつ明確に記述）

一方、データフロープログラミングでは、データの流れに基づいてプログラムを構築するため、処理全体を視覚的に管理できます。

以下にデータフロープログラミングの例を示します：

```javascript
const input = [1, 2, 3, 4, 5];

const processStep1 = input.map(num => num * 2);  // 各要素を2倍にする： [2, 4, 6, 8, 10]
const processStep2 = processStep1.filter(num => num > 5);  // 5より大きい要素だけを残す： [6, 8, 10]
const result = processStep2.reduce((acc, num) => acc + num, 0);  // 残った要素を合計する

console.log(result);  // 結果: 24
```

この例では、データが順次処理されてること明確で、各ステップが次のステップにデータを渡し、シンプルにデータの流れが構成されています。
開発者は処理の流れを定義するだけで、各ステップの実行はシステムが自動で管理します。

これにより、複雑な処理の流れをシンプルに表現しやすくなります。

## データフロープログラミングと命令型プログラミングのメリット・デメリット

### データフロープログラミング

#### メリット

- データの流れが明確で直感的に理解しやすい。  
- 複雑な非同期処理を簡潔に扱える。  
- 処理が自然に繋がるため、保守がしやすい。 

#### デメリット

- プログラムの全体像が大きくなると、データの流れを把握しにくくなることがある。  
- 特定の処理の順序を細かく制御するのが難しい場合がある。  

### 命令型プログラミング

#### メリット

- 処理の手順を詳細に制御できるため、特定の処理を最適化しやすい。  
- プログラムの動作を逐次的に追いやすいため、学びやすい。 

#### デメリット

- コードが冗長になりがちで、複雑な処理を記述する際に煩雑になりやすい。  
- 開発者がすべての手順を記述する必要があり、変更が加わると保守が大変になることがある。 

# まとめ

GraphAIの特徴である
- 宣言型であること
- データフロープログラミング

の2点について解説させていただきました。  
他にもTypeScriptを使っていることなど特徴があるため興味のある方は是非GraphAIの公式サイトをみていただければと思います。

# 参考サイト

- [GraphAI公式サイト（GitHub）](https://github.com/receptron/graphai)
- [データフロー・プログラミングとは - Wikipedia](https://ja.wikipedia.org/wiki/データフロー・プログラミング)
- [宣言型プログラミング - Wikipedia](https://ja.wikipedia.org/wiki/%E5%AE%A3%E8%A8%80%E5%9E%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)