😎

【LangChain】エージェントが何者かざっくり理解する

2024/03/16に公開

なぜエージェントが必要なのか

先日、大谷翔平が結婚を発表しました。
この記事を書いている時点では、gpt-4-0125が最新知識ですので、2月29日の結婚発表は当然ながらgpt-4の知識にはありません。

ですので、以下のように大谷翔平が結婚した時の年齢を聞くと失敗します。

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

template = """与えられたリクエストに回答してください
input:{input}
回答:"""

prompt = ChatPromptTemplate.from_template(template)

model = ChatOpenAI()

chain = prompt | model

chain.invoke({"input":"大谷翔平は何歳で結婚しましたか"})
AIMessage(content='大谷翔平は2021年に26歳で結婚しました。')

失敗どころか、嘘を教えてくるのでタチが悪いです

gpt-4にない知識を調べてちゃんとした回答を得るには、ネット上で大谷翔平が結婚した記事などを調べる必要があります。

過去に書いた記事のように検索先をFM802のサイトと指定できるのならweb loaderを使って検索することができますが、今回のような事例ではサイトを指定できませんし、「結婚を発表した記事」と「大谷翔平の誕生日」を調べる必要があります。

当然ながら、AIはインターネット上で必要な情報をググるのですが、そもそもググるという行為は簡単なように見えて実は「検索エンジンは何を使う」「どういったキーワードで検索する」「検索結果をどのように解釈する」といったように複数のステップを経ています。

特にLangchainでは、得た答えをもとに回答を生成するのですから、後工程が使いやすい形で検索結果を返す必要があります

その辺を良しなにやってくれるのがエージェントと捉えておけば、まずエージェントの意義・解釈としては十分かと思います。

どういうエージェントがいるのか

先ほどはええ感じにググって結果を返すエージェントがいると言いました。

他にどのようなエージェントがあるのか、公式ドキュメントを参考にします
https://python.langchain.com/docs/modules/agents/agent_types/

見た感じ、検索系と計算系が多い気がします。
逆に言うと、これらの機能は自分で適切なpromptテンプレートを作成したり、chainを実装するのは大変だということでしょうか。

車輪の再発明を防ぐためにも、どういったエージェントが世の中にあるのかウォッチしておこうと思います。

検索系エージェント(Tavily)の使い方

先ほど「AIにググらせる」と言いました。
ググらせて(つまり検索エンジンにgoogleを使ってインターネット検索する)、AI最適な形で答えを得るには、serpAPIというサービスがあります。
しかし、google検索はSEO対策汚染が年々酷くなってきていることや、よりAI最適な形で答えを得られるなどの理由から、Tavilyという検索エンジンが使われることが多いようです。

// 先にTavilyのAPI keyを入手しておいてください
import os
os.environ["TAVILY_API_KEY"] = "***"

// Tavily
from langchain_community.tools.tavily_search import TavilySearchResults

search = TavilySearchResults()

search.invoke("大谷翔平は何歳で結婚しましたか?", search_depth="advanced")
[{'url': 'https://www.bbc.com/japanese/articles/c6pq2ekvqe9o',
  'content': '大谷さんは「本日は皆さまに結婚いたしました事をご報告させていただきます」と書き、「お相手は日本人女性です」と紹介した。. 英語での ...'},
 {'url': 'https://www.bbc.com/japanese/articles/cx0zl97nx9jo',
  'content': '日本ではオンラインでは大勢が、大谷選手の妻の写真が公表されたことを歓迎した。これまで多くの人が何週間もの間、結婚相手は誰か推理を ...'},
・・・

なんとたった一行でネット検索して、有力な答えを返してくれるプログラムを組むことができました。

※ エージェント実行の時にinvokeではなく、runを使っている記事があると思います。
runは古い書き方(非推奨)ですので、runを使っているなら情報鮮度が古いと思っておいたほうが良いです。

ただし、これはあくまでTavilyを単独で使う場合の書き方で、使うとしても動作確認程度です。
実際はより詳しい回答を求めるために会話したり、得られた数値に対して統計をとるなど計算処理が必要になってくるかと思います。

動作を必要に応じてカスタマイズするには、 もう少しエージェントが何者か概念を理解しましょう

ReActの概念を理解する

JSフレームワークのReactではありません。(どうでもいいですが、私はReactよりNuxt/Vue派です)

ReActの概念を理解するにあたっては、こちらの記事がわかりやすいです。

https://qiita.com/mashmoeiar11/items/fec070f8497940cee0b7

要は、より高度な言語処理を行う思想として、人間側の質問に対して適切な回答を検索し、その答えが正しいか検証して回答を作成するというプロセスを経ることで実現できるよね、と賢い人が考えました。

そして、その思想を実現するために作られたフレームワークがReActであるとざっくり理解しています。

(ネット上で適当に調べた記事を検証もせずにコピペする人間が多い中、出来の悪い人間よりも賢いと思ってしまうのは私だけでしょうか)

全てのエージェントは、このReActの思想に基づいて作成されています。

つまり、先ほど試したTavilyは「ネット検索をする」という仕事を適切にこなさせるために、誰かがReAct概念に沿って作成したエージェントと捉えることができます。

toolsの概念を理解する

エージェントを使うにはもう一つ、hubとtoolsという概念を理解する必要があります。
私もまだ完全に理解しきれているわけではないのですが、公式をもとにざっくりとしたイメージを掴みました。
https://python.langchain.com/docs/modules/agents/agent_types/openai_tools

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

// ① tools、prompt、llmを定義
tools = [TavilySearchResults(max_results=1)]

prompt = hub.pull("hwchase17/openai-tools-agent")

llm = ChatOpenAI(model="gpt-3.5-turbo-1106", temperature=0)

// ② agentを作成
agent = create_openai_tools_agent(llm, tools, prompt)

agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

// ③ 実行
agent_executor.invoke({"input": "what is LangChain?"})

#->
> Entering new AgentExecutor chain...
以下略

これまではprompt、modelなどを繋げたchainを作成して実行していましたが、今回はagentを作成して実行しています。

私は解釈として、create_openai_tools_agentで作成される自作agentは「代理店・一次下請け」と考えています。(Agentを日本語訳すると代理店なので、まさに言葉の通りですね)
そしてagentを作成するときにtoolsとして用いられているTavilyは「二次下請け」と捉えています。

つまり、Tavilyそのものはネット検索するしか能がないので、一次下請けであるagentがユーザーの入力を受け取ってTavilyに渡す→そしてTavilyが返してきた答えに対して、いい感じに加工してユーザーに返すといった役割を果たしています。

※ もっとも、このシンプルなプログラムでは自作agentはユーザーの言葉を単純に下請けであるTavilyに流しているだけなので、単なる中抜き業者です。

例えて言うなら、自作agentは電通(広告代理店)、Tavilyはデザイナーです。

電通はデザイナーを多数抱えており、これらを自分たちの仕事をするための道具(tool)とみなしています。
hubというのは、電通の中で調整役をする社員です。

今回作成した一連の流れは、ユーザー(依頼主)のinput(依頼)に対してTavilyに丸投げして、Tavilyの結果をそのまま依頼主に返す電通という企業を構築し、それを実行したと解釈することができるでしょう。

最後に

Agentは少しわかりにくい概念でしたが、実在する代理店に例えたらかなり解釈を進めることができました。

今回はシンプルなプログラムのため自作agentは単なる中抜き業者でしたが、次は会話をさせるという「仲介業者」として役にたってもらいましょう。

※あくまで例えであり、実際に電通が中抜き業者であるかは知りません

Discussion