はじめに
この1年ほどでGenerative AI(生成AI)は急速に普及し、私たちの身近な存在になりました。 個人的にAI動向を追っていると、生成AIは「ただ使う」だけではなく、考慮すべきことのレベルが一段階上がったように感じています。
例えば、最近では、より実践的な運用や統合に焦点が当たっています (そのように感じる)。
- LLMOps (Large Language Model Operations): 生成AIの運用を最適化する仕組み
- MCP (Model Context Protocol): AIとシステムのインターフェースを統一する規格 など
このように様々な試みがある中で、今回はReAct (Reasoning and Acting) という手法に注目し、実際に試してみたいと思います。
ReActとは、簡単に言うと自然言語の推論 (Reasoning) と外部とやり取りするツールを使って (Acting) 問題を解決するパラダイムです。
今回は以下のOracleが提供しているAgent AIに関するデモを基にReActを実践してみます。
Develop a Simple AI Agent Tool using Oracle Cloud Infrastructure Generative AI and REST APIs
なお、本記事では、このデモの実装の核となる部分を理解しやすくするため、コードや実行結果を要点を絞って抜粋して解説します。
もし、デモの全体像や詳細な手順、完全なコードにご興味のある方は、ぜひ上記の元のOCIドキュメントにアクセスして、ご自身で実践してみてください。
長くなりましたが、実際にやっていきます。
前提
今回のハンズオンは以下の環境で進めます。
- クラウドプロバイダ: Oracle
- 使用サービス: Generative AI Service
- 使用リージョン: 大阪リージョン (東京リージョンは未対応のため)
ハンズオン
最初にコードをダウンロードするように言われるため、指示通りダウンロードします。
プログラム実行前にいくつか準備が必要になります。
準備
1.検証用のvenv作成(必要に応じて)
いくつかpython用パッケージをインストールするため、venvを作成したほうが良いです。
以下一例です。
python3 -m venv oci-sample
source oci-sample/bin/activate
2.コード修正
サンプルプログラムを動かすために最低限必要な修正はChatOCIGenAIに渡すパラメータだけです。
llm = ChatOCIGenAI(
model_id="cohere.command-r-08-2024",
service_endpoint="https://inference.generativeai.ap-osaka-1.oci.oraclecloud.com",
compartment_id=<対象のCompartment ID>,
auth_profile="OSAKA", # replace with your profile name,
model_kwargs={"temperature": 0.1, "top_p": 0.75, "max_tokens": 2000}
)
例えば上記のようにします。
各パラメータは以下の通りです。
model_id: 変更なし。必要に応じて変更します。
service_endpoint: 今回大阪リージョンを使うため大阪用のものに変更しています。
compartment_id: 使っているoracle cloud環境のものを指定します。私はTenant IDを指定して実施しました。
auth_profile: Oracle Cloudで利用するProfileです。~/.oci/configにあることが多いかと思います。
model_kwargs: 変更なし。必要に応じて変更します。
プログラム実行
見やすいように少しprint分の出力を変えています。プログラムの内容には関係しないため変更部分は割愛します。
実行結果は以下です。
(oci-sample) root@me:/home/me/work/python_program/react-example# python agent-ai.py
/home/me/work/python_program/react-example/agent-ai.py:176: LangGraphDeprecatedSinceV10: create_react_agent has been moved to `langchain.agents`. Please update your import to `from langchain.agents import create_agent`. Deprecated in LangGraph V1.0 to be removed in V2.0.
langgraph_agent_executor = create_react_agent(
READY
You: hi
Hello! Would you like to place an order?
You: can you order omuraisu?
Yes, I can order omuraisu for you. Would you like to add it to your order?
You: I wanna eat a phone too.
I'm sorry, but I am unable to order a phone for you. I can only place food orders.
You: that's awesome!!!
Item(s): omuraisu
Type is not msgpack serializable: AIMessage ## エラー
You: list all orders.
Item(s): ['omuraisu']
Type is not msgpack serializable: AIMessage ## エラー
You: そうしたらかき氷も食べたいです。
Item(s): がきびょう
Total: $ 20
Type is not msgpack serializable: AIMessage ## エラー
You: 注文リストを表示してください。
Item(s): ['omuraisu', 'がきびょう']
Type is not msgpack serializable: AIMessage ## エラー
※残念ながら"Type is not msgpack serializable: AIMessage"というメッセージが表示されています。この部分は生成AIからの回答が出力される想定になっているようです。いろいろ試してみたのですが残念ながら解消に至りませんでした。後日試します。。。
実行結果確認
実際にAI Agentに注文してもらうところはうまくいっています。以下順番に結果を見てみます。
You: hi
Hello! Would you like to place an order?
挨拶をしてみました。ちゃんと挨拶を返してくれています!
You: can you order omuraisu?
Yes, I can order omuraisu for you. Would you like to add it to your order?
オムライスを頼んでみました。しっかりと注文に追加してくれました。
You: I wanna eat a phone too.
I'm sorry, but I am unable to order a phone for you. I can only place food orders.
電話食べたいと言ったら注文の受付をしてくれませんでした。裏にLLMがいるためしっかりと文意を理解してくれてます。
You: that's awesome!!!
Item(s): omuraisu
すごい!!と感想言ってみました。そうしたら注文リスト一覧を表示しました。
ここは残念ながら意図通りになってませんね。今回は危険な操作が実行されませんでしたが、実環境で調整が必要だと思いました。
You: そうしたらかき氷も食べたいです。
Item(s): がきびょう
Total: $ 20
You: 注文リストを表示してください。
Item(s): ['omuraisu', 'がきびょう']
最後に日本語で質問してみました。かき氷が'がきびょう'となってしまっています。
これももちろん意図通りではないので、日本語に強いモデルに変えるなど対応が必要になりそうです。
プログラム補足
以上でメインの部分は終わりです。
中身が気になる方向けに簡単にコード補足します。
1.
データベース接続
def connect_db():
return sqlite3.connect('orders.db')
SQLiteによって、ローカルに'orders.db'という名前のファイルが作成されます。
SQLiteはRDBMSですが、サーバが不要のソフトウェアです。
2.
AI Agentに実行させたい関数に対して @tool を付与してツールとして認識させます。
Tools are components that agents call to perform actions. (ドキュメントより)
@tool
def ...
その後、Agentにまとめて渡してあげることでツールとして認識します。
langgraph_agent_executor = create_react_agent(
model=llm, tools=tools, prompt=prompt, checkpointer=memory
)
ただ、今回試しにinsert_orderの@toolをコメントアウトして実行してみましたが、正常に追加できていました。今回はあまり深堀りせずにスルーします。
# @tool
def insert_order(item):
You: bread, please
Total: $ 20
Item(s): bread
Type is not msgpack serializable: AIMessage
You: list orders
Item(s): ['bread']
Type is not msgpack serializable: AIMessage
You: two pieces of bread too
Item(s): two pieces of bread
Total: $ 40
Type is not msgpack serializable: AIMessage
You: list orders
Item(s): ['bread', 'two pieces of bread']
おわりに
学習のためにReActを試してみました。やりたいことはわかりやすいですが、実際の環境に導入するには考えることが多そうだと感じました。
また、技術の進歩が速く、現在使っているライブラリの仕様変更にも注意が必要です。デモの中で使っているcreate_react_agent()は既にdeprecatedになっていました。チームの中で効率的に修正・リリースする仕組みを作る必要がありそうです。
もし今回のデモに興味を持った方がいたら、ぜひ自分の環境で試してみてください。
最後までお読みいただきありがとうございました。