Blog

Python コードから Mermaid のフローチャートを生成する

こんにちは。気づいたら新卒 2 年目の statiolake です。人間がやらなくていいことは極力プログラムにやらせようと思って日々を過ごしています。

さて、最近関わっている業務の中で、draw.io を利用してかかれたフロー図をコードの修正に応じてメンテナンスするというタスクが発生しました。draw.io はこういう図を書くのに本当に便利ではあるのですが、だとしても後からステップや条件分岐を足したりするのは面倒です。正直コードを書く労力の 10 倍くらい大変な作業に感じました。この手間をなんとかなくしたいと考え、draw.io は難しくてもテキストベースの Mermaid であれば Python から自動生成することも可能なのではないか? と思い至り、色々試してみたというエントリです。

忙しい方向け

Python のコードを Mermaid に変換するツールを作りました。コードは以下のリポジトリに置いています。

また、このツールを Web から使うことができるようにもしました。以下のリンクから覗いてみてください。

Mermaid とは

Mermaid はテキストベースで色々なグラフがかけるツールです。その中にはフローチャートもあります。例えば以下のようなテキストを書いたとしましょう。

ここから以下のようなフローチャートを表示できます。

Mermaid は Notion や GitHub との相性もいいです。Markdown のコードブロックに上の Mermaid のコードを書くだけで、自動的にフローチャートが表示されるようになります。

本題: Python から Mermaid に変換したい

広く使われている言語であるところの Python からこんなに便利な Mermaid に変換する機能、需要もありそうですし、探せばどこかにはあるだろうと思っていました。しかし意外にも Google で検索した限りでは見つかりませんでした。となると何らかの方法で自分で用意する必要があります。

生成 AI の力を頼ってみる

現代なので、とりあえずこういう汎用的なタスクには生成 AI が使えるのではないかと考えるのが常です。実際、Python から Rust に書き換えるなど、プログラミング言語間の変換は割と正しくやってくれるイメージです。というわけで、同じように Python から Mermaid のコードに変換するようお願いしてみました。

今回使用した Python のサンプルコードは以下のコードです。いい感じにループや条件分岐があってよさそうな感じなので採用させていただきました。生成 AI によって生成された (ものを一部手直しした) 、ブラックジャックのスコア計算っぽい関数です。

で、まずこれを Claude 3 Haiku に投げてみました。プロンプトにはあまり凝っていません。それで生成されたのがこちら。

うーん、雰囲気は感じますが、フローチャートではないですね。突然矢印が途切れていますし、これを見せられたらより混乱してしまうような気がします。まだコードを直接読んだほうが簡単ではないでしょうか。ちなみに出てきたものをそのまま与えると syntax error になってしまい、手動での手直しも必要でした。

もう一つ、GPT-4o にも聞いてみました。

さすがというべきか、正しい処理フローは抑えています。ただこれもフローチャートとしては見づらいです。これも結局元のコードのほうが読みやすい気がします。

まあ、フローが間違っていない以上、GPT-4o 側というよりはどちらかというと Mermaid 側のレイアウト計算にとって難しいという問題なのかもしれません。だとしてもループなどの制御構造についてはもう少し見やすいほうがありがたく、まるで goto 文を見ているかのようです。

諦めて自力で実装してみた

結局生成 AI にそのまま聞くだけでは満足行く成果は得られませんでした。冷静に考えると元々が機械可読な Python のコードなわけですから、機械的に変換してしまったほうがよいかもしれません。こんな感じのステップでいけるはずです。

Rust に Python のパーサーがあったことが決め手となり、実装に踏み切りました。そしてその完成したツールがこちらです。

これを使って生成したフローチャートが以下です。

どうでしょう。個人的には一番きれいに生成できているのではないかと思います。また、生成 AI と違ってこのプログラムは何回実行しても同じフローチャートを返します。スタンドアロンなプログラムなので CI 環境下でも使えます。つまり… GitHub Actions に仕込めば、変更を自動的にフローチャートに反映させることも可能です。夢が広がりますね。

また、ここまででも結構いい感じなのですがもう一歩、この段階まで用意してあげてから生成 AI にかけると、構造を維持しながらラベルをもう少しわかりやすくすることもできます。あるいはもっとうまくプロンプトを指定してあげれば、冗長な部分を削ったり適当な粒度でステップを結合してくれたりもするかもしれません。そこまでできたらもう手動でフロー図を書く必要はないと言っても良さそうです。

なお、今後の余裕があればラベルをソースコード側でカスタマイズできるようにする機能追加も考えています。

おまけ: 手軽に試してみたいあなたに

せっかくなので、このツールを気軽に試せるよう、GitHub Pages を使って Web 化しました。

お手元の Python ソースコードをつっこんで遊んでやってください。

…ところでコアロジックは Rust で書かれています。GitHub Pages は静的サイトホスティングサービスなので、裏で Rust の API サーバーが動いているわけではありません。それではこの Web ページはどうやって変換処理を実行しているのでしょうか?

実はこの Web ページでは WebAssembly にコンパイルされた Rust のコードがあなたのパソコンの中で動いています!

今回のフロントエンドは GitHub Actions + SvelteKit (adapter-static) + Rust WebAssembly で構成されています。びっくりするほど簡単に Rust のプログラムをブラウザで動かすことができたので、もしかしたら次の記事で紹介するかもしれません。

終わりに

今回は Python のコードを Mermaid のフローチャートに変換するツールを実装しました。こういったルールベースの厳密な変換処理はただ適当に生成 AI に投げるだけでは厳しく、まだまだ手書きしたほうが強い部分もありそうです。また、確率的に文言を生成する AI の仕組み上、一定の品質で決定的な結果を得ることも難しいです。

ただし、ラベルの調整部分は AI の得意分野で、非常にわかりやすいフロー図にブラッシュアップしてくれました。些細な例ですが、このように他の手法と AI による手法を組み合わせることで質が大きく向上する例はいくらでもありそうです。AI をただ適当にそのまま使うのではなく、うまく組み合わせて更に高い価値を生み出すことができるように精進していきたいと感じました。

ニフティでは、
さまざまなプロダクトへ挑戦する
エンジニアを絶賛募集中です!
ご興味のある方は以下の採用サイトより
お気軽にご連絡ください!

Tech TalkやMeetUpも開催しております!
こちらもお気軽にご応募ください!

connpassでニフティグループに
参加いただくと
イベントの
お知らせが届きます!