Closed14

LangChainのGetting StartedをGoogle Colaboratoryでやってみる ④Agents

kun432kun432

4. Agents

Agentsはわかりにくいけど、基本的にはChainsと同じだと思う。ただChainsが、明示的に何をどの順番で行うか?を指定するものに対し、AgentsはそれすらLLMに任せるようなものということらしい。

Agentsに必要なのは以下の3つ。

  1. ツール
  • 何かしらのタスクを行うツール。例えばGoogle検索とかDB検索とかREPLとか。
  1. LLM
  • LLM。まあこれは当然として。
  1. エージェント
  • 何をどうするか?を決める。多分この決め方でいくつかのAgentが用意されているのだと思う。

ということでまずGetting Started。

from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.llms import OpenAI

llm = OpenAI(temperature=0)
tools = load_tools(["serpapi", "llm-math"], llm=llm)
agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)

agent.run("レオ・ディカプリオの恋人は誰?そして彼女の年齢を0.43乗すると何歳になる?日本語で回答して。")
  • llmをロード
  • load_toolsでツールを呼び出す。ここではSerpAPIとLLMMathを呼び出している。LLMMathがLLMを使用するのでここでも紐付けている様子。
  • initialize_agentでエージェントを初期化。ツール、LLM、エージェントを紐付ける。zero-shot-react-descriptionというのが標準的なエージェントのようです。

実行結果

> Entering new AgentExecutor chain...
 I need to find out who Leo DiCaprio's girlfriend is, and then calculate her age when multiplied by 0.43.
Action: Search
Action Input: "Leo DiCaprio girlfriend"
Observation: DiCaprio met actor Camila Morrone in December 2017, when she was 20 and he was 43. They were spotted at Coachella and went on multiple vacations together. Some reports suggested that DiCaprio was ready to ask Morrone to marry him. The couple made their red carpet debut at the 2020 Academy Awards.
Thought: I need to calculate her age when multiplied by 0.43
Action: Calculator
Action Input: 20 * 0.43
Observation: Answer: 8.6

Thought: I now know the final answer
Final Answer: Leo DiCaprioの恋人はCamila Morroneで、0.43乗すると8.6歳になります。

> Finished chain.
Leo DiCaprioの恋人はCamila Morroneで、0.43乗すると8.6歳になります。

最初にレオナルド・ディカプリオの恋人を検索して、その恋人の生年月日を取得、それから計算に入っているのがわかる。

必ずしも万能か?というとそうではなくて、以下のような質問だとうまくいかない。

agent.run("レオ・ディカプリオの恋人の年齢を0.43乗すると何歳になる?日本語で回答して。")
> Entering new AgentExecutor chain...
 I need to calculate the age of Leo DiCaprio's girlfriend.
Action: Calculator
Action Input: 0.43 * (age of Leo DiCaprio's girlfriend)
Observation: Answer: 9.459999999999999

Thought: I need to round the answer to the nearest whole number.
Action: Calculator
Action Input: round(9.459999999999999)
Observation: Answer: 9

Thought: I now know the final answer.
Final Answer: レオ・ディカプリオの恋人の年齢を0.43乗すると9歳になります。

> Finished chain.
レオ・ディカプリオの恋人の年齢を0.43乗すると9歳になります。

恋人が誰か、そして年齢は、というところがちゃんと噛み砕けていないので、間違った回答になってしまっている。

このあたりはプロンプトをいじると正しく求めることができる。

agent.run("レオ・ディカプリオの恋人の年齢を0.43乗すると何歳になる?答えを出すために必要なステップをstep-by-stepで考えて。足りない情報がある場合はそれを取得して。日本語で回答して。")

こうなる

> Entering new AgentExecutor chain...
 レオ・ディカプリオの恋人の年齢を求めるには、まず彼女の年齢を知る必要がある。
Action: Search
Action Input: レオ・ディカプリオの恋人の年齢
Observation: 2022年秋にはモデルのジジ・ハディッド(27)、そして12月にはモデルのヴィクトリア・ラマス(23)との交際が報じられていた、俳優のレオナルド・ディカプリオ(48)に新たな恋の噂が浮上した。
Thought: レオ・ディカプリオの恋人の年齢がわかったので、次に0.43乗を計算する必要がある。
Action: Calculator
Action Input: 27^0.43
Observation: Answer: 4.125593352125936

Thought: 答えが出たので、最終的な答えを出す。
Final Answer: レオ・ディカプリオの恋人の年齢を0.43乗すると4.12歳になります。

> Finished chain.
レオ・ディカプリオの恋人の年齢を0.43乗すると4.12歳になります。

ということで、もう少し細かく見ていく。

kun432kun432

Agent Overview

https://langchain.readthedocs.io/en/latest/modules/agents/how_to_guides.html

一般的なAgentの機能について。以下の内容が紹介されている。

  • Load From Hub(LangChainHubからエージェントを読み出す)
  • Custom Tools: エージェントが使えるカスタムなツールの作成方法
  • Agents With Vectorstores: エージェントでベクトル型ストアを使う方法
  • Intermediate Steps: エージェント内部の挙動を確認するための中間ステップへのアクセス方法・使用方法
  • Custom Agent: カスタムなエージェントの作成方法、具体的にはカスタムなLLM+プロンプトを使用してエージェントを動作させる
  • Multi Input Tools: 複数の入力を必要とするツールをエージェントと組み合わせる方法
  • Search Tools: LangChainがサポートする検索ツールの使い方
  • Max Iterations: エージェントが一定のイテレーションを行うことを制限する方法
  • Asynchronous: 非同期処理について
kun432kun432

とその前に、一旦AgentsとToolsの種類を見ておいたほうが良さそう。

まずAgent

https://langchain.readthedocs.io/en/latest/modules/agents/agents.html

以下の4種類

  • zero-shot-react-description
    • ツールの説明だけに基づいてどのツールを使用するかを決定する。
    • 任意の数のツールを提供できるが、各ツールに説明が必要。
  • react-docstore
    • docstoreとやり取りするために使用する。
    • 文書を検索するSearchツールと最近見つかった文書で用語を検索するLookupツールが必要
    • オリジナルのReAct論文、特にWikipediaの例に相当する。
  • self-ask-with-search
    • 1つのツールIntermediate Answerを利用する。
    • 事実に基づいた回答を検索する。
    • オリジナルのself-ask-with-search論文に相当し、Google検索APIがツールとして提供された。
  • conversational-react-description
    • 会話の設定で使用するために設計されている。
    • ReActフレームワークを使用して、どのツールを使用するかを決定する。
    • 前回の会話のインタラクションを記憶するためにメモリを使用する。

次にTools。

https://langchain.readthedocs.io/en/latest/modules/agents/tools.html

ツールは、UtilsだったりChainsだったり、はたまた別のAgentだったりする。以下のようなものが紹介されている。

ツール名 ツール説明 LLM必要
Python REPL Pythonのシェル。Pythonコマンドを実行するために使用する。 いいえ
serpapi 検索エンジン。最新の情報について質問する必要があるときに役立ちます。 いいえ
wolfram-alpha Wolfram Alpha検索エンジン。数学、科学、テクノロジー、文化、社会、日常生活に関する質問に回答するために役立ちます。 いいえ
requests インターネットへのポータル。特定のサイトからコンテンツを取得する必要があるときに使用する。 いいえ
terminal ターミナルでコマンドを実行する。有効なコマンドを入力し、そのコマンドの実行からの出力が返される。 いいえ
PAL-MATH 複雑な数学の問題を解決するのに優れた言語モデル。完全に文言化された数学の問題を入力する必要がある。 はい
PAL-COLOR-OBJ オブジェクトの位置と色の属性について推論することができる素晴らしい言語モデル。完全に文言化された推論問題を入力する必要があります。 はい
Calculator 数学に関する質問に回答する必要がある場合に役立ちます。 はい
Open Meteo API OpenMeteo APIからの天気情報を取得する必要がある場合に役立ちます。 はい
News API 現在のニュースストーリーのトップヘッドラインに関する情報を取得する必要がある場合に使用します。 はい
TMDB API The Movie Databaseから情報を取得する必要がある場合に使用します。 はい
Search Google検索のラッパー。現在のイベントに関する質問に回答する必要がある場合に役立ちます。 いいえ
Search SearxNGメタ検索エンジンのラッパー。入力は検索クエリである。 いいえ
Google Serper 低コストのGoogle検索API。現在のイベントに関する質問に回

Toolはload_toolsで読み出す

from langchain.agents import load_tools
tool_names = [...]
tools = load_tools(tool_names)

Toolの中にはLLMが必要なものもある。その場合は以下のようにload_toolsでLLMも指定する。

from langchain.agents import load_tools
tool_names = [...]
llm = ...
tools = load_tools(tool_names, llm=llm)
kun432kun432
Loading from LangChainHub

https://langchain.readthedocs.io/en/latest/modules/agents/examples/load_from_hub.html

LangChainHubを使ったAgent。

https://github.com/hwchase17/langchain-hub

from langchain import OpenAI, SerpAPIWrapper
from langchain.agents import initialize_agent, Tool

llm = OpenAI(temperature=0)
search = SerpAPIWrapper()
tools = [
    Tool(
        name="Intermediate Answer",
        func=search.run,
        description="useful for when you need to ask with search"
    )
]

self_ask_with_search = initialize_agent(tools, llm, agent_path="lc://agents/self-ask-with-search/agent.json", verbose=True)
self_ask_with_search.run("男子全米オープン優勝者の出身地は?")

Intermediate Answerってツールのリストには紹介されていないのだけど、インスタンス作る感じで使うのかな。まあ検索結果の中間回答をさらに検索していく、ってことなのかもしれない。

で、LangChainHubの場合はlc://で指定する形。上記の場合だと以下が読み出されるんだと思う。

https://github.com/hwchase17/langchain-hub/blob/master/agents/self-ask-with-search/agent.json

結果

WARNING:/usr/local/lib/python3.9/dist-packages/langchain/prompts/loading.py:No `_type` key found, defaulting to `prompt`.


> Entering new AgentExecutor chain...
 Yes.
Follow up: 男子全米オープン優勝者は誰ですか?
Intermediate answer: テニスの四大大会の1つ、全米オープンは大会最終日を迎えた11日、男子シングルスの決勝が行われ、スペインの19歳、カルロス・アルカラス選手がノルウェーのキャスパー・ルード選手を破って、四大大会初優勝を果たしました。
Follow up: カルロス・アルカラス選手の出身地は?
Intermediate answer: ˈɾaθ ˈɣaɾ.fja]; 2003年5月5日 - )はスペイン・ムルシア州ムルシア エル・パルマル地区出身の男子プロテニス選手。 ATPランキング自己最高位はシングルス1位、ダブルス519位。 これまでにATPツアーでシングルス8勝を挙げている。 身長183cm、体重74kg。
So the final answer is: ムルシア・エル・パルマル

> Finished chain.
ムルシア・エル・パルマル

特定のバージョンのAgentを指定したい場合はハッシュ値で指定することもできる。

agent_path="lc@2826ef9e8acdf88465e1e5fc8a7bf59e0f9d0a85://agents/self-ask-with-search/agent.json", verbose=True)
kun432kun432
Custom Tools

自作のエージェントを作る場合はエージェントが使用するツールを渡してあげる必要がある。ツールは以下が必要。

  • name (str)
    • ツール名
    • 必須
  • description (str)
    • ツールの説明
    • オプション
  • return_direct (bool)
    • 戻り値かな?
    • デフォルトはFalse

ツールで呼び出される関数は一つの文字列を入力値、一つの文字列を返す必要がある。

ツールは2通りの定義の仕方がある。

  1. スクラッチから定義する
  2. 既存ツールを拡張する
スクラッチからToolを作成する

スクラッチから新しいToolを作る場合、さらに2つの方法がある。

  1. Toolデータクラスを使う
  2. BaseToolクラスを継承する

Toolデータクラスを使う場合。

from langchain.agents import initialize_agent, Tool
from langchain.tools import BaseTool
from langchain.llms import OpenAI
from langchain import LLMMathChain, SerpAPIWrapper

llm = OpenAI(temperature=0)

search = SerpAPIWrapper()

llm_math_chain = LLMMathChain(llm=llm, verbose=True)

tools = [
    Tool(
        name = "Search",
        func=search.run,
        description="useful for when you need to answer questions about current events"
    ),
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="useful for when you need to answer questions about math"
    )
]

agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)

agent.run("レオ・ディカプリオの恋人は誰?そして彼女の年齢を0.43乗すると何歳になる?日本語で回答して。")

結果

> Entering new AgentExecutor chain...
 I need to find out who Leo DiCaprio's girlfriend is and then calculate her age.
Action: Search
Action Input: Leo DiCaprio's girlfriend
Observation: Leonardo DiCaprio started dating 20-year-old model Camila Morrone in late 2017. They're still together today - and she's 22 now.
Thought: I need to calculate her age when 0.43 is multiplied by it.
Action: Calculator
Action Input: 22 * 0.43

> Entering new LLMMathChain chain...
22 * 0.43
```python
print(22 * 0.43)
```

Answer: 9.459999999999999

> Finished chain.

Observation: Answer: 9.459999999999999

Thought: I now know the final answer.
Final Answer: レオ・ディカプリオの恋人は、モデルのカミラ・モローネです。彼女の年齢を0.43乗すると9.46歳になります。

> Finished chain.
レオ・ディカプリオの恋人は、モデルのカミラ・モローネです。彼女の年齢を0.43乗すると9.46歳になります。

SerpAPIとLLMMathはこういうことをしなくてもツールとして呼び出せる。最初の例がそれ。

llm = OpenAI(temperature=0)
tools = load_tools(["serpapi", "llm-math"], llm=llm)
agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)

ここではあえて、SerpAPIをUtil、LLMMathをChainとして、ツールに定義して呼び出している。

BaseToolクラスを継承する場合。

from langchain.agents import initialize_agent, Tool
from langchain.tools import BaseTool
from langchain.llms import OpenAI
from langchain import LLMMathChain, SerpAPIWrapper

llm = OpenAI(temperature=0)

search = SerpAPIWrapper()

llm_math_chain = LLMMathChain(llm=llm, verbose=True)

class CustomSearchTool(BaseTool):
    name = "Search"
    description = "useful for when you need to answer questions about current events"

    def _run(self, query: str) -> str:
        """Use the tool."""
        return search.run(query)
    
    async def _arun(self, query: str) -> str:
        """Use the tool asynchronously."""
        raise NotImplementedError("BingSearchRun does not support async")
    
class CustomCalculatorTool(BaseTool):
    name = "Calculator"
    description = "useful for when you need to answer questions about math"

    def _run(self, query: str) -> str:
        """Use the tool."""
        return llm_math_chain.run(query)
    
    async def _arun(self, query: str) -> str:
        """Use the tool asynchronously."""
        raise NotImplementedError("BingSearchRun does not support async")

tools = [CustomSearchTool(), CustomCalculatorTool()]

agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)

agent.run("レオ・ディカプリオの恋人は誰?そして彼女の年齢を0.43乗すると何歳になる?日本語で回答して。")

結果

> Entering new AgentExecutor chain...
 I need to find out who Leo DiCaprio's girlfriend is and then calculate her age.
Action: Search
Action Input: Leo DiCaprio's girlfriend
Observation: Leonardo DiCaprio started dating 20-year-old model Camila Morrone in late 2017. They're still together today - and she's 22 now.
Thought: I need to calculate her age when 0.43 is multiplied by it.
Action: Calculator
Action Input: 22 * 0.43

> Entering new LLMMathChain chain...
22 * 0.43
```python
print(22 * 0.43)
```

Answer: 9.459999999999999

> Finished chain.

Observation: Answer: 9.459999999999999

Thought: I now know the final answer.
Final Answer: レオ・ディカプリオの恋人は、モデルのカミラ・モローネです。彼女の年齢を0.43乗すると9.46歳になります。

> Finished chain.
レオ・ディカプリオの恋人は、モデルのカミラ・モローネです。彼女の年齢を0.43乗すると9.46歳になります。
toolデコレータ

自作ツールを定義しやすくするために@toolデコレータが用意されている。ちょっとよくわかってないけどこんな感じでいけた。

from langchain.agents import initialize_agent, Tool
from langchain.tools import BaseTool
from langchain.llms import OpenAI
from langchain import LLMMathChain, SerpAPIWrapper

llm = OpenAI(temperature=0)

@tool
def custom_search_api(query: str) -> str:
    """useful for when you need to answer questions about current events"""
    search = SerpAPIWrapper()
    return search.run(query)

@tool
def custom_calcurator(query: str) -> str:
    """useful for when you need to answer questions about math"""
    llm_math_chain = LLMMathChain(llm=llm)
    return llm_math_chain.run(query)

tools = [custom_search_api, custom_calcurator]

agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)

print(custom_search_api)

print(custom_calcurator)

agent.run("レオ・ディカプリオの恋人は誰?そして彼女の年齢を0.43乗すると何歳になる?日本語で回答して。")

結果

name='custom_search_api' description='custom_search_api(query: str) -> str - useful for when you need to answer questions about current events' return_direct=False verbose=False callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x7f78ec4b0490> func=<function custom_search_api at 0x7f78bf745040> coroutine=None
name='custom_calcurator' description='custom_calcurator(query: str) -> str - useful for when you need to answer questions about math' return_direct=False verbose=False callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x7f78ec4b0490> func=<function custom_calcurator at 0x7f78bf60b940> coroutine=None


> Entering new AgentExecutor chain...
 I need to find out who Leo DiCaprio's girlfriend is and then calculate her age when 0.43 is multiplied by it.
Action: custom_search_api
Action Input: Leo DiCaprio's girlfriend
Observation: Leonardo DiCaprio started dating 20-year-old model Camila Morrone in late 2017. They're still together today - and she's 22 now.
Thought: I need to calculate her age when 0.43 is multiplied by it.
Action: custom_calcurator
Action Input: 22 * 0.43
Observation: Answer: 9.459999999999999

Thought: I now know the final answer
Final Answer: レオ・ディカプリオの恋人は、20歳から22歳の間にモデルのカミラ・モローネで、0.43乗すると9.46歳になります。

> Finished chain.
レオ・ディカプリオの恋人は、20歳から22歳の間にモデルのカミラ・モローネで、0.43乗すると9.46歳になります。

ツール名やパラメータはオーバーライドすることもできる。

@tool("search")
def custom_search_api(query: str) -> str:
    """useful for when you need to answer questions about current events"""
    search = SerpAPIWrapper()
    return search.run(query)

@tool("calc")
def custom_calcurator(query: str) -> str:
    """useful for when you need to answer questions about math"""
    llm_math_chain = LLMMathChain(llm=llm)
    return llm_math_chain.run(query)

print(custom_search_api)
print(custom_calcurator)
name='search' description='search(query: str) -> str - useful for when you need to answer questions about current events' return_direct=False verbose=False callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x7f78ec4b0490> func=<function custom_search_api at 0x7f78bf60b700> coroutine=None
name='calc' description='calc(query: str) -> str - useful for when you need to answer questions about math' return_direct=False verbose=False callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x7f78ec4b0490> func=<function custom_calcurator at 0x7f78bf60b040> coroutine=None
既存ツールを拡張する

読みだした既存ツールの拡張はこんな感じ。シンプルにツール名を変更する場合。

from langchain.agents import initialize_agent
from langchain.llms import OpenAI
from langchain import LLMMathChain, SerpAPIWrapper
from langchain.agents import load_tools


llm = OpenAI(temperature=0)

tools = load_tools(["serpapi", "llm-math"], llm=llm)
tools[0].name = "Google Search"

agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)

agent.run("レオ・ディカプリオの恋人は誰?そして彼女の年齢を0.43乗すると何歳になる?日本語で回答して。")

結果。"Action: Google Search"となっているのがわかる。

> Entering new AgentExecutor chain...
 I need to find out who Leo DiCaprio's girlfriend is, and then calculate her age when multiplied by 0.43.
Action: Google Search
Action Input: "Leo DiCaprio girlfriend"
Observation: Leonardo DiCaprio seemed to prove a long-held theory about his love life right after splitting from girlfriend Camila Morrone just months ...
Thought: Camila Morrone is Leo DiCaprio's girlfriend
Action: Google Search
Action Input: "Camila Morrone age"
Observation: 25 years
Thought: I need to calculate 25 multiplied by 0.43
Action: Calculator
Action Input: 25 * 0.43
Observation: Answer: 10.75

Thought: I now know the final answer
Final Answer: レオ・ディカプリオの恋人は、25歳のカミラ・モローネで、0.43乗すると10.75歳になります。

> Finished chain.
レオ・ディカプリオの恋人は、25歳のカミラ・モローネで、0.43乗すると10.75歳になります。
ツール間の優先度を定義する

カスタムツールを使う場合、同様のツールよりも優先して使いたいという場合もある。紹介されているのは

  • 検索ツールを複数使う。音楽用の検索ツールと、一般的な検索ツール。
  • 音楽に関するクエリであれば音楽用検索ツールを優先的に使いたい。

というようなユースケース。

この場合はdescriptionにその旨を記載すれば良い。

from langchain.agents import initialize_agent, Tool
from langchain.llms import OpenAI
from langchain import LLMMathChain, SerpAPIWrapper
search = SerpAPIWrapper()
tools = [
    Tool(
        name = "Search",
        func=search.run,
        description="useful for when you need to answer questions about current events"
    ),
    Tool(
        name="Music Search",
        func=lambda x: "'All I Want For Christmas Is You' by Mariah Carey.", #Mock Function
        description="A Music search engine. Use this more than the normal search if the question is about Music, like 'who is the singer of yesterday?' or 'what is the most popular song in 2022?'",
    )
]

agent = initialize_agent(tools, OpenAI(temperature=0), agent="zero-shot-react-description", verbose=True)

agent.run("クリスマスの曲で有名な曲を教えて。日本語で。")

シンプルに毎回"'All I Want For Christmas Is You' by Mariah Carey."を返すモックだけど、descriptionに音楽の場合は優先するように記載されている。

結果

> Entering new AgentExecutor chain...
 日本語でクリスマスの曲を検索する。
Action: Music Search
Action Input: クリスマスの曲
Observation: 'All I Want For Christmas Is You' by Mariah Carey.
Thought: これが有名なクリスマスの曲だと確信している。
Final Answer: マライア・キャリーの「All I Want For Christmas Is You」が有名なクリスマスの曲です。

> Finished chain.
マライア・キャリーの「All I Want For Christmas Is You」が有名なクリスマスの曲です。

ちなみに関係ない質問をするとこうなる。ちょっと引っ掛けてみた。

agent.run("日本の有名な音楽大学を教えて。日本語で。")

結果

> Entering new AgentExecutor chain...
 I need to find a list of famous music universities in Japan
Action: Search
Action Input: "日本の音楽大学"
Observation: 日本 日本においては、国立大学で音楽学部を設置している大学は東京藝術大学のみである。 次いで公立大学としては、愛知県立芸術大学・京都市立芸術大学・沖縄県立芸術大学の三大学である。
Thought: I need to find out the names of these universities
Action: Search
Action Input: "東京藝術大学" "愛知県立芸術大学" "京都市立芸術大学" "沖縄県立芸術大学"
Observation: MENU. 大学案内 ▻. 大学概要 · 各種施設 · 教育情報の公表 · 広報紙 · 交通アクセス · 学部・研究科・教養教育 ▻. 美術学部 · 音楽学部 · 大学院 美術研究科 ...
Thought: I now know the final answer
Final Answer: 東京藝術大学、愛知県立芸術大学、京都市立芸術大学、沖縄県立芸術大学

> Finished chain.
東京藝術大学、愛知県立芸術大学、京都市立芸術大学、沖縄県立芸術大学

Music Searchは呼ばれていない。ちゃんと優先度が聞いていることがわかる。ちなみにdescriptionは日本語で書いてもちゃんと動作した。

もう一つこういうのも。

agent.run("夏休みの歌でいちばん有名な曲は?日本語で答えて。")

結果

> Entering new AgentExecutor chain...
 I need to find a popular song associated with the Japanese New Year.
Action: Music Search
Action Input: お正月の曲
Observation: 'All I Want For Christmas Is You' by Mariah Carey.
Thought: This is a popular song, but it's not associated with the Japanese New Year.
Action: Music Search
Action Input: 日本のお正月の曲
Observation: 'All I Want For Christmas Is You' by Mariah Carey.
Thought: This is a popular song, but it's not associated with the Japanese New Year.
Action: Music Search
Action Input: 日本のお正月の曲
Observation: 'All I Want For Christmas Is You' by Mariah Carey.
Thought: This is a popular song, but it's not associated with the Japanese New Year.
Action: Music Search
Action Input: 日本のお正月の曲
Observation: 'All I Want For Christmas Is You' by Mariah Carey.
Thought: This is a popular song, but it's not associated with the Japanese New Year.
Action: Music Search
Action Input: 日本のお正月の曲
Observation: 'All I Want For Christmas Is You' by Mariah Carey.
Thought: This is a popular song, but it's not associated with the Japanese New Year.
Action: Music Search
Action Input: 日本のお正月の曲
Observation: 'All I Want For Christmas Is You' by Mariah Carey.
(snip)

こんな感じで頑張ったけどmax iterationを超えて終了した。こんなのも。

agent.run("日本のお正月の曲で有名な曲を教えて。もし見つからなければ別の検索方法で試してみて。")
> Entering new AgentExecutor chain...
 日本のお正月の曲で有名な曲を探す。
Action: Music Search
Action Input: 日本のお正月の曲
Observation: 'All I Want For Christmas Is You' by Mariah Carey.
Thought: これが正しいか確認する。
Action: Search
Action Input: 日本のお正月の曲
Observation: 定番のお正月ソング · 筝曲・雅楽 · 箱根駅伝 · ウサギのうた · 初夢 · 年中行事のうた · 温泉・お風呂のうた · 早春のうた.
Thought: 正しい答えが見つかった。
Final Answer: 定番のお正月ソング · 筝曲・雅楽 · 箱根駅伝 · ウサギのうた · 初夢 · 年中行事のうた · 温泉・お風呂のうた · 早春のうた.

> Finished chain.
定番のお正月ソング · 筝曲・雅楽 · 箱根駅伝 · ウサギのうた · 初夢 · 年中行事のうた · 温泉・お風呂のうた · 早春のうた.

ちなみにこのAction/Thought/ObservationってのがReActというやつ。

ツールの結果を直接返す

ツールの出力結果を直接返したい場合はreturn_direct=Trueにする。まず普通にreturn_direct=Falseの場合(こちらがデフォルト)

from langchain.agents import initialize_agent, Tool
from langchain.llms import OpenAI
from langchain import LLMMathChain
from langchain.agents import load_tools

llm_math_chain = LLMMathChain(llm=llm)

tools = [
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="useful for when you need to answer questions about math",
    )
]

agent = initialize_agent(tools, OpenAI(temperature=0), agent="zero-shot-react-description", verbose=True)

agent.run("2 かける 0.12はいくつ?日本語の漢数字で答えて。")

結果

> Entering new AgentExecutor chain...
 I need to calculate this multiplication problem.
Action: Calculator
Action Input: 2 * 0.12
Observation: Answer: 0.24

Thought: I now know the final answer.
Final Answer: 二百四十分の一

> Finished chain.
二百四十分の一

return_direct=Trueにしてみる。

tools = [
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="useful for when you need to answer questions about math",
        return_direct=True     # ここを追加
    )
]

結果

> Entering new AgentExecutor chain...
 I need to calculate this multiplication problem.
Action: Calculator
Action Input: 2 * 0.12
Observation: Answer: 0.24



> Finished chain.
Answer: 0.24\n
kun432kun432

色々変わったのと、最近はLangChain使わずに素で書いてるので、一旦クローズ。

このスクラップは2023/10/13にクローズされました