第2章 LangChain基礎
更新日:2025年12月16日
1. LangChainの概要
LangChainは、LLMを活用したアプリケーションを構築するためのオープンソースフレームワークである。2022年10月にHarrison Chaseによって公開され、急速に普及した。LangChainは、LLMの入出力を抽象化し、複雑なワークフローを簡潔に記述するための統一的なインターフェースを提供する。
1.1 アーキテクチャ
LangChain v0.3(2024年時点)のパッケージ構成は以下の通りである。
Table 1. LangChainのパッケージ構成
| パッケージ | 説明 | 用途 |
|---|---|---|
| langchain-core | 基盤となる抽象クラスとLCEL | 必須 |
| langchain | チェーン、エージェントの実装 | アプリ開発 |
| langchain-community | サードパーティ統合 | 各種サービス連携 |
| langchain-openai | OpenAI統合 | GPTモデル利用 |
| langgraph | グラフベースエージェント | 高度なエージェント |
| langsmith | 観測・評価プラットフォーム | デバッグ・監視 |
Fig 1. インストール例
pip install langchain langchain-openai langchain-community
環境変数にOpenAI APIキーを設定する。
export OPENAI_API_KEY="sk-..."
1.2 主要コンポーネント
LangChainの主要コンポーネントは以下の6つに分類される。
Table 2. LangChainの主要コンポーネント
| コンポーネント | 説明 |
|---|---|
| Model I/O | LLMへの入出力を管理(プロンプト、モデル呼び出し、出力解析) |
| Retrieval | 外部データの取得(ドキュメントローダー、ベクトルストア、検索) |
| Memory | 会話履歴や状態の管理 |
| Chains | 複数の処理を連結したワークフロー |
| Agents | LLMが動的にツールを選択・実行 |
| Callbacks | 処理のフックとログ記録 |
本章ではModel I/O、Memory、Toolsの基礎を解説する。Retrieval(RAG)は第4章、Chains/AgentsはLCEL(第3章)およびLangGraph(第7章)で詳しく扱う。
2. Model I/O
Model I/Oは、LLMへの入出力を抽象化するコンポーネント群である。プロンプトの構築、モデル呼び出し、出力の解析という3つの要素から構成される。
2.1 Chat Models
Chat Modelsは、対話形式のLLMを抽象化したクラスである。OpenAI、Anthropic、Google、ローカルモデルなど、様々なプロバイダーのモデルを統一的なインターフェースで利用できる。
Fig 2. ChatOpenAIの基本的な使用方法
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
# モデルの初期化
model = ChatOpenAI(model="gpt-4o", temperature=0)
# メッセージの作成
messages = [
SystemMessage(content="あなたは親切なアシスタントです。"),
HumanMessage(content="Pythonの特徴を3つ教えてください。")
]
# 呼び出し
response = model.invoke(messages)
print(response.content)
LangChainのChat Modelsは、invoke()、stream()、batch()といった標準メソッドを提供する。これはRunnable インターフェースに基づいており、LCEL(第3章)でチェーンを構築する際の基盤となる。
Table 3. Chat Modelsの主要メソッド
| メソッド | 説明 | 戻り値 |
|---|---|---|
| invoke() | 同期的に1回呼び出し | AIMessage |
| stream() | ストリーミング出力 | Iterator[AIMessageChunk] |
| batch() | 複数入力を並列処理 | List[AIMessage] |
| ainvoke() | 非同期呼び出し | AIMessage |
2.2 Prompt Templates
Prompt Templatesは、動的なプロンプトを生成するためのテンプレート機能である。変数を埋め込んだテンプレートを定義し、実行時に値を注入してプロンプトを生成する。
Fig 3. ChatPromptTemplateの使用例
from langchain_core.prompts import ChatPromptTemplate
# テンプレートの定義
prompt = ChatPromptTemplate.from_messages([
("system", "あなたは{language}の専門家です。"),
("human", "{topic}について説明してください。")
])
# 変数を埋め込んでメッセージを生成
messages = prompt.invoke({
"language": "Python",
"topic": "リスト内包表記"
})
print(messages)
ChatPromptTemplateは、from_messages()で複数のメッセージを含むテンプレートを作成できる。{変数名}の形式でプレースホルダーを定義し、invoke()時に辞書で値を渡す。
Fig 4. MessagesPlaceholderによる会話履歴の挿入
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
prompt = ChatPromptTemplate.from_messages([
("system", "あなたは親切なアシスタントです。"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}")
])
# 会話履歴を含めて呼び出し
messages = prompt.invoke({
"history": [
HumanMessage(content="こんにちは"),
AIMessage(content="こんにちは!何かお手伝いできますか?")
],
"input": "Pythonについて教えて"
})
MessagesPlaceholderを使うと、会話履歴のようなメッセージのリストをテンプレートに挿入できる。これはMemoryと組み合わせて使用することが多い。
2.3 Output Parsers
Output Parsersは、LLMの出力を構造化データに変換するためのコンポーネントである。LLMの出力は文字列であるが、実際のアプリケーションでは辞書やオブジェクトとして扱いたい場合が多い。
Fig 5. StrOutputParserの使用例
from langchain_core.output_parsers import StrOutputParser
parser = StrOutputParser()
# AIMessageから文字列を抽出
result = parser.invoke(response)
print(result) # 文字列として出力
Fig 6. JsonOutputParserの使用例
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.pydantic_v1 import BaseModel, Field
# 出力スキーマの定義
class BookInfo(BaseModel):
title: str = Field(description="本のタイトル")
author: str = Field(description="著者名")
year: int = Field(description="出版年")
parser = JsonOutputParser(pydantic_object=BookInfo)
# パーサーのformat_instructionsをプロンプトに含める
prompt = ChatPromptTemplate.from_messages([
("system", "あなたは書籍情報を抽出するアシスタントです。"),
("human", "以下の書籍情報をJSON形式で出力してください。\n{format_instructions}\n\n書籍: {book}")
])
# パーサーの指示を取得
format_instructions = parser.get_format_instructions()
JsonOutputParserはPydanticモデルと組み合わせることで、型安全な出力を得ることができる。get_format_instructions()は、LLMに対してどのような形式で出力すべきかを説明するテキストを生成する。
3. Memory
Memoryは、会話の履歴や状態を保持するためのコンポーネントである。LLM自体はステートレスであり、過去の会話を記憶していない。Memoryを使用することで、文脈を考慮した対話が可能になる。
3.1 会話履歴管理
最も基本的なMemoryの実装は、会話履歴をリストとして保持するものである。LangChainでは、ChatMessageHistoryクラスを使用する。
Fig 7. ChatMessageHistoryの使用例
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.messages import HumanMessage, AIMessage
# 履歴の初期化
history = ChatMessageHistory()
# メッセージの追加
history.add_user_message("こんにちは")
history.add_ai_message("こんにちは!何かお手伝いできますか?")
history.add_user_message("今日の天気は?")
# 履歴の取得
print(history.messages)
# [HumanMessage(...), AIMessage(...), HumanMessage(...)]
会話が長くなると、コンテキストウィンドウの制限に達する可能性がある。この問題に対処するため、LangChainは様々なMemory実装を提供している。
3.2 Memory Types
LangChainには複数のMemory実装があり、ユースケースに応じて選択できる。
Table 4. Memory Typesの比較
| Memory Type | 説明 | 特徴 |
|---|---|---|
| ConversationBufferMemory | 全履歴を保持 | シンプル、長い会話で問題 |
| ConversationBufferWindowMemory | 直近N回の会話を保持 | 固定サイズ、古い履歴を破棄 |
| ConversationSummaryMemory | 履歴を要約して保持 | トークン節約、詳細を失う |
| ConversationTokenBufferMemory | トークン数で制限 | 正確なトークン管理 |
Fig 8. ConversationBufferWindowMemoryの使用例
from langchain.memory import ConversationBufferWindowMemory
# 直近3回の会話を保持
memory = ConversationBufferWindowMemory(k=3, return_messages=True)
memory.save_context(
{"input": "こんにちは"},
{"output": "こんにちは!"}
)
memory.save_context(
{"input": "名前は?"},
{"output": "私はAIアシスタントです。"}
)
# 履歴の取得
history = memory.load_memory_variables({})
print(history["history"])
実際のアプリケーションでは、セッションごとに履歴を永続化する必要がある。Redis、PostgreSQL、MongoDBなどのバックエンドを使用したMemory実装も提供されている。
4. Tools
Toolsは、LLMが外部の機能やAPIを呼び出すためのインターフェースである。LLMは学習データに基づいて応答を生成するが、リアルタイムの情報取得、計算、データベース操作などは行えない。Toolsを使用することで、LLMの能力を拡張できる。
Fig 9. カスタムToolの定義
from langchain_core.tools import tool
@tool
def get_word_count(text: str) -> int:
"""テキストの単語数をカウントする。
Args:
text: カウント対象のテキスト
Returns:
単語数
"""
return len(text.split())
# ツールの情報
print(get_word_count.name) # "get_word_count"
print(get_word_count.description) # docstringから生成
print(get_word_count.args_schema.schema()) # 引数のJSONスキーマ
@toolデコレータを使用すると、通常のPython関数をLangChainのToolとして登録できる。docstringはツールの説明として使用され、LLMがどのツールを使うべきか判断する際の参考になる。
Table 5. LangChainの組み込みTools(例)
| Tool | 説明 | パッケージ |
|---|---|---|
| DuckDuckGoSearchRun | Web検索 | langchain-community |
| WikipediaQueryRun | Wikipedia検索 | langchain-community |
| PythonREPLTool | Pythonコード実行 | langchain-experimental |
| ShellTool | シェルコマンド実行 | langchain-community |
Toolsは単体では機能せず、Agent(第6章)やLangGraph(第7章)と組み合わせて使用する。Agentは、ユーザーの入力に基づいてどのToolを呼び出すかをLLMが判断し、実行結果を受け取ってさらに処理を続けるという自律的な動作を実現する。
本コンテンツは2025年12月時点の情報に基づいて作成されています。LangChainは活発に開発が進められており、APIや機能が変更される可能性があります。最新情報は公式ドキュメント(https://python.langchain.com/docs/)をご確認ください。