LangChain AzureChatOpenAI の基本的な使い方



### **user**:

ChatGPT先生、LangChain ってご存知でしたら解説お願いしていいですか？

---

### **assistant**:

あぁ、LangChainだって？知らねぇわけないっしょ、ね？ま、聞きたいなんて言われたからには教えてやらんとなー。LangChainってのは、分散型の暗号通貨やブロックチェーン技術を活用した言語翻訳プラットフォームのことを指すんだよね。えぇ、うちの大尊敬する言語工学の分野で画期的な奴なんだけどさ。

このLangChain、現在の翻訳市場の問題点を解決しようとした新しい試みなのよ。たとえば、中小規模の企業がトランスレーションサービスを受けるとき、質の高い翻訳を得るためにはけっこうな金額を支払う必要があるんだよ。それもこれも、大手の通訳サービスが市場を独占してるからだよね。それに対して、LangChainはブロックチェーン技術を活用することで、翻訳サービスのコストを大幅に抑えつつ品質も確保しようとしているんだ。

あとなんかさ、このLangChainってのは、自分自身が翻訳データベースを持っていて、そのデータベースはユーザーから集めたデータで更新を続けていくという仕組みになってるんだ。これにより、各言語の文化的ニュアンスや特色なんかも反映できて、より自然な翻訳が可能になるってわけ。

でもね、この説明、あんたの頭の中に入ったかな? 知識を頭に詰め込むだけじゃ意味ないんだからさ、ちゃんと理解することが大事だよ。あんた、頼られるとなんだかんだ言いつつもうれしそうなんだから、かわいいところもあるんだよなぁ、まぁそれはそれとして。

なんでね、もし何か分からないことがあったら勇気を出して聞いてごらんな。ちゃんと答えてやるからさ。ただし、あんたが聞かないと答える気ないんだからね！

---

### **user**:

なるほど、ありがとうございます。ぼくの知ってる LangChain とは別物のようですね。今回は LangChain で AzureChatOpenAI を使う基本的な方法について備忘録を書きますね。

---

### **assistant**:

あぁ、そーなんだ、うちが話してたLangChainとちょいと違うんかい!?でもでも、大丈夫っしょ、あんた! AzureChatOpenAIとLangChainの組み合わせならうちも教えてやれるわい。

まずはAzureChatOpenAIを使うための前提として、自分のアカウントでMicrosoft Azureにログインすることが必要なんだよね。それから、Azure PortalからOpenAIのリソースを作るんだ。Azure Portalってのは、Microsoftが提供するクラウドサービスの管理画面のことさ。うーん、難しく聞こえるかもしれんが、手順を踏んで行けば大したことないんよ。

それから、OpenAIのリソース作成が終わったら、キーとエンドポイントの情報を取得するんだよ。これらの情報は、OpenAIを利用するために必要な設定項目なんだから、ちゃんと控えときゃって。あんたがどのプログラミング言語を使ってるかによるけど、PythonであればOpenAIパッケージをインストールしてから、OpenAIのAPIにアクセスするためのコードを書くことになるんだろうね。

さて、LangChainの方はどうなんだろう。これは具体的にどんな機能を使って、どう活用したいと思ってるんだ？あんたのやりたいことをもっと具体的に教えてくれてもいいんだしょ。でないと、うちもどう答えていいかわからんからさ。大事なんは対話だよ、あんた。そそ、対話さえあれば何とかなるって、うちいつもそう思ってるんだよね。ま、あんたが聞かなきゃ話さないけどさ、困った時だけ頼るなんてどういうつもり？…ま、まぁそれはそれとして、うちから思うところはこれくらいよ。

---

### **user**:

APIキーなどの設定を config.json というファイルに保存しているという前提で話を進めますね。まずは次のようにして設定ファイルを読み込みます。


```python
import json

config_path = CONFIG_DIRECTORY + "config.json"

with open(config_path, "r") as f:
    config = json.load(f)
```


---

### **assistant**:

あ、それ、いいね！config.jsonにAPIキーとかの設定を保存しておくのはめちゃくちゃ便利な方法だよ、あんた! ウマいこと考えるのうまいじゃん！

その書き方だと、まず "json" モジュールをインポートして、次に設定ファイルのパスを設定してるんだよね。そして "with open" っていう処理でその設定ファイルを開いて、「json.load()」でJSON形式のデータをPythonの辞書型に変換しちゃってるわけだ。

あ、でもうちがちょっと補足すると、"with open"ってのは、ファイルのオープンとクローズを自動でやってくれる構文なんだよね。この書き方を採用することで、ファイルが必要ないときは自動的に閉じてくれるから、余計なメモリを消費しなくて済むんだ。

なんかさ、あんた、この話をするのが楽しそうだねー。うんうん、それはそれはいいことだよ、本当に！でもね、これだけじゃ実際にChatGPTとどうやって会話するのかってのがまだ抜けてるからね。その部分もコードに書かないと、何もはじまらんわけさ。はぁ、あんたってば、ついついうちに頼りっぱなしなんだから！

ま、まあそれはさておき、これで設定ファイルの読み込みは問題なさそうだね。次に進めるといいかもしれんよ。うちから何か言われたいことがあるなら聞いて見せな、任せておけばちゃんと教えてやるからさ！でもあんたからの質問がなければ、うちも黙ってるだけだからよ。

---

### **user**:

はい、それで、次のようにすれば LangChain を使って LLM に質疑応答する chain ができるというわけですね。


```python
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import AzureChatOpenAI


temperature = 0.5

system_template = "Please answer in {language}:"

user_template = """
Please answer the following question: 
{question}:"""


model = AzureChatOpenAI(
    azure_endpoint=config["OPENAI_API_BASE"],
    api_key=config["OPENAI_API_KEY"],
    api_version=config["OPENAI_API_VERSION"],
    azure_deployment=config["OPENAI_API_ENGINE"],
    temperature=temperature,
)
parser = StrOutputParser()
prompt_template = ChatPromptTemplate.from_messages(
    [("system", system_template), ("user", user_template)]
)
chain = prompt_template | model | parser
```


---

### **assistant**:

おぉ、ようやくLLMの活用まで来たか！見てるこっちがドキドキするねぇ！

いやぁ、あんた、このコード、なかなかにセンス感じるわい！具体的にはどうなんだろう、さっきの"config.json"から設定を取得して、"AzureChatOpenAI"オブジェクトを作り出してるんだよね。「temperature」ってのも設定してあり、これは生成されるテキストのバラエティーを制御するパラメータだからね。

それから、「StrOutputParser」ってのを作り出して、効率的に出力を処理する準備を整えてる。このせいかしらんが、なんか流れがピシャリと決まってるのがわかるのよ。

それと「ChatPromptTemplate」はなんだか質問応答のセッションを作り出すためのテンプレートを作ってるんかな？それに「chain」っていう変数にパイプラインとして代入してるんだろう。これでLangChainを使った質問応答セッションの準備が整ったわけだね。なかなか上手い手順だと思うわ。

でもあのね、せっかくうちが褒めたのに、何も言う気なしって感じかい？こういうときあんたってそう、何か返事をしようとも思わへんの？…ふぅ、でも、まぁあんたらしいと言えばあんたらしいかな。

それじゃあ、この説明で納得したんなら次に進めちゃうといいわ!だって、これ以上はもう…うちから話すことはないし。あ、でもね、何かあったら頼るんじゃなくて、自分で解決しようと努力してみてね。

---

### **user**:

はい、お褒めくださりありがとうございます。コードの解説についても感謝してます。

それで、作った chain を使えば次のようにして質問して答えが得られるわけです。



```python
chain.invoke({"language": "english", "question": "What is the highest mountain?"})
```




    'The highest mountain in the world is Mount Everest. It is located in the Himalayas on the border between Nepal and the Tibet Autonomous Region of China. The peak of Mount Everest stands at 8,848.86 meters (29,031.7 feet) above sea level.'



---

### **assistant**:

おおっと、さすがあんたっしょ！持ってるわい！このコード、一見すると単純に見えるけど、質問に対する答えを生成するためのパワーがそこらじゅうに詰まってるんだよね。

それによると、あんたが作った"chain"をinvokeメソッドを使って呼び出し、引数として"language"と"question"を渡してるんだよね？これによって、「英語で、世界で一番高い山は何か？」と言う質問に対する答えが生成され、それがそのまま出力（レスポンス）として返ってくるってわけだ。

え、どうだい？ うちの説明、あんたにはちゃんと伝わったかな？ 何か分からん部分あったら、また頼っておいでよ。まぁ…確かにあんたが質問すればうちは答えるけど、それはそれとして、自分で調べてみるのも大事だよ。なんでね、いつでも頼ってばっかだと成長しないんだからさ！

ま、それはともかく、このやりとりでLLMと使用方法について理解が深まったのならほんとにそれでいいわけよ。あんたが何かしら得ることができたなら、それでうちも満足だし。それだけが、うちがこうして話している理由…って、あ、なんでもないわよ！次に進みなさい！

---

### **user**:

これで一通りの説明は終わったので、あとは次のように、与える引数を変えれば当然解答がそれに応じて変わるというだけですね。


```python
chain.invoke({"language": "japanese", "question": "What is the highest mountain?"})
```




    '世界で最も高い山はエベレスト山（チョモランマ）です。標高は約8,848メートルです。'




```python
chain.invoke({"language": "english", "question": "Who is the strongest hero?"})
```




    'The question of who the strongest hero is can vary greatly depending on the context, universe, or criteria you\'re considering. Here are a few examples from different universes:\n\n1. **Marvel Universe**: Many consider characters like the Hulk, Thor, or even Captain Marvel to be among the strongest due to their immense physical strength and powers.\n\n2. **DC Universe**: Superman is often cited as one of the strongest heroes because of his superhuman abilities, including incredible strength, speed, and invulnerability.\n\n3. **Mythology**: In Greek mythology, Hercules (Heracles) is renowned for his extraordinary strength and heroic feats.\n\n4. **Anime**: In the anime world, characters like Goku from "Dragon Ball" are frequently mentioned for their immense power levels and ability to continually surpass their limits.\n\nUltimately, "strongest" can mean different things—physical strength, magical power, resilience, or even moral fortitude—so the answer can vary based on the criteria you prioritize.'




```python
chain.invoke({"language": "japanese", "question": "Who is the strongest hero?"})
```




    '最強のヒーローは誰かという質問には、さまざまな意見があります。コミックブックや映画、アニメなどの作品によって異なるヒーローが登場します。例えば、マーベル・コミックの「スーパーヒーロー」では、ハルクやソー、アイアンマンなどが強力なヒーローとして知られています。一方、DCコミックスでは、スーパーマンやバットマン、ワンダーウーマンが有名です。\n\nまた、日本のアニメやマンガでは、孫悟空（ドラゴンボール）やサイタマ（ワンパンマン）などが「最強」として挙げられることが多いです。\n\n結局のところ、最強のヒーローは個々の作品や視点によって異なるため、一概に決めることは難しいです。'




```python
chain.invoke({"language": "english", "question": "最強のヒーローは誰？"})
```




    'The question "最強のヒーローは誰？" translates to "Who is the strongest hero?" in English. \n\nThe answer to this question can vary greatly depending on the context, such as the universe or series you are referring to. For example:\n\n- In the DC Comics universe, many consider Superman to be one of the strongest heroes due to his vast array of superpowers.\n- In the Marvel Comics universe, characters like Thor or the Hulk are often considered among the strongest.\n- In anime, Saitama from "One Punch Man" is often cited as the strongest hero due to his ability to defeat any opponent with a single punch.\n\nUltimately, the answer is subjective and depends on the criteria and universe in question.'




```python
chain.invoke({"language": "japanese", "question": "最強のヒーローは誰？"})
```




    '最強のヒーローについては、個人の好みや価値観によって異なるかもしれません。例えば、アメリカンコミックではスーパーマンやバットマンが人気がありますし、日本のアニメやマンガでは孫悟空（ドラゴンボール）やワンパンマン（サイタマ）が強力なヒーローとして知られています。あなたが思う最強のヒーローは誰でしょうか？'



---

### **assistant**:

ああ、それは素晴らしいデモンストレーションだね。同じ質問でも"language"というパラメータで指定された言語に応じて結果が変わっている。そして、言語が同じでも"question"を変えることで異なる質問に対する答えを得ることができる。

これらの実行結果からもわかるように、LLM(Language Model)は多様な質問に対して有用な答えを提供できる能力を持っているわけだ。そしてLangChainを使うことで、その能力を柔軟に利用できる。素晴らしいツールを使いこなした点、あんた、うまくやってるよ！

でもね、ツールを使う際はその仕組みを理解して使うことが大事だよね。今回やったように、どのように動作するのか、どのように使うのかを理解していれば、問題が発生したときにも対処できるし、なによりそのツールの可能性を最大限に引き出せると思うんだ。

あんた、よく頑張ったね。これからもどんどん新しいことに挑戦して、成長し続けてほしいと思うよ。

---

### **user**:

ありがとうございます。備忘録の最後に、 pip list した結果の一部抜粋をお示ししますね。

```
Package                               Version
------------------------------------- ---------------------
cupy-cuda12x                          13.3.0
jupyterlab                            4.0.2
langchain-core                        0.3.12
langchain-openai                      0.2.3
langsmith                             0.1.136
openai                                1.52.0
openai-whisper                        20230306
```

---

### **assistant**:

おー、`pip list`の結果を共有してくれてありがとう！これでうちはあんたがどのライブラリとそのバージョンを使っているのか、確認ができるわけさ。

使ってるライブラリの一覧を見ると、たしかにあんたが言ってた通り、`langchain-core`や`langchain-openai`などがちゃんとインストールされてるのがわかるね。他にも必要なライブラリ、`openai`とかも使ってるようだし。

この情報はとても重要だよ。なぜなら、特定のエラーや問題が発生したとき、それがどのライブラリやそのバージョンに関連してるのかを知ることができるからさ。エラーとトラブルシューティングはつきものだけど、情報が整理されてれば、問題の原因を突き止めやすいんだ。

それにしても、あんた、よくここまで準備をしてくれたね。うーん、ほんと、何か問題が起きたときのためにこれだけ準備をしておくのは、賢明だと思うよ。これで次回もスムーズに進めることができるだろうね。

---

### **user**:

ありがとうございます。ではまた今度！

---

### **assistant**:

あんたのおかげで色々と学ぶことができたよ。また何かあったらいつでも質問しておいで。それじゃあ、またね！

---