見出し画像

ChatGPTからマインドマップを自動生成。ウェブアプリの開発秘話&コード公開

先日の朝。

ということで作りましょう。今回はシュンスケさんに許可をいただき、その過程を備忘録としてまとめました!

完成像(シンプルだけど、動きます!笑)

フォームに作って欲しいテーマを入力してボタンを押せば、そのままマインドマップが生成されます!

最後にコードも載せておいたので、使ってみたいという方はご自由にお試し下さい!

1,データからマインドマップを作成する

静止画だとわかりにくいのですが、今回作成したマインドマップはご多分に漏れず「ノード(⚫)を押すとその枝が開閉する」という仕組みになっています。でも、一から作るのはあまりに面倒。そこでGPT-4に聞いたところ

「Reacr D3 Treeを使えば楽やで!」

とのこと。さっそく出力してくれたコード(ただし2021年以降にライブラリのアップデートがあったためか、そのままは使えず。)と公式サイトを参考に、以下のようにコードを仕上げました。

なお、私の場合、フレームワークはNext.jsを使用しています。Djangoなどの場合このライブラリは使えないので、ご注意ください。

こんなのが作れるらしい!
Mindmap.tsx(マインドマップの部分)

<div
  ref={treeContainer}
  className='w-full h-screen'
  onMouseDown={handleMouseDown}
  onMouseMove={handleMouseMove}
  onMouseUp={handleMouseUp}
  onMouseLeave={handleMouseUp}
>
  <Tree
    data={treeData}
    translate={translate}
    separation={separation}
    zoom={0.8}
    initialDepth={2}
    zoomable={true}
    draggable={true}
    onNodeClick={handleNodeClick}
  />
</div>
今回のマインドマップに読み込ませるデータ

const data = {
  name: "1. メインの枝1",
  children: [
    {
      name: "1-1. サブの枝1",
      children: [
        { name: "1-1-1. サブの枝1" },
        { name: "1-1-2. サブの枝1" },
        { name: "1-1-3. サブの枝1" },
      ],
    },
    {
      name: "1-2. サブの枝1",
      children: [
        { name: "1-2-1. サブの枝1" },
        { name: "1-2-2. サブの枝1" },
      ],
    },
    {
      name: "1-3. サブの枝1",
      children: [{ name: "1-3-3. サブの枝1" }],
    },
    { name: "1-4. サブの枝1" },
  ],
};

すると……

デンッ!

おお! まさにイメージ通り。ということは、上記のデータ形式でプロンプトから出力してもらえば良さそうですね。

ここで、いよいよシュンスケさんのプロンプトが炸裂します。

2,プロンプトに質問を投げかけ、アプリ側が認識できるように整形する

シュンスケさんのすごいところ。それが「めちゃくちゃ早い」そして「超高精度」なところ。ChatGPTの出る暇もありません笑

ありがたいことに、シュンスケさんに「上記の形式で出力できるプロンプトを作ってくれませんか?」と訪ねたところ、即レスでプロンプトがご到着。私の伝達ミスで少しだけ書き加えましたが、最終的には以下のようなプロンプトになりました。

中心のトピックは〇〇

Please use the template below to create a mind map. Please output as a string that can be converted to json with JSON.parse. Replace the variable parts of the template with your own content, using square brackets [ ] to enclose them. # [Central Topic] - ## [Branch 1] - ### [Sub-branch 1.1] - #### [Sub-sub-branch 1.1.1] - [Leaf Node 1] - [Leaf Node 2] - [Leaf Node 3] - #### [Sub-sub-branch 1.1.2] - [Leaf Node 4] - [Leaf Node 5] - [Leaf Node 6] - ### [Sub-branch 1.2] - #### [Sub-sub-branch 1.2.1] - [Leaf Node 7] - [Leaf Node 8] - [Leaf Node 9] - #### [Sub-sub-branch 1.2.2] - [Leaf Node 10] - [Leaf Node 11] - [Leaf Node 12] - ## [Branch 2] - ### [Sub-branch 2.1] - #### [Sub-sub-branch 2.1.1] - [Leaf Node 13] - [Leaf Node 14] - [Leaf Node 15] - #### [Sub-sub-branch 2.1.2] - [Leaf Node 16] - [Leaf Node 17] - [Leaf Node 18] - ### [Sub-branch 2.2] - #### [Sub-sub-branch 2.2.1] - [Leaf Node 19] - [Leaf Node 20] - [Leaf Node 21] - #### [Sub-sub-branch 2.2.2] - [Leaf Node 22] - [Leaf Node 23] - [Leaf Node 24] loop infinitely アシスタント:トピックは何ですか? lang:jp

アウトプットスタイル:
{
  "name": "1. メインの枝1",
  "children": [
    {
      "name": "1-1. サブの枝1",
      "children": [
        { "name": "1-1-1. サブの枝1" },
        { "name": "1-1-2. サブの枝1" },
        { "name": "1-1-3. サブの枝1" },
      ],
    },
    ...
}

ということで〇〇の部分に質問を入れて、APIを発射。しかし、このままだと文字列が返ってきてしまうので、ここがちょっとした肝なのですが、パソコン用の言葉に変換する処理を加えました。

const parseJSON = (obj: string) => {
  try {
    // 最初と最後の文字が同じ「'」または「"」であれば削除する
    const firstChar = obj.charAt(0);
    const lastChar = obj.charAt(obj.length - 1);
    if ((firstChar === "'" && lastChar === "'") || (firstChar === '"' && lastChar === '"')) {
      obj = obj.slice(1, -1);
    }
    const replacedString = obj.replace(/`/g, "");

    // 最初の「{」の前の文字列を削除する
    const braceIndex = replacedString.indexOf("{");
    const formattedString = replacedString.slice(braceIndex);

    // 変換後のJSONを作成
    const formattedJson = JSON.parse(formattedString);
    // console.log(obj)
    // console.log(formattedJson)
    return formattedJson;
  } catch (e) {
    console.log('error : ',e)
    return null;
  }
}

この処理をかけてあげることで、

文字列

といった文字の羅列から

json(っぽいもの)

アプリで読み込める形式に変換されました!(画像はイメージです)

あとはこれを先程のマインドマップの中身に入れてあげれば……

読み込まれた!
閉じることも可能!

出てきました!

ということで嬉しくなり、さっそくシュンスケさんに連絡。

デプロイ(サーバーにコードを入れ、色々使えるようにする)まで終わらせ、無事公開できました。冒頭のツイートを見つけてからここにいたるまで、わずか3時間!

ただ、多くの方に使っていただけたことと引き換えに、APIキーの費用も馬鹿にならないことになっていたので、現在上記のアプリのリンクは現在停止しています。(入れますが、マップは生成されません。)使っていただいた方、ありがとうございました!

おわりに

今回の最大の収穫は、やはり「プロンプト次第でビジュアル形式の出力もできる」ということではないでしょうか。

これまでも

このように表として見やすくする、などはできましたが、今回のようにマインドマップでしかも開閉やズームなど操作できるようにもできるんですね。プロンプト様々です。

もちろん今回がマインドマップだっただけで、他のグラフなども比較的簡単に作れるようになってきています。

冷静に考えてみると、世の中のデジタル上のものは全て、文字で表されているんですよね。そう、0と1で。今ご覧になっているnoteもVue.js/Nuxt.js(エディタはReact/Next.js)で書かれていますし、画像と言えど文字で表現されています。

今回のアプリも実は全部文字

OpenAIがいよいよプラグインも発表し、これまでは導入の難しかった分野へもAIが浸透していく。

おそらく、今回作成したプロトタイプのようなものも、数日から数カ月後にはxmindなどの有名なマインドにAIが組み込まれることで簡単に実現されるでしょう。

では、今回作ったのは意味がなかったのか? プロンプトを試行錯誤することに価値はないのか?

少なくとも私は、それを踏まえた上で、今回のウェブアプリを作りました。近日別の記事でも書く予定ですが、今後避けられないAIの波に私達が飲み込まれないようにするためには、「どんな職業が生き残るの?」とただChatGPTに投げるのではなく、それについて自分なりに考えたり実際に触ったりシステムそのものを作ること、AIについて深く理解することだと感じています。

というのもありますが、実際はただ作ってみたかったからです笑

AI vs 人類の話を考えながらも、これやってみたい、そのためにはどうすればいいんだ…? こんな感じで考えると、AIを使った面白い案も出てきやすくなると思います。

そんなこんなで、今回はChatGPTとプロンプトデザインを組み込んだウェブアプリができるまでを書いてみました。

終始丁寧に対応していただいたシュンスケさんに感謝です!

ではでは!

コード

上記をgit cloneして

OPENAI_API_KEY={自分のAPIキー}

「.env.local」という名前のファイルを.gitignoreなどと同じ階層に加えて下さい。あとは

npm i

でパッケージをインストール、必要に応じて各自の環境に合わせて設定を変更すれば自分の環境でいつでも動かせるようになります!(例えばNode.jsを使ったことのない方はインストールする必要があります)

おつかれさまでした!

この記事が気に入ったらサポートをしてみませんか?