LoginSignup
9
7
記事投稿キャンペーン 「2024年!初アウトプットをしよう」

langchain(v0.13)でAzure OpenAIを使うまでの導入

Last updated at Posted at 2024-01-31

はじめに

langchainが安定版であるバージョン0.1Xをリリースしたようなので、以前書いたコードをリファクタしようとしました。
すると非推奨の警告メッセージがたくさん出てきたり、どのドキュメントが最新なのか非常に分かりづらかったので、備忘録として書き残します。

事前準備

ライブラリ

pip installしてください

pip install langchain, langchain-openai
requirements.txt
langchain==0.1.3
langchain-openai==0.0.3
langchain-community==0.0.15
langchain-core==0.1.15
langsmith==0.0.83

環境変数

Azure側で準備してから、以下の環境変数を入れてください。

.env
AZURE_OPENAI_API_KEY = "APIキー"
AZURE_OPENAI_ENDPOINT = "エンドポイント"

書く

インポート

AzureChatOpenAIlangchain_openaiからインポートしてください。
langchain.chat_modelsは非推奨になっています。

from langchain.schema import HumanMessage
from langchain_openai import AzureChatOpenAI

モデル用意

AzureChatOpenAIでLLMを用意します。
2024年1月現在、APIのバージョン名は2023-12-01-previewが最新みたいです。

APIのバージョン名はここに載っているようです。

model = AzureChatOpenAI(
    openai_api_version="APIのバージョン名",
    azure_deployment="デプロイ名",
)

呼び出し

invokeで呼び出します。
runは非推奨になっています。そのままinvokeに書き換えればOKです。

message = "こんにちは"

res = model.invoke(message)

print(res)

結果

ちゃんと帰ってきました。

content='こんにちは!お元気ですか?何かお手伝いできることはありますか?'

Chainを使う

langchainと言えば!の機能、Chainも使ってみます。
基本的に以前と書き方は変わりません。LCEL使ってないのは許してください…

from os.path import join, dirname
from dotenv import load_dotenv
import langchain
from langchain_openai import AzureChatOpenAI
from langchain.chains import LLMChain
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from langchain.chains import SequentialChain
from pydantic import BaseModel, Field
from typing import List

langchain.verbose = True

# フォーマット
## 食材と数
class Foods(BaseModel):
    name: str = Field(description="食材の名前")
    count: str = Field(description="")

## 買い物リスト
class BuyList(BaseModel):
    buyList: List[Foods]

# ローカル用環境変数呼び出し
dotenv_path = join(dirname(__file__), ".env")
load_dotenv(dotenv_path)

# LLM用意
model = AzureChatOpenAI(
    openai_api_version="2023-12-01-preview",
    azure_deployment="デプロイ名",
)

template1 = """
{recipe}のレシピを簡潔に教えてください。
食材とその個数は必ず教えてください。

"""

template2 = """
以下のレシピに必要な食材とその個数をまとめて教えてください。
### レシピ
{res1}

{format_instructions}
"""

# 実行関数
def generate_questions(recipe: str):
    # 命令1: 1回目
    ## プロンプト作成
    prompt1 = PromptTemplate(
        template=template1,
        input_variables=["recipe"],
    )
    ## chain作成
    chain1 = LLMChain(llm=model, prompt=prompt1, output_key="res1")

    # 命令1: 2回目
    ## Parser作成
    parser = PydanticOutputParser(pydantic_object=BuyList)
    ## プロンプト作成
    prompt2 = PromptTemplate(
        template=template2,
        input_variables=["res1"],
        partial_variables={"format_instructions": parser.get_format_instructions()},
    )
    ## chain作成
    chain2 = LLMChain(llm=model, prompt=prompt2)

    # chains作成
    chains = SequentialChain(
        chains=[chain1, chain2],
        input_variables=["recipe"],
    )

    # chains実行
    answer = chains.invoke({"recipe":recipe})
    
    # JSON整形
    s = "```json\n"
    answer = answer['text'].strip(s)

    # 表示
    print(answer)
    print(type(answer))

    return answer

if __name__ == "__main__": 
    recipe = "カレー"
    output = generate_questions(recipe)

結果

> Entering new SequentialChain chain...

> Entering new LLMChain chain...
Prompt after formatting:

カレーのレシピを簡潔に教えてください。
食材とその個数は必ず教えてください。

> Finished chain.

> Entering new LLMChain chain...
Prompt after formatting:

以下のレシピに必要な食材とその個数をまとめて教えてください。
### レシピ
材料:
- 玉ねぎ: 1個
- にんじん: 1本
- じゃがいも: 2個
- 鶏肉or牛肉: 300g
- カレールー: 1箱
- 水: 500ml
- サラダ油: 大さじ1
- 塩: 小さじ1/2

作り方:
1. 食材を準備する。玉ねぎ、にんじん、じゃがいもをそれぞれみじん切りにする。肉は食べやすい大き
さに切る。
2. 鍋にサラダ油を熱し、玉ねぎを炒める。
3. 玉ねぎが透明になったら肉を加えて炒める。
4. にんじん、じゃがいもを加えて炒め、水を加えて煮る。
5. カレールーを加え、溶かしてから塩で味を調える。
6. 全体が煮えたら完成です。ご飯と一緒にお召し上がりください。

# Parser用プロンプトのため割愛
The output should be formatted as a JSON instance that conforms to the JSON schema below.     

> Finished chain.

> Finished chain.
{
  "buyList": [
    {"name": "玉ねぎ", "count": "1個"},
    {"name": "にんじん", "count": "1本"},
    {"name": "じゃがいも", "count": "2個"},
    {"name": "鶏肉or牛肉", "count": "300g"},
    {"name": "カレールー", "count": "1箱"},
    {"name": "水", "count": "500ml"},
    {"name": "サラダ油", "count": "大さじ1"},
    {"name": "塩", "count": "小さじ1/2"}
  ]
}
<class 'str'>

しっかりChain出来ていることが確認できます。
Parserも効いており、指定したJSON形式に変換されています。

おわりに

langchainは便利ですが、更新が非常に速いので追いつくのが大変でした。
公式ドキュメントすら最新化が追い付いてないので、恐ろしいですね…

また、AzureChatOpenAIのパラメータであるopenai_api_versionの参照先が本当に分からなくて調べるのに時間がかかりました。
Azureの画面上か、モデル詳細に記載しておいてほしいです、切実に

参照ドキュメント

langchain 0.13
AzureChatOpenAI
langcahin_openai

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7