Skip to content

第2章 LangChainの基本概念と使い方

2.1 LangChainとは何か

LangChainは、LLM(大規模言語モデル)のパワーを最大限に引き出し、実用的なアプリケーションを効率的に開発するためのオープンソースのフレームワークです。LLMとシステムを接続するための様々なツールや共通のルールを提供しており、PythonやTypeScriptなどの言語で利用することができます。これを使うことで、開発者は低レベルなAPI呼び出しの手間を減らし、アプリケーションのロジック構築に集中できます。

通常、LLMを用いたシステムを構築する場合、APIキーの管理、プロンプトの送受信、応答の解析など、多くの定型的な処理を書く必要があります。LangChainはこれらの基本的な処理をカプセル化(まとめること)し、統一された方法で扱えるようにします。さらに、様々なAIベンダー(OpenAI、Anthropic、Googleなど)の異なるモデルを、コードを大きく変えることなく切り替えて使えるように抽象化する役割も持っています。

また、外部のドキュメント検索システムや電卓などの各種ツールとLLMを結びつけるためのコネクターとしての役割も担っています。これにより、単に言葉を返すだけのチャットボットから、外部データを参照して業務をこなす高度なシステムまで、一貫したアプローチで開発を進めることが可能になります。LangChainは、変化の激しいAI開発において、土台となる強力なフレームワークとして位置づけられています。

2.2 LLMとChatModelsの基本的な扱い方

LangChainでは、LLMを操作するためのインターフェースとして、大きく分けて「LLMs」と「ChatModels」の2つの仕組みを提供しています。「LLMs」は、純粋なテキストを入力として受け取り、その後に続くテキストを予測して出力する古いタイプのインターフェースです。一方、「ChatModels」は、チャットのようなメッセージのやり取り(会話履歴)を入力として受け取り、AIの返答メッセージを出力する現代的なインターフェースです。

現在、多くの主要なAIモデルは会話形式のデータで追加学習されているため、LangChainでもChatModelsの利用が強く推奨されています。ChatModelsでは、発言者を区別するためにいくつかのメッセージタイプを使い分けます。ユーザーからの入力を表す「HumanMessage」、AIからの返答を表す「AIMessage」、そしてAIの振る舞いを指定する前提ルールを設定する「SystemMessage」などがあります。

これらをリスト形式でモデルに渡すことで、AIはこれまでの文脈を正しく理解し、指定された役割に沿った適切な回答を返すことができるようになります。プログラムからこれらのメッセージを生成・送受信する記述方法は統一されているため、裏側で動作するAIモデルをGPT-4からClaude 3などに切り替える際も、メッセージの扱い方を変える必要がありません。この高い柔軟性が、LangChainが提供するインターフェースの大きな強みです。

2.3 プロンプトテンプレートの定義と設計

LLMから期待する回答を得るためには、AIに対する命令文である「プロンプト」を工夫する必要があります。しかし、ユーザーの入力内容ごとにプロンプトを最初から手作業で組み立てるのは非効率的です。そこでLangChainは、プロンプトの一部を変数として定義し、実行時に動的に値を差し込める「プロンプトテンプレート」という機能を提供しています。

プロンプトテンプレートを使用すると、例えば「以下の文章を{target_language}に翻訳してください:{text}」といった雛形を作ることができます。プログラムの実行時に、target_languageに「日本語」、textに翻訳したい英文を代入することで、完成したプロンプトが自動生成されてLLMに送られます。これにより、プロンプトの再利用性が高まり、コードと命令文の管理が非常に容易になります。また、システムとしての指示(SystemMessage)と、ユーザーの個別入力(HumanMessage)を分離して綺麗にテンプレート化することも容易です。

プロンプトテンプレートは、単なる文字列の組み立てにとどまらず、少数の回答例をプロンプト内に含める「フューショット・プロンプティング」のテンプレート化など、高度なプロンプト設計の手法もサポートしています。これにより、LLMの回答精度を向上させるためのプロンプト調整が簡単に行えるようになります。

2.4 出力パーサーによる構造化データの抽出

LLMは通常、自然言語(話し言葉)で回答を返します。しかし、システム開発においては、AIの回答をそのまま画面に表示するだけでなく、回答の中から「日付」や「金額」などの特定のデータを取り出してデータベースに保存したり、次のプログラムの処理に回したりしたい場合が多々あります。LLMの応答テキストから必要な情報を取り出して、プログラムで扱いやすい形式(JSONやオブジェクトなど)に変換する役割を持つのが「出力パーサー(Output Parser)」です。

出力パーサーを使用すると、まずLLMに対して「回答は以下のJSON形式で出力してください」という指示(スキーマ情報)をプロンプトに自動的に付与します。そして、LLMから返ってきたテキストを自動で解析し、Pythonの辞書型(dict)やPydanticのモデルクラスに変換します。もしLLMが指定された形式を崩して出力してしまった場合には、自動的に「形式が違います。修正して出力してください」とLLMに再送して修正を促すパーサー(RetryParser)なども用意されています。

出力パーサーを組み込むことで、不確実性の高いAIの出力を、信頼性の高い構造化データとしてシステムに組み込むことができるようになります。これは、AIをWebサービスのAPIサーバーやバックエンド処理と連携させる上で欠かせない重要なステップです。

2.5 LCEL(LangChain Expression Language)による処理の連結

LangChainで最も特徴的な機能の一つが、LCEL(LangChain Expression Language)と呼ばれる独自の記述ルールです。これは、プロンプトテンプレート、ChatModel、出力パーサーなど、これまで紹介したさまざまなコンポーネントを一本の処理の鎖(チェーン)として繋ぎ合わせるための書き方です。Unixコマンドのように |(パイプ)記号を使って記述します。

例えば、chain = prompt | model | parser のように書くことで、プロンプトに値を入力し、それをモデルに渡し、返ってきたテキストをパーサーで解析する、という一連の流れを一行で表現できます。LCELで書かれたチェーンは、自動的にストリーミング出力(文字を少しずつ表示する処理)や、非同期処理(他の処理を止めずに実行する処理)、並列処理に対応するという特徴を持っています。

さらに、エラーが起きた際のリトライ処理や、特定のモデルが使えない場合のバックアップモデルへの切り替えといった複雑なロジックも、パイプラインの一部として簡潔に書き加えることができます。このように、複雑になりがちなAIアプリケーションのコードを、誰が見ても分かりやすく、かつ高機能に保つことができるのがLCELのメリットです。

2.6 メモリ(会話履歴の保持)の仕組み

LLMとのやり取りは、基本的には「一問一答」の形式であり、前後の関係を保持していません。しかし、一般的なチャットアプリのように「さっき言ったことを踏まえて回答してほしい」という場合には、過去の会話履歴をモデルに渡し続ける必要があります。この会話履歴の記憶と管理を自動で行うのが「メモリ(Memory)」の仕組みです。

LangChainでは、会話履歴を一時的に保持する単純なメモリから、データベースに永続化(保存)するメモリまで、用途に合わせたさまざまなメモリコンポーネントが用意されています。最も基本的なメモリは、これまでのメッセージ履歴をすべて単純に蓄積し、次のリクエストの際にプロンプトに含める方式です。しかし、会話が長くなるとメッセージ全体の量が膨大になり、APIの利用料金が高くなったり、LLMが処理できる文字数の限界を超えてしまったりします。

そこで、古い会話を自動で要約してコンパクトにするメモリや、最新の数往復分だけを保持するメモリなどの高度な管理手法も提供されています。メモリを適切に設計することで、ユーザーにとってストレスのない、文脈を捉えた自然な対話システムを作ることができます。これはチャットボットだけでなく、長期にわたるタスクを実行するAIエージェントの構築においても極めて重要です。

2.7 RAG(検索拡張生成)の基礎

LLMは学習した時点の古い情報しか持っておらず、公開されていない社内の機密データなどを知ることはできません。この問題を解決するために、外部のデータベースから関連する情報を検索し、その情報をプロンプトに含めてLLMに質問する手法を「RAG(Retrieval-Augmented Generation:検索拡張生成)」と呼びます。LangChainは、RAGに必要な処理フローを簡単に実装するための部品をすべて備えています。

RAGの一般的な流れは、まずPDFやテキストファイルなどの文書を読み込み、扱いやすいサイズに分割(ドキュメントスプリット)します。次に、それぞれのテキストの意味(概念)を数値に変換(エンベディング)し、ベクトルデータベースと呼ばれる特殊なデータベースに保存(Vector Store)します。ユーザーが質問をすると、システムはその質問の意味と近い内容のテキストをデータベースから検索(Retrieval)して探し出します。

最後に、見つかったドキュメントの内容を「参考資料」としてプロンプトに貼り付け、LLMに回答を生成させます。LangChainを使うことで、これらの複雑な処理パイプラインを数行のコードで繋ぐことができ、自社のデータに特化した高精度な回答を生成するシステムを容易に構築できます。RAGは、現在のエンタープライズ(企業向け)AI開発において、最も広く使われている技術の一つです。