Chainは、複数の処理をつないだ流れ

これまでに、入力を作るプロンプト、応答を生成するモデル、結果を項目に整理する構造化出力を学びました。この節では、それらを一つの処理の流れとしてつなぐ考え方へ進みます。入力と出力の種類が曖昧なら、第5節の型とスキーマが土台になります。

Chainは、ある処理の出力を次の処理の入力へ渡す、一連の流れです。たとえば、質問を受け取り、プロンプトを組み立て、モデルへ送り、応答から表示用の文章を取り出す処理が考えられます。ひとつのモデルを呼ぶだけでも、前後には入力と出力を整える段階があります。

この場合、どの順で処理するかは開発者が決めています。モデルは与えられた入力に応答しますが、プロンプト作成の前に出力整形を行う、といった順序変更を自分で決めるわけではありません。この決まった流れと、後に扱うエージェントの動的なツール選択を区別しておきます。

Runnableは、部品を共通の扱い方で実行するための仕組み

LangChainには、Runnable(ランナブル)という共通の実行インターフェースがあります。第2節で説明した、部品を使うための取り決めの一種です。モデルやプロンプトなど、Runnableの約束に対応した部品を、「入力を渡し、出力を受け取るもの」として共通の方法で扱えます。

ただし、共通なのは呼び方であり、入力や出力の種類がすべて同じになるわけではありません。プロンプトの部品は差し込む値を受け取り、モデルへ渡す入力を返します。会話モデルはメッセージを受け取り、応答のメッセージを返します。出力を整える部品は、そのメッセージから文章などを取り出します。

つなぐときには、前の部品が返すものを、次の部品が受け取れることが必要です。文章を想定する場所へ、複数の項目をまとめたデータをそのまま渡すなど、入出力がかみ合わなければ、流れは成立しません。前の節で学んだ型の違いも、つなげるかどうかに関わります。

部品受け取るもの次へ渡すもの
プロンプト質問、参考資料などの値役割付きメッセージとして組み立てた入力
会話モデル組み立てた入力AIMessageなどの応答
出力の変換モデルの応答表示に使う文字列など

この表の右側を、次の行の左側へ渡すのが基本の接続です。たとえば最後に文章を取り出した後、その文字列に対してさらに別の分類を行うなら、分類する部品がその形式を受け取れるかを確認します。

LCELは、組み合わせを表す記法

LCELはLangChain Expression Languageの略で、Runnableを組み合わせて処理の流れを表すための記法です。たとえばprompt | model | parserという形は、プロンプトを作り、モデルで生成し、その結果を整える順序を表します。縦棒は、前の出力を次へ渡す組み合わせとして読みます。

この式のpromptは入力のひな型、modelは会話モデル、parserは結果を読み取って変換する部品の名前です。parser(パーサー)は、モデルの応答から文章を取り出すなどの役割を持ちます。回答の事実確認まで自動的に済ませるものではありません。

式は部品をつなぐ順序を表します。実際に処理を動かすには、組み立てた流れへ入力を渡します。LCELは、決まった入出力の処理を組み合わせる方法です。後の第5章では、次のツールをモデルが選ぶエージェントや、処理の経路を細かく決めるLangGraphへ学習を広げます。

invoke・batch・streamは、結果の受け取り方の違い

invokeは、一つの入力について実行し、結果を受け取る基本の方法です。batchは、複数の入力をまとめて扱うための方法です。たとえば複数の問い合わせを分類するとき、それぞれに同じ処理を適用できます。batchを使うことが、外部APIの一回の課金や一回の通信を意味するわけではありません。

streamは、結果を途中から順次受け取るために使います。文章が少しずつ画面に現れるチャットの動作が一例です。最初の表示を早くできる場合がありますが、生成する情報が減るわけではなく、すべての処理時間や費用が必ず減るわけでもありません。途中の部品が結果をまとめてから返す場合は、その段階で待ち時間が生じます。

途中で受け取る情報は、まだ完成していない場合があります。文章を少しずつ画面へ出すことと、構造化した項目やツールの引数が確定したと判断することは別です。後続の処理に使う値は、必要な情報を受け取り、形や内容を確かめてから利用します。

非同期の実行にはainvokeなどがあります。これは、通信などを待つ間にほかの処理を進められるようにする仕組みです。モデルの回答能力を変える機能ではなく、アプリケーション側の実行方法を変えます。

固定の流れを理解することが、応用の土台になる

固定の流れには、どの処理が行われたかを追いやすい利点があります。入力の差し込みで失敗したのか、モデルとの通信で失敗したのか、結果の変換で失敗したのかを、部品ごとに考えられます。検索や生成を組み合わせるRAGでも、まず固定の流れを理解すると、どこで品質が変わるかを調べやすくなります。

ここまでで、入力を作り、モデルへ渡し、結果を受け取る基本がつながりました。次の章では、この一回の流れを会話の中で利用するために、過去の情報をどのように保持して渡すのかを説明します。