LangChainについて解説。大規模言語モデル(LLM)を効率よく実装するためのフレームワーク

記事タイトルとURLをコピーする

G-gen 又吉です。LangChain とは、大規模言語モデル (LLM) を効率よく実装するために使用するフレームワークです。

当記事では LangChain を用いて、Google Cloud (旧称 : GCP) の LLM である PaLM 2 を操作する基本的な方法をご紹介します。

はじめに

Vertex AI PaLM API

PaLM 2 は Google の LLM であり、Bard の裏側でも使われています。Vertex AI では、PaLM 2 のエンドポイントを Vertex AI PaLM API として公開しています。

開発者は Vertex AI PaLM API を使用することで、自社のアプリケーションで LLM を組み込むことが可能となります。

詳細については、以下のブログをご覧ください。

blog.g-gen.co.jp

LLM 開発の課題

学習コスト

Google Cloud や OpenAI の他にも、様々な企業が LLM を提供しております。それぞれの LLM の長所を活かして使い分ける際、LLM の種類が増えるごとに学習コストがかかってしまいます。

入力トークン制限

LLM のプロンプトに入力できるトークン数には制限があります。そのため、長いテキストをそのままの形では処理できない場合は、入力テキストを複数に分割して処理する必要があります。

事実と異なる回答

LLM は確率的に高いテキストを並べて回答を生成しているため、時には事実と異なることを回答する、いわゆるハルシネーション (幻覚) を起こしてしまうことがあります。 そこで、事実に基づいた回答を生成させるため、正しい情報を先に取得して、その情報から回答を生成させるなどの工夫が必要です。

最新情報に対応していない

LLM は過去のデータを学習させてモデルを構築しています。そのため、学習データより後のできごとには回答できません。ちなみに、Vertex AI 基盤モデルの text-bison は、2023 年 2 月までのデータを学習データとしてます。

参考:Foundation models

準備

環境構築

当記事では、LangChain の解説で Python コードを実行する際に Notebook を使用します。また、Notebook 環境は Colab Enterprise を用います。

Colab Enterprise を使用すると、インフラストラクチャを管理せずに Notebook で作業できます。

Colab Enterprise の Notebook 作成方法は公式ドキュメントのクイックスタートをご参考下さい。

cloud.google.com

尚、Colab Enterprise は 2023 年 9 月時点で Preview となります。

ライブラリの準備

Notebook が立ち上がり、ランタイムと接続できましたら以下のコードを実行してライブラリのインストールとインポートを行います。

# ライブラリのインストール
! pip install langchain==0.0.301 openai==0.28.0 faiss-cpu==1.7.4 transformers==4.33.2
# ライブラリのインポート
import time
from typing import List
  
import langchain
from pydantic import BaseModel
from google.cloud import aiplatform
from langchain.chat_models import ChatVertexAI
from langchain.embeddings import VertexAIEmbeddings
from langchain.llms import VertexAI, OpenAI
from langchain.schema import HumanMessage, SystemMessage
  
print(f"LangChain version: {langchain.__version__}")
print(f"Vertex AI SDK version: {aiplatform.__version__}")
# 出力
LangChain version: 0.0.301
Vertex AI SDK version: 1.32.0

ユーティリティ関数を定義

Vertex AI Embedding API for Text で使用するユーティリティ関数を定義します。

def rate_limit(max_per_minute):
    period = 60 / max_per_minute
    print("Waiting")
    while True:
        before = time.time()
        yield
        after = time.time()
        elapsed = after - before
        sleep_time = max(0, period - elapsed)
        if sleep_time > 0:
            print(".", end="")
            time.sleep(sleep_time)
  
  
class CustomVertexAIEmbeddings(VertexAIEmbeddings, BaseModel):
    requests_per_minute: int
    num_instances_per_batch: int
  
    # Overriding embed_documents method
    def embed_documents(self, texts: List[str]):
        limiter = rate_limit(self.requests_per_minute)
        results = []
        docs = list(texts)
  
        while docs:
            # Working in batches because the API accepts maximum 5
            # documents per request to get embeddings
            head, docs = (
                docs[: self.num_instances_per_batch],
                docs[self.num_instances_per_batch :],
            )
            chunk = self.client.get_embeddings(head)
            results.extend(chunk)
            next(limiter)
  
        return [r.values for r in results]

各 AI モデルを初期化

当記事では、以下の AI モデルを使用します。

No 提供元 モデル名 概要
1 OpneAI text-davinci-003 OpenAI が提供する汎用的な LLM であり、さまざまな言語タスクに適している。
2 Google Cloud text-bison@001 Google Cloud が提供する汎用的な LLM であり、さまざまな言語タスクに適している。
3 Google Cloud chat-bison@001 Google Cloud が提供する会話に最適化された LLM です。
4 Google Cloud textembedding-gecko@001 Google Cloud が提供するテキストエンべディングをサポートするモデルです。
API_KEY = ${OpenAI の API Key}
  
## OpenAI
# LLM 
llm_openai = OpenAI(
    openai_api_key = API_KEY,
    model_name = "text-davinci-003",
    max_tokens = 256,
    temperature = 0.2,
    top_p = 0.95
    )
  
## Vertex AI
# LLM
llm = VertexAI(
    model_name="text-bison@001",
    max_output_tokens=256,
    temperature=0.1,
    top_p=0.8,
    top_k=40,
    verbose=True,
)
  
# Chat model
chat = ChatVertexAI(
    model_name="chat-bison@001"
)
  
# Embedding model
EMBEDDING_QPM = 100
EMBEDDING_NUM_BATCH = 5
embeddings = CustomVertexAIEmbeddings(
    requests_per_minute=EMBEDDING_QPM,
    num_instances_per_batch=EMBEDDING_NUM_BATCH,
)

参考:langchain.llms.openai.OpenAI

参考:langchain.llms.vertexai.VertexAI

参考:langchain.chat_models.vertexai.ChatVertexAI

参考:langchain.embeddings.vertexai.VertexAIEmbeddings

LangChain とは

概要

LangChain とは、LLM を用いてアプリケーションを効率よく開発するためのフレームワークです。

LangChain を用いることで、先に述べた LLM 開発の課題に比較的容易に対処することが可能です。

LangChain にはさまざまなモジュールが提供されており、そのモジュールを組み合わせて複雑なアプリケーションを構築することができます。また、それらのモジュールは大きく 6 つのコンポーネントに分けることができます。

LangChain フレームワーク

また、2023 年 9 月現在対応しているプログラム言語は、Python と JavaScript (TypeScript) のみとなっており、当記事では Python での実装を行います。

参考:LangChain - Python Doc

参考:LangChain - JS/TS Doc

Models

概要

Models とは、Google の PaLM 2 や OpenAI の GPT-4 をはじめとした様々な言語モデルを切り替えたり、組み合わせたりできる機能です。

LangChain Models では、以下の AI モデルタイプをサポートしています。

  • LLMs
  • Chat models
  • Text embedding models

参考:LangChain - Language models

参考:LangChain - Text embedding models

LLMs

LLMs には、Vertex AI PaLM API for TextOpenAI GPT-3.5 などが統合されています。

ここでは、Vertex AI と OpenAI の LLM を LangChain を用いて同じ記述で実行しています。

PROMPT = "Tell me a joke"
  
# Vertex AI LLM の呼び出し
res_vertexai = llm(PROMPT)
print(f"Joke from Vertex AI : {res_vertexai}")
  
print("-----")
  
# OpenAI LLM の呼び出し
res_openai = llm_openai(PROMPT)
print(f"Joke from OpenAI : {res_openai}")
# 出力
Joke from Vertex AI : 
What's the difference between a snowman and a snowwoman? Snowballs.
-----
Joke from OpenAI : 
Q: What did the fish say when it hit the wall?
A: Dam!

Chat model

Chat model は、Vertex AI PaLM API for Text chat と統合されています。 ここでは、SystemMessage に AI の役割を与え、HumanMessage に ユーザーが入力するプロンプトを設定しています。

messages = [
    SystemMessage(content="あなたは旅行計画を立てるのに役立つ AI ボットです。"),
    HumanMessage(content="ニューヨークに行きたいのですが、どうすればよいですか?")
]
  
res = chat(messages).content
  
print(res)
# 出力
 ニューヨークへの旅行を計画する際には、以下の点に注意してください。

* いつ行くか。ニューヨークは一年中楽しめる街ですが、最も人気のある時期は春(4月~6月)と秋(9月~11月)です。この時期は、天候が穏やかで、観光客も少なめです。
* どこに行くか。ニューヨークには、見どころがたくさんあります。自由の女神、エンパイアステートビル、タイムズスクエア、セントラルパークなど、誰もが知っている観光スポットから、地元の人しか知らない穴場まで、あらゆるものがあります。

Text Embedding Model

Text Embedding Model は、Vertex AI Embedding API for Text と統合されています。

text = "こんにちは"
  
text_embedding = embeddings.embed_query(text)
  
print(f"次元数 : {len(text_embedding)}")
print(f"サンプル: {text_embedding[:5]}...")
次元数 : 768
サンプル: [-0.0027207613456994295, 0.026091288775205612, -0.003294411115348339, 0.0031894829589873552, 0.01808055490255356]...

Memory

概要

Memory とは、ユーザーと LLM model との会話履歴を保存および取得する機能です。Memory を用いることで、過去の会話を記憶した上で LLMs が回答を生成することがようにできます。

もちろん、Chat Models で会話履歴に対応した回答を生成することもできますが、LLMs のみで会話履歴にも対応したいというユースケースでの利用が期待できます。

ここでは、ConversationBufferMemory をご紹介しますが、Memory には多くの機能があるため、ユースケースに合わせて使い分けましょう。

参考:Memory types

ConversationBufferMemory

ConversationBufferMemory を使用すると、ユーザーと LLM の過去の会話を保存し、また会話を抽出できます。

from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
  
conversation = ConversationChain(
    llm=llm, verbose=False, memory=ConversationBufferMemory()
)
  
conversation.predict(input="""
私の名前はまたゆーです。私の特徴を以下に記載します。
  
* 出身地:沖縄県
* 好きな言語:Python
* 好きな食べ物 : 寿司
""")
# 出力1
はじめまして、またゆーさん。沖縄県出身なんですね。私は沖縄県に行ったことがありませんが、いつか行ってみたいです。
Pythonがお好きなんですね。私もPythonが好きです。寿司も大好きです。
conversation.predict(input="私の名前はわかりますか?")
# 出力2
はい、あなたの名前はまたゆーさんです。
conversation.predict(input="私の出身地を教えてください。")
# 出力3
沖縄県です。

Prompts

概要

Prompts とは、プロンプトの構築と操作を容易に管理できます。

また、チーム開発をする際、プロンプトの統一化が図れるのも利点です。

LangChain Prompts には、以下 3 つの機能があります。

  • Prompt Template
  • Output Parser
  • Example Selectors

Prompt Template

Prompt template を用いて、プロンプトのテンプレートを作成できます。

ここでは、テンプレートの中に location という変数を入れています。format メソッドを用いることで、変数に任意の文字列が代入してプロンプトを作成できます。

from langchain import PromptTemplate
  
# テンプレートを作成し、location を変数化
template = """
私は {location} に旅行したいと思っています。 そこで何をすればいいでしょうか?
  
短い文で返答する
"""
  
# PromptTemplate をインスタンス化
prompt = PromptTemplate(
    input_variables=["location"],
    template=template,
)
  
# formatのメソッドを使って、location に「ローマ」を代入してプロンプトを作成 
final_prompt = prompt.format(location="ローマ")
  
print(f"Final Prompt: {final_prompt}")
print("-----------")
print(f"LLM Output: {llm(final_prompt)}")
# 出力
Final Prompt: 
私は ローマ に旅行したいと思っています。 そこで何をすればいいでしょうか?

短い文で返答する

-----------
LLM Output: ローマはイタリアの首都であり、世界で最も人気のある観光地の1つです。 ローマには、コロッセオ、パンテオン、トレヴィの泉など、多くの歴史的な建造物があります。 ローマはまた、活気のあるナイトライフと素晴らしいレストランを備えています。 ローマを訪れる際には、これらの場所を訪れ、ローマの文化と歴史を体験することをお勧めします。

Output Parser

Output parsers とは、言語モデルから得られる出力のフォーマットを指定することができる機能です。

例えば、CSV や JSON のような形式で出力できます。

また、指定のフォーマットにならなかった際、再試行または修正してくれるオプションもあります。

Example Selectors

Example selectors は、多数のデータから、一部のみランダムで選択 (サンプリング) できる機能です。

例えば、リストに入った 100 個の語句データから、ランダムで 30 個だけ抽出したい時などに利用します。

Indexes

概要

Indexes とは、LLM がドキュメントを操作するのに役立つ機能がいくつか用意されています。

Indexes には、以下 4 つの機能があります。

  • Document loaders
  • Text splitters
  • Vector stores
  • Retrievers

Document loaders

Document loaders を用いることで、PDF や Web ページなどのテキストコンテンツを容易にドキュメント化することができます。もちろん、それらドキュメントをテキストにして LLM の入力に与えることが可能です。

ここでは、WebBaseLoader メソッドを使用して Google Cloud 公式ブログ からテキストを抽出しています。

from langchain.document_loaders import WebBaseLoader
  
#  Google Cloud 公式ブログ からテキストを抽出
loader = WebBaseLoader("https://cloud.google.com/blog/products/ai-machine-learning/how-to-use-grounding-for-your-llms-with-text-embeddings")
data = loader.load()
  
print(f"# ドキュメント数 : {len(pg_work)}")
print(f"# 文字数 : {len(data[0].page_content)}")
print(f"# 最初の100文字 : {data[0].page_content[:100]}")
# 出力
# ドキュメント数 : 1
# 文字数 : 13684
# 最初の100文字 : How to use Grounding for your LLMs with text embeddings | Google Cloud BlogJump to ContentCloudBlogC

Text splitters

Text splitters を用いることで、長いテキストを分割することができます。つまり、LLM への入力トークン数の制限への対策に有効です。

こちらは、RecursiveCharacterTextSplitter メソッドを用いて、指定した文字数以下になるように分割します。尚、その際、すべての段落 (次に文、そして単語) をできるだけ長くまとめて保持しようとする効果もあります。

from langchain.text_splitter import RecursiveCharacterTextSplitter
  
# 100 文字以下で文字を分割 (尚、オーバーラップ 50 文字まで許容) 
text_splitter = RecursiveCharacterTextSplitter(
    # Chunk の設定
    chunk_size=100,
    chunk_overlap=50,
)
 
#  Google Cloud 公式ブログ から抽出したテキストを 100 文字以下に分割 
texts = text_splitter.split_documents(pg_work)
print(f"# ドキュメント数 : {len(texts)}")
# 出力
# ドキュメント数 : 272
# 最初の 10 個のドキュメントからテキストを表示
for i in range(10):
    print(f"[{len(texts[i].page_content)}文字]{texts[i].page_content}", "\n")
# 出力
[82文字]How to use Grounding for your LLMs with text embeddings | Google Cloud BlogJump to 
  
[98文字]with text embeddings | Google Cloud BlogJump to ContentCloudBlogContact sales Get started for free 
  
[82文字]sales Get started for free CloudBlogSolutions & technologyAI & Machine LearningAPI 
  
[81文字]& technologyAI & Machine LearningAPI ManagementApplication DevelopmentApplication 
  
[94文字]ManagementApplication DevelopmentApplication ModernizationChrome EnterpriseComputeContainers & 
  
[99文字]ModernizationChrome EnterpriseComputeContainers & KubernetesData AnalyticsDatabasesDevOps & SREMaps 
  
[72文字]KubernetesData AnalyticsDatabasesDevOps & SREMaps & GeospatialSecurity & 
  
[69文字]& SREMaps & GeospatialSecurity & IdentityInfrastructureInfrastructure 
  
[96文字]& IdentityInfrastructureInfrastructure ModernizationNetworkingProductivity & CollaborationSAP on 
  
[82文字]& CollaborationSAP on Google CloudStorage & Data TransferSustainabilityEcosystemIT 

Vector stores

Vector stores とは、エンべディングされたデータを保管し、ベクター検索することができる機能となります。ベクター検索では、クエリに対し「最も類似したテキスト」を取得することもできます。

尚、Vector stores ではベクトルデータベースとして一般的な ChromaFAISS だけでなく、Vertex AI Vector Search (旧称 : Vertex AI Matching Engine) もサポートしています。

ここでは、以下の流れで実装します。

1. Web 上のテキストをエンべディングして保管

  • Web サイトからテキスト抽出
  • テキストを LLM のトークン制限にかからないように分割
  • Embeddings model を用いて、分割したテキストをベクトル化
  • Vector Storesにベクトル化した情報を保管

2. ユーザーの質問をエンべディングして類似検索

  • ユーザーの質問をベクトル化
  • similarity_search メソッドで、Vector Stores に保管されたベクトルと類似のテキストを検索

3. LLM で回答生成

  • 検索結果をもとに LLM で回答を生成
from langchain.document_loaders import TextLoader
from langchain.embeddings import VertexAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import WebBaseLoader
from langchain.vectorstores import FAISS
  
#  Google Cloud 公式ブログ からテキストを抽出
loader = WebBaseLoader("https://cloud.google.com/blog/products/ai-machine-learning/how-to-use-grounding-for-your-llms-with-text-embeddings")
documents = loader.load()
  
# 100 文字以下で文字を分割 (尚、オーバーラップ 50 文字まで許容) 
text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=50)
texts = text_splitter.split_documents(documents)
  
# VertexAIEmbeddings を用いて分割したテキストをそれぞれエンべディングして VectorStores に保存
db = FAISS.from_documents(texts, VertexAIEmbeddings())
# query に対し類似したテキストをベクター検索して上位 3 つのテキストを取得
# query訳 : Vertex AI Embeddings for Text の入力トークン制限は何トークンですか?
query = "What is the input token limit for Vertex AI Embeddings for Text?"
docs = db.similarity_search(query, 3)
  
for index, doc in enumerate(docs):
    print(f"No{index+1}. {doc.page_content}")
# 出力
No1. URL /blog/products/ai-machine-learning/how-to-use-grounding-for-your-llms-with-text-embeddings was
No2. ModernizationChrome EnterpriseComputeContainers & KubernetesData AnalyticsDatabasesDevOps & SREMaps
No3. KubernetesData AnalyticsDatabasesDevOps & SREMaps & GeospatialSecurity &
from langchain import PromptTemplate
  
  
# 上位 3 つの回答を結合
facts = "\n".join([doc.page_content for doc in docs])
  
# プロンプトテンプレートを作成
template = """
Prease generate answer based on facts for the following query.
  
query: {query}
  
facts: {facts}
  
answer:
"""
  
prompt = PromptTemplate(
    input_variables=["query", "facts"],
    template=template,
)
  
final_prompt = prompt.format(query=query, facts=facts)
  
print(f"Final Prompt: {final_prompt}")
print("-----------")
print(f"LLM Output: {llm(final_prompt)}")
# 出力
Final Prompt: 
Prease generate answer based on facts for the following query.
  
query: What is the input token limit for Vertex AI Embeddings for Text?
  
facts: on Vertex AI Model Garden. Embeddings for Text : The API takes text input up to 3,072 input tokens
The API takes text input up to 3,072 input tokens and outputs 768 dimensional text embeddings, and
"librarian-level" precision Vertex AI Embeddings for Text has an embedding space with 768
  
answer:

-----------
LLM Output: The input token limit for Vertex AI Embeddings for Text is 3,072.

LLM の回答を日本語訳すると「 Vertex AI Embeddings for Text の入力トークン制限は 3,072 です 」となり、この回答は Google Cloud 公式ブログから参照しているため正しい回答が生成されていることがわかります。

Retriever

Retriever とは、クエリからドキュメントを返すインターフェイスです。ドキュメントを保管する必要がないため、ドキュメントの保管とベクター検索を分離できます。また、Vectorstore よりも汎用的です。

Chains

概要

Chains は、複数のプロンプトを実行するための機能であり、一度の処理で複雑な回答を生成したいときに有効です。

ユースケースとしては、LLM が生成した回答を、次の LLM のプロンプトとして渡すことが可能です。また、長いテキストを複数に分割し、それぞれを要約後、それらをまとめて一つの要約テキストにすることも可能です。

Simple Sequential Chains

SimpleSequentialChain は、各ステップが LLM の出力を次のステップへの入力として使用するシンプルな Chains です。

この手法は、複雑な質問に対し、一度中間的な回答を生成し、最終的な回答を生成することで LLM の回答精度を高めることができます。このような手法を一般的に Chain of Thought (CoT) プロンプティングといいます。

参考:Language Models Perform Reasoning via Chain of Thought

from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.chains import SimpleSequentialChain
  
  
# 1 つ目の Chain を定義
prompt_1 = PromptTemplate(
    input_variables=["occupation"],
    template="Question : {occupation}が使いそうなGoogle Cloudのプロダクトを1つ教えてください? \nAnswer :"
)
chain_1 = LLMChain(llm=llm, prompt=prompt_1)
  
# 2 つ目の Chain を定義
prompt_2 = PromptTemplate(
    input_variables=["google_cloud_product"],
    template="{google_cloud_product}の勉強法を300字で教えてください",
)
chain_2 = LLMChain(llm=llm, prompt=prompt_2)
  
# SimpleSequentialChain を作成
sequential_chain = SimpleSequentialChain(chains=[chain_1, chain_2], verbose=True)
  
# 実行
print(sequential_chain("データエンジニア"))
# 出力
> Entering new SimpleSequentialChain chain...
 BigQuery
 BigQueryの勉強法は、以下の通りです。
  
1. BigQueryの基礎を学ぶ。
2. BigQueryのドキュメントを読む。
3. BigQueryのチュートリアルをこなす。
4. BigQueryのサンプルコードを読む。
5. BigQueryのコミュニティに参加する。
6. BigQueryの認定試験を受ける。
  
BigQueryの基礎を学ぶには、以下のリソースが役に立ちます。
  
* [BigQueryのドキュメント](https://cloud.google.com/bigquery/docs/)
* [BigQueryのチュートリアル](https://cloud.google
  
> Finished chain.
{'input': 'データエンジニア', 'output': ' BigQueryの勉強法は、以下の通りです。\n\n1. BigQueryの基礎を学ぶ。\n2. BigQueryのドキュメントを読む。\n3. BigQueryのチュートリアルをこなす。\n4. BigQueryのサンプルコードを読む。\n5. BigQueryのコミュニティに参加する。\n6. BigQueryの認定試験を受ける。\n\nBigQueryの基礎を学ぶには、以下のリソースが役に立ちます。\n\n* [BigQueryのドキュメント](https://cloud.google.com/bigquery/docs/)\n* [BigQueryのチュートリアル](https://cloud.google'}

Summarization Chain

Summarization Chain は、長いテキストの要約を容易に実行できる Chain です。

参考:Summarization

from langchain.chains.summarize import load_summarize_chain
from langchain.document_loaders import WebBaseLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
  
#  Google Cloud 公式ブログ からテキストを抽出
loader = WebBaseLoader("https://cloud.google.com/blog/products/ai-machine-learning/how-to-use-grounding-for-your-llms-with-text-embeddings")
documents = loader.load()
  
print(f"# 文字数 : {len(documents[0].page_content)}")
  
# 1500 文字以下で文字を分割 (尚、オーバーラップ 50 文字まで許容) 
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1500, chunk_overlap=50)
texts = text_splitter.split_documents(documents)
  
# 長いテキストを要約する Chain を初期化
chain = load_summarize_chain(llm, chain_type="map_reduce")
  
# 要約を実行
summary = chain.run(texts)
  
print(f"要約:{summary}")
# 出力
# 文字数 : 13705
要約:This blog post introduces two new APIs from Google: Embeddings API for Text and Embeddings API for Image. The Embeddings API for Text is a public preview and is available to trusted testers. The API takes text input and outputs 1024 dimensional embeddings. The Embeddings API for Image is still in development and will be released in a future blog post.

要約後のテキストを Google 翻訳で日本語に変換すると、以下のとおりです。

このブログ投稿では、Google の 2 つの新しい API、Embeddings API for Text と Embeddings API for Image を紹介します。 Embeddings API for Text はパブリック プレビューであり、信頼できるテスターが利用できます。 API はテキスト入力を受け取り、1024 次元の埋め込みを出力します。 画像用の埋め込み API はまだ開発中であり、将来のブログ投稿でリリースされる予定です。

Agents

概要

Agents とは、ユーザーの要求に対し、どのアクションで、どの順番で解決するかを LLM を使って決定してくれる機能です。

Tools

Tools とは、Agent が「外の世界と対話」することができる機能です。

Google 検索ができる Tool や、Wikipedia の情報を参照できる Tool など、さまざまな Tools が提供されています。

他にもさまざまな Tools が存在するため、ユースケースにあわせて選択してください。

参考:Tools

Agent Types

Agents には、いくつかの種類 (Agent Types) があります。

例えば、Zero-shot ReAct Agent を用いると、任意の数の Tool を利用している場合、それぞれの Tool の説明 (description) に基づいて、どのツールを用いるかを決める Agent Type になります。この場合、各 Tool の説明がしっかりと書かれている必要があります。

他にもさまざまな Agent Types が存在するため、ユースケースにあわせて選択してください。

参考:Agent Types

実装例

Tool には Google 検索が行える SerpAPIWrapper を用いて、Agent には Zero-shot ReAct Agent を用い最新の情報を元に LLM に回答を生成させてみます。

参考:SerpAPI

ここでは、以下の流れで実行したいと思います。

  1. Agents を使わずに LLM から回答を生成
  2. Agents を使い Google 検索を用いて最新情報を基に LLM から回答を生成
llm("""
株式会社G-genの代表取締役は誰ですか?
また、CTOは誰ですか?
""")
# 出力
 株式会社G-genの代表取締役は、小林 大地氏です。CTOは、小林 大地氏です。

LLM (Vertex AI 基盤モデル text-bison) にそのまま回答させると、出力は間違っていました。

正しくは、株式会社G-genの代表取締役は羽柴孝、CTOは杉村勇馬です。

それでは次に、Agents を用いて実行してみます。

from langchain.utilities import GoogleSerperAPIWrapper
from langchain.llms.vertexai import VertexAI
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
  
  
SERPER_API_KEY = ${SERPER_API_KEY}
  
# Tools の初期化
search = GoogleSerperAPIWrapper()
tools = [
    Tool(
        name="Intermediate Answer",
        func=search.run,
        description="useful for when you need to search for latest information in web"
    )
]
  
# Agent の初期化
self_ask_with_search = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
  
# クエリを実行
self_ask_with_search.run("""
株式会社G-genの代表取締役は誰ですか?
また、CTOは誰ですか?
""")
# 出力
> Entering new AgentExecutor chain...
 株式会社G-genの代表取締役は田中裕介氏です。
CTOは小池啓介氏です。
Action: Intermediate Answer
Action Input: 株式会社G-gen 代表取締役
Observation: 株式会社G-gen(本社:東京都新宿区、代表取締役:羽柴孝)は、新ソリューション「Google Cloud ではじめる Generative AI 活用支援ソリューション」をリリースしたことをお知らせいたします。
Thought: 株式会社G-genの代表取締役は羽柴孝氏です。
Action: Intermediate Answer
Action Input: 株式会社G-gen CTO
Observation: 株式会社G-gen(本社:東京都新宿区、代表取締役:羽柴孝)はCOOに鈴木 達文 氏、CTOに杉村 勇馬 氏が就任したことをお知らせいたします。 杉村 勇馬. 執行役員CTO / クラウドソリューション部 部長. 株式会社G-gen上智大学 Sophia University. 日本 東京都 新宿区. 25人のフォロワー 24人のつながり. 執行役員CTO. 杉村 勇馬Yuma Sugimura. 杉村 勇馬. Twitter; Facebook. 会社概要. 商号, 株式会社G-gen(カブシキガイシャ ジージェン). 所在地, 〒162-0824 東京都新宿区 ... 株式会社G-gen(本社:東京都新宿区、代表取締役:羽柴孝)は、12月13日(火)にエンジニア向けのイベント「ベンチャー企業 CTO が語る! G-gen の CTO の杉村です。今回はエンジニアの成長の方法について、私なりの考え方を書いてみたいと思います。「できるエンジニア」と銘打って文章を ... クラウドネイティブな10の働き方とは? 杉村 勇馬. 株式会社G-gen / 執行役員CTO ... 株式会社G-gen / 執行役員CTO. Google Cloud 技術ブログで Google ... 会社の特長. CTOがいる B2B 1億円以上の資金を調達済み フルリモート可 転勤なし 副業してもOK 残業30H以内 服装自由 学歴不問 言語未経験可. 言語. Python SQL. イチオシ. 株式会社 G-gen 杉村 勇馬. 2012 年に上智大学を卒業後、埼玉県警察の警察官という異色の経歴を経て IT エンジニアに。インフラ中心のキャリアを積み ... 経営・CxO職. CEO・経営企画・経営管理. COO. CTO・CIO. CFO. CMO. 経理・管理・バックオフィス職. 人事・総務. 財務・会計・経理. 広報・IR. 法務(コンプライアンス)・ ... G-gen 杉村勇馬氏. 株式会社G-gen 執行役員CTO クラウドソリューション部部長杉村勇馬氏. 佐久間氏:当社は経営的な視点で、技術的要素も含めて提案 ...
Thought: 株式会社G-genの代表取締役は羽柴孝氏、CTOは杉村勇馬氏です。
Final Answer: 株式会社G-genの代表取締役は羽柴孝氏、CTOは杉村勇馬氏です。
  
> Finished chain.
株式会社G-genの代表取締役は羽柴孝氏、CTOは杉村勇馬氏です。

インターネット上の最新情報を取得して、LLM が回答を生成していることがわかります。また、正しい回答が生成されていました。

又吉 佑樹(記事一覧)

クラウドソリューション部

はいさい、沖縄出身のクラウドエンジニア!

セールスからエンジニアへ転身。Google Cloud 全 11 資格保有。Google Cloud Champion Innovator (AI/ML)。Google Cloud Partner Top Engineer 2024。Google Cloud 公式ユーザー会 Jagu'e'r でエバンジェリストとして活動中。好きな分野は AI/ML。