はじめに
この記事は「LLM・LLM活用 Advent Calendar 2024」4日目の記事になります。
生成AIについての話題を聞かない日はないくらい、生成AIが盛り上がりを見せていますね。そんな生成AIの中でも、私はAIエージェントに注目しています。
AIエージェントは特定のタスクを自律的に実行し、環境と相互作用する能力を持つようなAIシステムのことで、2025年はAIエージェントが話題の中心になるとも言われています。AIエージェントにもさまざまな種類がありますが、大きく「シングル型」と「マルチ型」に分けることが出来ます。
本記事では、シングルAIエージェントの中でも非常に有名な"ReAct"というAIエージェントの内容と実装方法を紹介します。
ReActとは
"ReAct"は2022年に公開された「ReAct: Synergizing Reasoning and Acting in Language Models」という論文で提案されたAIエージェントです。
これまで、AIによる推論 (Reasoning) と行動 (Acting) は別々のトピックとして研究されてきましたが、双方を合わせて行う形にすることで、「自分で考え、行動し、問題を解決する」ということが出来るようになりました。
具体的には、まずユーザがアイディアやタスクをAIエージェントに投げかけます。
AIエージェントはツールを保持しており、渡されたタスクに対して保持しているツールを使うべきかを判断します。
ツールを使う場合、ツールを実行して得られた結果をAIエージェントに返し、その内容を元にユーザへの回答を提示します。
実装方法
実装においては、LangGraphのReActのページが参考になります。
まず最初に、必要なライブラリをインストールします。
他の記事などではLangChainを利用しているものが多いですが、現在はLangGraphを利用することが推奨されています。
$ pip install -U langgraph langchain-openai
次に、使用するLLMのセッティングを行います。
API KEYはスクリプトに直書きでも良いですが、安全性を考えるならば.envファイルに記述することをオススメします。
import os
# OpenAI API KEYの例
os.environ["OPENAI_API_KEY"] = "{API KEY}"
model = ChatOpenAI(model="gpt-4o", temperature=0)
続いて、AIエージェントが必要に応じて使用するツールを作成します。
今回は例として、東京と岩手の天気予報を提供するツールを作成します。
@tool
def get_weather(city: Literal["tokyo", "iwate"]):
"""Use this to get weather information."""
if city == "tokyo":
return "It might be cloudy in tokyo"
elif city == "iwate":
return "It's always snow in iwate"
else:
raise AssertionError("Unknown city")
tools = [get_weather]
次にgraphの構築です。
graphの構築はたった1行で出来ます。
どのようなgraphが出来たか、確認することもでき、今回の場合、図のような非常にシンプルなgraphが構築されていることが分かります。
# graphの構築
graph = create_react_agent(model, tools=tools)
# グラフの可視化
png_data = Image(graph.get_graph().draw_mermaid_png())
with open("output_graph.png", "wb") as f:
f.write(png_data.data)
最後に、プロンプトを設定して実行してみましょう!
def print_stream(stream):
for s in stream:
message = s["messages"][-1]
if isinstance(message, tuple):
print(message)
else:
message.pretty_print()
inputs = {"messages": [("user", "what is the weather in iwate")]}
print_stream(graph.stream(inputs, stream_mode="values"))
こちらを実行すると、以下のような出力が得られるかと思います。
まず最初に、ユーザが入力したプロンプトが"Human Message"で示されており、AIエージェントはToolが必要と判断してcity: iwateの情報を取得しています。
取得した情報が"It's always snow in iwate"なので、その情報を元にAIエージェントがユーザに"The weather in Iwate is snowy"と回答しています。
================================ Human Message =================================
what is the weather in iwate
================================== Ai Message ==================================
Tool Calls:
get_weather (call_PMPG39UHUqPrSQXWVaamDQL0)
Call ID: call_PMPG39UHUqPrSQXWVaamDQL0
Args:
city: iwate
================================= Tool Message =================================
Name: get_weather
It's always snow in iwate
================================== Ai Message ==================================
The weather in Iwate is snowy.
一方、Toolを使っても判断できない情報が渡されると、以下のようにToolを使わずにLLMが持っている情報から回答を作成します。
inputs = {"messages": [("user", "who built you?")]}
================================ Human Message =================================
who built you?
================================== Ai Message ==================================
I was developed by OpenAI, a research organization focused on creating and promoting friendly AI for the benefit of all humanity.
今回使用したスクリプトの全体は以下の通りです。
全体スクリプト
from langchain_openai import ChatOpenAI
from typing import Literal
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
from IPython.display import Image
import os
os.environ["OPENAI_API_KEY"] = "{API KEY}"
# LLMモデル設定
model = ChatOpenAI(model="gpt-4o", temperature=0)
# toolで与えるデータの設定
@tool
def get_weather(city: Literal["tokyo", "iwate"]):
"""Use this to get weather information."""
if city == "tokyo":
return "It might be cloudy in tokyo"
elif city == "iwate":
return "It's always snow in iwate"
else:
raise AssertionError("Unknown city")
tools = [get_weather]
# graphの構築
graph = create_react_agent(model, tools=tools)
# グラフの可視化
png_data = Image(graph.get_graph().draw_mermaid_png())
with open("output_graph.png", "wb") as f:
f.write(png_data.data)
def print_stream(stream):
for s in stream:
message = s["messages"][-1]
if isinstance(message, tuple):
print(message)
else:
message.pretty_print()
inputs = {"messages": [("user", "what is the weather in iwate")]}
print_stream(graph.stream(inputs, stream_mode="values"))
まとめ
今回はAIエージェントの中でも有名なReActについてご紹介しました。
ReActはAutoGPTでも用いられていたりなど、非常に重要な技術となっています。
AIエージェントについてのキャッチアップの一助になれば幸いです。