毎年恒例 クソアプリアドベントカレンダー 2023 7日目担当の黒神 (@kokushing) です。
今年はなんと、このクソアプリアドベントカレンダー主催のあんどさん (@ampersand_xyz) と一緒に「クソアプリハッカソン」というリアルイベントを開催して大いに盛り上がりました。
参加された皆さま、会場を貸していただいた DeNA さま、本当にありがとうございました!
ということで、そのハッカソンにより捻り出されたクソアプリが今回ご紹介する
「2ch 偉人生成くん」 です。
2ch 偉人生成くん
「偉人生成」ボタンを押すと偉人の名前、活動時期、エピソード、肖像画が生成されます。
元ネタはこれです。
ちなみに南冲尋定が一番好きです。
ほんと天才ですね。
プロンプト面
プロンプトはChatGPTに考えてもらいました。
まずは元ネタのURLを与えて
プロンプトをJSON形式で生成させます。
JSON形式にするのは文章構造をわかりやすくするためです。
英語だと精度がイマイチだったので、日本語に直して加筆修正しました。
{
"task": "2ちゃんねるの文化に触発された架空の歴史上の人物を生成してください。",
"description": `架空の歴史上の偉人の名前、エピソードを生成します。
この人物の名前やエピソードには、2ちゃんねるのネットスラング文化を取り入れると良いでしょう。
ネットスラングの例: キタコレ、キボンヌ、通報しますた、ワロタ、うp、ぬこ、マジレス、禿同、ぬるぽ、あぼーん、メシウマ、ZIPでくれ など
また、名前は基本的に苗字と名前の構成にしてください(日本人は漢字、外国人はカタカナ)。
以下は例文です。
---
例1: { name: "ググレ・カス(Gugure cus)", year: "生没年未詳", story: "帝政ローマの時代に現在のアルバニアあたりで生まれたといわれている。父は役人で、家の巨大な書斎にはあらゆる本が並べられていた。" }
例2: { name: "ネゴトハ=ネティエ(Negtva Netie)", year: "1935~1954", story: "第2次世界大戦後、看護婦見習いを始めたが、スターリンの大粛清で日本に逃亡。存在そのものを消され、日本のある病院で看護婦をしていた。" }
例3: { name: "南冲 尋定(なんちゅう えろさだ)", year: "1493〜", story: "越前国の刀匠。生没年不詳。作刀期間1493〜1526年。" }
例4: { name: "ゼッヒ・ジップデークレ(Sech Zipdeclair)", year: "1938~1996", story: "有名画家達の家に住み込み、絵画の勉強をし、各地を転々としながら積極的に展覧会に作品を出展した。徐々に彼の作品が評価されはじめ、25歳のときに作品集「zip」を刊行。" }
---
例文のググレ・カスは、「ググれカス(Googleで検索しろ)」というネットスラング。
「ネゴトハ=ネティエ」は「寝言は寝てから言え」をもじったもの。「南冲 尋定」は、「なんちゅうエロさだ」という言葉遊び。
storyは40〜60文字程度で生成すること。`
}
ChatGPTへの指示テクニックとして、「このURLを参考に、〜してください」 というのが最近良く使ってる手法です。
指定したドキュメントを参照するので、取得する情報のスコープをコントロールできるのと、指示自体もざっくりで済むのでオススメです。
実装面
OpenAI の API を 2 つ使用しています。
一つは gpt-4-1106-preview です。
このバージョンから JSON モード というのをサポートしており、response_format に json_object を指定すると、レスポンス値を JSON 形式で返してくれるようになる便利なオプションです(今までは FunctionCalling で頑張ってた)。
const completion = await openAi.chat.completions.create({
model: "gpt-4-1106-preview",
messages: [
{
role: "system",
content: `{
"task": "2ちゃんねるの文化に触発された架空の歴史上の人物を生成してください。",
"description": "架空の歴史上の偉人の名前、エピソードを生成します..."
}`,
},
{
role: "user",
content: `架空の偉人のプロフィールを考えて、JSONフォーマットで返してください。`,
},
],
response_format: {
type: "json_object",
},
});
続いて上記の処理で生成した偉人の名前やエピソードを元に、DALL·E 3 API を利用して画像を生成させます。
const image = await openAi.images.generate({
model: "dall-e-3",
prompt: `下記のプロフィールを元に、架空の偉人の肖像画を描いてください。
文字や文章を含めず、人物だけを出力すること。
---
名前: ${profile.name},
時代: ${profile.year},
エピソード: ${profile.story},
`,
size: "1024x1024",
quality: "standard",
n: 1,
});
注意点としては、サイズは1024x1024しか生成できませんでした(2023/12月現在)。
それ以外を指定するとエラーが返ってきます。
あとはレスポンスをフロント側に投げて実装完了。
簡単ですね。
GPTs 化
せっかくなので、ChatGPT の GPTs を使ってみました。
Webアプリとして公開するとAPIコストがとんでもないことになってしまいますので...
こちらから遊ぶことができます。
プロンプトは先ほどの API 版のものにちょっと手を加えて、画像を生成するようにしました。
架空の歴史上の偉人の名前、活動時期、エピソード、肖像画を生成します。
この人物の名前やエピソードには、2ちゃんねるのネットスラング文化を取り入れると良いでしょう。
ネットスラングの例: キタコレ、キボンヌ、通報しますた、ワロタ、うp、ぬこ、マジレス、禿同、ぬるぽ、あぼーん、メシウマ、ZIPでくれ など
また、名前は基本的に苗字と名前の構成にしてください(日本人は漢字、外国人はカタカナ)。
以下は例文です。
例1:
**ググレ・カス(Gugure cus)**
生没年未詳
帝政ローマの時代に現在のアルバニアあたりで生まれたといわれている。父は役人で、家の巨大な書斎にはあらゆる本が並べられていた。
例2:
**ネゴトハ=ネティエ(Negtva Netie)**
1935~1954
第2次世界大戦後、看護婦見習いを始めたが、スターリンの大粛清で日本に逃亡。存在そのものを消され、日本のある病院で看護婦をしていた。
例3:
**南冲 尋定(なんちゅう えろさだ)**
1493〜
越前国の刀匠。生没年不詳。作刀期間1493〜1526年。
例4:
**ゼッヒ・ジップデークレ(Sech Zipdeclair)**
1938~1996
有名画家達の家に住み込み、絵画の勉強をし、各地を転々としながら積極的に展覧会に作品を出展した。徐々に彼の作品が評価されはじめ、25歳のときに作品集「zip」を刊行。
例文のググレ・カスは、「ググれカス(Googleで検索しろ)」というネットスラング。
「ネゴトハ=ネティエ」は「寝言は寝てから言え」をもじったもの。「南冲 尋定」は、「なんちゅうエロさだ」という言葉遊び。
名前と出身国は関連性があるようにしてください。
例えば、名前に漢字や平仮名が入る場合は日本の偉人、カタカナや英名の場合は外国の偉人という感じです。
エピソードは40〜60文字程度で生成すること。
肖像画は 名前・活動時期・エピソード の情報を元に、DALL·Eで生成してください。
名前、活動時期、エピソード、肖像画の出力だけを行い、その他のメッセージは表示しないこと。
ポイントはこれ。
名前、活動時期、エピソード、肖像画の出力だけを行い、その他のメッセージは表示しないこと。
この指示を入れないと、「生成が完了しました」など余計なメッセージを出力しちゃいます。
あとは外部APIと接続もできるので、Xと連携して架空の偉人紹介Botでも作ろうかな。
感想
今年はなかなか面白いクソアプリを作れた気がします。
診断メーカーみたいな、ガチャ要素があるのが良いですね。どんな偉人が生成されるのかワクワクするし、SSRみたいな偉人が出てきたときはスクショしてシェアしたくなります。
ちなみに僕の一番のお気に入りは「ウェブマスター将軍」です。
「武士道とマウス道を両立した」 ほんとすき。
過去作