RAGアプリやLLMエージェントをオーケストレーションできるフレームワーク「Dynamiq」を試す
ここで知った。
GitHubレポジトリ
Dynamiq
DynamiqはエージェントAIとLLMアプリケーションのためのオーケストレーションフレームワークである。
Dynamiqへようこそ!🤖
Dynamiqは、AI搭載アプリケーションの開発を効率化するために設計された、オールインワンのGen AIフレームワークです。Dynamiqは、検索支援生成(RAG)と大規模言語モデル(LLM)エージェントのオーケストレーションに特化しています。
ドキュメント
Getting Started
Getting Startedに従って進めてみる。なお、要件がPython-3.12以上ということで、Colaboratoryでは動かない・・・
ということで、ローカルのMac上で試す。JupyterLabのDockerイメージを使う。
$ docker run --rm -p 8888:8888 -v .:/home/jovyan/work quay.io/jupyter/minimal-notebook:latest
出力されるURLにアクセスして、以降はJupyterLab上の作業。
パッケージインストール
!pip install dynamiq
!pip freeze | grep -i dynamiq
dynamiq==0.3.0
OpenAI APIキーをセット。
import getpass
import os
os.environ["OPENAI_API_KEY"] = getpass.getpass('OPENAI_API_KEY')
ではまずシンプルなLLMフロー。入力内容を翻訳するというもの。
from dynamiq.nodes.llms.openai import OpenAI
from dynamiq.connections import OpenAI as OpenAIConnection
from dynamiq import Workflow
from dynamiq.prompts import Prompt, Message
import json
# 翻訳用のプロンプトテンプレートを定義
prompt_template = """
Translate the following text into Japanese: {{ text }}
"""
# 定義されたテンプレートでプロンプトオブジェクトを作成
prompt = Prompt(messages=[Message(content=prompt_template, role="user")])
# LLMノードをセットアップ
llm = OpenAI(
id="openai", # ノードの一意な識別子
connection=OpenAIConnection(), # APIキーを使って接続
model="gpt-4o-mini", # 使用するモデル
temperature=0.3, # モデルのtemperature
max_tokens=1000, # 最大出力トークン
prompt=prompt # モデルに与えるプロンプト
)
# ワークフローオブジェクト
workflow = Workflow()
# ワークフローにLLMノードを追加
workflow.flow.add_nodes(llm)
# 入力データでワークフローを実行
result = workflow.run(
input_data={
"text": "Hola Mundo!" # 翻訳されるテキスト
}
)
# 翻訳結果を表示
print(json.dumps(result.output, indent=2, ensure_ascii=False))
結果
{
"openai": {
"status": "success",
"input": {
"text": "Hola Mundo!"
},
"output": {
"content": "こんにちは、世界!",
"tool_calls": null
}
}
}
次にシンプルなReActエージェント。ここではツールとしてe2bのCode Interpreterを与えてコードを実行させる。e2bのAPIキーが必要。
e2bのAPIキーをセット。
os.environ["E2B_API_KEY"] = getpass.getpass('E2B_API_KEY')
ReActエージェントのコード。そこそこに時間がかかる。
from dynamiq.nodes.llms.openai import OpenAI
from dynamiq.connections import OpenAI as OpenAIConnection, E2B as E2BConnection
from dynamiq.nodes.agents.react import ReActAgent
from dynamiq.nodes.tools.e2b_sandbox import E2BInterpreterTool
# E2Bツールを初期化
e2b_tool = E2BInterpreterTool(
connection=E2BConnection()
)
# LLMをセットアップ
llm = OpenAI(
id="openai",
connection=OpenAIConnection(),
model="gpt-4o-mini",
temperature=0.3,
max_tokens=1000,
)
# ReActエージェントを作成
agent = ReActAgent(
name="react-agent",
llm=llm,
tools=[e2b_tool],
role="シニアデータサイエンティスト",
max_loops=10,
)
# 入力を元にエージェントを実行
result = agent.run(
input_data={
"input": "最初の10個の数字を計算し、その結果が素数であるかどうかを判定して。",
}
)
print(result.output.get("content"))
結果
The prime status of the first 10 natural numbers is as follows:
- 1: Not prime
- 2: Prime
- 3: Prime
- 4: Not prime
- 5: Prime
- 6: Not prime
- 7: Prime
- 8: Not prime
- 9: Not prime
- 10: Not prime
マルチエージェントの例。この例では、e2bに加え、さらに検索ツールとしてScale SERPというものが使用されているのだが、調べてみた感じ、Scale SERPにはどうも無料枠がなさそう。他の検索ツールだとTavilyが使用できるようなので、それに書き換えてみた。
TavilyのAPIキーをセット
os.environ["TAVILY_API_KEY"] = getpass.getpass('TAVILY_API_KEY')
マルチエージェントのコード。
from dynamiq.connections import (OpenAI as OpenAIConnection,
Tavily as TavilyConnection,
E2B as E2BConnection)
from dynamiq.nodes.llms import OpenAI
from dynamiq.nodes.agents.orchestrators.adaptive import AdaptiveOrchestrator
from dynamiq.nodes.agents.orchestrators.adaptive_manager import AdaptiveAgentManager
from dynamiq.nodes.agents.react import ReActAgent
from dynamiq.nodes.agents.reflection import ReflectionAgent
from dynamiq.nodes.tools.e2b_sandbox import E2BInterpreterTool
from dynamiq.nodes.tools.tavily import TavilyTool
# ツールの初期化
python_tool = E2BInterpreterTool(
connection=E2BConnection()
)
search_tool = TavilyTool(
connection=TavilyConnection()
)
# LLMを初期化
llm = OpenAI(
connection=OpenAIConnection(),
model="gpt-4o-mini",
temperature=0.1,
)
# エージェントを定義
coding_agent = ReActAgent(
name="coding-agent",
llm=llm,
tools=[python_tool],
role=(
"コーディングスキルを持つエキスパート・エージェント。"
"ゴールは、Pythonのソフトウェアエンジニアリングスキルを使って、"
"入力タスクに対するソリューションを提供すること。"
),
max_loops=15,
)
planner_agent = ReflectionAgent(
name="planner-agent",
llm=llm,
role=(
"企画力のあるエキスパートエージェント。"
"ゴールは、複雑な要求を分析し、詳細な行動計画を提供すること。"
),
)
search_agent = ReActAgent(
name="search-agent",
llm=llm,
tools=[search_tool],
role=(
"Web検索スキルを持つエキスパート・エージェント。"
"ゴールは、ウェブ検索と要約のスキルを使って、"
"入力タスクの解決策を提供すること"
),
max_loops=10,
)
# adaptive agent managerを初期化
agent_manager = AdaptiveAgentManager(llm=llm)
# オーケストレータを作成
orchestrator = AdaptiveOrchestrator(
name="adaptive-orchestrator",
agents=[coding_agent, planner_agent, search_agent],
manager=agent_manager,
)
# 入力タスクの定義
input_task = (
"コーディングスキルを使って、過去10年間のNvidiaとIntelの株価に関するデータを収集し、"
"各社の年平均を計算し、表を作成する。そしてレポートを作成し、10年前に100ドルを投資して"
"いたらどうなっていたか、という結論を加える。"
)
# オーケストレータを実行
result = orchestrator.run(
input_data={"input": input_task},
)
# 結果を出力
print(result.output.get("content"))
ざっとみた感じ、
- 3人のエージェントが用意されている
- コーディングエージェント
- コードを書いて処理するReActエージェント
- e2bでPython実行環境がツールとして与えられている
- プランナーエージェント
- 要求分析・行動計画を立てるReflectionエージェント
- ツールはなし
- 検索エージェント
- Web検索を行うReActエージェント
- Tavily検索がツールとして与えられている
- コーディングエージェント
- adaptive agent managerというのが恐らくこれらのエージェントへのタスク割当などを行う
という感じで、エージェントが強調して株価を元にレポートを作成するというもの。
実行した結果は以下。そこそこに時間がかかった。
### Final Report on Nvidia and Intel Stock Performance Over the Past Decade
#### Introduction
This report analyzes the stock performance of Nvidia Corporation (NVDA) and Intel Corporation (INTC) over the past ten years. It includes the calculation of annual average stock prices for both companies and evaluates the potential returns on a hypothetical investment of $100 made ten years ago.
#### Annual Average Stock Prices
The following table summarizes the annual average stock prices for Nvidia and Intel from 2014 to 2024:
| Year | Average Price NVDA | Average Price INTC |
|------|---------------------|---------------------|
| 2014 | $0.504400 | $35.669778 |
| 2015 | $0.592956 | $32.179127 |
| 2016 | $1.344030 | $33.329127 |
| 2017 | $3.744593 | $37.794661 |
| 2018 | $5.809604 | $49.054980 |
| 2019 | $4.364692 | $51.375198 |
| 2020 | $9.890709 | $54.892055 |
| 2021 | $19.521993 | $55.851786 |
| 2022 | $18.568956 | $38.594502 |
| 2023 | $36.569260 | $33.826800 |
| 2024 | $100.900029 | $32.910000 |
#### Investment Analysis
To assess the investment potential of both stocks, we consider a hypothetical investment of $100 made ten years ago (in 2014):
- **Nvidia (NVDA)**:
- The average price in 2014 was approximately $0.5044.
- With an investment of $100, the number of shares purchased would be:
\[
\text{Shares} = \frac{100}{0.5044} \approx 198.51 \text{ shares}
\]
- As of October 2024, the price of Nvidia stock is approximately $100.90.
- The current value of the investment would be:
\[
\text{Current Value} = 198.51 \times 100.90 \approx 20,073.59
\]
- **Intel (INTC)**:
- The average price in 2014 was approximately $35.6698.
- With an investment of $100, the number of shares purchased would be:
\[
\text{Shares} = \frac{100}{35.6698} \approx 2.80 \text{ shares}
\]
- As of October 2024, the price of Intel stock is approximately $32.91.
- The current value of the investment would be:
\[
\text{Current Value} = 2.80 \times 32.91 \approx 92.15
\]
#### Conclusion
The analysis reveals a stark contrast in the investment performance of Nvidia and Intel over the past decade. If $100 had been invested in Nvidia ten years ago, it would be worth approximately **$20,073.59** today, reflecting a remarkable return on investment. In contrast, the same investment in Intel would yield a value of approximately **$92.15**, indicating minimal growth.
This significant disparity highlights Nvidia's exceptional growth trajectory compared to Intel, making it a more lucrative investment option over the past ten years. Investors should consider these trends when evaluating future investment opportunities in the semiconductor industry.
Click to add a cell.
んー、なんか最終回答を英語で出力しがちな感がある。。。。
所感
- コード見てるだけでなんとなく雰囲気はわかるし、見様見真似でも書けそうな気がする
- (書けるとは言ってない。)
- コード的には過去いくつか見てきたエージェントフレームワークとそんなに大差はない気がする。
- というか、Dynamiqならでは、という点はあまり見えない。
- (ここは自分の経験が足りないとかも当然ある)
まあエージェントフレームワークたくさん出てきた中で、ある程度、これが標準、みたいな設計パターンはあるように思うので、後発という点でもまあ真っ当な実装という感はある。
ただ、Quick Start見てても細かい説明が一切ないので、どういう思想で作ったのか、 とかが全然わからないんだよな。
で、ドキュメント見てると、チュートリアルを見たほうが良さそうに思えるのだが、
ただこれも説明そんなにないんだよねぇ、この内容だとコメントと変わらん。
それ以外のドキュメントはコンポーネントのAPIリファレンスになってるっぽくて、サンプルコードみたいなものも上記以外にはないし、読み物的なドキュメントも一切見当たらない。
ある程度雰囲気が分かればリファレンスを追っていくだけでも書けそうではあるし、自分のスキルレベルですらある程度予測しながら書けそうではあるので、設計としてはしっかりしてるんじゃないか、という気はする。
ただ、ドキュメントの感じとか、あと、Quick Startなのに有償しか提供してないツールを選んでいるところとか、なんというか使う人を選びそうではある。
とりあえずRAGのところざっとみたけど、ここはエージェントほど抽象化されてなくて、ややベタな雰囲気を感じた。