😗

【Python】LangChainのAgentで複数の関数を使う

2024/03/11に公開

はじめに

ユーザーの入力に対して関数を使用する回数と順序をモデル自体に決定させて実行させる場合には、Agentが便利です。下記のサンプルコードを使い、LangSmithでトレースした結果も確認してみます。

https://python.langchain.com/docs/use_cases/tool_use/quickstart#agents

LangSmithの使い方はこの記事を参照してください。
https://zenn.dev/nari007/articles/e1531d3b9370cb

サンプルコード

※ envファイルにOPENAI_API_KEYの値を設定しています。

import os
from dotenv import load_dotenv

from langchain_core.tools import tool
from langchain import hub
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_openai import ChatOpenAI
from operator import itemgetter

load_dotenv()
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")


# 掛け算
@tool
def multiply(first_int: int, second_int: int) -> int:
    """2つの整数を掛け合わせます"""
    return first_int * second_int


# 足し算
@tool
def add(first_int: int, second_int: int) -> int:
    """2つの整数を加算します"""
    return first_int + second_int


# toolsにセット
tools = [multiply, add]

prompt = hub.pull("hwchase17/openai-tools-agent")
# promptの確認
prompt.pretty_print()

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

agent = create_openai_tools_agent(model, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

# 実行
# response = agent_executor.invoke({"input": "3と9を足したらいくつ?"})
response = agent_executor.invoke({"input": "3と9を足して。結果に2をかけてください。"})

# 結果
print(response["input"])
print(response["output"])

コードを実行してみます。
python test.py

実行結果

hwchase17/openai-tools-agentでのプロンプトの中身を確認するために
prompt.pretty_print()で表示させた内容です。

================================ System Message ================================

You are a helpful assistant

============================= Messages Placeholder =============================

{chat_history}

================================ Human Message =================================

{input}

============================= Messages Placeholder =============================

{agent_scratchpad}

agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
でverbose=Trueにしているとターミナルで下記のように経過を表示してくれます。
2つの関数が呼び出されています。

> Entering new AgentExecutor chain...

Invoking: `add` with `{'first_int': 3, 'second_int': 9}`


12
Invoking: `multiply` with `{'first_int': 12, 'second_int': 2}`


24
3と9を足すと12になります。そして、12に2をかけると24になります。

> Finished chain.

最後にprintのinputとoutputの内容です。

3と9を足して。結果に2をかけてください。
3と9を足すと12になります。そして、12に2をかけると24になります。

res = agent_executor.invoke({"input": "3と9を足したらいくつ?"})という質問をした場合は、1つの関数だけが呼び出されます。

res = agent_executor.invoke({"input": "こんにちは"})という質問をした場合は、当然ながら関数は実行されません。

LangSmithのトレース結果

それでは、この実行結果のトレース内容を確認してみます。

こちらをみるとChatOpenAIを2回呼び出しています。2つの関数呼び出しでの結果とそれを渡して回答を生成させるという流れで、「3と9を足すと12になります。そして、12に2をかけると24になります。」というOutputが返ってきていることがわかります。

まとめ

Toolを使う方法としてChainとAgentがありますが、Agentの場合はToolを最終応答までループするようなので、繰り返す回数がケースによって変わるかと思います。なので要件によって使い分けるのが良いですね。

https://python.langchain.com/docs/use_cases/tool_use/

Discussion