Langchain を使って LLM から回答させてみる

# やりたいこと
業務で Azure OpenAI Service を使う機会があり、LangChain を使っていろいろとやってみたので複数回で記事にまとめます。今回は、単純に LLM から回答させる実装を行います。
すでに多くの方が情報発信していますが、その1つとして参考にしてもらえると幸いです！

# 他の記事
1. [Langchain を使って LLM から回答させてみる](https://qiita.com/coitate/private/14b5ee27162ba5344b37) ← イマココ
1. [LangChain を使ってローカルファイルを RAG で回答させてみる](https://qiita.com/coitate/items/d0fa841f9ce7fa579103)
1. [LangChain を使って Azure Cognitive Search のデータを RAG で回答させてみる](https://qiita.com/coitate/items/90ff3a9ecdcea9aa6504)

# 前提
* WSL (Ubuntu 22.04) 上で行います
* Python で実装します
* LLM のモデルには、GPT-3.5 を使用します
* Azure OpenAI Service で `gpt-35-turbo` モデルのデプロイメントは作成済み
* Azure OpenAI Service を使うため、OpenAI 社のものを使う場合と異なる場合があります

# LangChain とは

https://www.langchain.com/

公式ドキュメントによると以下とのこと。
`LangChain is a framework for developing applications powered by language models.`
(言語モデルを利用したアプリケーションを開発するための便利なフレームワーク)

LLM を扱う際の便利な機能が揃っており、LLM を使う際のデファクトスタンダードになりつつあるのではと個人的には思う。開発スピードも速く、毎日のようにバージョンアップされている。

# 実装
## パラメータ設定
OpenAI 関連のパラメータを事前に `.env` ファイルとして定義しておく。コードの中で環境変数として読み込み使用する。今回は分かりやすさのために引数に設定する形にするが、`DEPLOYMENT_NAME` 以外のパラメータは環境変数に設定されていれば引数で与える必要はない。

``` .env
OPENAI_API_TYPE=azure
OPENAI_API_VERSION=2023-05-15
OPENAI_API_BASE={YOUR_OPENAI_API_BASE}
OPENAI_API_KEY={YOUR_OPENAI_API_KEY}
DEPLOYMENT_NAME={YOUR_DEPLOYMENT_NAME}
```

## 使用するライブラリ
バージョンは任意のもので可。`pip install -r requirements.txt` でインストールする。

``` requirements.txt
python-dotenv==1.0.0
langchain==0.0.268
openai==0.27.8
```

## コード本体
`temperature` は回答のばらつき具合を指定するパラメータ。0 にすると毎回同じ回答になる。

``` chat_llm.py
import os
import dotenv
from langchain.schema import AIMessage, HumanMessage, SystemMessage
from langchain.chat_models import AzureChatOpenAI

dotenv.load_dotenv()

OPENAI_API_TYPE = os.getenv('OPENAI_API_TYPE')
OPENAI_API_VERSION = os.getenv('OPENAI_API_VERSION')
OPENAI_API_BASE = os.getenv('OPENAI_API_BASE')
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
DEPLOYMENT_NAME = os.getenv('DEPLOYMENT_NAME')

llm = AzureChatOpenAI(openai_api_key=OPENAI_API_KEY,
                      openai_api_type=OPENAI_API_TYPE,
                      openai_api_base=OPENAI_API_BASE,
                      openai_api_version=OPENAI_API_VERSION,
                      deployment_name=DEPLOYMENT_NAME,
                      temperature=0)

# 環境変数でパラメータを与える場合は引数は以下で可 (deployment_name は必須)
# llm = AzureChatOpenAI(deployment_name=os.getenv('DEPLOYMENT_NAME'),
#                       temperature=0)


messages = [SystemMessage(content='You are a helpful and great assistant.')]

prompt = ''
while (True):
    prompt = input('Q: ')

    if prompt == 'q' or not prompt:
        break

    messages.append(HumanMessage(content=prompt))
    res = llm(messages=messages)
    answer = res.content
    messages.append(AIMessage(content=answer))

    print('A:', answer)

print('-- Chat History --')
for msg in messages:
    print(msg.type, '\t>> ', msg.content)
```

## 実行してみる
以下のような形で LLM とチャット形式でやりとりできる。`Q: ` がユーザのプロンプト入力で、空もしくは `q` を入力するとチャットを終了する。`A: ` が LLM からの回答。画像では英語でやりとりしているが、日本語の入力でも問題なく回答してくれる。
チャットを終了すると、それまでのやりとりの履歴を表示する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1743460/9eb58ed1-4788-0ae3-2875-1632eed402da.png)

# ということで
LangChain を使って、LLM (GPT-3.5) とチャット形式でやりとりするコードを実装しました！
次回は、RAG を行っていきます。

# 次回
LangChain を使ってローカルファイルを RAG で回答させてみる

以上です。