LangChain.js の公式情報などを見つつ Azure OpenAI Service（モデルは GPT-4 Turbo）との組み合わせを試してみる

## はじめに
今回の内容は、Azure OpenAI Service に関する内容です。

Azure OpenAI Service を使った内容に関しては、最近、JavaScript（Node.js）を使って以下の記事に書いた内容を試していました。
以下の記事では、Azure OpenAI Service の「GPT-4 Turbo」のモデルを「@azure/openai」 を使った内容を書いています。

●Azure OpenAI Service の公式情報などを見つつ「GPT-4 Turbo」の「Chat Completions の JSON Mode」を試す：【Node.js（JavaScript）で「@azure/openai」を利用】 - Qiita
　https://qiita.com/youtoy/items/c9a879624c18d40bbdd7

今回の記事でも JavaScript（Node.js）を使うのと、「Azure OpenAI Service の GPT-4 Turbo のモデル」を試すのは同じです。
上記の記事との違いは、「@azure/openai」を使うのではなく、「LangChain.js」を使う点です。

## LangChain.js について
今回使う [LangChain.js](https://js.langchain.com/docs/get_started/introduction) について、最初に少しだけ補足します。

「LangChain.js」は、以下の LangChain というものを JavaScript で扱えるものです。

●LangChain
　https://www.langchain.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6e05cd07-9c65-3de7-768d-d8a0796a1686.png)

LangChain というのは、[以下の公式ドキュメント](https://python.langchain.com/docs/get_started/introduction)に書かれている記載をもとに説明すると、「大規模言語モデル (LLM) などの言語モデルを使ったアプリ開発に利用できるフレームワーク」です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1d340c3d-f077-2aba-c496-f63107025184.png)

例えば OpenAI の ChatGPT の API などの開発まわりの情報を調べていると、LangChain の情報を見かけることがあるかと思います。
また、日本語の書籍も複数出ているので、ChatGPT の API を用いた開発などに関する技術書を検索していても見かけるかもしれません。

LangChain で何ができるかや利用するメリットに関しては、検索するとたくさん出てくると思うので、ここでは説明を割愛します。

### LangChain.js と Azure OpenAI Service を組み合わせる
上記の LangChain.js は、Azure OpenAI Service とも組み合わせることができます。それに関する説明が、以下の公式ドキュメントに書かれていたりします。

●Azure OpenAI | 🦜️🔗 Langchain
　https://js.langchain.com/docs/integrations/llms/azure

●Azure ChatOpenAI | 🦜️🔗 Langchain
　https://js.langchain.com/docs/integrations/chat/azure

#### Azure OpenAI や Azure ChatOpenAI など
上記の 2つのドキュメントの `import` ・ `model` の部分を見ると、上側のほうは「OpenAI」クラスを使っており、下側のほうは「ChatOpenAI」クラスを使っています。

●Azure OpenAI | 🦜️🔗 Langchain
　https://js.langchain.com/docs/integrations/llms/azure

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ce3e82d5-15ba-9f86-fbc3-587cd0145ab3.png)

それらの違いを見ていくと、以下の Components の [LLMs](https://js.langchain.com/docs/integrations/llms/) か [Chat models](https://js.langchain.com/docs/integrations/chat/) かのどちらになるか、という違いのようでした。

●Components | 🦜️🔗 Langchain
　https://js.langchain.com/docs/integrations/components

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/8477a29c-6db1-8f0f-c6cf-13925b256c13.png)

いまいち違いが分からなかったので、APIリファレンス上の記載を比べてみました。

そうすると、以下のように「OpenAI」は「Create completion」に対応し、「ChatOpenAI」は「Create chat completion」に対応しているようでした。

●OpenAI | LangChain.js - v0.1.2
　https://api.js.langchain.com/classes/langchain_openai.OpenAI.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/b608beb2-ab3c-cf09-6fab-451a1831e62d.png)

●ChatOpenAI | LangChain.js - v0.1.2
　https://api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/eb465a40-fc9d-015b-bc07-533c31d76050.png)

[「Create completion」は、OpenAI のドキュメントでレガシーとなっているもの](https://platform.openai.com/docs/api-reference/completions)かと思われるため、「Create chat completion」に対応するほうを使っていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/3012041b-841e-6e0e-133b-8317f71f5c97.png)

## LangChain.js と Azure OpenAI Service を組み合わせて使ってみる
それでは、LangChain.js と Azure OpenAI Service とを組み合わせて使ってみます。

### 下準備
下準備として、上で掲載していた公式ドキュメントの手順に従い、npmコマンドでパッケージをインストールします。

```bash
$ npm install @langchain/openai
```

そして公式ドキュメントを見てみると、JavaScript のプログラムを書く際に、Azure OpenAI Service の APIキーをなどを設定する方法が書いてあります。

```javascript
import { ChatOpenAI } from "@langchain/openai";

const model = new ChatOpenAI({
  temperature: 0.9,
  azureOpenAIApiKey: "SOME_SECRET_VALUE", // In Node.js defaults to process.env.AZURE_OPENAI_API_KEY
  azureOpenAIApiVersion: "YOUR-API-VERSION", // In Node.js defaults to process.env.AZURE_OPENAI_API_VERSION
  azureOpenAIApiInstanceName: "{MY_INSTANCE_NAME}", // In Node.js defaults to process.env.AZURE_OPENAI_API_INSTANCE_NAME
  azureOpenAIApiDeploymentName: "{DEPLOYMENT_NAME}", // In Node.js defaults to process.env.AZURE_OPENAI_API_DEPLOYMENT_NAME
});
```

情報として必要になるのは、以下の 4つになるようです。

- 設定で記載する Azure OpenAI Service関連の情報
   - APIキー
   - APIバージョン
   - インスタンス名
   - デプロイ名

この中の OpenAI の APIバージョンで記載する内容は、Azure上の表示で以下となっているものをベースに書く形です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6604842d-bfbd-a802-ef49-afce932df426.png)

Microsoft公式の以下のページを見ると、（開発情報自体は Python の事例ではありますが） `"2023-12-01-preview"` と書けば良さそうでした。

●Azure OpenAI Serviceで JSON モードを使用する方法 - Azure OpenAI | Microsoft Learn
　https://learn.microsoft.com/ja-jp/azure/ai-services/openai/how-to/json-mode?tabs=python

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/21c47d14-c65f-fcf3-0773-023921348721.png)

### 簡単なプログラムを作って動かしてみる
Azure OpenAI Service にモデルをデプロイしていれば、「APIキー、インスタンス名、デプロイ名」の情報もあるかと思います。
これらと、上記の「APIバージョン」の情報を使い、API 経由でレスポンスを得られる要にプログラムを書いてみます。

#### JavaScript　のプログラム
[公式ドキュメントの内容](https://api.js.langchain.com/classes/langchain_openai.ChatOpenAI.html)を参考にしつつ、お試し用のプログラムを以下のようにしてみました。
なお、ES Module の import を利用するなどの対応のために、ファイルの拡張子を mjs にしています。

```javascript:app.mjs
import { ChatOpenAI } from "@langchain/openai";

const model = new ChatOpenAI({
  temperature: 0.9,
  azureOpenAIApiKey: process.env.AZURE_OPENAI_API_KEY,
  azureOpenAIApiVersion: process.env.AZURE_OPENAI_API_VERSION,
  azureOpenAIApiInstanceName: process.env.AZURE_OPENAI_API_INSTANCE_NAME,
  azureOpenAIApiDeploymentName: process.env.AZURE_OPENAI_API_DEPLOYMENT_NAME,
});

const message = "あなたは誰？"

console.log("== 処理を実行 ==");
console.log({message});

const res = await model.invoke(message);
console.log(res);
```

#### 環境変数の設定（一時的な対応）
上のプログラムでは、「APIキー、APIバージョン、インスタンス名、デプロイ名」を環境変数から読み込むようにしています。

環境変数の設定について、とりあえずの対応で、一時的にコマンドを使った設定を行うことにします（※ 必要に応じて永続化などを行ってください）。
なお今回の以下の手順は、Mac のターミナルを利用して進めています。

```bash:Macの場合
$ export AZURE_OPENAI_API_KEY='【APIキー】'
$ export AZURE_OPENAI_API_INSTANCE_NAME='【インスタンス名】'
$ export AZURE_OPENAI_API_DEPLOYMENT_NAME='【デプロイ名】'
$ export AZURE_OPENAI_API_VERSION='【APIバージョン】'
```

#### プログラムの実行
それでは、上記のプログラムを実行してみます。
実行後、以下のように　API からのレスポンスを得られることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/848b812e-ec76-bb03-38c3-6ccbbe2e0912.png)