Introduction to LangChain

LangChainとは?
LangChainは、大規模言語モデル(LLM)を活用したアプリケーション開発のためのフレームワークで、LLMアプリケーションのライフサイクルを簡素化できます。
- Developments:LangChainのオープンソースの構成要素、コンポーネント、サードパーティ連携を使用してアプリケーションを構築できます。LangGraphを使えば、ストリーミングとHuman-in-the-Loopをサポートするエージェントを作成できます。
- Productionization:LangSmithを使用してチェーンの検査、監視、評価を行い、継続的な最適化と安全なデプロイを実現できます。
- Deployment:LangGraph Cloudを使用して、LangGraphアプリケーションを本番環境に対応したAPIやアシスタントに変換できます。
具体的には、以下のオープンソースライブラリで構成されています。
langchain-core
:基本的な抽象化とLangChain表現言語。langchain-community
:サードパーティ連携。- パートナーパッケージ(例:
langchain-openai
、langchain-anthropic
など):一部の連携機能は、langchain-core
のみに依存する軽量なパッケージとして分離されています。
- パートナーパッケージ(例:
langchain
:アプリケーションの認知アーキテクチャを構成するチェーン、エージェント、検索戦略。LangGraph
:グラフのエッジとノードをモデル化することで、LLMを使用した堅牢で状態を持つマルチアクターアプリケーションを構築します。LangChainとシームレスに統合できますが、単独でも使用可能です。LangServe
:LangChainのチェーンをRESTful APIとしてデプロイします。LangSmith
:LLMアプリケーションのデバッグ、テスト、評価、モニタリングを可能にする開発者向けプラットフォームです。

事始め
LangChainは、AIアプリケーション開発を支援するPythonライブラリです。表現言語LCEL
と、OpenAI APIとの連携機能を提供します。
LangChainのインストールは、pipコマンドで行います。
$ pip install langchain==0.2.7 langchain-community==0.2.7 langchain-openai==0.1.12 unstructured==0.14.10 markdown==3.6
注意: LangChainはv0.1リリースでlangchainとlangchain_openaiの2つに分割されました。OpenAI APIとの連携機能はlangchain_openaiパッケージで提供されています。
また、OpenAI APIを使用するには、APIキーが必要です。
- OpenAIアカウントの作成: https://platform.openai.com/ からアカウントを作成します。
- APIキーの発行: ログイン後、画面右上の「User API keys」からAPIキーを発行します。
発行されたAPIキーは、環境変数OPENAI_API_KEY
に設定します。
import os os.environ["OPENAI_API_KEY"] = "YOUR-API-KEY"
LangChainの主要モジュール
LangChainは、以下の6つの主要モジュールから構成されています。これらのモジュールを組み合わせることで、複雑なAIアプリケーションを効率的に構築することができます。
Models
: 言語モデル(LLM)やチャットモデルとのインターフェースを提供します。OpenAI、Hugging Face、その他のAIプロバイダーのモデルを統一的に扱うことができます。Prompts
: モデルへの入力を構造化し、テンプレート化する機能を提供します。動的なプロンプト生成やプロンプトの最適化を行うツールも含まれます。Chains
: 複数のコンポーネント(モデル、プロンプト、その他の処理)を連結して、より複雑なタスクを実行するためのフレームワークです。Indexes
: 大量のテキストデータを効率的に検索・クエリするための機能を提供します。ベクトルデータベースやその他の検索手法を利用できます。Memory
: 会話の文脈や過去の情報を保持し、それを後続の処理に活用する機能を提供します。チャットボットなどの対話システムで特に重要です。Agents
: 特定のタスクを自律的に実行する「エージェント」を作成するためのフレームワークです。エージェントは与えられた目標に向けて、適切なツールを選択し実行します。
以降で、これらの6つのモジュールの簡単な使い方を解説します。
Models (LLMs, Chat Models)
Models
は、LangChainで使用する機械学習モデルを指定するものです。Modelsには、以下の3種類があります。
LLMs
: OpenAI の Completions API (gpt-3.5-turbo-instruct
)などの大規模言語モデルChat Models
: OpenAI の Chat API (gpt-4
やgpt-3.5-turbo
)のためのモジュールText Embedding Models
: テキストをベクトル化するためのモデル
langchain_openai.OpenAI
の使い方
from langchain_openai import OpenAI def try_llm(prompt: str, model_name: str = "gpt-3.5-turbo-instruct") -> str: llm = OpenAI(model_name=model_name, temperature=0) result = llm.invoke(prompt) return result if __name__ == "__main__": import os os.environ["OPENAI_API_KEY"] = "YOUR-OPENAI-KEY" try_llm(prompt="深層学習について教えて下さい。")
langchain_openai.ChatOpenAI
の使い方
from langchain_openai import ChatOpenAI def try_chat(prompt: str, model_name: str = "gpt-3.5-turbo") -> None: chat = ChatOpenAI(model_name=model_name, temperature=0) result = chat.invoke(prompt) print(result) if __name__ == "__main__": import os os.environ["OPENAI_API_KEY"] = "YOUR-OPENAI-KEY" try_chat(prompt="深層学習について教えて下さい。")
Prompts (Prompt Template)
Promptsは、モデルの入力を組み立てるためのモジュールで、大きく以下の4つの要素が存在します。
- Prompt Template: テキスト生成のためのテンプレートを作成する機能です。変数を含む文字列テンプレートを定義し、実行時に具体的な値を挿入してプロンプトを生成します。これにより、動的で再利用可能なプロンプトの作成が可能になります。
- Chat Prompt Template: チャットベースのモデル用に最適化されたプロンプトテンプレートです。複数のメッセージを含む会話形式のプロンプトを作成できます。システムメッセージ、ユーザーメッセージ、AIアシスタントのメッセージなど、異なる役割のメッセージを組み合わせることができます。
- Example Selectors: Few-shot Learningのために、プロンプトに含める例を動的に選択する機能です。タスクや入力に応じて最も関連性の高い例を選び、モデルの性能を向上させることができます。
RandomExampleSelector
: ランダムに例を選択LengthBasedExampleSelector
: 入力の長さに基づいて例を選択SemanticSimilarityExampleSelector
: 意味的類似性に基づいて例を選択
- Output Parsers: モデルの出力を構造化されたデータに変換する機能です。テキスト出力を特定のフォーマット(JSON、リスト、カスタム構造体など)に解析し、プログラムで扱いやすい形式に変換します。
langchain.prompts.PromptTemplate
の実装例
from langchain.prompts import PromptTemplate def try_template(keyword: str) -> str: template = """ 次の用語の概要を箇条書きで説明して下さい。 用語: {keyword} """ prompt = PromptTemplate(input_variables=["keyword"], template=template) result = prompt.format(keyword=keyword) return result if __name__ == "__main__": import os os.environ["OPENAI_API_KEY"] = "YOUR-OPENAI-KEY" print(try_template("深層学習"))
langchain.output_parsers.PydanticOutputParser
の実装例
import textwrap from typing import List from langchain_openai import ChatOpenAI from langchain.chains import LLMChain from langchain.prompts import PromptTemplate from langchain.output_parsers import PydanticOutputParser from pydantic import BaseModel, Field, validator class Recipe(BaseModel): ingredients: List[str] = Field(description="ingredients of the dish") steps: List[str] = Field(description="steps to make the dish") def create_chat(model_name: str = "gpt-3.5-turbo") -> ChatOpenAI: return ChatOpenAI(model_name=model_name, temperature=0) def create_template() -> PromptTemplate: template = textwrap.dedent(""" 料理のレシピを教えてください。 {format_instructions} 料理名: {dish} """) parser = PydanticOutputParser(pydantic_object=Recipe) return PromptTemplate( template=template, input_variables=["dish"], partial_variables={"format_instructions": parser.get_format_instructions()}, ) def try_chain(dish: str) -> str: chain = LLMChain( llm=create_chat(), prompt=create_template() ) return chain.invoke(dish) if __name__ == "__main__": import langchain import os # APIキーの設定 os.environ["OPENAI_API_KEY"] = "YOUR-OPENAI-KEY" # LangChainの出力を冗長にする langchain.verbose = True # Chainの実行 result = try_chain("カレー") print(result) # 結果のパース parser = PydanticOutputParser(pydantic_object=Recipe) print(parser.parse(result))
Chains
Chains
は、各モジュール(Models
やTemplates
など)を連結するために使用します。SimpleSequentialChain
を使うと、Chain
同士を直列につなぐことができます。
langchain.chains.LLMChain
の実装例
import textwrap from langchain_openai import ChatOpenAI from langchain.chains import LLMChain from langchain.prompts import PromptTemplate def create_chat(model_name: str = "gpt-3.5-turbo") -> ChatOpenAI: return ChatOpenAI(model_name=model_name, temperature=0) def create_template() -> PromptTemplate: template = textwrap.dedent(""" 次の専門用語を説明して下さい。ただし、書式に準拠した内容でまとめて下さい。 専門用語: {keyword} 書式: 箇条書き """) return PromptTemplate(input_variables=["keyword"], template=template) def try_chain(keyword: str) -> str: chain = LLMChain( llm=create_chat(), prompt=create_template() ) return chain.invoke(keyword) if __name__ == "__main__": import langchain import os # APIキーの設定 os.environ["OPENAI_API_KEY"] = "YOUR-OPENAI-KEY" # LangChainの出力を冗長にする langchain.verbose = True # Chainの実行 print(try_chain("地球温暖化"))
langchain.chains.SimpleSequentialChain
の実装例
import textwrap from langchain_openai import ChatOpenAI from langchain.chains import LLMChain, SimpleSequentialChain from langchain.prompts import PromptTemplate def create_chat(model_name: str = "gpt-3.5-turbo") -> ChatOpenAI: return ChatOpenAI(model_name=model_name, temperature=0) def create_cot_template() -> PromptTemplate: template = textwrap.dedent(""" 以下の質問に回答して下さい。 ### 質問 ### {question} ### 質問終了 ### ステップバイステップで考えましょう。 """) return PromptTemplate(input_variables=["question"], template=template) def create_summarize_template() -> PromptTemplate: template = textwrap.dedent(""" 入力を結論だけ一言で要約して下さい。 ### 入力 ### {input} ### 入力終了 ### """) return PromptTemplate(input_variables=["input"], template=template) def create_cot_chain(chat: ChatOpenAI) -> LLMChain: return LLMChain(llm=chat, prompt=create_cot_template()) def create_summarize_chain(chat: ChatOpenAI) -> LLMChain: return LLMChain(llm=chat, prompt=create_summarize_template()) def try_sequential_chain(question: str) -> str: chat = create_chat() simple_chain = SimpleSequentialChain(chains=[ create_cot_chain(chat), create_summarize_chain(chat) ]) return simple_chain(question) if __name__ == "__main__": import langchain import os # APIキーの設定 os.environ["OPENAI_API_KEY"] = "YOUR-OPENAI-KEY" # LangChainの出力を冗長にする langchain.verbose = True # SimpleSequentialChainの実行 question = textwrap.dedent(""" 私は市場に行って10個のリンゴを買いました。隣人に2つ、修理工に2つ渡しました。 それから、5つのリンゴを買って1つ食べました。残りは何個ですか? """) print(try_sequential_chain(question))
Indexes
様々なテーマに対して的確に応答する大規模言語モデルですが、学習に使用されていない情報については正確に回答できません。そのため、ハルシネーション(Hallucination, 幻覚) と呼ばれる間違った情報を生成することがあります。
そこで、この問題を解決するため、Vector Store
と呼ばれる機能を活用します。大規模言語モデルが未学習の情報(テキスト)をベクトル化して Vector Store
に保存しておき、入力と近いベクトルの文章をVector Store
から検索してコンテキストに含める手法です。
langchain_community.document_loaders.DirectoryLoader
の実装例
from langchain_openai import ChatOpenAI from langchain_openai import OpenAIEmbeddings from langchain_community.document_loaders import DirectoryLoader from langchain_community.vectorstores import Chroma from langchain.indexes import VectorstoreIndexCreator from langchain.indexes.vectorstore import VectorStoreIndexWrapper def create_chat(model_name: str = "gpt-3.5-turbo") -> ChatOpenAI: return ChatOpenAI(model_name=model_name, temperature=0) def create_index() -> VectorStoreIndexWrapper: embeddings = OpenAIEmbeddings() loader = DirectoryLoader("./diffusers/docs/source/ja", glob="**/*.md") index = VectorstoreIndexCreator(vectorstore_cls=Chroma, embedding=embeddings).from_loaders([loader]) return index def try_vector_store(question: str) -> str: chat = create_chat() index = create_index() return index.query(question, llm=chat) if __name__ == "__main__": import os import langchain # APIキーの設定 os.environ["OPENAI_API_KEY"] = "YOUR-OPENAI-KEY" # LangChainの出力を冗長にする # langchain.verbose = True # 動作確認用の環境を作成する if not os.path.exists("diffusers"): os.system("git clone https://github.com/huggingface/diffusers") # Vector Storeの動作確認 print(try_vector_store("diffusersの基本的な使い方を教えてください。"))
Memory
大規模言語モデルを利用したアプリケーションでは、対話インターフェースが一般的で、会話内の以前の情報を参照することが重要となります。このときに使用されるのがMemory
で、Memory
は以前の対話情報を保存する機能を提供します。また、読み取りと書き込みの2つの基本アクションをサポートし、対話型AIは実行前に読み取り、実行後に書き込むことで過去の情報を利用可能にできます。
langchain.memory.ConversationBufferMemory
の実装例
from langchain_openai import ChatOpenAI from langchain.chains import ConversationChain from langchain.memory import ConversationBufferMemory def create_chat(model_name: str = "gpt-3.5-turbo") -> ChatOpenAI: return ChatOpenAI(model_name=model_name, temperature=0, max_tokens=100) def try_memory(max_iter: int = 3) -> None: chat = create_chat() conversation = ConversationChain(llm=chat, memory=ConversationBufferMemory()) for _ in range(max_iter): user_message = input("You: ") response = conversation.predict(input=user_message) print(f"ChatGPT: {response}") if __name__ == "__main__": import os # APIキーの設定 os.environ["OPENAI_API_KEY"] = "YOUR-API-KEY" # Memoryの動作確認 try_memory()
Agents
- Agentsを使用すると、LLMが様々なツールを選択して使用しながら動作します。
- 実際には、LLMがツールを使用するわけではなく、ツールを使用しているように動作します。
- ツールの例
- Bash
- Google検索
- Pythonインタプリタ
- ウィキペディアのAPI
- etc…
- Agentsは、MRKLやReActといった仕組みのプロンプトで動作します。
- MRKL (Multi-Round Knowledge Loop): AIエージェントが複数のツールやアプローチを組み合わせてタスクを解決するための枠組みです。
- ReAct: LLMが外部ツールと対話して追加情報を取得し、より信頼性の高い事実に基づく回答を生成するための機能です。
Linux Terminalを使用した例
from langchain_openai import ChatOpenAI from langchain.agents import load_tools, initialize_agent from langchain.agents.agent import AgentExecutor def create_chat(model_name: str = "gpt-3.5-turbo") -> ChatOpenAI: return ChatOpenAI(model_name=model_name, temperature=0) def create_agent() -> AgentExecutor: chat = create_chat() tools = load_tools(["terminal"], llm=chat) return initialize_agent(tools, chat, agent="zero-shot-react-description") def try_agent() -> None: agent_chain = create_agent() result = agent_chain.run("What is your current directory ?") print(result)
今回は、LangChainの基本的な使い方を紹介しましたが、この他にも様々な機能が実装されています。詳しくは、公式のドキュメント等をご確認ください。