【プロンプト解説】ChatGPTとPlantUMLでソースコードからシーケンス図を作成する方法

ChatGPTを使用すれば、ソースコードからすぐに本格的でわかりやすいシーケンス図を作成することができます。

シーケンス図を作成することで、仕様をわかりやすく説明したり、プログラミング教育に使うこともできそうです。

以下のプロンプトを使用し、結果をPlantUMLのこちらに貼り付けることで、画像が生成されます。

プロンプト

以下のプロンプトの赤字部分を修正して使用してください。

GPT-4にて検証済みです。


# 命令書:
あなたはプロのエンジニアです。
以下の制約条件とソースコードをもとにシーケンス図を出力してください。

# 制約条件:
・わかりやすく書いてください。
・日本人に読みやすくしてください。プログラム中の名称以外は日本語にしてください。
・外部のURLは含めないでください。
・PlantUMLのシーケンス図が生成できるテキストを提供してください。ただし、AWSのアイコンを使用しないでください。

# ソースコード:
[ソースコード]

結果はこちらに貼り付けて画像を生成してください。

※ChatGPTがAWSのアイコンなどの外部URLを含めた結果を生成することがあり、これを貼り付けるとエラーになったため制約条件に条件を追加しています。

実行例

今回はツイッターAPIを使用してツイートを収集するプログラムのシーケンス図を作成しました。

プロンプト

# 命令書:
あなたはプロのエンジニアです。
以下の制約条件とソースコードをもとにシーケンス図を出力してください。

# 制約条件:
・わかりやすく書いてください。
・日本人に読みやすくしてください。プログラム中の名称以外は日本語にしてください。
・外部のURLは含めないでください。
・PlantUMLのシーケンス図が生成できるテキストを提供してください。ただし、AWSのアイコンを使用しないでください。

# ソースコード:

import requests
import os
import json
import time
import datetime
import codecs
# from janome.tokenizer import Tokenizer
# from botocore.vendored.requests.exceptions import ChunkedEncodingError

# 環境変数"BEARER_TOKEN"を設定する必要がある。APIで取得した値を設定する。


def auth():
    # return os.environ.get("BEARER_TOKEN")
    return "xxxxxx"


# tweet.fields=以下でTwitterから取得する属性を指定
def create_url():
    return "https://api.twitter.com/2/tweets/sample/stream?tweet.fields=id,created_at,author_id,lang,conversation_id,referenced_tweets,public_metrics,source,geo,entities,organic_metrics,promoted_metrics,context_annotations,attachments,withheld"
    # return "https://api.twitter.com/2/tweets/sample/stream?expansions=attachments.poll_ids,attachments.media_keys,author_id,entities.mentions.username,in_reply_to_user_id,referenced_tweets.id,referenced_tweets.id.author_id&media.fields=duration_ms,height,media_key,preview_image_url,type,url,width,alt_text&place.fields=contained_within,country,country_code,full_name,id,name,place_type&poll.fields=duration_minutes,end_datetime,id,options,voting_status&tweet.fields=attachments,author_id,context_annotations,conversation_id,created_at,entities,id,in_reply_to_user_id,lang,possibly_sensitive,referenced_tweets,reply_settings,source,text&user.fields=created_at,description,entities,id,location,name,pinned_tweet_id,profile_image_url,protected,url,username,verified"
    # public_metrics.retweet_count,public_metrics.reply_count,public_metrics.like_count,public_metrics.quote_count"


def create_headers(bearer_token):
    headers = {"Authorization": "Bearer {}".format(bearer_token)}
    return headers

# jsonに書き込むための関数

def write_json(data, path):
    if len(data) != 0:
        f = codecs.open(path, 'w', 'utf-8_sig')
        json.dump(data, f, indent=2, ensure_ascii=False)


def main():
    bearer_token = auth()
    url = create_url()
    headers = create_headers(bearer_token)
    # timeout = 0
    count = 0
    start = time.time()

    while True:
        # 15分あたりのリクエスト数上限50を超えないための条件分岐
        if count == 50:
            count = 0
            t = time.time() - start
            start = time.time()
            if t > 900:
                continue
            else:
                print("TooManyRequests, wait 15min")
                time.sleep(900)
                continue
        try:
            h = 'null'
            path = 'null'
            d_update = {}
            with requests.request("GET", url, headers=headers, stream=True) as response:
                print(response.status_code)
                for response_line in response.iter_lines():
                    if response_line:
                        json_response = json.loads(response_line)
                        if json_response["data"]["lang"] == "ja":
                            datatime = json_response["data"]["created_at"]
                            # 初めてのデータだったら、日付とパスを入れてjsonデータを読み取る
                            # 今までの日付と違ったら、jsonデータをファイルに入れて新しいファイルからjsonデータを読み取る
                            if h != datatime[5:13]:
                                if path != 'null':
                                    write_json(d_update, path)
                                h = datatime[5:13]
                                path = "daydata/" + h + ".json"
                                if not os.path.exists(path):
                                    d_new = {"data_num": 0}
                                    write_json(d_new, path)
                                with open(path, encoding="utf-8_sig") as f:
                                    d_update = json.load(f)
                            d_data = {}
                            m = datatime[14:19]
                            for k, v in json_response["data"].items():
                                if k == "lang":
                                    continue
                                if k == "conversation_id" and json_response["data"]["id"] == v:
                                    v = -1
                                d_data[k] = v
                            # リクエスト時の時刻(日本時間)
                            d_data["requested_time"] = str(
                                datetime.datetime.now())
                            j = d_update["data_num"]
                            d_update[j] = d_data
                            d_update["data_num"] += 1
                            print('{0} {1} {2}' .format(
                                j, h, m))
                            # break  # テスト用

            if not response.status_code == 200:
                raise Exception(
                    "Request returned an error: {} {}".format(
                        response.status_code, response.text
                    )
                )
                write_json(d_update, path)
            count += 1

        except KeyboardInterrupt:
            print("Ctrl+Cで停止しました")
            write_json(d_update, path)
            break

        except Exception as e:
            print(e)
            write_json(d_update, path)
            pass

    # connect_to_endpoint(url, headers)  # テスト用 while文はコメントアウトせよ

    # timeout += 1


if __name__ == "__main__":
    main()

出力(ChatGPT)

以下に、シーケンス図のPlantUMLテキストを提供します。このテキストをPlantUMLで使ってシーケンス図を生成できます。

plantuml
Copy code
@startuml
actor ユーザー
participant main関数
participant auth関数
participant create_url関数
participant create_headers関数
participant write_json関数
database JSONファイル

ユーザー -> main関数 : プログラムの実行
main関数 -> auth関数 : トークン取得
auth関数 --> main関数 : bearer_token

main関数 -> create_url関数 : URL作成
create_url関数 --> main関数 : url

main関数 -> create_headers関数 : ヘッダー作成
create_headers関数 --> main関数 : headers

main関数 -> main関数 : リクエストのカウントと時間を管理

loop 1回目のリクエストから15分以内で50回目のリクエストまで
    main関数 -> main関数 : リクエストの処理
    main関数 -> write_json関数 : JSONデータの保存
    write_json関数 -> JSONファイル : データ書き込み
    JSONファイル --> write_json関数 : 確認
    write_json関数 --> main関数 : 結果

    alt リクエストが成功しなかった場合
        main関数 -> main関数 : 例外処理
        main関数 -> write_json関数 : JSONデータの保存
        write_json関数 -> JSONファイル : データ書き込み
        JSONファイル --> write_json関数 : 確認
        write_json関数 --> main関数 : 結果
    end

    main関数 -> main関数 : リクエストカウントを増やす
end

main関数 -> main関数 : 15分待機
@enduml

PlantUMLに貼り付けた結果

このように、素早く本格的なシーケンス図を作成することができました。
あなたもこのプロンプトを使ったりカスタマイズしてシーケンス図を作ってみてください。