LangChainは、LLM(大規模言語モデル)を活用したアプリケーション開発を支援するオープンソースライブラリです。この記事では、LangChainを用いて会話型エージェントを作成する方法を、具体的なコード例とともに解説します。
- 1. 環境構築
- 2. LangChainの基本: Chat Modelとの連携
- 3. 会話型エージェントの構築: メモリの導入
- 4. エージェントの拡張: ツールとの連携
- 5. より高度なエージェント
- まとめ
1. 環境構築
まず、LangChainを使用するための環境を準備します。
1.1. 必要なライブラリ
Pythonのpipを用いて、LangChainとOpenAIのライブラリをインストールします。
pip install langchain openai
1.2. APIキーの設定 (OpenAIの例)
OpenAIのAPIを利用するには、APIキーが必要です。OpenAIのウェブサイトでAPIキーを取得し、環境変数に設定するか、コード内で直接指定します。
推奨: 環境変数に設定する場合
export OPENAI_API_KEY="your-openai-api-key"
.envファイルを作成して、その中にOPENAI_API_KEY="your-openai-api-key"を記述してもよいです。
set OPENAI_API_KEY="your-openai-api-key"
$env:OPENAI_API_KEY="your-openai-api-key"
永続的に設定したい場合はシステム環境変数に設定します。
コード内で直接指定する場合
自身の身が利用するテスト環境などでは、後続のコード内で直接APIキーを指定しても問題ありません。それ以外の場合は、セキュリティの観点から、APIキーはコードに直接書き込まず、環境変数から読み込むことをおすすめします。
openai_api_key = "your-openai-api-key"
2. LangChainの基本: Chat Modelとの連携
LangChainの中核機能の一つは、LLMとの連携です。ここでは、OpenAIのChat Modelを使用する基本的な例を示します。
2.1. Chat Modelの初期化
from langchain.chat_models import ChatOpenAI from langchain.schema import HumanMessage, AIMessage, SystemMessage # Chat Modelの初期化 (環境変数からAPIキーを読み込む場合) chat_model = ChatOpenAI(temperature=0.7) # Chat Modelの初期化 (APIキーを直接指定する場合) # chat_model = ChatOpenAI(openai_api_key=openai_api_key, temperature=0.7)
ChatOpenAIクラスはOpenAIのチャットモデルを利用するためのクラスです。temperatureパラメータは、出力の多様性を調整します。値を小さくするほど、出力はより確定的になります。
2.2. メッセージの送受信
# HumanMessage: ユーザーからのメッセージ # AIMessage: AI(モデル)からのメッセージ # SystemMessage: システムの振る舞いを指定するメッセージ(オプション) messages = [ SystemMessage(content="あなたは親切なアシスタントです。"), HumanMessage(content="LangChainについて教えてください。") ] response = chat_model.predict_messages(messages) print(response.content)
predict_messages メソッドにメッセージのリストを渡して、モデルから応答を取得します。応答はAIMessageオブジェクトとして返され、そのcontent属性にテキストが含まれます。
3. 会話型エージェントの構築: メモリの導入
単純なQ&Aだけでなく、会話の文脈を理解するエージェントを構築するために、LangChainのメモリ機能を活用します。
3.1. ConversationBufferMemory の利用
ConversationBufferMemoryは、会話履歴を保持する最もシンプルなメモリクラスです。
from langchain.memory import ConversationBufferMemory from langchain.chains import ConversationChain memory = ConversationBufferMemory() conversation = ConversationChain( llm=chat_model, memory=memory ) response1 = conversation.run("LangChainとは何ですか?") print(response1) response2 = conversation.run("それを使って何ができますか?") print(response2)
ConversationChainにより、LLMとメモリを組み合わせた基本的な会話フローを管理します。ここで、runメソッドは、入力テキストをLLMに渡し、応答を返し、会話履歴をメモリに保存します。
3.2. メモリの内容確認
print(memory.buffer)
memory.bufferの中身を確認することにより、ConversationBufferMemoryに保存されている会話の履歴を確認できます。
4. エージェントの拡張: ツールとの連携
LangChainの強力な機能の一つは、エージェントが外部ツールを利用できることです。これにより、LLMの能力を拡張し、より複雑なタスクを実行できます。
4.1. カスタムツールの作成
Python関数をツールとして定義し、エージェントに組み込むことができます。
from langchain.agents import tool @tool def calculate_square(number: int) -> int: """与えられた数値の二乗を計算します。""" return number ** 2 # ツールのリスト (複数のツールを定義可能) tools = [calculate_square]
@toolデコレータを使用することにより、関数がLangChainのツールとして認識されます。ツールのdescription(docstring)は、エージェントがツールを適切に使用するために重要です。
4.2. エージェントの初期化と実行
from langchain.agents import initialize_agent, AgentType agent = initialize_agent( tools, chat_model, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True ) response = agent.run("12の二乗は?") print(response)
initialize_agent関数で、ツール、LLM、エージェントタイプを指定してエージェントを初期化します。ここで指定しているAgentType.ZERO_SHOT_REACT_DESCRIPTIONは、ツールのdescriptionに基づいてエージェントが行動を決定するタイプです。また、verbose=Trueにすると、エージェントの思考過程(中間ステップ)が表示されます。
5. より高度なエージェント
LangChainは、より高度なエージェントタイプやカスタマイズオプションを提供しています。
5.1. Structured Tools の利用
複数の引数を取るツールを定義する場合は、StructuredToolを使用します。
from langchain.tools import StructuredTool def multiply(a: int, b: int) -> int: """2つの数値を掛け合わせます。""" return a * b multiply_tool = StructuredTool.from_function(multiply) tools = [multiply_tool] # 複数のツールをリストにまとめる # Structured Toolsを利用するエージェントを初期化 agent = initialize_agent( tools, chat_model, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, # エージェントタイプを変更 verbose=True ) response = agent.run("3と7を掛けた結果は?") print(response)
5.2 AgentTypeの変更
上記のコードに出てくるAgentTypeを変更することで、エージェントが利用できる機能や推論方法が変わります。
| AgentType | 説明 |
|---|---|
ZERO_SHOT_REACT_DESCRIPTION |
ツールの説明(description)のみに基づいて、どのツールを使用するかを決定し、単一の入力を受け取ります。 |
STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION |
複数のツールをより適切に活用できるように設計されています。StructuredToolと共に使用され、複数の入力をツールに渡すことができます。 |
OPENAI_FUNCTIONS |
OpenAIの関数呼び出し機能に最適化されており、モデルが関数呼び出しを行うかどうか、またどの関数を呼び出すかをより適切に決定できます。より少ないプロンプトで推論できるため、他のエージェントタイプよりも高速で、コストが低く済む場合があります。ただし、OpenAIの関数呼び出しに対応したモデルでのみ動作します。 |
CONVERSATIONAL_REACT_DESCRIPTION |
会話型のエージェントを構築するために設計されています。ConversationBufferMemoryと組み合わせて使用することで、会話の履歴を考慮しながら、ツールの使用や応答の生成を行うことができます。 |
5.3 複数のツール利用
複数のツールを登録して複雑な処理を行う例を紹介します。
# ツールを定義 @tool def add(a: int, b: int) -> int: """2つの数値を足し合わせる""" return a + b @tool def power(a:int, b:int) -> int: """aをb乗する""" return a**b # StructuredToolとして定義 add_tool = StructuredTool.from_function(add) power_tool = StructuredTool.from_function(power) tools = [add_tool, power_tool] agent = initialize_agent( tools, chat_model, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True ) response = agent.run("2と3を足した結果を5乗してください") print(response)
まとめ
LangChainは、LLMの能力を最大限に引き出し、高度なAIアプリケーションを構築するための強力なフレームワークです。この記事で紹介した基本機能を足がかりに、より複雑なエージェントの開発に挑戦してみてください。
参考ドキュメント
- LangChain公式ドキュメント: https://js.langchain.com/docs/introduction/
[PR]