🗂
LangChain のプログラムを Azure OpenAI で動くように書き換える
LangChain を Python で使う | Hakky Handbook を見ながら LangChain を勉強し始めました。
が、OpenAI前提で書かれていて、企業内でよく利用検討される Azure OpenAI で動かすとしたらどうするんだ?というところで試行錯誤していました。
エージェントをチャットモデルと組合わせて使用する のサンプルプログラムを使って Azure OpenAI 上で動作させるにはどうすれば?を OpenAI with Web Browsing に壁打ちしてもらいながらやってみました。
書き換え前の Python スクリプト
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.chat_models import ChatOpenAI
from langchain.llms import OpenAI
# チャットモデルのラッパーを初期化
chat = ChatOpenAI(temperature=0.7)
# LLM ラッパーを初期化
llm = OpenAI(temperature=0.7)
# ツールを導入します。 `llm-math` ツールを使うのに LLM を指定する必要があることに注意してください
tools = load_tools(["serpapi", "llm-math"], llm=llm)
# エージェントを初期化します
# 初期化時には、使用するツールの一覧と、使用する LLM, エージェントの種類を指定します
# ここで指定している "zero-shot-react-description" というエージェントは、ツールの説明のみに基づいて、どのツールを使用するかを決定してくれます
agent = initialize_agent(
tools, chat, agent="chat-zero-shot-react-description", verbose=True)
# エージェントにタスクを実行してもらいます
agent.run("水卜アナウンサーの結婚相手は誰ですか?また、その人の年齢は何歳ですか?さらにその人の年齢の値を x としたとき、x ^ 0.23 は何ですか?")
問題となるのは ChatOpenAI
と OpenAI
のコンストラクターのところです。このサンプルだと暗黙的に OPENAI_API_KEY
環境変数の認証情報を使うことを前提になっています。
書き換えるポイント
- Azure の認証情報を引き渡す
- Azure OpenAI の API エンドポイントを使わせるように設定する
- Azure OpenAI のリソース上にデプロイされているモデルを明示的に指定する (企業向けだと結構カスタムな名前でデプロイしたがりますよね……)
Azure OpenAI を利用するように書き換えた後の Python スクリプト
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.chat_models import ChatOpenAI
from langchain.llms import OpenAI
import openai
openai.api_type = "azure"
openai.api_version = "2023-05-15"
# チャットモデルのラッパーを初期化
chat = ChatOpenAI(temperature=0.7, openai_api_key="xxxxxxxxxxxx",
openai_api_base="https://xxxxxxxxxxx.openai.azure.com/", model_kwargs={'deployment_id': "gpt-35-turbo"})
# LLM ラッパーを初期化
llm = OpenAI(temperature=0.7, openai_api_key="xxxxxxxxxxxx",
openai_api_base="https://xxxxxxxxxxx.openai.azure.com/", model_kwargs={'deployment_id': "gpt-35-turbo-instruct"})
# ツールを導入します。 `llm-math` ツールを使うのに LLM を指定する必要があることに注意してください
tools = load_tools(["serpapi", "llm-math"], llm=llm)
# エージェントを初期化します
# 初期化時には、使用するツールの一覧と、使用する LLM, エージェントの種類を指定します
# ここで指定している "zero-shot-react-description" というエージェントは、ツールの説明のみに基づいて、どのツールを使用するかを決定してくれます
agent = initialize_agent(
tools, chat, agent="chat-zero-shot-react-description", verbose=True)
# エージェントにタスクを実行してもらいます
agent.run("水卜アナウンサーの結婚相手は誰ですか?また、その人の年齢は何歳ですか?さらにその人の年齢の値を x としたとき、x ^ 0.23 は何ですか?")
書き換えるポイントに従って、書き換えたものが上記のプログラムです。
Azure OpenAI のエンドポイント、APIキーを渡す
単一の Azure OpenAI リソースを使う場合は、環境変数などを用いてグローバルに設定してしまうのが多いと思います。
import openai
import os
openai.api_key = os.getenv("OPENAI_API_KEY") # Or set it directly: openai.api_key = "your-api-key"
openai.api_type = os.getenv("OPENAI_API_TYPE") # Or set it directly: openai.api_type = "azure"
openai.api_version = os.getenv("OPENAI_API_VERSION") # Or set it directly: openai.api_version = "2023-05-15"
openai.api_base = os.getenv("OPENAI_API_BASE") # Or set it directly: openai.api_base = "https://your-resource-name.openai.azure.com"
ただ、この場合だと ChatOpenAI (chat) と OpenAI (Completion) で同一のリソースしか指定できないので、「"gpt-35-turbo" は Azure 東日本リージョンにあるのを使いたいんだけど、"gpt-35-turbo-instruct" は Azure 米国東海岸リージョンにしかない」みたいな時に困ります。
そのときはコンストラクターのところで個別に指定することができます。API タイプや API バージョンは Azure 全体で一緒なのでグローバルに設定してしまって、個別のものだけ分けて指定することができます。
import openai
openai.api_type = "azure"
openai.api_version = "2023-05-15"
llm = OpenAI(temperature=0.7, openai_api_key="xxxxxxxxxxxx",
openai_api_base="https://xxxxxxxxxxx.openai.azure.com/", model_kwargs={'deployment_id': "gpt-35-turbo-instruct"})
プログラムを実行してみた様子
$ python3 example8-aoai.py
> Entering new AgentExecutor chain...
Thought: I need to find information about the marriage partner of Mizutani Anna. I can start by searching for news articles or interviews that mention her marriage. Once I find the name of her spouse, I can search for their age. Finally, I can use a calculator to calculate the value of x ^ 0.23.
Action:
{
"action": "Search",
"action_input": "水卜アナウンサー 結婚相手"
}
Observation: Tomoya Nakamura
Thought:I have found the name of Mizutani Anna's spouse, Tomoya Nakamura. Now I need to find his age.
Action:
{
"action": "Search",
"action_input": "中村倫也 年齢"
}
Observation: 36 years
Thought:I have found Tomoya Nakamura's age, which is 36 years. Now I can calculate the value of x ^ 0.23 using a calculator.
Action:
{
"action": "Calculator",
"action_input": "36 ^ 0.23"
}
Observation: Answer: 2.2800773226742175
Thought:I have calculated the value of x ^ 0.23, which is 2.2800773226742175.
Final Answer:
水卜アナウンサーの結婚相手は中村倫也さんで、中村倫也さんの年齢は36歳です。また、中村倫也さんの年齢の値をxとしたとき、x ^ 0.23の値は2.2800773226742175です。
> Finished chain.
うまく動いていそうですね。
Discussion