LoginSignup
6
5

LangChain Expression Language (LCEL)

LangChainのチェーン記法がリニューアルされていたので試してみた。

これまではLLMChainを作成してプロンプト、モデルを渡す書き方だったが、

from langchain import LLMChain
llm_chain = LLMChain( prompt=prompt, llm=model)
llm_chain("ice cream")

LCELでは ”|” で連結してChainを実装できる。(直感的にわかりやすくなっている)
またoutput_parserを繋げてレスポンスの後処理もできる。

chain = prompt | model | output_parser
chain.invoke({"topic": "ice cream"})

JSON Mode

ChatGPTからの応答がJSONで返ってくるのを保証するモード。2023/11/6に本家でリリース、11/17にAzure OpenAIでリリースされた模様。
LLM応答でJSON”だけ”返して欲しいのに、余計な文言がついてしまうようなケースを回避できるらしい。

LCELコード例

まず通常の利用。こちらはこれまでのgpt-35-turbo, gpt-4 (0613)、APIバージョン2023-07-01-previewで動く。

from langchain.chat_models import AzureChatOpenAI
from langchain.prompts import PromptTemplate


prompt = PromptTemplate.from_template("""ショートジョークを言ってください。 お題: {topic}""")

model = AzureChatOpenAI(
    openai_api_base=BASE_URL,
    openai_api_version="2023-07-01-preview",
    deployment_name=DEPLOYMENT_NAME,
    openai_api_key=API_KEY,
    openai_api_type="azure",
    temperature=0)

LCELでのチェーン定義部とチェーンの実行。

chain = prompt | model

result = chain.invoke({"topic": "カレー"})

print(result.content)

実行結果 (面白いかは別。。)

なぜカレーがパーティーに行きたがらなかったの?

だって、いつもスパイスが多すぎて汗ばんでしまうからさ!

output_parser

次にoutput parserを使ってみる。こちらはJSON Modeを使う必要がある。
JSON Modeを使用するにはgpt-35-turbo-1106とgpt-4-1106-previewのデプロイが必要で、2023/12/1時点では、オーストラリア東部、インド南部、アメリカ東部のリージョンに限定されるので注意。

output parserで扱うオブジェクトをBaseModelを継承して作成する。出力項目(例の場合は材料と手順)をフィールド定義する。

from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field

class Recipe(BaseModel):
    ingredients: list[str] = Field(description="ingredients of the dish")
    steps: list[str] = Field(description="steps to make the dish")

output_parser = PydanticOutputParser(pydantic_object=Recipe)

テンプレート設定。(ここらは参考サイトのコードを拝借させていただいた)
AOAIモデルはJSON Modeを利用するため、上記のリージョン作成のgpt-35-turbo、バージョン1106を使用。APIバージョンは2023-10-01-preview。
.bindとしてresponse_formatを指定してJSON Modeを有効化する。

prompt = PromptTemplate.from_template(
    """料理のレシピを考えてください。

{format_instructions}

料理名: {dish}""",
    partial_variables={"format_instructions": output_parser.get_format_instructions()},
)

model = AzureChatOpenAI(
    openai_api_base=BASE_URL,
    openai_api_version="2023-10-01-preview",
    deployment_name=DEPLOYMENT_NAME,
    openai_api_key=API_KEY,
    openai_api_type="azure",
    temperature=0).bind(
        response_format={"type": "json_object"}
    )

チェーンの作成と実行。output parserをパイプする。

chain = prompt | model | output_parser

result = chain.invoke({"dish": "肉じゃが"})
print(type(result))
print(result)

実行結果。Recipeクラスで定義した、ingredients, stepsのリストとして応答を取得することができる。応答のJSONをパースしているのがわかる。

<class '__main__.Recipe'>
ingredients=['牛肉', 'じゃがいも', 'にんじん', '玉ねぎ', 'しょうが', 'にんにく', '醤油', 'みりん', '砂糖', '水'] steps=['1. 牛肉を食べやすい大きさに切る。', '2. じゃがいも、にんじん、玉ねぎを食べやすい大きさに切る。', '3. 鍋に油を熱し、しょうがとにんにくを炒める。', '4. 牛肉を加えて炒める。', '5. じゃがいも、にんじん、玉ねぎを加えて炒める。', '6. 醤油、みりん、砂糖、水を加えて煮る。', '7. 全体に味がなじんだら完成。']

参考

6
5
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
6
5