本記事ではGoogle Colaboratory上でLangChainのSimpleSequentialChain使って、複数のChainをつないでLLMで簡単な会話をしていきます。
Google Colaboratoryの使い方がわからない方は、まずこちらの記事をご覧ください。
複数のChainを繋ぐスクリプト
複数のChainを繋ぐとは、1つ目の会話の返答を2つ目の会話のインプットとして使う、というものです。もちろん、2つだけでなく3つ4つと繋げていくことができます。
どんな時に使うのか
例えば、1つ目の返答が長くて読みにくく、要約して欲しい時などにこれを使います。
スクリプトを書く
今回は1つ目のChainで質問を投げかけて返答をもらうという会話をします。2つ目のChainでその返答を要約してもらう、ということをやっていきます。LLMChainで作ったChainをSimpleSequentialChainで繋いでいきます。
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain import LLMChain
from langchain.chains import SimpleSequentialChain
chat = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0, api_key="ここにAPI Keyを貼る")
# 質問に答えるChainを作成する
cot_template = """以下の質問に回答してください
質問: {question}
ステップバイステップで考えましょう
"""
cot_prompt = PromptTemplate(
input_variables=["question"],
template=cot_template
)
cot_chain = LLMChain(llm=chat, prompt=cot_prompt)
# 質問への回答を要約するChainを作成する
summarize_template = """以下の文章を結論だけ一言で要約してください
{input}
"""
summarize_prompt = PromptTemplate(
input_variables=["input"],
template=summarize_template
)
summarize_chain = LLMChain(llm=chat, prompt=summarize_prompt)
# 2つのChainを繋げる
cot_summarize_chain = SimpleSequentialChain(
chains=[cot_chain, summarize_chain]
)
result = cot_summarize_chain("私は市場に行って卵を50個買いました。20個を料理に使って、10個は隣のレストランのシェフに渡しました。それから卵を15個買いました。残りの卵は何個ですか?")
print(result["output"])
これでスクリプトが完成です。
出力はこんな感じになりました。文章問題がちゃんと計算できています✨
残りの卵の数は35個。
結果としては正しいのですが、中でどんなふうに動いているのか見てみたいと思います。
どうすれば動きが見えるか、というと以下のようにします。
import langchain
langchain.verbose = True
langchain.debug = True
これで先ほどのスクリプトを実行するとこんなふうに出力されます。
[chain/start] [1:chain:SimpleSequentialChain] Entering Chain run with input:
{
"input": "私は市場に行って卵を50個買いました。20個を料理に使って、10個は隣のレストランのシェフに渡しました。それから卵を15個買いました。残りの卵は何個ですか?"
}
[chain/start] [1:chain:SimpleSequentialChain > 2:chain:LLMChain] Entering Chain run with input:
{
"question": "私は市場に行って卵を50個買いました。20個を料理に使って、10個は隣のレストランのシェフに渡しました。それから卵を15個買いました。残りの卵は何個ですか?"
}
[llm/start] [1:chain:SimpleSequentialChain > 2:chain:LLMChain > 3:llm:ChatOpenAI] Entering LLM run with input:
{
"prompts": [
"Human: 以下の質問に回答してください\n\n質問: 私は市場に行って卵を50個買いました。20個を料理に使って、10個は隣のレストランのシェフに渡しました。それから卵を15個買いました。残りの卵は何個ですか?\n\nステップバイステップで考えましょう"
]
}
[llm/end] [1:chain:SimpleSequentialChain > 2:chain:LLMChain > 3:llm:ChatOpenAI] [76.52s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "1. 最初に市場で卵を50個買いました。\n2. そのうち20個を料理に使いました。\n3. 残りの卵の数は50 - 20 = 30個です。\n4. さらに10個の卵を隣のレストランのシェフに渡しました。\n5. 残りの卵の数は30 - 10 = 20個です。\n6. その後、さらに15個の卵を買いました。\n7. 最終的な残りの卵の数は20 + 15 = 35個です。\n\nしたがって、残りの卵の数は35個です。",
"generation_info": {
"finish_reason": "stop"
},
"type": "ChatGeneration",
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "1. 最初に市場で卵を50個買いました。\n2. そのうち20個を料理に使いました。\n3. 残りの卵の数は50 - 20 = 30個です。\n4. さらに10個の卵を隣のレストランのシェフに渡しました。\n5. 残りの卵の数は30 - 10 = 20個です。\n6. その後、さらに15個の卵を買いました。\n7. 最終的な残りの卵の数は20 + 15 = 35個です。\n\nしたがって、残りの卵の数は35個です。",
"additional_kwargs": {}
}
}
}
]
],
"llm_output": {
"token_usage": {
"completion_tokens": 177,
"prompt_tokens": 117,
"total_tokens": 294
},
"model_name": "gpt-3.5-turbo",
"system_fingerprint": null
},
"run": null
}
[chain/end] [1:chain:SimpleSequentialChain > 2:chain:LLMChain] [76.52s] Exiting Chain run with output:
{
"text": "1. 最初に市場で卵を50個買いました。\n2. そのうち20個を料理に使いました。\n3. 残りの卵の数は50 - 20 = 30個です。\n4. さらに10個の卵を隣のレストランのシェフに渡しました。\n5. 残りの卵の数は30 - 10 = 20個です。\n6. その後、さらに15個の卵を買いました。\n7. 最終的な残りの卵の数は20 + 15 = 35個です。\n\nしたがって、残りの卵の数は35個です。"
}
[chain/start] [1:chain:SimpleSequentialChain > 4:chain:LLMChain] Entering Chain run with input:
{
"input": "1. 最初に市場で卵を50個買いました。\n2. そのうち20個を料理に使いました。\n3. 残りの卵の数は50 - 20 = 30個です。\n4. さらに10個の卵を隣のレストランのシェフに渡しました。\n5. 残りの卵の数は30 - 10 = 20個です。\n6. その後、さらに15個の卵を買いました。\n7. 最終的な残りの卵の数は20 + 15 = 35個です。\n\nしたがって、残りの卵の数は35個です。"
}
[llm/start] [1:chain:SimpleSequentialChain > 4:chain:LLMChain > 5:llm:ChatOpenAI] Entering LLM run with input:
{
"prompts": [
"Human: 以下の文章を結論だけ一言で要約してください\n\n1. 最初に市場で卵を50個買いました。\n2. そのうち20個を料理に使いました。\n3. 残りの卵の数は50 - 20 = 30個です。\n4. さらに10個の卵を隣のレストランのシェフに渡しました。\n5. 残りの卵の数は30 - 10 = 20個です。\n6. その後、さらに15個の卵を買いました。\n7. 最終的な残りの卵の数は20 + 15 = 35個です。\n\nしたがって、残りの卵の数は35個です。"
]
}
[llm/end] [1:chain:SimpleSequentialChain > 4:chain:LLMChain > 5:llm:ChatOpenAI] [4.05s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "残りの卵の数は35個。",
"generation_info": {
"finish_reason": "stop"
},
"type": "ChatGeneration",
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "残りの卵の数は35個。",
"additional_kwargs": {}
}
}
}
]
],
"llm_output": {
"token_usage": {
"completion_tokens": 13,
"prompt_tokens": 204,
"total_tokens": 217
},
"model_name": "gpt-3.5-turbo",
"system_fingerprint": null
},
"run": null
}
[chain/end] [1:chain:SimpleSequentialChain > 4:chain:LLMChain] [4.05s] Exiting Chain run with output:
{
"text": "残りの卵の数は35個。"
}
[chain/end] [1:chain:SimpleSequentialChain] [80.57s] Exiting Chain run with output:
{
"output": "残りの卵の数は35個。"
}
残りの卵の数は35個。
中でしっかり1つ1つ計算が行われていることがわかります。
以上、簡単ですがSimpleSequentialChainを使って複数のChainを繋く方法のまとめでした。