🗂

LangChain のプログラムを Azure OpenAI で動くように書き換える

2023/10/31に公開

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 は何ですか?")

問題となるのは ChatOpenAIOpenAI のコンストラクターのところです。このサンプルだと暗黙的に 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