このクイックスタートガイドでは、LangChainを使用してエンドツーエンドの言語モデルアプリケーションを構築する方法について説明します。
インストール
まず、次のコマンドでLangChainをインストールします。
仮想環境を入れます。
python3 -m venv env
source env/bin/activate
ライブラリのインストール
pip install langchain
# もしくは
conda install langchain -c conda-forge
環境のセットアップ
LangChainを使用するには、通常、モデルプロバイダ、データストア、APIなどとの統合が必要になります。
この例では、OpenAIのAPIを使用するため、まずそのSDKをインストールする必要があります。
“`
pip install openai
“`
次に、ターミナルで環境変数を設定する必要があります。
“`
export OPENAI_API_KEY="..."
“`
または、Jupyterノートブック(またはPythonスクリプト)内から環境変数を設定することもできます。
“`
import os
os.environ["OPENAI_API_KEY"] = "..."
“`
APIキーを動的に設定したい場合は、OpenAIクラスを初期化する際に`openai_api_key`パラメータを使用することができます。
from langchain.llms import OpenAI
llm = OpenAI(openai_api_key="OPENAI_API_KEY")
言語モデルアプリケーションの構築:LLMs
LangChainをインストールし、環境をセットアップしたので、言語モデルアプリケーションの構築を始めることができます。
LangChainは、言語モデルアプリケーションを構築するために使用できる多くのモジュールを提供しています。モジュールは組み合わせてより複雑なアプリケーションを作成するか、単独で単純なアプリケーションに使用することができます。
LLMs:言語モデルからの予測の取得
LangChainの最も基本的な構成要素は、LLMをいくつかの入力に対して呼び出すことです。これを行うための簡単な例を見てみましょう。この目的のために、会社が何を作っているかに基づいて会社名を生成するサービスを構築していると想像しましょう。
これを行うためには、まずLLMのラッパーをインポートする必要があります。
“`
from langchain.llms import OpenAI
“`
次に、任意の引数でラッパーを初期化します。この例では、出力がよりランダムになるようにしたいので、高い温度で初期化します。
llm = OpenAI(temperature=0.9)
これで、いくつかの入力で呼び出すことができます。
text = "What would be a good company name for a company that makes colorful socks?"
print(llm(text))
出力:
Feetful of Fun
Could not import azure.core python package.
のエラーに対してはこちら
Prompt Templates:LLMsのためのプロンプトの管理
LLMを呼び出すことは素晴らしい第一歩ですが、これは始まりに過ぎません。通常、アプリケーションでLLMを使用する場合、ユーザーの入力を直接LLMに送信するのではありません。代わりに、ユーザーの入力を受け取り、それをプロンプトとして構築し、それをLLMに送信することが一般的です。
たとえば、前の例では、渡したテキストはユーザーがカラフルな靴下を作る会社の名前を尋ねるためにハードコーディングされていました。この架空のサービスでは、会社が行うことを説明するユーザーの入力のみを受け取り、それを使用してプロンプトをフォーマットしたいとします。
これはLangChainで簡単に行うことができます。
まず、プロンプトテンプレートを定義しましょう
“`
from langchain.prompts import PromptTemplate
prompt = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)
次に、これがどのように機能するかを見てみましょう!`.format`メソッドを呼び出してフォーマットすることができます。
print(prompt.format(product="colorful socks"))
出力:
What is a good name for a company that makes colorful socks?
Chains:LLMsとプロンプトを組み合わせた多段階のワークフロー
ここまで、PromptTemplateやLLMのプリミティブ単体で作業してきました。しかし、実際のアプリケーションは、1つのプリミティブではなく、それらの組み合わせです。
LangChainのチェーンは、LLMsや他のチェーンなどのプリミティブで構成されています。
もっとも基本的なチェーンのタイプは、LLMChainで、PromptTemplateとLLMで構成されています
前の例を拡張して、ユーザーの入力を受け取り、プロンプトでフォーマットし、フォーマットされた応答をLLMに渡すLLMChainを作成できます。
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
llm = OpenAI(temperature=0.9)
prompt = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)
これで、ユーザーの入力を受け取り、それをプロンプトでフォーマットし、それをLLMに送信する非常にシンプルなチェーンを作成できます。
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
それでは、製品を指定してそのチェーンを実行してみましょう!
chain.run("colorful socks")
出力:
‘\n\nSocktastic!’
これで最初のチェーンができました – LLM Chainです。これはより単純なチェーンのタイプですが、これの動作原理を理解することで、より複雑なチェーンの取り扱いにも役立ちます。
Agents:ユーザーの入力に基づいて動的にチェーンを呼び出す
これまで見てきたチェーンは、予め決められた順序で実行されます。
しかし、Agentsはそうではありません。AgentsはLLMを使用して、アクションを決定し、順序を決めて実行し、結果を観察するために使用します。アクションは、ツールを使用してその出力を観察するか、ユーザーに返すことができます。
正しく使用すると、Agentsは非常に強力なツールとなります。このチュートリアルでは、最もシンプルで高レベルなAPIを使用してAgentsを簡単に使用する方法を紹介します。
Agentsをロードするためには、次の概念を理解する必要があります:
– Tool:
特定の役割を果たす関数です。これには、Google検索、データベースの検索、Python REPL、他のチェーンなどが含まれます。ツールのインターフェースは、現在は文字列を入力として受け取り、文字列を出力として返す関数であることが期待されています。
– LLM:
Agentの背後にある言語モデル。
– Agent:
使用するエージェントです。これは、サポートされている標準エージェントクラスを参照する文字列である必要があります。このノートブックでは、最も単純で高レベルなAPIを使用するため、これはサポートされている標準エージェントのみをカバーしています。カスタムエージェントを実装する場合は、カスタムエージェントのドキュメントを参照してください(近日公開予定)
サポートされているエージェントとその仕様の一覧については、こちらを参照してください。
ツールについては、予め定義されたツールとその仕様の一覧については、こちらを参照してください。
Google本家のほうが安いですhttps://note.com/npaka/n/nd9a4a26a8932
Googleで検索APIの作成
下記環境変数を設定
os.environ["GOOGLE_CSE_ID"] = "<Googleカスタム検索_検索エンジンID>"
os.environ["GOOGLE_API_KEY"] = "<Googleカスタム検索_APIキー>"
で設定するか、
export GOOGLE_CSE_ID=""
export GOOGLE_API_KEY="..."
必要なライブラリのインストール
Google本家のAPIを使う場合は下記
pip install google-api-python-client
serpAPIを使う場合
適切な環境変数を設定します。
import os
os.environ["SERPAPI_API_KEY"] = "..."
pip install google-search-results(serp apiを使う場合)
それでは、始めましょう!
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.llms import OpenAI
# まず、エージェントを制御するために使用する言語モデルをロードしましょう。
llm = OpenAI(temperature=0)
# 次に、使用するツールをロードします。`llm-math`ツールはLLMを使用するため、それを渡す必要があります。
tools = load_tools(["google-search", "llm-math"], llm=llm)
# 最後に、ツール、言語モデル、使用するエージェントのタイプを指定してエージェントを初期化します。
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# さあ、テストしてみましょう!
agent.run("What was the high temperature in SF yesterday in Fahrenheit? What is that number raised to the .023 power?")
出力:
> Entering new AgentExecutor chain…
I need to find the temperature first, then use the calculator to raise it to the .023 power.
Action: Search
Action Input: “High temperature in SF yesterday”
Observation: San Francisco Temperature Yesterday. Maximum temperature yesterday: 57 °F (at 1:56 pm) Minimum temperature yesterday: 49 °F (at 1:56 am) Average temperature …
Thought: I now have the temperature, so I can use the calculator to raise it to the .023 power.
Action: Calculator
Action Input: 57^.023
Observation: Answer: 1.0974509573251117
Thought: I now know the final answer
Final Answer: The high temperature in SF yesterday in Fahrenheit raised to the .023 power is 1.0974509573251117.
> Finished chain.
メモリ:
チェーンやエージェントに状態を追加する
これまで、すべてのチェーンやエージェントは状態を持たないものでした。しかし、多くの場合、チェーンやエージェントには前のやり取りに関する情報を記憶させる必要があります。これによって、より良い会話をするためのコンテキストを活用することができます。これは「短期記憶」と呼ばれるものの最も明確で単純な例です。より複雑な例としては、チェーンやエージェントが時間の経過とともに重要な情報を記憶することが考えられます。これは「長期記憶」と呼ばれるものの形態です。後者の具体的なアイデアについては、この素晴らしい論文を参照してください。
LangChainは、このような目的のために特別に作成されたいくつかのチェーンを提供しています。このノートブックでは、このうちの1つのチェーン(ConversationChain)を2つの異なるタイプのメモリと共に使用する方法について説明します
デフォルトでは、ConversationChainには、すべての以前の入力/出力を記憶し、それらを渡されたコンテキストに追加するというシンプルなタイプのメモリがあります。これを使って、どのように動作するか見てみましょう(プロンプトを表示するためにverbose=Trueに設定します)。
“`
from langchain import OpenAI, ConversationChain
llm = OpenAI(temperature=0)
conversation = ConversationChain(llm=llm, verbose=True)
output = conversation.predict(input="Hi there!")
print(output)
> Entering new chain…
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.
Current conversation:
Human: Hi there!
AI:
> Finished chain.
‘ Hello! How are you today?’
output = conversation.predict(input="I'm doing well! Just having a conversation with an AI.")
print(output)
出力:
> Entering new chain…
Prompt after formatting:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.
Current conversation:
Human: Hi there!
AI:
Hello! How are you today?
Human: I’m doing well! Just having a conversation with an AI.
AI:
> Finished chain.
” That’s great! What would you like to talk about?”
LangChainアプリケーションを構築する方法:チャットモデル
LLMの代わりにチャットモデルを使用することもできます。チャットモデルは言語モデルのバリエーションです。チャットモデルは内部で言語モデルを使用しますが、公開するインターフェースは「チャットメッセージ」が入力と出力となります。
チャットモデルのAPIは比較的新しいものですので、正しい抽象化方法をまだ見つけている最中です。
チャットモデルからメッセージの補完を取得するには、1つ以上のメッセージをチャットモデルに渡します。応答はメッセージです。LangChainでサポートされているメッセージのタイプはAIMessage、HumanMessage、SystemMessage、ChatMessageです。ほとんどの場合、HumanMessage、AIMessage、SystemMessageを使用します。
from langchain.chat_models import ChatOpenAI
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
chat = ChatOpenAI(temperature=0)
単一のメッセージを渡すことで補完を取得できます。
chat([HumanMessage(content="Translate this sentence from English to French. I love programming.")])
# -> AIMessage(content=”J’aime programmer.”, additional_kwargs={})
また、OpenAIのgpt-3.5-turboおよびgpt-4モデルでは、複数のメッセージを渡すこともできます。
messages = [
SystemMessage(content="You are a helpful assistant that translates English to French."),
HumanMessage(content="I love programming.")
]
chat(messages)
# -> AIMessage(content="J'aime programmer.", additional_kwargs={})
さらに、複数のメッセージのセットに対して補完を生成することもできます。これはLLMResultという追加のメッセージパラメータを持つLLMResultを返します。
batch_messages = [
[
SystemMessage(content="You are a helpful assistant that translates English to French."),
HumanMessage(content="I love programming.")
],
[
SystemMessage(content="You are a helpful assistant that translates English to French."),
HumanMessage(content="I love artificial intelligence.")
],
]
result = chat.generate(batch_messages)
result
出力:
LLMResult(generations=[[ChatGeneration(text=”J’aime programmer.”, generation_info=None, message=AIMessage(content=”J’aime programmer.”, additional_kwargs={}))], [ChatGeneration(text=”J’aime l’intelligence artificielle.”, generation_info=None, message=AIMessage(content=”J’aime l’intelligence artificielle.”, additional_kwargs={}))]], llm_output={‘token_usage’: {‘prompt_tokens’:
57, ‘completion_tokens’: 20, ‘total_tokens’: 77}})
このLLMResultからトークンの使用状況などを取得できます。
result.llm_output['token_usage']
# -> {‘prompt_tokens’: 57, ‘completion_tokens’: 20, ‘total_tokens’: 77}
チャットプロンプトテンプレート
LLMsと同様に、MessagePromptTemplateを使用してテンプレートを作成し、ChatPromptTemplateとして使用することができます。MessagePromptTemplateの1つ以上を使用してChatPromptTemplateを構築できます。ChatPromptTemplateのformat_promptメソッドを使用してプロンプトをフォーマットできます。
便利な点として、テンプレート上にfrom_templateメソッドが公開されています。このテンプレートを使用する場合の例を以下に示します。
“`
from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
chat = ChatOpenAI(temperature=0)
template = "You are a helpful assistant that translates {input_language} to {output_language}."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
# フォーマットされたメッセージでチャット補完を取得します
chat(chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages())
# -> AIMessage(content=”J’aime programmer.”, additional_kwargs={})
チェーンとチャットモデル
前のセクションで説明したLLMChainは、チャットモデルでも使用できます。
from langchain.chat_models import ChatOpenAI
from langchain import LLMChain
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
chat = ChatOpenAI(temperature=0)
template = "You are a helpful assistant that translates {input_language} to {output_language}."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
chain = LLMChain(llm=chat, prompt=chat_prompt)
chain.run(input_language="English", output_language="French", text="I love programming.")
# -> “J’aime programmer.”
チャットモデルとエージェント
チャットモデルを使用する場合、AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTIONをエージェントタイプとして使用してエージェントを初期化できます。
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.chat_models import ChatOpenAI
from langchain.llms import OpenAI
# まず、エージェントを制御するために使用する言語モデルをロードしましょう。
chat = ChatOpenAI(temperature=0)
# 次に、使用するツールをロードします。`llm-math`ツールはLLMを使用するため、それを渡す必要があります。
llm = OpenAI(temperature=0)
tools = load_tools(["serpapi", "llm-math"], llm=llm)
# 最後に、ツール、言語モデル、使用するエージェントのタイプを指定してエージェントを初期化します。
agent = initialize_agent(tools, chat, agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# さあ、テストしてみましょう!
agent.run("Who is Olivia Wilde's boyfriend? What is his current age raised to the 0.23 power?")
出力:
> Entering new AgentExecutor chain…
Thought: I need to use a search engine to find Olivia Wilde’s boyfriend and a calculator to raise his age to the 0.23 power.
Action: Search
Action Input: “Olivia Wilde boyfriend”
Observation: Sudeikis and Wilde’s relationship ended in November 2020. Wilde was publicly served with court documents regarding child custody while she was presenting Don’t Worry Darling at CinemaCon 2022. In January 2021, Wilde began dating singer Harry Styles after meeting during the filming of Don’t Worry Darling.
Thought:I need to use a search engine to find Harry Styles’ current age.
Action: Search
Action Input: “Harry Styles age”
Observation: 29 years
Thought:Now I need to calculate 29 raised to the 0.23 power.
Action: Calculator
Action Input: “29^0.23”
Observation: Answer: 2.169459462491557
Thought:I now know the final answer.
Final Answer: 2.169459462491557
> Finished chain.
‘2.169459462491557’
以上が、LangChainを使用したエンドツーエンドの言語モデルアプリケーションのクイックスタートガイドの解説です。ご質問があれば、どうぞお気軽にお聞かせください。
コメント