AIネイティブなクリエーションエンジン「refly」を試す
Xかなんかで見かけて、Difyみたいなワークフロー作る的なやつなのかなと思いきや、なんかちょっと雰囲気が違っていそうで気になった。
紹介動画
公式(クラウドサービス)
GitHubレポジトリ
Refly.AI - AIネイティブなクリエーションエンジン
ReflyはオープンソースのAIネイティブなクリエーションエンジンです。その直感的なフリーフォームキャンバスインターフェースは、マルチスレッド対話、ナレッジベースRAG統合、コンテキストメモリ、インテリジェント検索、WYSIWYG AIエディターなどを組み合わせ、アイデアを簡単にプロダクションレベルのコンテンツへと変換できるようにします。
主な機能
- マルチスレッド対話
Reflyは革新的なマルチスレッド対話メカニズムを採用し、複数の独立した会話トピックを自由に切り替えることができます。これにより、従来の会話の制約を打破し、より自然で流動的な思考展開や深い議論を実現します。人間とAIの協働によるエージェント型ワークフローの構築に役立ちます。- AIによる高度な機能
AIモデルを活用し、入力した質問に対してキャンバス内の任意のノードをコンテキストとして使用して新しいノードを生成できます。AIウェブ検索、ナレッジベース検索、AI推奨質問、AIドキュメント生成などの機能が統合されており、Perplexity AIやStanford Stormのような技術を一つのワークスペースに組み込んでいます。- コンテキストメモリ
各会話のための一時的なナレッジベースを提供し、AIがより正確に質問を理解し、回答できるようにします。Cursorのように、キャンバス内の任意のノードを柔軟に選択してコンテキストとして追加できます。- ナレッジベース統合
外部リソースをインポートし、キャンバス内で知識システムとして活用できます。RAG(Retrieval-Augmented Generation)のような技術により、セマンティック検索を実現し、真の「第二の脳」として活用可能です。- 引用機能
各種リソースやドキュメント、メモ、スキルの出力を柔軟に選択し、ワンクリックでコンテキスト参照として追加可能。- AIドキュメント編集
強力なリアルタイムMarkdown編集機能を提供。Notionのような使いやすいAIエディターとして、AI支援による精密な編集が可能。
なんだろう、Perplexity的でもありChatGPT Canvas的でもありNotebookLMでもあり、って感じなのかな?
こちらのほうが説明が詳しいかもしれない
使い方
- クラウド版
- 設定不要で使用できるRefly Cloudを提供。GPT-4o-miniを無料で利用でき、GPT-4oやClaude-3.5-Sonnetの試用も可能。
- https://refly.ai/ にアクセスしてすぐに開始。
- セルフホスティング
- セルフホスティングガイドを参照し、自分の環境で実行可能。
- 企業・組織向け
- プライベートデプロイに関する問い合わせは support@refly.ai まで。
クラウドサービスもあるけど、セルフホストもできると。ただし、
ライセンス
このリポジトリはReflyAI Open Source Licenseのもとでライセンスされています。Apache 2.0ライセンスに追加の制限が適用されています。
Apache-2.0ベースだけど、企業での商用の場合は商用ライセンスが必要とという追加事項がある感じ。逆に個人利用の場合には個人の商業活動もOK、って感じに読める。
クラウドサービスを使う場合の価格はこちら
斎場のプランでも$8.3/月ってのは、この手のサービスとしては結構安いのでは?あんまりちゃんと読んでないのでわからないけども。ただ、ちょっと何ができるかまだわかってないので、それ次第で高い安いは判断かな。
インストール
セルフホストのドキュメントはこちら。めちゃめちゃ簡易な内容だが、docker composeで立ち上げれそう。
とりあえず対応している各種LLMモデル等は以下
- LLM
- OpenRouter
- OpenAI
- Embedding
- OpenAI
- Jina
- Fireworks
- Web検索
- Serper
上記以外にも連携できるAPIはいろいろあるようだが、主要なものは上記あたり。
で、reflyがメインで想定しているLLMプロバイダーはOpenRouterらしく、例えばOpenAIを使う場合にはデータベースの書き換えが必要になるらしい。今回はreflyの想定に従って
- LLM: OpenRouter
- Embedding: Jina
- Web検索: Serper
を使うことにする。それぞれのAPIキーを用意しておく。
環境はローカルのMacで。まずレポジトリクローン。
git clone https://github.com/refly-ai/refly && cd refly
dockerのディレクトリに移動
cd deploy/docker
.envの雛形から.envを作成
cp .env.example .env
デフォルトの.envはこんな感じ。コメント部分を日本語化してある。
# ----------------------------------------------
# APIサービスに必要な環境変数
# ----------------------------------------------
# 埋め込みプロバイダー(選択肢: jina, openai, fireworks)
EMBEDDINGS_PROVIDER=jina
# 使用する埋め込みモデルの名前
EMBEDDINGS_MODEL_NAME=jina-embeddings-v3
# OpenAI APIキー(LLM推論および埋め込みに使用)
OPENAI_API_KEY=
# OpenRouter APIキー(LLM推論に使用)
# 設定されている場合、LLM推論では OPENAI_API_KEY よりも優先される
OPENROUTER_API_KEY=
# Jina APIキー(埋め込みに使用)
JINA_API_KEY=
# Fireworks APIキー(埋め込みに使用)
FIREWORKS_API_KEY=
# Serper APIキー(Web検索に使用)
SERPER_API_KEY=
# ----------------------------------------------
# APIサービスのオプション環境変数
# (デフォルト値が適用される)
# ----------------------------------------------
# 一般設定
NODE_ENV=development
PORT=5800
WS_PORT=5801
ORIGIN=http://localhost:5700
STATIC_ENDPOINT=http://localhost:5800/v1/misc/
# Redis設定
REDIS_HOST=
REDIS_PORT=
REDIS_PASSWORD=
# データベース設定
DATABASE_URL=postgresql://refly:test@localhost:5432/refly?schema=refly
# ベクトルストア設定
QDRANT_HOST=
QDRANT_PORT=
QDRANT_API_KEY=
REFLY_VEC_DIM=768
# Elasticsearch設定
ELASTICSEARCH_URL=
ELASTICSEARCH_USERNAME=
ELASTICSEARCH_PASSWORD=
# MinIO設定(内部)
MINIO_INTERNAL_ENDPOINT=
MINIO_INTERNAL_PORT=
MINIO_INTERNAL_USE_SSL=
MINIO_INTERNAL_ACCESS_KEY=
MINIO_INTERNAL_SECRET_KEY=
MINIO_INTERNAL_BUCKET=
# MinIO設定(外部)
MINIO_EXTERNAL_ENDPOINT=
MINIO_EXTERNAL_PORT=
MINIO_EXTERNAL_USE_SSL=
MINIO_EXTERNAL_ACCESS_KEY=
MINIO_EXTERNAL_SECRET_KEY=
MINIO_EXTERNAL_BUCKET=
# 認証設定
AUTH_SKIP_VERIFICATION=true
REFLY_COOKIE_DOMAIN=
LOGIN_REDIRECT_URL=
JWT_SECRET=
JWT_EXPIRATION_TIME=
JWT_REFRESH_EXPIRATION_TIME=
# コラボレーション設定
COLLAB_TOKEN_EXPIRY=
# メール認証
EMAIL_AUTH_ENABLED=true
EMAIL_SENDER=
# Resend APIキー(メール認証が有効な場合に必要)
# https://resend.com/ で独自のキーを取得可能
RESEND_API_KEY=re_123
# GitHub認証
GITHUB_AUTH_ENABLED=false
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_CALLBACK_URL=
# Google認証
GOOGLE_AUTH_ENABLED=false
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_CALLBACK_URL=
# 埋め込み設定
EMBEDDINGS_DIMENSIONS=768
EMBEDDINGS_BATCH_SIZE=512
# リランカー(再ランク付け)設定
RERANKER_TOP_N=10
RERANKER_MODEL=jina-reranker-v2-base-multilingual
RERANKER_RELEVANCE_THRESHOLD=0.5
# スキル設定
REFLY_DEFAULT_MODEL=openai/gpt-4o-mini
SKILL_IDLE_TIMEOUT=10000
SKILL_EXECUTION_TIMEOUT=180000
# Stripe設定
STRIPE_API_KEY=
STRIPE_ACCOUNT_WEBHOOK_SECRET=test
STRIPE_ACCOUNT_TEST_WEBHOOK_SECRET=test
STRIPE_SESSION_SUCCESS_URL=
STRIPE_SESSION_CANCEL_URL=
STRIPE_PORTAL_RETURN_URL=
# クォータ設定(制限値)
QUOTA_T1_TOKEN=-1
QUOTA_T2_TOKEN=-1
QUOTA_T1_REQUEST=-1
QUOTA_T2_REQUEST=-1
QUOTA_STORAGE_FILE=-1
QUOTA_STORAGE_OBJECT=-1
QUOTA_STORAGE_VECTOR=-1
いろいろとオプションはあるようだが、LLM・Embedding・Web検索の3つが必須って感じに思えるので以下を設定した。(変更箇所だけ記載している)
EMBEDDINGS_PROVIDER=jina
EMBEDDINGS_MODEL_NAME=jina-embeddings-v3
OPENROUTER_API_KEY=XXXXXXXXXXXX
JINA_API_KEY=XXXXXXXXXXXX
SERPER_API_KEY=XXXXXXXXXXXX
docker composeで起動
docker compose up -d
以下のようなコンテナが立ち上がる。
docker compose ps
NAME IMAGE (snip) SERVICE (snip) STATUS PORTS
refly_api reflyai/refly-api:latest (snip) api (snip) Up 4 minutes (unhealthy) 3000/tcp, 0.0.0.0:5800-5801->5800-5801/tcp
refly_db postgres:16-alpine (snip) db (snip) Up 4 minutes (healthy) 0.0.0.0:5432->5432/tcp
refly_elasticsearch reflyai/elasticsearch:7.10.2 (snip) elasticsearch (snip) Up 4 minutes (healthy) 0.0.0.0:9200->9200/tcp, 9300/tcp
refly_minio minio/minio:RELEASE.2025-01-20T14-49-07Z (snip) minio (snip) Up 4 minutes (healthy) 0.0.0.0:9000-9001->9000-9001/tcp
refly_qdrant reflyai/qdrant:v1.13.1 (snip) qdrant (snip) Up 4 minutes (healthy) 0.0.0.0:6333-6334->6333-6334/tcp
refly_redis redis/redis-stack:latest (snip) redis (snip) Up 4 minutes (healthy) 0.0.0.0:6379->6379/tcp, 0.0.0.0:8001->8001/tcp
refly_web reflyai/refly-web:latest (snip) web (snip) Up 4 minutes (healthy) 0.0.0.0:5700->80/tcp
おっと、refly_api
が"Unhealthy"になっている・・・が、FAQに書いてある。
トラブルシューティング
アプリケーションが正常に動作しない場合は、以下の手順を試してみてください:
docker ps
を実行してUnhealthyなコンテナを特定します。docker logs <container_id>
を実行して、エラーに関する詳細情報を取得します。- Unhealthyなコンテナがrefly_api の場合は、
docker restart refly_api
を実行してコンテナを再起動します。- その他の場合は、コンテナのログからエラーメッセージの原因を検索できます。
問題が解決しない場合は、GitHub リポジトリで問題を提起するか、Discordサーバで私たちに連絡してください。
ということでrefly_api
を再起動してみる。
docker restart refly_api
docker ps
NAME IMAGE (snip) STATUS (snip)
refly_api reflyai/refly-api:latest (snip) Up 7 seconds (healthy) (snip)
(snip)
"Healthy"になったのでOKっぽい。
ブラウザでhttp://localhost:5700
にアクセスすると以下の画面になる。クラウドサービスと同じだが、ブラウザのURLを見るとローカルになっている。「Get Started」をクリック。
サインイン画面がでてくるが、初回はアカウント作成が必要なのでサインアップのリンクをクリック。
サインアップする。ローカルだとOAuthは効かないような気がしたので、自分はメアド+パスワードにした。
初回のセットアップ。インタフェースの言語とLLMが出力する言語を選択できる。インタフェースの方は英語・中国語だけなのだが、LLM出力の言語は日本語が選べた。自分はPC経由で使用するので「マウスフレンドリーモード」を選択。
機能の紹介ビデオがいくつか用意されているので、どういうことができるか?を理解する上で役に立つかもしれない。ボタンを見ているとインタラクティブなチュートリアルがあるように思えるので、それを試してみようと思う。
キャンバス画面に戻ってきた。インタラクティブなチュートリアルはどこ・・・?と思いながら「New Canvas」をクリックしてみる。
どうやらここでチュートリアルができそう。
チュートリアルを進めつつ使い方を学んでみる。
チュートリアル
ということで使い方をインタラクティブチュートリアルで進めていく、といっても実際に操作を行う訳ではないようなのだけど。
「Enter Fullscreen」でチュートリアルをブラウザの最大に表示するとやりやすい。
「View Steps」で進める。
サイドバーから「New Canvas」で新しいキャンバスを開く。
キャンバスの中央にある「Create Document」をクリックすると、新しい「ドキュメントノード」と「ドキュメントプレビューカード」が開く。
開いたドキュメントプレビューカードをピン留めしておく。
作成したドキュメントのタイトルを入力する。「Refly.aiとは何?」というタイトルになっている。(インタラクティブと言いつつ、入力はできないのだなぁ・・・)
キャンバスの空いてるスペースをダブルクリックすると「アクションメニューバー」が開く。
「Ask AI」をクリックして「AIノード」を作成。
AIノードでスラッシュ(/
)を入力して、「AIスキル選択」を有効にする。現時点ではReflyは4つの「スキル」を提供している。
「ネットワーク検索」スキル(画面では「Web検索」となっているが・・・)をクリックすると、すべてのネットワークを検索して、関連コンテンツの取得や質問回答が行える。
質問を入力する。「Refly.aiとは何?」
質問を送信
「AI回答カード(ノード)」をクリックして、回答の詳細を見る。
「View more and import to canvas」をクリックして、AIが生成した文書の根拠となる検索データを見ることができる。ここはちょっと意訳で、原文では「執筆マテリアルの根拠」というような言い方をしている。
関連する検索結果を選択していく。1つ目。
2つ目。
3つ目。
4つ目。
「Add to Canvas」で選択した検索結果=「執筆マテリアル」をキャンバスに追加して調査のために使うことができる。
キャンバスに追加された「執筆マテリアル」をクリックすると、「マテリアルプレビューカード」が開いて、マテリアルの詳細を確認することができる。追加されたマテリアルはAIの知識ベースにデフォルトで登録され、セマンティック検索を使って質問回答が行える。
執筆マテリアルのコンテンツを選択して、質問回答やメモを作成する事ができる。
マテリアルプレビューカードを閉じる。
マウスで範囲指定して複数ノードを選択して同じ処理を行うことができる。
複数の「執筆マテリアル」を選択して「Ask AI」をクリックすると、選択された複数のマテリアルに基づいて質問回答ができる。
でてきたAI質問ボックスに質問を入力する。「Refly.aiのコアバリューは?」
質問を送信。選択された執筆マテリアルはAIの質問コンテンツに追加され、それらを理解した上で回答が行われる。
AIドキュメントエディターに移動して、タイトルに「Refly.aiのコアバリューは?」と入力する。
AI回答ノードに移動して、ノードをマウスオーバーすると表示されるポップアップメニューバーから「Insert Document」をクリック。AIの回答がドキュメントエディタに追加される。
AIエディタで、2番目のパラグラフを作成、「Reflyのコア顧客は?」と入力。
キャンバスの空いてるスペースでダブルクリックして、アクションメニューバーを有効化、そして「Ask AI」をクリックしてAIノードを作成。
AIノードで/
を入力してスキルを有効にする。
「ナレッジベース」スキル(画面では「ライブラリ検索」となっているが・・・)を選択すると、インポートされたマテリアルがデフォルトで登録されているAIのナレッジベースに対してセマンティック検索を行って質問回答が可能になる。
ナレッジベーススキルを使って、「Reflyのコア顧客は?」と入力し、ナレッジベーススキルを使って検索・質問する。
質問を送信。自動的にナレッジベースが検索され、関連するマテリアルやドキュメントなどが質問回答に使用される。
AIエディタに戻って、空いてるところにパラグラフを書いていく
キャンバスに戻り、「AIナレッジベース回答」ノードをマウスオーバーして出てくるメニューバーから「Insert Document」をクリックして、コンテンツをエディタに追加する。
エディタ内のすべてのコンテンツを選択してポップアップしてくる「Ask AI」をクリックして、AIにコンテンツの最適化を手伝ってもらうことができる。
最適化してもらう要件を入力する。「2箇所最適化して」
送信するとReflyが選択されたコンテンツに基づいてAIに質問を行い、最適化されたコンテンツを出力する。
最適化された出力が得られたら「Replace Selection」で選択された箇所を置き換えることができる。
最後にドキュメントメニューを開く。
「Copy Content」でドキュメントがMarkdownとしてコピーされ、いろいろなプラットフォーム向けに活用できる
というのが一連の使い方の流れっぽい。
なるほど、やっぱり最初に感じた
なんだろう、Perplexity的でもありChatGPT Canvas的でもありNotebookLMでもあり、って感じなのかな?
ってのはあながち間違っていなかったのかもしれないな。
ただ、じゃあ実際に使ってみよう!ということでドキュメントを作成しようとすると・・・
こうなる・・・
セルフホストなのに・・・設定がまだ足りないのかも?とりあえずIssueあげた。
現時点でのまとめ
まだ実際に動くところを試せていない(一応LLMへのリクエストができることは確認した)のだけども、個人的な印象としては、当初イメージした通りのもので、
- ゴールとしては、何かしらの「ドキュメント」っぽいので、ChatGPT Canvasが一番近しい印象
- ChatGPT Canvasよりも、思考プロセスを細かく分解して、可視化しているような感じ
- どんどんWeb検索で情報集めて、取捨選択して、深堀りして、ナレッジに積み上げていって・・・というところは、Perplexity的でもありNotebookLM的でもあるように感じる
というような、思索のためのツール、というふうに認識した。多分こんな感じの思索フローになるのだと推測。
複数のツールを組み合わせて、こういう思索「プロセス」を実現することはできると思うのだけども、それを1つのインタフェース上で完結できる、というのがウリなのではなかろうか。
ただDeep Researchとかのようなそのへんのプロセスをまるっとやってくれるようなものもでてきていて、思考プロセスをマニュアルでやりたいのか自動でお任せしたいのかで、合う合わないはありそうだし、それぞれのメリデメもありそう。
Issueの回答が来たらもう少し触ってみようと思う。
ただ、じゃあ実際に使ってみよう!ということでドキュメントを作成しようとすると・・・
こうなる・・・
セルフホストなのに・・・設定がまだ足りないのかも?とりあえずIssueあげた。
Issueに回答くれた。以下のようにしてDBの設定を変更すればいいらしい。
docker exec -i refly_db psql 'postgresql://refly:test@localhost:5432/refly' << EOF
update refly.storage_usage_meters set file_count_quota = 10000
EOF
いけたー、制限のところも書き換わってる。
ちょっと色々触ってみようと思う。
チュートリアルに従って、サラッと進めてみた。テーマは「pygameのオーディオ処理」について。
最終的なドキュメント
pygameのオーディオ処理
pygameのセットアップ
Pygameのセットアップ方法を以下にまとめます。
1. Pygameのインストール
PygameライブラリをPCにインストールします。コマンドプロンプトで以下のコマンドを実行します。
pip install pygame
インストールが成功すると、「Successfully installed pygame -version ~」と表示されます。
2. サンプルゲームの実行
インストール後、サンプルゲームを実行してみましょう。コマンドプロンプトで以下のコマンドを実行します。
python -m pygame.examples.aliens
問題がなければ、ゲームのウィンドウが開きます。
3. 基本的なウィンドウの作成
Pygameを初期化し、ゲームウィンドウを作成します。以下は基本的なコードの例です。
import pygame import sys # 初期化 pygame.init() # ウィンドウの作成 screen = pygame.display.set_mode((800, 600)) # サイズを指定 pygame.display.set_caption("Pygame 基礎") # 色の定義 white = (255, 255, 255) # メインループ running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False screen.fill(white) # 背景色を塗る pygame.display.flip() # 画面を更新 pygame.quit() sys.exit()
このコードを実行すると、白い背景のウィンドウが表示されます。
まとめ
これらの手順を踏むことで、Pygameの基本的なセットアップが完了します。ゲーム開発を始める準備が整いました!
pygameでのサウンド処理
Pygameで効果音やBGMを再生するには、以下の手順を実行します。
- 音声ファイルを保存するディレクトリを作成:
snd/
というフォルダを作成し、その中に音声ファイル(例:shoot.wav
)を保存します。
- 音声ディレクトリのパスを変数に格納:
snd_folder = os.path.join(game_folder, "snd")
- Pygameの初期化:
pygame.init() pygame.mixer.init() # 音を扱うための初期化
Sound
クラスのインスタンスを作成:
- 音声ファイルの絶対パスを作成し、
pygame.mixer.Sound()
に渡してインスタンスを作成します。shoot_sound = pygame.mixer.Sound(os.path.join(snd_folder, "shoot.wav"))
- 音声を再生:
shoot_sound.play() # 音を再生 shoot_sound.set_volume(0.5) # 音量を調整
これで、Pygameを使用して効果音やBGMを再生する準備が整います。
サウンド再生を非同期で行うには、Pygameの
pygame.mixer
モジュールを使用します。以下の手順で実装できます。
- Pygameの初期化:
import pygame pygame.init() pygame.mixer.init()
- 音声ファイルの読み込み:
sound = pygame.mixer.Sound('path/to/soundfile.wav')
- 音声の再生:
sound.play() # 非同期で音声を再生
この方法で、音声はメインプログラムの実行をブロックせずに再生されます。音声の再生中に他の処理を行うことが可能です 。
また、音声の再生が終了した後に特定の処理を行いたい場合は、
set_endevent
を使用してイベントを設定することもできます 。以下のように、音声の再生終了イベントの設定と処理方法について説明を追加します:
# 音声の再生終了イベントを設定 SOUND_END = pygame.USEREVENT + 1 pygame.mixer.music.set_endevent(SOUND_END) # イベントループ内で再生終了を検知 while running: for event in pygame.event.get(): if event.type == SOUND_END: print("音声の再生が終了しました") # ここに再生終了後の処理を記述
音声の音量制御も重要な機能です。以下のメソッドを使用して音量を調整できます:
# 音量の設定(0.0から1.0の範囲) sound.set_volume(0.5) # 50%の音量に設定 # BGMの音量設定 pygame.mixer.music.set_volume(0.7) # 70%の音量に設定
その他の便利な音声制御機能:
- 一時停止と再開:
pygame.mixer.music.pause() # 一時停止 pygame.mixer.music.unpause() # 再開
- ループ再生:
sound.play(-1) # -1を指定すると無限ループ sound.play(3) # 3回繰り返し再生
- 再生の停止:
sound.stop() # 効果音の停止 pygame.mixer.music.stop() # BGMの停止
- フェードエフェクト:
pygame.mixer.music.fadeout(1000) # 1秒かけてフェードアウト
注意点:
WAV形式の音声ファイルが最も安定して動作します
MP3形式も使用可能ですが、追加のセットアップが必要な場合があります
同時に再生できる音声チャンネル数には制限があります
これらの機能を組み合わせることで、ゲームに適した音声制御を実現できます。
内容の精査まではしてないけど、ワークフローとしてはなんとなく理解できた気がする。
上に書いた「現時点でのまとめ」と印象は変わらない。
ただ、やるならフルスクリーンでやるのが良さそう、狭い画面やウインドウサイズだとしんどい。