チャット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 の機能
- @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ノードとは同居できません)
インストール
ほかのカスタムノード同様、「パレットの管理」の「ノードを追加」から導入可能です。

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

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

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

サンプルフロー
一番簡単なサンプル
入力のInjectノードでmsg.topicを指定すると、Auther欄に表示されます。
出力は、入力欄に入力した文字列がmsg.payloadに出力されます。
また、入力時刻とあわせて吹き出し内に表示されます。
Markdownの表示
@flowfuse/node-red-dashboard-2-ui-chatは入出力ともにMarkdown表示に対応しています。
Markdownの編集には、TemplateノードのMarkdown構文が便利です

Markdownがmsg.payloadとして入力されると、レンダリングされて表示されます。絵文字もOK。
入力中の表示
msg.topicに「_typing」と入力すると、
入力中のアニメーションの吹き出しが表示されます。(次に別の入力がされると消えます)
OpenAI社のAPIと合わせて簡易ChatGPT
カスタムノードで、OpenAI APIに対応したものは多数ありますが、OpenAIの最近のモデルに対応したものがなかなか見つからず...
とりあえず、@inductiv/node-red-openai-api を使ったサンプルフローを作成してみました。
サンプルフロー
[{"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 のノードプロパティは以下のように設定し、

ServiceHostの設定ノードとして、OpenAIのAPI-Platformから取得したAPI Key
と、Org IDを設定します。
ChatGPTのように、AIとチャットを行うことができます~
ほかのWidgetとの連動
ノード紹介ページには node-red-contrib-web-worldmapの連動サンプルが紹介されています。
おわりに
ChatGPTの登場で、それまであまりニーズのなかった自然言語のUIが脚光を浴びている感じです。5分でできるNode-REDのユースケースにぜひ活用ください。












