Closed4
LCEL(Langchain Expression Language)でChatGPTに創作料理を提案させてみる
環境
langchain==0.0.310
プログラム
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from dotenv import load_dotenv
from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser
load_dotenv()
model = ChatOpenAI(temperature=1.0, model="gpt-4")
# 創作料理の食材の提案チェーン
suggest_ingredients_prompt = ChatPromptTemplate.from_template(
"創作料理の食材を{num_ingredients}個提案してください"
)
suggest_ingredients_function = {
"name": "set_ingredients",
"description": "set ingredients list",
"parameters": {
"type": "object",
"properties": {"ingredients": {"type": "array", "items": {"type": "string"}}},
"required": ["ingredients"],
},
}
suggest_ingredients_chain = (
suggest_ingredients_prompt
| model.bind(
function_call={"name": suggest_ingredients_function["name"]},
functions=[suggest_ingredients_function],
)
| JsonOutputFunctionsParser()
)
# 創作料理の提案チェーン
suggest_dish_prompt = ChatPromptTemplate.from_template(
"以下を食材として利用した創作料理を提案してください: {ingredients}"
)
suggest_dish_function = {
"name": "set_dish",
"description": "set dish",
"parameters": {
"type": "object",
"properties": {
"dish_name": {"type": "string"},
"dish_description": {"type": "string"},
},
"required": ["name", "description"],
},
}
suggest_dish_chain = (
suggest_dish_prompt
| model.bind(
function_call={"name": suggest_dish_function["name"]},
functions=[suggest_dish_function],
)
| JsonOutputFunctionsParser()
)
# 食材の提案チェーンと創作料理の提案チェーンを合成
total_chain = suggest_ingredients_chain | suggest_dish_chain
# チェーンを実行
result = total_chain.invoke({"num_ingredients": "5"})
print(result)
実行結果
{'dish_name': 'エビとブロッコリーのチーズ焼き', 'dish_description': '新鮮なエビと栄養満点のブロッコリーをフレッシュトマトと一緒にオーブンで焼き上げます。アクセントにニンニクを加え、チーズの風味と絶妙に結びついた一 品です。エビのプリプリとした食感とブロッコリーのシャキシャキ感が楽しい、ヘルシーなグラタン風料理です。'}
残課題
- function定義部をpydantic利用などで簡略化できないか
- 途中経過をstreamで標準出力に流したい
Langsmithでトレース取れるのはとても良い
パラ実行も簡単
食材提案 → (食材で料理提案×3)
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI
from dotenv import load_dotenv
from langchain.output_parsers.openai_functions import JsonOutputFunctionsParser
import random
from operator import itemgetter
from langchain.schema.runnable import RunnableLambda
load_dotenv()
model = ChatOpenAI(temperature=1.0, model="gpt-4")
# 創作料理の食材の提案チェーン
suggest_ingredients_prompt = ChatPromptTemplate.from_template(
"創作料理の食材を{num_ingredients}個提案してください"
)
suggest_ingredients_function = {
"name": "set_ingredients",
"description": "set ingredients list",
"parameters": {
"type": "object",
"properties": {"ingredients": {"type": "array", "items": {"type": "string"}}},
"required": ["ingredients"],
},
}
suggest_ingredients_chain = (
suggest_ingredients_prompt
| model.bind(
function_call={"name": suggest_ingredients_function["name"]},
functions=[suggest_ingredients_function],
)
| JsonOutputFunctionsParser()
)
# 創作料理の提案チェーン
suggest_dish_prompt = ChatPromptTemplate.from_template(
"以下を食材として利用した創作料理を提案してください: {ingredients}"
)
suggest_dish_function = {
"name": "set_dish",
"description": "set dish",
"parameters": {
"type": "object",
"properties": {
"dish_name": {"type": "string"},
"dish_description": {"type": "string"},
},
"required": ["name", "description"],
},
}
suggest_dish_chain = (
suggest_dish_prompt
| model.bind(
function_call={"name": suggest_dish_function["name"]},
functions=[suggest_dish_function],
)
| JsonOutputFunctionsParser()
)
# listのなかからランダムに指定個数の要素を取り出し新しいlistを作成する関数
def random_choice_list(lst, num):
return random.sample(lst, num)
random_choise_chain = {
"ingredients": itemgetter("ingredients")
| RunnableLambda(lambda x: random_choice_list(x, 3))
}
chef_chain = random_choise_chain | suggest_dish_chain
# 食材の提案チェーンと創作料理の提案チェーンを合成
total_chain = suggest_ingredients_chain | {
"chef1": chef_chain,
"chef2": chef_chain,
"chef3": chef_chain,
}
# チェーンを実行
result = total_chain.invoke({"num_ingredients": "5"})
print(result)
Langsmithでのトレースも複雑になってきた
このスクラップは2023/10/10にクローズされました