概要

最近、生成 AI 周りのサービスに興味を持っており、中でも LangChain について興味があるので、色々触れてみて学習してみようとの思いから本記事を執筆しました。
第一弾である今回は、ひとまず全体像を掴むことが大事かなと思い、「LangChain ってそもそも何なんだ」という部分や LangChain で使用することのできる機能についてまとめてみました。

LangChainとは

LangChain is a framework for developing applications powered by large language models (LLMs).

(LangChain公式の文章を引用)

LangChain 公式によれば、LangChain は大規模言語モデル(LLM)を利用したアプリケーションを開発するためのフレームワークとのことです。

LangChain の他にも、LangSmith, LangServe というものがあります。

LangSmith

LangChain を使った LLM アプリケーションのパフォーマンスの監視ができるサービスです。
Projects(下記画像参照)という部分で、
アプリケーションが実行された際の、回答にかかった時間や実行時消費されたトークンの数、料金などを GUI 上で確かめることができるようです。

LangServe

LangChain で作ったものをAPI化することができるサービスです。
これによって、LangChain をいろんなアプリケーションに組み込むことができるようです。

LangChain の構成要素

LangChain の構成要素についてざっくりまとめてみました。
LangChain の主要な構成要素として、Model I/O, Agents, Memory, Chains, Retrieval, Callbacks があります。一部の構成要素は軽く触ってみたりしました。

Model I/O

プロンプト(質問文)に対する回答を生成するための基盤となる機能です。

(LangChain 公式より引用)

Model I/Oは、ChatModels, LLMs, Prompt Templates, Output parsers の機能からなっています。
だいぶざっくりですが、LangChain を使った回答の生成については、①→②→③のようなイメージで進んでいくと整理できると思います。

①Prompt Templates を使い、LLM に投げるプロンプトの雛形を作成する(動的に値を埋め込むことができるようにしておく)

②そのプロンプトを使って言語モデルが推論を行う
(LangChain には LLM と、ChatModel という二つのオブジェクトがあるようです。
文字列を返すか、メッセージを返すかで違いがあるようです。詳しくはこちらを参照

③Output parsers を使い、LLM から返却される回答を必要に応じて整形した上で、回答を返却する

Agents

言語モデルにどのような行動をさせるかを指定する機能です。
LLM 自体はプロンプト(質問)に対して、「自身の持っている知識をベースにテキストを出力する」という単純作業しかできません。
Agents という機能を使えば、『「A」というプロンプトが来た場合にはまず Web ページを検索して、回答を生成する』といった具合で、LLM の行動を事前に指定することができます。
LangGraphというものを使うことで Agent を構築することができるようです。

Memory

会話履歴の保持を行う機能です。
基本的にユーザーと言語モデルとのやり取りは、独立したものとしてみなされてしまいますが、Memory という機能を使えば、ユーザーとの以前の対話を記憶して、それに基づいた回答を生成させることが可能です。
LangChain を使ってチャットボットを作る際は、この機能が必須ですね。

Chains

複数のタスクを連続して実行するための機能です。
例えば、「英語で書かれている文章Aを要約」→「その要約した文章を日本語に翻訳する」といったやや複雑なタスクをこなしてもらう際に活用します。

Retrieval

LLM の学習データの中に存在しない新しい知識(Web 上に存在しないプライベートなデータ)を補完して回答を生成させるための機能です。
Retrievalを使うことで、いわゆる RAG(検索拡張生成)の実装を行うことが可能です。
例えば、「社内文書を検索して回答を生成させるようなチャットボットを作る場合」などが Retrieval の機能の使い所です。
Retrieval は、Document loaders, Text Splitting, Text embedding models, Vector stores, Retrievers, Indexing の機能に分かれています。

こちらの記事で、Retrieval の中の Vector stores の機能を使い、簡単なRAGを実装してみる、ということを試してみましたのでよろしければご覧ください。

Callbacks

「モデルがプロンプトを受け取る時」、「モデルが回答を生成する時」というような、特定のタイミングで何かを実行したい時に使用する機能です。
ログ収集やモニタリングなどが主なユースケースのようです。
以下は、ConsoleCallbackHandler というクラスを使って出力させてみたものです。
内部で何が行われているかが分かりづらい LangChain ですが、
こういった形で出力してみることで、何が実行されているかの、理解の助けになりそうですね。

<br />[chain/start] [chain:RunnableSequence] Entering Chain run with input:
{
  "input": "二つのPDFファイルの違いを簡単に説明して"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<reference_info,question>] Entering Chain run with input:
{
  "input": "二つのPDFファイルの違いを簡単に説明して"
}
[chain/start] [chain:RunnableSequence > chain:RunnableParallel<reference_info,question> > chain:RunnablePassthrough] Entering Chain run with input:
{
  "input": "二つのPDFファイルの違いを簡単に説明して"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<reference_info,question> > chain:RunnablePassthrough] [4ms] Exiting Chain run with output:
{
  "output": "二つのPDFファイルの違いを簡単に説明して"
}
[chain/end] [chain:RunnableSequence > chain:RunnableParallel<reference_info,question>] [237ms] Exiting Chain run with output:
[outputs]
[chain/start] [chain:RunnableSequence > prompt:ChatPromptTemplate] Entering Prompt run with input:
[inputs]
[chain/end] [chain:RunnableSequence > prompt:ChatPromptTemplate] [1ms] Exiting Prompt run with output:
[outputs]
[llm/start] [chain:RunnableSequence > llm:ChatOpenAI] Entering LLM run with input:
{
  "prompts": [
    "Human: 次の情報を参照して、質問に答えてください\n参照する情報: [Document(page_content='令和5年版\\n労働経済の分析\\n-持続的な賃上げに向けて-\\n〔\\n概\\n要\\n〕\\n令和5年9月\\n厚\\n生\\n労\\n働\\n省\\n○\\n賃金は、1970年から1990年代前半まではほぼ一貫して増加していたが、1990年代後半以降、それまで\\nの増加トレンドから転換し、減少又は横ばいで推移している。(⇒6ページ)\\n○\\n1990年代後半以降、物価の影響も考慮すると、一人当たりの実質労働生産性は他の主要先進国並みに\\n上昇しているものの、実質賃金は伸び悩んでいる。
    ・・・・・(本来はもっと長く続きますが長すぎるので省略)
  ]
}
[llm/end] [chain:RunnableSequence > llm:ChatOpenAI] [31.35s] Exiting LLM run with output:
{
  "generations": [
    [
      {
        "text": "二つのPDFファイルは、それぞれ異なる内容の報告書を示しています。\n\n1. 最初のPDFファイルは、「令和5年版 労働経済の分析 -持続的な賃上げに向けて-」というタイトルの厚生労働省による報告書です。この報告書は、賃金の動向、労働市場の状況、賃上げの効果、企業の賃上げ状況、スタートアップ企業の賃金関連の分析、転職や正規雇用転換の影響、最低賃金制度や同一労働同一賃金の政策の影響など、労働経済に関する幅広いトピックをカバーしています。また、賃金の伸び悩みの背景や、企業と労働者に対する賃上げの好影響についても言及しています。\n\n2. 二つ目のPDFファイルは、「令和4年版 厚生労働白書(令和3年度厚生労働行政年次報告)-社会保障を支える人材の確保-」というタイトルの報告書です。この報告書は、医療・福祉分野における人材確保が主なテーマであり、現状と見通し、これまでの取り組みと課題、今後の方向性、具体的な取り組み例などに焦点を当てています。特に、高齢化社会における医療・福祉人材の必要性、人材の供給と需要のギャップ、さまざまな職種の就業者数の推移、地域ごとのニーズに応じた人材確保の重要性などが強調されています。\n\n要するに、最初のPDFは労働経済と賃金に関する分析を、二つ目のPDFは医療・福祉分野の人材確保に関する報告をそれぞれ扱っています。",
        "generation_info": {
          "finish_reason": "stop",
          "logprobs": null
        },
        "type": "ChatGeneration",
        "message": {
          "lc": 1,
          "type": "constructor",
          "id": [
            "langchain",
            "schema",
            "messages",
            "AIMessage"
          ],
          "kwargs": {
            "content": "二つのPDFファイルは、それぞれ異なる内容の報告書を示しています。\n\n1. 最初のPDFファイルは、「令和5年版 労働経済の分析 -持続的な賃上げに向けて-」というタイトルの厚生労働省による報告書です。この報告書は、賃金の動向、労働市場の状況、賃上げの効果、企業の賃上げ状況、スタートアップ企業の賃金関連の分析、転職や正規雇用転換の影響、最低賃金制度や同一労働同一賃金の政策の影響など、労働経済に関する幅広いトピックをカバーしています。また、賃金の伸び悩みの背景や、企業と労働者に対する賃上げの好影響についても言及しています。\n\n2. 二つ目のPDFファイルは、「令和4年版 厚生労働白書(令和3年度厚生労働行政年次報告)-社会保障を支える人材の確保-」というタイトルの報告書です。この報告書は、医療・福祉分野における人材確保が主なテーマであり、現状と見通し、これまでの取り組みと課題、今後の方向性、具体的な取り組み例などに焦点を当てています。特に、高齢化社会における医療・福祉人材の必要性、人材の供給と需要のギャップ、さまざまな職種の就業者数の推移、地域ごとのニーズに応じた人材確保の重要性などが強調されています。\n\n要するに、最初のPDFは労働経済と賃金に関する分析を、二つ目のPDFは医療・福祉分野の人材確保に関する報告をそれぞれ扱っています。",
            "response_metadata": {
              "token_usage": {
                "completion_tokens": 647,
                "prompt_tokens": 33755,
                "total_tokens": 34402
              },
              "model_name": "gpt-4-1106-preview",
              "system_fingerprint": null,
              "finish_reason": "stop",
              "logprobs": null
            },
            "type": "ai",
            "id": "run-57c50c90-2bf7-43ce-8f8f-ce32f28cfcdc-0",
            "tool_calls": [],
            "invalid_tool_calls": []
          }
        }
      }
    ]
  ],
  "llm_output": {
    "token_usage": {
      "completion_tokens": 647,
      "prompt_tokens": 33755,
      "total_tokens": 34402
    },
    "model_name": "gpt-4-1106-preview",
    "system_fingerprint": null
  },
  "run": null
}
[chain/start] [chain:RunnableSequence > parser:StrOutputParser] Entering Parser run with input:
[inputs]
[chain/end] [chain:RunnableSequence > parser:StrOutputParser] [0ms] Exiting Parser run with output:
{
  "output": "二つのPDFファイルは、それぞれ異なる内容の報告書を示しています。\n\n1. 最初のPDFファイルは、「令和5年版 労働経済の分析 -持続的な賃上げに向けて-」というタイトルの厚生労働省による報告書です。この報告書は、賃金の動向、労働市場の状況、賃上げの効果、企業の賃上げ状況、スタートアップ企業の賃金関連の分析、転職や正規雇用転換の影響、最低賃金制度や同一労働同一賃金の政策の影響など、労働経済に関する幅広いトピックをカバーしています。また、賃金の伸び悩みの背景や、企業と労働者に対する賃上げの好影響についても言及しています。\n\n2. 二つ目のPDFファイルは、「令和4年版 厚生労働白書(令和3年度厚生労働行政年次報告)-社会保障を支える人材の確保-」というタイトルの報告書です。この報告書は、医療・福祉分野における人材確保が主なテーマであり、現状と見通し、これまでの取り組みと課題、今後の方向性、具体的な取り組み例などに焦点を当てています。特に、高齢化社会における医療・福祉人材の必要性、人材の供給と需要のギャップ、さまざまな職種の就業者数の推移、地域ごとのニーズに応じた人材確保の重要性などが強調されています。\n\n要するに、最初のPDFは労働経済と賃金に関する分析を、二つ目のPDFは医療・福祉分野の人材確保に関する報告をそれぞれ扱っています。"
}
[chain/end] [chain:RunnableSequence] [31.59s] Exiting Chain run with output:
{
  "output": "二つのPDFファイルは、それぞれ異なる内容の報告書を示しています。\n\n1. 最初のPDFファイルは、「令和5年版 労働経済の分析 -持続的な賃上げに向けて-」というタイトルの厚生労働省による報告書です。この報告書は、賃金の動向、労働市場の状況、賃上げの効果、企業の賃上げ状況、スタートアップ企業の賃金関連の分析、転職や正規雇用転換の影響、最低賃金制度や同一労働同一賃金の政策の影響など、労働経済に関する幅広いトピックをカバーしています。また、賃金の伸び悩みの背景や、企業と労働者に対する賃上げの好影響についても言及しています。\n\n2. 二つ目のPDFファイルは、「令和4年版 厚生労働白書(令和3年度厚生労働行政年次報告)-社会保障を支える人材の確保-」というタイトルの報告書です。この報告書は、医療・福祉分野における人材確保が主なテーマであり、現状と見通し、これまでの取り組みと課題、今後の方向性、具体的な取り組み例などに焦点を当てています。特に、高齢化社会における医療・福祉人材の必要性、人材の供給と需要のギャップ、さまざまな職種の就業者数の推移、地域ごとのニーズに応じた人材確保の重要性などが強調されています。\n\n要するに、最初のPDFは労働経済と賃金に関する分析を、二つ目のPDFは医療・福祉分野の人材確保に関する報告をそれぞれ扱っています。"
}
結果:
二つのPDFファイルは、それぞれ異なる内容の報告書を示しています。

1. 最初のPDFファイルは、「令和5年版 労働経済の分析 -持続的な賃上げに向けて-」というタイトルの厚生労働省による報告書です。この報告書は、賃金の動向、労働市場の状況、賃上げの効果、企業の賃上げ状況、スタートアップ企業の賃金関連の分析、転職や正規雇用転換の影響、最低賃金制度や同一労働同一賃金の政策の影響など、労働経済に関する幅広いトピックをカバーしています。また、賃金の伸び悩みの背景や、企業と労働者に対する賃上げの好影響についても言及しています。

2. 二つ目のPDFファイルは、「令和4年版 厚生労働白書(令和3年度厚生労働行政年次報告)-社会保障を支える人材の確保-」というタイトルの報告書です。この報告書は、医療・福祉分野における人材確保が主なテーマであり、現状と見通し、これまでの取り組みと課題、今後の方向性、具体的な取り組み例などに焦点を当てています。特に、高齢化社会における医療・福祉人材の必要性、人材の供給と需要のギャップ、さまざまな職種の就業者数の推移、地域ごとのニーズに応じた人材確保の重要性などが強調されています。

要するに、最初のPDFは労働経済と賃金に関する分析を、二つ目のPDFは医療・福祉分野の人材確保に関する報告をそれぞれ扱っています。

最後に

LangChain でできることは幅広いなと改めて実感しました。
その一方で、幅広さゆえに細かい機能まで全て理解するのは結構大変だな、とも感じました。
また、ドキュメントやライブラリの更新のスパンが早いので、最新情報をしっかりキャッチアップしていくようにしていきたいです。

参考文献

https://www.youtube.com/watch?v=aywZrzNaKjs&t=14s
https://zenn.dev/umi_mori/books/prompt-engineer/viewer/langchain_overview
https://itnext.io/getting-started-with-langchain-a-beginners-guide-6265def07f28
https://qiita.com/sakue_103/items/f8180758df4f281e0bc6
https://qiita.com/xxyc/items/980f8fffe3e13aa2ac64