1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

node-red-dashboard-2-ui-chat でチャットUIを簡単につくってみる

Last updated at Posted at 2025-12-05

チャットUIを簡単につくりたい

会話型の生成AI UXとしてのChatGPT https://chatgpt.com/ の活用が進み、Node-REDでも各種LLMに対応したノードがたくさんリリースされていますが、Node-REDでチャットUIを簡単につくるのはなかなか大変でした。これまでは、node-red-dashboardのtemplateノードを使って、がんばって作るしかなかったのですが、2025年6月に、FlowFuseさん公式の @flowfuse/node-red-dashboard-2-ui-chat がリリースされ、ほかのユースケース並みに簡単にチャットUIが作れるようになりました。

本稿では、@flowfuse/node-red-dashboard-2-ui-chatで簡単にチャットUIを作ってみる方法を紹介します。

node-red-dashboard-2-ui-chat の機能

image.png

  • @flowfuse/node-red-dashboard 上で使えるチャットUI widget パネル
  • フロー入力については、plain textだけでなく markedjs / marked を使った GitHub Flavored Markdown に対応
  • フローからのテキスト動的送信(「入力中...」などステータス更新機能)
  • ユーザーのテキストをフローに送信
  • レスポンシブデザイン対応

なお、いまのところ画像やファイル添付、マルチメディア系の機能はないようです。@flowfuse/node-red-dashboardの別のWidgetと併用する必要があります。

準備

@flowfuse/node-red-dashboard-2-ui-chat@flowfuse/node-red-dashboard の拡張Widgetなので、まだ@flowfuse/node-red-dashboardを導入していない場合は先に導入が必要です。(古いnode-red-dashboardノードとは同居できません)

インストール

ほかのカスタムノード同様、「パレットの管理」の「ノードを追加」から導入可能です。
image.png

導入完了後、パレットの「ダッシュボード2」内にノードが追加されます。
image.png

ノードプロパティ

image.png

Groupにて、所属するダッシュボードグループを選択します。
Sizeはグループ内のChatのサイズを決めます。自動にするとグループの高さはグループの高さいっぱいに拡張されますが、高さを指定するとチャット内にスクロールバーが表示されます。
image.png

Show Autherにチェックを入れると、入力側のmsg.topicで指定した文字列が投稿者として表示されるようになります。
image.png

サンプルフロー

一番簡単なサンプル

image.png

入力のInjectノードでmsg.topicを指定すると、Auther欄に表示されます。

image.png

出力は、入力欄に入力した文字列がmsg.payloadに出力されます。
また、入力時刻とあわせて吹き出し内に表示されます。

image.png

Markdownの表示

@flowfuse/node-red-dashboard-2-ui-chatは入出力ともにMarkdown表示に対応しています。

image.png

Markdownの編集には、TemplateノードのMarkdown構文が便利です
image.png

Markdownがmsg.payloadとして入力されると、レンダリングされて表示されます。絵文字もOK。

image.png

入力中の表示

msg.topicに「_typing」と入力すると、

image.png

入力中のアニメーションの吹き出しが表示されます。(次に別の入力がされると消えます)

image.png

OpenAI社のAPIと合わせて簡易ChatGPT

カスタムノードで、OpenAI APIに対応したものは多数ありますが、OpenAIの最近のモデルに対応したものがなかなか見つからず...

とりあえず、@inductiv/node-red-openai-api を使ったサンプルフローを作成してみました。

image.png

サンプルフロー
[{"id":"7040d18ff2a02ff8","type":"ui-chat","z":"99375ea01c0bdca7","name":"","group":"5b76d627d38b3491","order":1,"width":"9","height":"7","showAuthor":true,"x":370,"y":100,"wires":[["dac2d4fe8491b28a","93158734034e47f4","166c5464e67f8101"]]},{"id":"dac2d4fe8491b28a","type":"debug","z":"99375ea01c0bdca7","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":580,"y":60,"wires":[]},{"id":"3e5145e390f3f7ef","type":"OpenAI API","z":"99375ea01c0bdca7","name":"OpenAIにChatを渡す","property":"payload","propertyType":"msg","service":"","method":"createChatCompletion","x":920,"y":100,"wires":[["0830c7d4b342e613","986d81120d834801"]]},{"id":"93158734034e47f4","type":"change","z":"99375ea01c0bdca7","name":"OpenAIに渡すオブジェクト作成","rules":[{"t":"set","p":"chat","pt":"msg","to":"payload","tot":"msg","dc":true},{"t":"set","p":"payload","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"payload.model","pt":"msg","to":"gpt-5-mini","tot":"str"},{"t":"set","p":"payload.messages","pt":"msg","to":"[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"MSGBODY\"}]}]","tot":"json"},{"t":"change","p":"payload.messages[0].content[0].text","pt":"msg","from":"MSGBODY","fromt":"str","to":"chat","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":650,"y":100,"wires":[["f06c010e60c56315","3e5145e390f3f7ef"]]},{"id":"0830c7d4b342e613","type":"debug","z":"99375ea01c0bdca7","name":"debug 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1120,"y":60,"wires":[]},{"id":"f06c010e60c56315","type":"debug","z":"99375ea01c0bdca7","name":"debug 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":880,"y":60,"wires":[]},{"id":"986d81120d834801","type":"switch","z":"99375ea01c0bdca7","name":"Assistant回答あったら","property":"payload.choices[0].message.role","propertyType":"msg","rules":[{"t":"eq","v":"assistant","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":1160,"y":100,"wires":[["822ae756e2a1e4d4"],["aba77d7d188e33b4"]]},{"id":"822ae756e2a1e4d4","type":"change","z":"99375ea01c0bdca7","name":"ChatUIの入力に成形","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.choices[0].message.content","tot":"msg","dc":true},{"t":"set","p":"topic","pt":"msg","to":"OpenAI","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1420,"y":160,"wires":[["7040d18ff2a02ff8"]]},{"id":"166c5464e67f8101","type":"change","z":"99375ea01c0bdca7","name":"OpenAIが返るまでTyping","rules":[{"t":"set","p":"topic","pt":"msg","to":"_typing","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":630,"y":180,"wires":[["7040d18ff2a02ff8"]]},{"id":"aba77d7d188e33b4","type":"change","z":"99375ea01c0bdca7","name":"ChatUIの入力に成形","rules":[{"t":"set","p":"payload","pt":"msg","to":"エラーかも?","tot":"str","dc":true},{"t":"set","p":"topic","pt":"msg","to":"OpenAI","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1420,"y":200,"wires":[["7040d18ff2a02ff8"]]},{"id":"5b76d627d38b3491","type":"ui-group","name":"Chat","page":"8371a201ccdd7508","width":"12","height":"6","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"8371a201ccdd7508","type":"ui-page","name":"chat page","ui":"b877a1cf4595ef72","path":"/page1","icon":"home","layout":"grid","theme":"c1f1387768ea1739","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":1,"className":"","visible":"true","disabled":"false"},{"id":"b877a1cf4595ef72","type":"ui-base","name":"My Dashboard","path":"/dashboard","appIcon":"","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"headerContent":"page","navigationStyle":"default","titleBarStyle":"default","showReconnectNotification":true,"notificationDisplayTime":1,"showDisconnectNotification":true,"allowInstall":false},{"id":"c1f1387768ea1739","type":"ui-theme","name":"Default Theme","colors":{"surface":"#ffffff","primary":"#0094CE","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"density":"default","pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}},{"id":"57864467dacc6e0c","type":"global-config","env":[],"modules":{"@flowfuse/node-red-dashboard-2-ui-chat":"1.2.0","@inductiv/node-red-openai-api":"1.103.0-patch.1","@flowfuse/node-red-dashboard":"1.29.0"}}]

@inductiv/node-red-openai-api のノードプロパティは以下のように設定し、
image.png

ServiceHostの設定ノードとして、OpenAIのAPI-Platformから取得したAPI Key
と、Org IDを設定します。

image.png

ChatGPTのように、AIとチャットを行うことができます~

image.png

ほかのWidgetとの連動

ノード紹介ページには node-red-contrib-web-worldmapの連動サンプルが紹介されています。

image.png

おわりに

ChatGPTの登場で、それまであまりニーズのなかった自然言語のUIが脚光を浴びている感じです。5分でできるNode-REDのユースケースにぜひ活用ください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?