LangChainでJSON配列を出力
作るもの
こんな感じに構造的な出力を得られるコードを作ります
% python character.py 鬼滅の刃の登場人物は? | tr "'" '"' | jq -r ".characters[]|[.name, .sex, .age, .personality]|@csv" | xsv table
竈門炭治郎 男 15 優しい、責任感が強い
禰豆子 女 14 おとなしい、強い意志を持つ
我妻善逸 男 16 臆病、しかし勇敢な一面も
嘴平伊之助 男 15 野生的、好戦的
煉獄杏寿郎 男 20 情熱的、正義感が強い
富岡義勇 男 23 冷静、責任感が強い
胡蝶しのぶ 女 18 知的、優雅
無惨 男 1000 冷酷、狡猾
事前準備
今回は安いのでOpenAIのGPT-4o-miniを使います
環境変数にOPENAI_API_KEYを設定しておいてください
とても参考になる記事はこちら
python環境の設定は済ませておいてください
langchainのインストールは済ませておいてください
構造化したデータを出力する流れ
LangChainでアウトプットパーサーを使うと構造化した出力を得られます。(JSON、XML、Pydanticなど)
さっそく以下の順番で作っていきましょう
構造体を定義する
パーサーを設定する
プロンプトを設定する
LLMを設定する
Chainを実行する
結果を出力する
結果を確認する
1. 構造体(配列)を定義する
langchain.output_parsers から ResponseSchemaを使います
from langchain.output_parsers import ResponseSchema
構造体の定義
映像作品の登場人物について以下を取得してみます
名前 → name(string型)
性別 → sex(string型)
年齢 → age(int型)
性格 → personality(string型)
# 構造体の設定
response_schemas = [
ResponseSchema(
name="characters",
description="配列形式の項目リスト。例: [{name: string,sex: string,age: int,personality: string}]",
type="array(objects)"
)
]
charactersは配列として複数人返ってくることを想定して、「名前」「性別」「年齢」「性格」は大括弧で括ります。
2. パーサーを設定する
langchain.output_parsers から StructuredOutputParser を使います
from langchain.output_parsers import ResponseSchema, StructuredOutputParser
パーサーの設定
先ほど設定した response_schemas を出力する構造体(from_response_schemas)に指定します。
# パーサーの設定
parser = StructuredOutputParser.from_response_schemas(response_schemas)
3. プロンプトを設定する
langchain.prompts から ChatPromptTemplate を使います
from langchain.prompts import ChatPromptTemplate
プロンプトの設定
format_instructions には、先ほど設定した parser のget_format_instructions() から取り出した内容を指定し、テンプレートに埋め込みます。
テンプレートの中の {question} は、chain の実行時に内容を指定するための変数です。
# プロンプトの設定
prompt_template=ChatPromptTemplate.from_template(
template="次の質問に回答してください\n{format_instructions}\n{question}",
partial_variables={"format_instructions": parser.get_format_instructions()}
)
4. LLMを設定する
langchain_openai から ChatOpenAI を使います
from langchain_openai import ChatOpenAI
LLMの設定
ここでは temperature と model を指定しています
お好みに合わせて設定してください
# LLMの設定
llm = ChatOpenAI(
temperature=0.7,
model="gpt-4o-mini"
)
5. Chainを実行する
chain の実行
先ほど用意した以下をパイプで繋げます
prompt_template
llm
parser
# Chainの実行
chain = prompt_template | llm | parser
6. 結果を出力する
コード実行時に引数で質問を書けるようにします
sys を使います
import sys
結果の出力
引数を question に指定して実行します
引数がない場合はドラえもんについて質問します
# 結果の出力
question = sys.argv[1] if len(sys.argv) > 1 else "ドラえもんの登場人物は?"
result = chain.invoke({"question": question})
print(result)
7. 結果を確認する
結果の確認
文字列がシングルクォートなので tr でダブルクォートに置換しています
出力結果を jq で整形しています
% python character.py 美女と野獣の登場人物は? | tr "'" '"' | jq .
{
"characters": [
{
"name": "ベル",
"sex": "女性",
"age": 17,
"personality": "知的で勇敢"
},
{
"name": "野獣",
"sex": "男性",
"age": 21,
"personality": "孤独で優しい"
},
{
"name": "ガストン",
"sex": "男性",
"age": 25,
"personality": "自信過剰で傲慢"
},
{
"name": "ルミエール",
"sex": "男性",
"age": 50,
"personality": "陽気でおしゃべり"
},
{
"name": "コグスワース",
"sex": "男性",
"age": 60,
"personality": "几帳面で真面目"
},
{
"name": "ポット夫人",
"sex": "女性",
"age": 55,
"personality": "優しくて母性的"
},
{
"name": "チップ",
"sex": "男性",
"age": 5,
"personality": "無邪気で好奇心旺盛"
}
]
}
コード全文
from langchain.output_parsers import ResponseSchema, StructuredOutputParser
from langchain.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
import sys
# 構造体の定義
response_schemas = [
ResponseSchema(
name="characters",
description="配列形式の項目リスト。例: [{name: string,sex: string,age: int,personality: string}]",
type="array(objects)"
)
]
# パーサーの設定
parser = StructuredOutputParser.from_response_schemas(response_schemas)
# プロンプトの設定
prompt_template=ChatPromptTemplate.from_template(
template="次の質問に回答してください\n{format_instructions}\n{question}",
partial_variables={"format_instructions": parser.get_format_instructions()}
)
# LLMの設定
llm = ChatOpenAI(
temperature=0,
model="gpt-4o-mini"
)
# Chainの実行
chain = prompt_template | llm | parser
# 結果の出力
question = sys.argv[1] if len(sys.argv) > 1 else "ドラえもんの登場人物は?"
result = chain.invoke({"question": question})
print(result)
この記事が気に入ったらサポートをしてみませんか?