LangChainとは?
LangChainは2022年にHarrison Chase氏によって開発され、現在はLangChain社によって管理されています。GitHubのスター数は138,000を超え、月間のダウンロード数は数百万回に達しています。活発なコミュニティがあり、Discordサーバーには数万人の開発者が参加しています。
LangChainのアーキテクチャは、以下のコンポーネントで構成されています:
- Models:LLMとのインターフェースを提供し、OpenAI、Anthropic、Google、Hugging Faceなどのプロバイダーを統一的に扱えます
- Prompts:プロンプトテンプレートの管理と最適化を行い、動的な値の埋め込みやプロンプトチェーンをサポートします
- Parsers:LLMの出力を構造化されたデータに変換し、JSON、XML、CSVなどの形式に対応します
- Documents:テキストデータを構造化し、メタデータと共に管理します
- Vector Stores:ベクトルデータベースと連携し、類似検索を高速に行います
- Embeddings:テキストをベクトルに変換し、セマンティック検索を可能にします
- Tools:外部APIやデータベースとの連携を抽象化し、エージェントが使用可能な機能を提供します
- Chains:複数の処理を論理的に連結し、複雑なワークフローを構築します
- Agents:ツールを使用して自律的にタスクを実行し、目標達成のための推論を行います
- Callbacks:処理の各段階でカスタムロジックを実行し、ロギングや監視を容易にします
LangChainはPythonとJavaScriptの両方で利用可能で、言語間で共通の概念とアーキテクチャを共有しています。Python版はより成熟しており、JavaScript版は急速に開発が進んでいます。
LangChainはAIエージェントを構築するためのオープンソースフレームワークです。PythonとJavaScriptで利用でき、138,000以上のGitHubスターを誇る人気のライブラリです。大規模言語モデル(LLM)と外部データ・ツールを連携させ、複雑なAIアプリケーションを簡単に構築できます。
主な特徴:
- LLM統合:OpenAI、Anthropic、Googleなど主要なLLMプロバイダーに対応
- チェーン構築:複数のLLM呼び出しを論理的に連結
- RAG対応:ベクトルデータベースと連携した検索拡張生成
- エージェント:ツール使用・推論・実行を自律的に行うAIエージェージェント
- 豊富な統合:50以上のツール・データソースに対応
GitHubリポジトリでは活発な開発が行われており、MITライセンスで商用利用も可能です。公式ドキュメントはpython.langchain.comで公開されています。
環境セットアップ
LangChainのインストールにはpipを使用します。開発環境にはPython 3.8以上が必要です。推奨される仮想環境のセットアップ方法:
# 仮想環境の作成
python -m venv langchain_env
source langchain_env/bin/activate # Linux/Mac
# langchain_envScriptsactivate # Windows
# LangChainと主要パッケージのインストール
pip install langchain langchain-openai langchain-community langchain-core
# 開発用の追加パッケージ
pip install jupyter ipython python-dotenv
環境変数の設定は、.envファイルを使用するのが一般的です:
# .envファイル
OPENAI_API_KEY=sk-proj-***
ANTHROPIC_API_KEY=sk-ant-***
LANGCHAIN_API_KEY=ls-***
LANGCHAIN_TRACING_V2=true
LangChain APIキーを設定すると、LangSmithによるトレーシングが有効になり、チェーンの実行を可視化・デバッグできます。LangSmithはLangChain公式の観測プラットフォームで、無料枠内で使用可能です。
LangChainのバージョン確認とアップデート:
# バージョン確認
python -c "import langchain; print(langchain.__version__)"
# アップデート
pip install --upgrade langchain langchain-openai langchain-community
まずLangChainをインストールします。Pythonの場合:
pip install langchain langchain-openai langchain-community
必要なAPIキーを環境変数に設定します:
export OPENAI_API_KEY=*** class="language-python">from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# LLMの初期化
llm = ChatOpenAI(model="gpt-4o", temperature=0)
# プロンプトテンプレート
prompt = ChatPromptTemplate.from_messages([
("system", "あなたは親切なAIアシスタントです。"),
("user", "{input}")
])
# 出力パーサー
output_parser = StrOutputParser()
# チェーンの構築
chain = prompt | llm | output_parser
# 実行
result = chain.invoke({"input": "LangChainについて説明してください"})
print(result)
このコードはLangChainの基本的な使用パターンを示しています。プロンプトテンプレート、LLM、出力パーサーをパイプ演算子(|)で連結し、簡潔にチェーンを構築できます。LangGraphを使うと、より複雑なステートマシンも定義可能です。公式ドキュメントの概念解説も参照してください。
LangChainはv0.1からv0.2へのアップデートで大幅なAPI変更がありました。古いコードを使用している場合は、マイグレーションガイドを参照してください。特にチェーンの作成方法がLCEL(LangChain Expression Language)に統合され、より直感的な記述が可能になりました。
RAG(検索拡張生成)の実装
RAG(Retrieval-Augmented Generation)は、LLMの知識限界を克服する重要なアプローチです。LLMは訓練データに含まれる情報しか知りませんが、RAGは外部のドキュメントを検索し、その内容をコンテキストとしてLLMに提供することで、最新情報や社内ドキュメントに基づいた回答を可能にします。
RAGのワークフローは以下のステップで構成されます:
- インデキシング:ドキュメントをチャンクに分割し、各チャンクをベクトル化してベクトルデータベースに保存
- 検索:ユーザーの質問をベクトル化し、ベクトルデータベースから類似度の高いチャンクを取得
- 生成:検索されたチャンクをコンテキストとしてLLMに渡し、回答を生成
LangChainはRAGの実装に必要なすべてのコンポーネントを提供しており、数行のコードで本格的なRAGシステムを構築できます。
ベクトルデータベースの選択肢:
- Chroma:軽量でセットアップが簡単、開発・プロトタイピングに最適
- Pinecone:マネージドサービス、スケーラビリティに優れる
- Weaviate:オープンソース、豊富な機能セット
- FAISS:Metaが開発、高速なベクトル検索
- Milvus:オープンソース、大規模データに対応
RAGは外部知識をLLMに提供する重要なパターンです。LangChainでRAGを実装します。
まず、ドキュメントをベクトル化して保存:
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
# ドキュメントの読み込み
loader = TextLoader("./documentsdocuments/sample.txt")
documents = loader.load()
# テキスト分割
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
splits = text_splitter.split_documents(documents)
# ベクトル化と保存
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
documents=splits,
embedding=embeddings,
persist_directory="./chroma_db"
)
テキスト分割はRAGの精度に大きく影響します。RecursiveCharacterTextSplitterは段落や文単位で分割し、文脈を保持しやすい方法です。chunk_sizeとchunk_overlapは検索対象のドキュメントに合わせて調整してください。RAGチュートリアルでは詳細な実装例が紹介されています。
ドキュメントローダーはテキスト以外にも、PDF、Markdown、Webページなど多くのフォーマットに対応しています。例えば、PDFから読み込む場合は:
from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader("./documents/report.pdf")
documents = loader.load()
Webページから読み込む場合は:
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://example.com/article")
documents = loader.load()
検索と生成のチェーン構築:
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
# 検索チェーンの準備
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# プロンプトテンプレート
prompt = ChatPromptTemplate.from_template("""
以下の文脈を参考にして質問に答えてください:
文脈:
{context}
質問:{input}
""")
# ドキュメント結合チェーン
document_chain = create_stuff_documents_chain(llm, prompt)
# 検索チェーン
retrieval_chain = create_retrieval_chain(retriever, document_chain)
# 実行
result = retrieval_chain.invoke({"input": "この文書の要点を教えて"})
print(result["answer"])
create_retrieval_chainは検索と生成を一つのチェーンに統合するヘルパー関数です。retriever.as_retriever()で検索オブジェクトを取得し、search_kwargsで取得するドキュメント数を指定します。より高度なRAG実装では、高度なRAGパターンも参照してください。
RAGの精度を向上させるための高度なテクニックとして、以下の方法があります:
- セマンティックチャンキング:文脈に基づいて意味的に適切な境界で分割する
- ハイブリッド検索:キーワード検索とベクトル検索を組み合わせる
- 再ランク:検索結果をLLMで再評価し、関連性を高める
- マルチクエリ:質問を複数の検索クエリに拡張し、検索範囲を広げる
AIエージェントの構築
AIエージェントは、目標を達成するためにツールを自律的に使用するプログラムです。従来のプログラムが固定された手順でタスクを実行するのに対し、エージェントは実行時に最適なアクションを選択し、状況に応じて計画を修正します。
LangChainのエージェントアーキテクチャは、以下の要素で構成されています:
- Agent:推論エンジンであり、現在の状態と利用可能なツールに基づいて次のアクションを決定
- Tools:外部世界とのインターフェースであり、API呼び出し、データベースクエリ、ファイル操作などを抽象化
- AgentExecutor:エージェントの実行を管理し、ツール呼び出し、結果の解析、終了条件のチェックを処理
- Memory:会話の文脈や中間結果を保持し、エージェントが過去の履歴を参照可能にする
エージェントの種類:
- ReAct Agent:推論とアクションを交互に実行し、思考プロセスを明示
- Tool Calling Agent:ツール呼び出しに最適化されたプロンプトを使用し、効率的なツール選択
- Structured Chat Agent:構造化された出力を生成し、複雑なタスクに対応
- Self-Critique Agent:自己評価を行い、出力の品質を向上
エージェントの実用例として、カスタマーサポート、データ分析、コンテンツ生成、自動化タスクなどが挙げられます。LangChainのエージェントは、これらのユースケースを柔軟にサポートします。
エージェントはツールを使って自律的にタスクを実行します。検索、計算、API呼び出しなどのツールを定義します。
ツールの定義:
from langchain.tools import Tool
from langchain_community.utilities import SerpAPIWrapper
# 検索ツール
search = SerpAPIWrapper()
search_tool = Tool(
name="Search",
func=search.run,
description="最新情報を検索する"
)
# 計算ツール
from langchain.chains import LLMMathChain
math_chain = LLMMathChain.from_llm(llm)
math_tool = Tool(
name="Calculator",
func=math_chain.run,
description="数式を計算する"
)
tools = [search_tool, math_tool]
ツールのdescriptionはエージェントがツールを選択する際に重要です。具体的に何ができるか、どのような入力を受け付けるかを明確に記述してください。エージェントチュートリアルでは多くのツール例が紹介されています。
カスタムツールを作成することも簡単です。例えば、天気予報を取得するツール:
import requests
def get_weather(location: str) -> str:
"""指定された場所の天気を取得する"""
# 実際には天気APIを呼び出す
response = requests.get(f"https://api.weather.com/current?location={location}")
return response.json()["description"]
weather_tool = Tool(
name="Weather",
func=get_weather,
description="指定された場所の現在の天気を取得する。引数は場所名(例:東京、大阪)"
)
tools.append(weather_tool)
エージェントの初期化と実行:
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
# エージェント用プロンプト
prompt = ChatPromptTemplate.from_messages([
("system", "あなたは役立つAIアシスタントです。利用可能なツールを使って質問に答えてください。nn利用可能なツール:n{tools}nnツールの使用形式:n{{"tool_name": , "tool_input": }}"),
("user", "{input}"),
("placeholder", "{agent_scratchpad}")
])
# エージェントの作成
agent = create_tool_calling_agent(llm, tools, prompt)
# エージェントエグゼキューターの初期化
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# 実行
result = agent_executor.invoke({"input": "今日の天気と25×15の計算結果を教えて"})
print(result["output"])
create_tool_calling_agentはツール呼び出しに最適化されたエージェントを作成します。AgentExecutorはエージェントの実行を管理し、verbose=Trueで実行過程を確認できます。より複雑なエージェントでは、LangGraphを使ってステートマシンを定義することも可能です。
エージェントの実行制御にはいくつかのオプションがあります:
- max_iterations:エージェントの最大反復回数を制限する
- max_execution_time:最大実行時間を設定する
- early_stopping_method:早期停止の条件を設定する
- handle_parsing_errors:ツール出力の解析エラーを処理する
失敗パターンと対策
LangChainを使用する際、開発者はいくつかの共通の課題に直面します。これらの課題を理解し、適切な対策を講じることで、より堅牢で効率的なAIアプリケーションを構築できます。
LangChainのコミュニティでは、これらの課題に関する議論や解決策が活発に共有されています。GitHubのIssuesやDiscordサーバーで類似の問題を検索すると、多くの場合、既に解決策が見つかります。
デバッグにはLangSmithが強力なツールです。LangSmithはチェーンの実行を可視化し、各ステップの入力・出力、実行時間、トークン使用量などを確認できます。これにより、ボトルネックの特定やエラーの原因究明が容易になります。
また、LangChainのロギング機能を活用することも重要です。詳細なログを有効にすることで、内部的な処理を追跡し、問題の早期発見が可能になります。
LangChainを使用する際によくある問題と解決策:
トークン制限エラー
長いドキュメントを処理する際、LLMのコンテキストウィンドウを超えるとエラーが発生します。対策:
- 適切なチャンキング戦略を適用する
- チャンクサイズを小さくする
- 長いドキュメントは要約してから処理する
- コンテキストウィンドウの大きいLLMモデルを使用する
チャンキング戦略にはいくつかの種類があります:
- 固定サイズチャンキング:指定した文字数で均等に分割する
- 再帰的チャンキング:段落、文、単語の順に分割を試みる
- セマンティックチャンキング:文脈に基づいて意味的に適切な境界で分割する
RAGチャンキング戦略の解説記事では、各戦略の詳細と選択基準が解説されています。
検索精度が低い
RAGで関連性の低いドキュメントが返される問題。対策:
- チャンキング戦略を調整する(セマンティックチャンキングを試す)
- 埋め込みモデルを変更する(より高品質なモデルを使用)
- ハイブリッド検索を試す(キーワード検索とベクトル検索の組み合わせ)
- 再ランクを実装する(検索結果をLLMで再評価)
高度なRAGパターンでは再ランクやハイブリッド検索の実装例が紹介されています。
ハイブリッド検索の実装例:
from langchain.retrievers import EnsembleRetriever
# キーワード検索(BM25)
from langchain_community.retrievers import BM25Retriever
bm25_retriever = BM25Retriever.from_documents(splits)
# ベクトル検索
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# アンサンブル検索(ハイブリッド)
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, vector_retriever],
weights=[0.5, 0.5]
)
エージェントがツールを適切に選択しない
エージェントが間違ったツールを呼び出す、またはツールを使わない問題。対策:
- ツールのdescriptionを明確にする
- ツールの数を減らす(関連性の高いツールのみ提供)
- プロンプトを調整する(ツール使用の指示を強化)
- few-shot例を追加提供する
ツールのdescriptionはエージェントのツール選択精度に直接影響します。以下の点に注意してください:
- ツールが何をするかを簡潔に説明する
- どのような入力を受け付けるかを明示する
- どのような出力を返すかを説明する
- 使用例を含める
パフォーマンス問題
応答時間が長い、またはコストが高い問題。対策:
- ベクトルストアのインデックスを最適化する
- キャッシュを有効にする(LLMの応答をキャッシュ)
- バッチ処理を使用する(複数のリクエストをまとめて処理)
- 安価なLLMモデルを使用する(タスクに応じてモデルを選択)
- ストリーミング出力を有効にする(ユーザー体験向上)
LangChainにはキャッシュ機能が組み込まれています。例えば、LLMの応答をキャッシュするには:
from langchain.cache import InMemoryCache
llm.cache = InMemoryCache()
ストリーミング出力を有効にするには:
for chunk in chain.stream({"input": "LangChainについて説明してください"}):
print(chunk, end="", flush=True)
まとめ
LangChainはAIエージェント構築のための強力なフレームワークです。基本的なチェーンからRAG、ツール使用エージェントまで、段階的に学習できます。豊富な統合と活発なコミュニティにより、複雑なAIアプリケーションを短期間で構築可能です。
LangChainの学習リソース:
- 公式ドキュメント - 包括的なAPIリファレンスとチュートリアル
- GitHubリポジトリ - ソースコードと問題報告
- Discordコミュニティ - 質問と情報共有
LangChainを活用して、ビジネス課題を解決するAIエージェントを構築してみましょう。RAGチャンキング戦策の解説記事やHuman-in-the-loop設計ガイドもあわせてご覧ください。
この記事を読んで導入イメージが固まってきた方へ
UravationではAIエージェント導入の研修・コンサルを行っています。
