強力な自動タスクを実行するための LangChain エージェントの使い方
Published on
言語モデルと自動化の魅力的な世界において、LangChain エージェントはイノベーションの象徴として際立ち、開発者やテック愛好家が、まるでSF小説から飛び出してきたかのような洗練された自動タスクを作成できるようにします。LangChain エージェントの領域に飛び込みたいが、どこから始めればよいかわからない場合は、正しい場所にいます。このガイドでは、そのプロセスを解説し、アクセスしやすく、わかりやすくします。ですので、コーヒーを飲んで、一緒にこのエキサイティングな旅に出発しましょう。
LangChain エージェントの使い方:クイックスタート
エージェントフレームワークを最良に理解するためには、2つのツールを持つエージェントを構築しましょう:オンラインでの検索を行うためのものと、インデックスに読み込んだ特定のデータを検索するためのものです。
これは、LLMと検索に関する知識を前提としています。これらのセクションをすでに探求していない場合は、そうすることをお勧めします。
セットアップ:LangSmith
定義上、エージェントはユーザー向けの出力を返す前に、自己決定的で、入力に依存する手順のシーケンスを実行します。これにより、これらのシステムのデバッグが特に難しく、観測が特に重要になります。LangSmith はそのようなケースに特に役立ちます。
LangChain でビルドする際は、すべてのステップが自動的に LangSmith でトレースされます。LangSmith を設定するには、次の環境変数を設定する必要があります:
export LANGCHAIN_TRACING_V2="true"
export LANGCHAIN_API_KEY="<your-api-key>"
ツールの定義
まず最初に使用したいツールを作成する必要があります。2つのツールを使用します:オンラインで検索するための Tavily(Tavily という名前の検索エンジンを使用)と、読み込んだローカルインデックスを対象とする検索を行うためのリトリーバー。
- Tavily
LangChain には、Tavily 検索エンジンを簡単に使用するための組み込みツールがあります。API キーが必要ですが、無料のティアがあります。キーがない場合や作成したくない場合は、このステップを無視することもできます。
API キーを作成したら、次のようにエクスポートする必要があります:
export TAVILY_API_KEY="..."
from langchain_community.tools.tavily_search import TavilySearchResults
search = TavilySearchResults()
search.invoke("what is the weather in SF")
- リトリーバー
自分自身のデータに対するリトリーバーを作成します。ここで各ステップの詳細な説明を読むことができます。
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
loader = WebBaseLoader("https://docs.smith.langchain.com/overview")
docs = loader.load()
documents = RecursiveCharacterTextSplitter(
chunk_size=1000, chunk_overlap=200
).split_documents(docs)
vector = FAISS.from_documents(documents, OpenAIEmbeddings())
retriever = vector.as_retriever()
retriever.get_relevant_documents("how to upload a dataset")[0]
これで、リトリーバーに対して検索を行うインデックスが準備できたので、簡単にツールに変換できます(エージェントが正しく使用するために必要な形式です)。
from langchain.tools.retriever import create_retriever_tool
retriever_tool = create_retriever_tool(
retriever,
"langsmith_search",
"LangSmith に関する情報を検索します。LangSmith に関する質問については、このツールを使用する必要があります。",
)
ツール
これで両方のツールを作成したので、下流で使用するツールのリストを作成できます。
tools = [search, retriever_tool]
LangChain エージェントの作成方法
ツールを定義したので、エージェントを作
成できます。ここでは OpenAI Functions エージェントを使用します。このタイプのエージェントについての詳細な情報は、このガイドを参照してください。
まず、エージェントをガイドする LLM を選択します。
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
次に、エージェントをガイドするプロンプトを選択します。
from langchain import hub
# 使用するプロンプトを取得します。これを変更することができます!
prompt = hub.pull("hwchase17/openai-functions-agent")
prompt.messages
さて、LLM、プロンプト、およびツールでエージェントを初期化できます。エージェントは入力を受け取り、どのアクションを実行するかを決定する責任があります。重要なのは、エージェントがこれらのアクションを実行しないことです。これはエージェントエグゼキュータによって行われます(次のステップ)。
from langchain.agents import create_openai_functions_agent
agent = create_openai_functions_agent(llm, tools, prompt)
最後に、エージェント(脳)とツールを AgentExecutor の中で組み合わせます(これにより、エージェントが繰り返し呼び出され、ツールが実行されます)。これらのコンポーネントの考え方についての詳細については、コンセプトガイドを参照してください。
from langchain.agents import AgentExecutor
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
エージェントを実行する
これで、いくつかのクエリでエージェントを実行できます!今のところ、これらはすべてステートレスクエリです(以前のインタラクションを覚えません)。
agent_executor.invoke({"input": "hi!"})
agent_executor.invoke({"input": "how can langsmith help with testing?"})
agent_executor.invoke({"input": "what's the weather in sf?"})
メモリを追加する
前述のように、このエージェントはステートレスです。つまり、以前のインタラクションを覚えません。メモリを与えるには、以前の chat_history を渡す必要があります。注意:これは、使用しているプロンプトのために chat_history と呼ばれる必要があるためです。別のプロンプトを使用する場合は、変数名を変更できます。
# ここでは、chat_history の最初のメッセージなので、空のメッセージリストを渡しています
agent_executor.invoke({"input": "hi! my name is bob", "chat_history": []})
from langchain_core.messages import AIMessage, HumanMessage
agent_executor.invoke(
{
"chat_history": [
HumanMessage(content="hi! my name is bob"),
AIMessage(content="Hello Bob! How can I assist you today?"),
],
"input": "what's my name?",
}
)
これらのメッセージを自動的に追跡する場合は、これを RunnableWithMessageHistory でラップできます。これの使用方法についての詳細については、このガイドを参照してください。
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
message_history = ChatMessageHistory()
agent_with_chat_history = RunnableWithMessageHistory(
agent_executor,
# これは、ほとんどの実世界のシナリオで、セッション ID が必要なためです
# ここでは単純なインメモリ ChatMessageHistory を使用しているため、実際にはあまり使用されません
lambda session_id: message_history,
input_messages_key="input",
history_messages_key="chat_history",
)
agent_with_chat_history.invoke(
{"input": "hi! I'm bob"},
# これは、ほとんどの実世界のシナリオで、セッション ID が必要なためです
# ここでは単純なインメモリ ChatMessageHistory を使用しているため、実際にはあまり使用されません
config={"configurable": {"session_id": "<foo>"}},
)
LangChain エージェントの種類
エージェントの種類
LangChain エージェントの世界では、多様性が鍵です。これらのエージェントはさまざまな味わいで、それぞれ異なるタスクや能力に適しています。エージェントの種類の微妙な世界を探求し、意図されたモデルタイプ、チャット履歴のサポート、マルチ入力ツール、並行関数呼び出し、および必要なモデルパラメータを分解しましょう。これらのカテゴリを理解することで、プロジェクトに最適なエージェントを選択できます。
-
OpenAI Tools: 最新の OpenAI モデル(1106以降)に最適化された先進的なエージェント。チャットのインタラクションを処理し、マルチ入力ツールをサポートし、並行関数呼び出しを実行するよう設計されています。 'tools' モデルパラメータが必要です。OpenAI の最新の提供を活用している方に最適です。
-
OpenAI Functions: OpenAI または OpenAI の関数呼び出し機能を模倣したファインチューンされたオープンソースモデル用にカスタマイズされたエージェント。このエージェントは、関数呼び出しがタスクの中心であるシナリオに特に適しています。最新のモデルでは、新しいモデルのためにツールを優先し、OpenAI はこのアプローチを廃止しました。
-
XML: このエージェントは、XML を操作するのに長けたモデル(Anthropic のような)に最適化されています。このエージェントは、LLM(チャットモデルではありません)に向けられており、チャット履歴をサポートし、単一の文字列入力を必要とする構造化ツールと最適に機能します。XML に習熟したモデルと一緒に作業する場合は、これを選択してください。
-
Structured Chat: マルチ入力ツールをサポートする柔軟なエージェントで、複雑なツールの相互作用に必要な機能です。これは、複雑なツールの相互作用を必要とするプロジェクトに最適であり、追加のモデルパラメータを必要としません。
-
JSON Chat: JSON に優れたモデル向けに設計された、チャットアプリケーション向けのエージェント。JSON フレンドリーモデルの操作を簡素化し、チャットベースのアプリケーションの開発を効率化します。
-
ReAct: シンプルですが効果的なエージェントで、基本的な LLM アプリケーション向けに設計されています。直感的な実装が必要なシンプルなモデルの開始点として優れています。
-
Self Ask With Search: 単一の検索ツールを持つシンプルなモデルに最適なエージェントであり、簡潔で焦点を絞ったツールセットが必要なプロジェクトに適しています。
各エージェントタイプには独自の強みがあり、プロジェクトの特定の要件に合わせてエージェントを選択することが重要です。チャット履歴のサポート、マルチ入力ツール、または並行関数呼び出しの必要性を考慮すると、そのニーズに合ったエージェントがあります。タスクの複雑さ、選択した言語モデルの機能、アプリケーションが処理するインタラクションの性質を考慮し、これらの要因を正しくエージェントタイプに適用することで、プロジェクトでの LangChain エージェントのフルポテンシャルを引き出し、革新的なソリューションと効率的なワークフローの道を切り開くことができます。
LangChain エージェントの微妙な点を探求することで、異なるエージェントタイプの理解と実践的なアプリケーションを提供することを目指しています。詳細なサンプルコードとシナリオを探求することで、プロジェクトのニーズに最適なエージェントを選択し、実装する洞察を提供します。それでは、LangChain エージェントの探求を始めましょう!
LangChain エージェントの種類 #1: OpenAI Tools エージェント
OpenAI Tools エージェントは、最新の OpenAI モデルとシームレスに連携し、複数の機能または「ツール」を同時に実行できるように設計されています。このエージェントは、複数の外部 API とのやり取りが必要なアプリケーションや、複数のタスクを並行して実行する場合に特に有用です。これにより、全体の処理時間が短縮されます。
サンプルコード:
# 必要なライブラリとツールをインポートします
from langchain import hub
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
# Tavily Search ツールを初期化します
tools = [TavilySearchResults(max_results=1)]
# プロンプトを取得し、LLM をセットアップします
prompt = hub.pull("hwchase17/openai-tools-agent")
llm = ChatOpenAI(model="gpt-3.5-turbo-1106", temperature=0)
# OpenAI Tools エージェントを作成します
agent = create_openai_tools_agent(llm, tools, prompt)
# サンプル入力でエージェントを実行します
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
response = agent_executor.invoke({"input": "LangChain とは何ですか?"})
print(response)
この例では、create_openai_tools_agent
関数が、ユーザーの入力に基づいてどのツールを呼び出すかを知的に決定するエージェントを構築しています。ここでは Web 検索機能をデモするために Tavily Search ツールを使用しています。
LangChain エージェントの種類 #2: OpenAI Functions エージェント
OpenAI Functions エージェントは、モデルが入力に基づいて呼び出す関数の有無とどの関数を呼び出すかを判断する必要がある場合に最適です。Tools エージェントに類似していますが、タスクに関数の呼び出しが中心となるシナリオに特に適しており、新しいモデルではツールを優先しており、OpenAI はこのアプローチを廃止しました。
サンプルコード:
# OpenAI Functions エージェントのセットアップ
from langchain import hub
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
# ツールを初期化し、LLM を選択します
tools = [TavilySearchResults(max_results=1)]
prompt = hub.pull("hwchase17/openai-functions-agent")
llm = ChatOpenAI(model="gpt-3.5-turbo-1106")
# OpenAI Functions エージェントを構築して実行します
agent = create_openai_functions_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
response = agent_executor.invoke({"input": "LangChain とは何ですか?"})
print(response)
この例では、特定の関数を呼び出すために Tavily Search をツールとして使用して、OpenAI Functions エージェントの設定と使用方法を示しています。
LangChain エージェントの種類 #3: XML エージェント
XML エージェントは、XML 構造を生成および解釈するのに長けたモデル向けに最適化されています。このエージェントタイプは、構造化されたデータを扱う場合や、モデルとのやり取りが XML の構造化形式で有益な場合に有利です。
サンプルコード:
# XML エージェントの初期化
from langchain import hub
from langchain.agents import AgentExecutor, create_xml_agent
from langchain_community.chat_models import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
tools = [TavilySearchResults(max_results=1)]
prompt = hub.pull("hwchase17/xml-agent-convo")
llm = ChatAnthropic(model="claude-2")
# XML エージェントを作成し実行します
agent = create_xml_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
response = agent_executor.invoke({"input": "LangChain とは何ですか?"})
print(response)
このセットアップでは、XML エージェントを Claude-2 と呼ばれる Anthropic モデルと共に使用しています。XML 形式は、エージェントとモデル間の通信を構造化する方法を提供し、複雑なデータ処理を容易にします。
LangChain エージェントの種類 #4: JSON Chat エージェント
JSON Chat エージェントは、応答データを JSON 形式で生成するために JSON 形式を利用し、構造化された応答データが必要なアプリケーションに適しています。このエージェントは、JSON フレンドリーモデルを処理および生成するのに優れています。
サンプルコード:
# JSON Chat エージェントのセットアップ
from langchain import hub
from langchain.agents import AgentExecutor, create_json_chat_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
tools = [TavilySearchResults(max_results=1)]
prompt = hub.pull("hwchase17/react-chat-json")
llm = ChatOpenAI()
# JSON Chat エージェントを作成して実行します
agent = create_json_chat_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
response = agent_executor.invoke({"input": "LangChain とは何ですか?"})
print(response)
ここでは、JSON Chat エージェントを使用して入力を処理し、JSON 構造化応答を生成し、Web 検索機能をデモするために Tavily Search ツールを利用しています。このエージェントは、応答を構造化する必要がある場合や、ユーザーとのより構造化された対話が必要な場合に特に有用です。
LangChain エージェントの種類 #5: Structured Chat エージェント
Structured Chat エージェントは、マルチ入力ツールをサポートし、複雑なクエリとツールの相互作用を効果的に行うことができます。詳細なプロンプトを指定し、適切な言語モデルを選択することで、このエージェントは複雑なクエリとツールの相互作用をシームレスにナビゲートします。
サンプルコード:
# Structured Chat エージェントの初期化
from langchain import hub
from langchain.agents import AgentExecutor, create_structured_chat_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
tools = [TavilySearchResults(max_results=1)]
prompt = hub.pull("hwchase17/structured-chat-agent")
llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo-1106")
# Structured Chat エージェントを構築し、実行します
agent = create_structured_chat_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True)
response = agent_executor.invoke({"input": "LangChain とは何ですか?"})
print(response)
この例では、マルチ入力ツールと対話するために Structured Chat エージェントを使用しています。詳細なプロンプトと適切な言語モデルを選択することで、このエージェントは複雑なクエリとツールの相互作用を効果的に処理します。
これらの LangChain エージェントの違いと機能を理解することで、開発者はアプリケーションをより効果的にカスタマイズして言語モデルと自動化タスクのフルポテンシャルを活用することができます。単純な関数呼び出しから構造化データ処理や複雑なマルチツールの相互作用まで、必要なエージェントを選択して適用することで、よりスマートで効率的なアプリケーションを構築できます。これらの例を基にして、より知識豊かな、効率的な、応答性の高いアプリケーションを構築する準備が整いました。
結論
LangChain エージェントは、高度な言語モデルの機能をアプリケーションに統合する開発者向けの多目的で強力なツールセットを提供します。OpenAI Tools や Functions エージェントから XML、JSON Chat、Structured Chat エージェントまで、各エージェントタイプの微妙な違いを理解し、プロジェクトの特定の要件に合った適切なツールを選択できます。これらのエージェントは、単純な関数呼び出しから複雑なマルチツールの相互作用まで、幅広いタスクを処理できます。
LangChain エージェントの理解を深めることで、開発者は言語モデルや自動化タスクの機能を最大限に活用することができます。アプリケーションが単純な関数呼び出しか、構造化データ処理、複雑なマルチツールの相互作用を必要とするかに応じて、適切なエージェントを選択します。これらの例を基にして、より知識豊かな、効率的な、応答性の高いアプリケーションを構築する準備が整いました。