LangChain v0.3 クイックスタートガイド - Python版
Python版の「LangChain」のクイックスタートガイドをまとめました。
1. LangChain
「LangChain」は、「大規模言語モデル」 (LLM : Large language models) と連携するアプリの開発を支援するライブラリです。
「LLM」という革新的テクノロジーによって、開発者は今まで不可能だったことが可能になりました。しかし、「LLM」を単独で使用するだけでは、真に強力なアプリケーションを作成するのに不十分です。真の力は、それを他の 計算 や 知識 と組み合わせた時にもたらされます。「LangChain」は、そのようなアプリケーションの開発をサポートします。
2. LangChainのユースケース
主なユースケースは、次の3つになります。
3. LangChain のモジュール
「LangChain」は、言語モデル アプリケーションの構築に使用できる多くのモジュールを提供します。モジュールを組み合わせて複雑なアプリケーションを作成したり、個別に使用したりできます。
主なモジュールは、次のとおりです。
モジュールは、単純なアプリケーションではモジュール単体で使用でき、より複雑なユースケースではモジュールをチェーンで繋げて利用することができます。
4. インストール
Google Colabでのインストール手順は、次のとおりです。
(1) パッケージのインストール。
# パッケージのインストール
!pip install langchain==0.3.0
!pip install langchain_community
!pip install langgraph
!pip install langchain_openai
(2) 環境変数の準備。
左端の鍵アイコンで「OPENAI_API_KEY」を設定してからセルを実行してください。
import os
from google.colab import userdata
# 環境変数の準備 (左端の鍵アイコンでOPENAI_API_KEYを設定)
os.environ["OPENAI_API_KEY"] = userdata.get("OPENAI_API_KEY")
5. Model I/O
LLMアプリケーションの中核はLLMです。「LangChain」は、様々なLLMを手順で操作できる共通インタフェースを提供します。
主な構成要素は、次の3つです。
5-1. Language Model
「LangChain」の最も基本的な機能は、LLMを呼び出すことです。「Language Model」は、LLMを呼び出すモジュールになります。
次の2種類のインタフェースを提供します。
・LLM
今回は例として、「テキスト生成モデル」でLLMの呼び出しを行います。テキスト→テキストのインタフェースになります。
from langchain_openai import OpenAI
# LLMの準備
llm = OpenAI(temperature=0.9)
# LLMの実行
output = llm.invoke("コンピュータゲームを作る日本語の新会社名をを1つ提案してください。")
print(type(output))
print(output)
<class 'str'>
ツクルゲームス
LLMの入力は文字列、出力は文字列になります。Messageリストで入力することも可能です。
・ChatModel
次に、「チャットモデル」でLLMの呼び出しを行います。メッセージリスト→メッセージのインタフェースになります。
from langchain_core.messages import HumanMessage
from langchain_openai import ChatOpenAI
# ChatModelの準備
chat_model = ChatOpenAI(temperature=0.9)
# ChatModelの実行
messages = [
HumanMessage(content="コンピュータゲームを作る日本語の新会社名をを1つ提案してください。")
]
output = chat_model.invoke(messages)
print(type(output))
print(output)
<class 'langchain_core.messages.ai.AIMessage'>
content='「夢遊計画」(ゆめあるけいかく)' response_metadata={'token_usage': {'completion_tokens': 18, 'prompt_tokens': 38, 'total_tokens': 56}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_b28b39ffa8', 'finish_reason': 'stop', 'logprobs': None} id='run-93614b2e-aaba-40c6-ace3-f6abced6610e-0'
ChatModelの入力はMessageリスト、出力はMessageになります。文字列で入力することも可能です。
メッセージは役割 (システム、ユーザー、AIなど) とコンテンツの情報を持ちます。「LangChain」の主なメッセージ型は、次の3種類です。
5-2. Prompt Template
「Prompt Template」は、ユーザー入力からプロンプトを生成するためのテンプレートです。アプリケーションで LLM を使用する場合、通常、ユーザー入力を直接LLM に渡すことはありません。ユーザー入力を基に「Prompt Template」でプロンプトを作成して、それをLLMに渡します。
今回は例として、ユーザー入力「作るもの」を基に「○○を作る日本語の新会社名をを1つ提案してください」というプロンプトを生成します。
from langchain_core.prompts import PromptTemplate
# プロンプトテンプレートの準備
prompt_template = PromptTemplate(
input_variables=["product"],
template="{product}を作る日本語の新会社名をを1つ提案してください",
)
# プロンプトテンプレートの実行
output = prompt_template.invoke({"product": "家庭用ロボット"})
print(type(output))
print(output)
<class 'langchain_core.prompt_values.StringPromptValue'>
text='家庭用ロボットを作る日本語の新会社名をを1つ提案してください'
「Prompt Template」の入力は辞書、出力は「PromptValue」です。
「PromptValue」は、LLMとChatModelの入力となるクラスです。文字列(LLMの入力)にキャストするto_string()と、Messageリスト(ChatModelの入力)にキャストするto_messages()を持ちます。
5-3. Output Parser
「Output Parser」 は、「Language Model」の出力を用途にあわせて変換するモジュールです。
主な用途は次のとおりです。
今回は、「StrOutputParser」でMessageリストをプレーンテキストに変換します。
from langchain_core.output_parsers import StrOutputParser
from langchain_core.messages import AIMessage
# Output Parserの準備
output_parser = StrOutputParser()
# Output Parserの実行
message = AIMessage(content="AIからのメッセージです")
output = output_parser.invoke(message)
print(type(output))
print(output)
<class 'str'>
AIからのメッセージです
「StrOutputParser」の入力は「Language Model」の出力 (文字列またはMessageリスト)、出力は文字列になります。
提供されている「OutputParser」は、次のとおりです。
6. Chain
単純なアプリケーションであれば「LLM」や「ChatModel」の単独使用で問題ありませんが、それらモジュール (Runnable) をチェーンで繋げることで、複雑なアプリケーションを構築することができます。
Chainの実装方法には、次の2種類があります。
「LangChain」ではこのチェーンを「LCEL」(LangChain Expression Language)と呼ばれる表現言語で記述します。基本的な使い方は、モジュールを「|」で繋げるだけになります。
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
# プロンプトテンプレートの準備
prompt_template = PromptTemplate(
input_variables=["product"],
template="{product}を作る日本語の新会社名を1つ提案してください",
)
# ChatModelの準備
chat_model = ChatOpenAI(temperature=0.9)
# OutputParserの準備
output_parser = StrOutputParser()
# チェーンをつなげて実行
chain = prompt_template | chat_model | output_parser
output = chain.invoke({"product": "家庭用ロボット"})
print(output)
家庭ロボットテクノロジー株式会社
7. Agent
7-1. Agentの概要
「Agent」は、ユーザーの要求に応じて、どの「Action」をどういう順番で実行するかを決定するモジュールです。「Chain」の機能の実行の順番はあらかじめ決まっていますが、「Agent」はユーザーの要求に応じてLLM自身が決定します。この「Agent」が「Action」で実行する特定の機能のことを「Tool」と呼びます。
今回は例として、次の2つのToolを使うAgentを作成します。
7-2. Tavility Toolの準備
(1) パッケージのインストール。
「Tavily」のパッケージをインストールします。
# パッケージのインストール
!pip install tavily-python
(2) 環境変数の準備。
左端の鍵アイコンで「TAVILY_API_KEY」を設定してからセルを実行してください。
import os
from google.colab import userdata
# 環境変数の準備 (左端の鍵アイコンでTAVILY_API_KEYを設定)
os.environ["TAVILY_API_KEY"] = userdata.get("TAVILY_API_KEY")
(3) Tavilityツールの準備。
from langchain_community.tools.tavily_search import TavilySearchResults
# Tavilyの準備
tavily_tool = TavilySearchResults()
# 動作確認
tavily_tool.invoke("2024年夏の日本で一番人気のアニメは?")
7-3. Retriever Toolの準備
(1) パッケージのインストール。
ベクトルストア関連のパッケージをインストールします。
# パッケージのインストール
!pip install unstructured faiss-cpu
(2) ドキュメントの準備。
今回は、マンガペディアの「ぼっち・ざ・ろっく!」のドキュメントを用意しました。
・bocchi.txt
(3) Colabにdataフォルダを作成して配置。
(4) Retrieverの準備。
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
# ドキュメントの準備
loader = DirectoryLoader("./data/", glob="*.txt", loader_cls=TextLoader)
docs = loader.load()
docs = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
).split_documents(docs)
# ベクトルストアの準備
vector = FAISS.from_documents(docs, OpenAIEmbeddings())
# Retrieverの準備
retriever = vector.as_retriever()
# 動作確認
retriever.invoke("ぼっち・ざ・ろっくのぼっちちゃんの本名は?")
[Document(page_content='後藤ひとり(ごとうひとり)\n\n秀華高校に通う女子。...', metadata={'source': 'data/bocchi.txt'}),
Document(page_content='長谷川あくび(はせがわあくび)\n\nメタルバンド...', metadata={'source': 'data/bocchi.txt'}),
Document(page_content='2号(にごう)\n\n美術大学の映像学科に在籍する女子。...', metadata={'source': 'data/bocchi.txt'}),
Document(page_content='山田リョウ(やまだりょう)\n\n下北沢高校に通う女子。...', metadata={'source': 'data/bocchi.txt'})]
(5) Retriever Toolの準備。
from langchain_core.tools.retriever import create_retriever_tool
# Retriever Toolの準備
retriever_tool = create_retriever_tool(
retriever,
"bocchi_search",
"ぼっち・ざ・ろっくに関する情報を検索します。ぼっち・ざ・ろっくに関する質問がある場合は、このツールを使用する必要があります。",
)
7-4. Agentの準備
(1) Toolsの準備。
# Toolsの準備
tools = [tavily_tool, retriever_tool]
(2) ToolsとLLMの準備。
from langchain_openai import ChatOpenAI
# Toolsの準備
tools = [tavily_tool, retriever_tool]
# LLMの準備
llm = ChatOpenAI(temperature=0)
(3) Agentの準備。
from langgraph.prebuilt import chat_agent_executor
# Agentの準備
agent_executor = chat_agent_executor.create_tool_calling_executor(
llm,
tools=tools
)
(3) 動作確認1。
オンライン検索が必要な場合は、「Tavility Tool」が呼ばれます。
# 動作確認
response = agent_executor.invoke(
{"messages": [("human", "2024年夏の日本で一番人気のアニメは?")]}
)
response["messages"][-1].content
(4) 動作確認2。
ローカル検索が必要な場合は、「Retriever Tool」が呼ばれます。
# 動作確認
response = agent_executor.invoke(
{"messages": [("human", "ぼっち・ざ・ろっくのぼっちちゃんの本名は?")]}
)
response["messages"][-1].content
8. Memory
これまでの「Chain」や「Agent」はステートレスでしたが、「Memory」を使うことで、「Chain」や「Agent」で過去の会話のやり取りを記憶することができます。過去の会話の記憶を使って、会話することができます。
Agentに「Memory」を追加する手順は、次のとおりです。
(1) Memoryの準備。
from langgraph.checkpoint.memory import MemorySaver
# Memoryの準備
memory = MemorySaver()
(2) Memory付きAgentの準備。
# Memory付きAgentの準備
agent_executor = chat_agent_executor.create_tool_calling_executor(
llm,
tools=tools,
checkpointer=memory
)
(3) コンフィグの準備。
# コンフィグの準備
config = {"configurable": {"thread_id": "abc123"}}
(2) 動作確認1。
# 動作確認
response = agent_executor.invoke(
{"messages": [("human", "ぼっち・ざ・ろっくのぼっちちゃんの本名は?")]},
config=config
)
response["messages"][-1].content
(3) 動作確認2。
過去の会話内容を覚えていることがわかります。
# 動作確認
response = agent_executor.invoke(
{"messages": [("human", "性格は?")]},
config=config
)
response["messages"][-1].content