見出し画像

OpenAI GPT APIを用いたAI小説生成環境の作成 ー生成AI・チャットと小説ー

 前回の続き。現状報告+α になります。小説生成環境はそれなりに機能追加しながら文章生成のテストを繰り返しています。ただ、これなら面白い小説が書けそうだ!というものにはなっておりません。加えて言うなら「面白い」という方向に向かうためには、技術的なブレイクスルーが必要だということが実感としてわかってしました。

考えてみれば当たり前。これまでChatGPTが話題になる以前から、AIで小説を書かせる研究をされてきた方々やサービスを展開されている方々がたくさんおられる中、似たようなことは既に何度もトライされているはず。
GPT-3が出てきた時点で、面白い小説が自動で書けるようなら、とっくにやってますよね。

チャットというアプリケーション

いまChatGPTが話題になっているのも、OpenAIが「チャット」というアプリケーションに絞ってサービスを公開したからここまで話題になったわけで、GPT-3が発表された頃はAI研究者以外はそれほど騒いでいませんでしたよね。

去年、MidjourneyやStable Diffusionが急に話題になり始めた頃、とあるセミナーで、確か松尾豊教授だったと思いますが、"AI研究者の間ではGPT-3でかなり盛り上がったのに世間は結構知らん顔だなと思ってたら、MidjourneyやStable Diffusionはリリースされたとたんに世間が騒いでいるので意外な感じだ" というようなことを仰っていました。

その時は、絵が出るってわかりやすいのかな?みたいな話になったと記憶していますが、いまになって思えば、GPT-3はアプリケーションになっていなかったということだったのですね。

チャットというのは微妙なアプリケーションで、AIの相手をする人間の方がAIを擬人化してしまうんですよね。60年ほど前に開発され、当時かなり話題になったというELIZAも、セラピストの会話を真似たチャットシステムです。

もう少し最近だと、インターネット以前のパソコン通信時代を知っておられる方は覚えていると思いますが、電子掲示板(BBS)で、シグオペがいなくても、適当に会話をして場をつなぐ人工無能(人工無脳)というプログラムがありました。

ちょっとした辞書を持っていて、ユーザーが入力した文章に、辞書に載っている単語があれば、該当する返答を返すというだけの簡単なプログラムなのですが、それでも、ある程度大きな辞書(といっても、いまの感覚ではむちゃくちゃ小さいですが)と気の利いた返答のセットをあらかじめ作っておけば、それなりに会話めいたことができたのです。

ん……まぁ、当時は「会話ができる」というよりは、人工無能のとんちんかんな返答に、人間が話を合わせて珍妙な会話を楽しむという感じでしょうか。
積極的に人間がコンピュータプログラムを擬人化してやると、それなりに楽めるのですね。

つまり、文章生成AIのアプリケーションをチャットに絞ってチューニングしたのは、ビジネスとしてとてもうまい。
特に、「ChatGPTに質問したらこんな答えが返ってきました!」っていうノリは、人類としては、既に60年前と、30年前に経験済みで、21世紀になっても同じ遊びで盛り上がっているわけです。
もちろん、中身の技術レベルははるかに高度になっていますが。

チャットシステムに特化されたAIで小説を書くということ

この1、2か月、ChatGPT とOpenAIのGPT関連のAPIをいじってみてわかったことは、まるで人間のように会話はしてくれるものの、結局、こいつらは誰でも言いそうな返事を返してくれるだけだということ。

それは、LLMが誰が書いたかもわからない大量の文章から単語の羅列を学習してしまっているからなのか、最終段階で人による強化学習が行われて無難な回答をするようにチューニングされているからなのかはわかりませんが、ともかく、思考をもう一歩踏み込ませることができません。

たぶん、世界中で膨大な人々が経験したと思いますが、OpenAIのGPTを使って物語を作成しようとしたとき、自然言語の文章として破綻していない長文を出力させることはできても、主人公が活躍する肝心な場面になると「困難を乗り越え」とか「苦労の末」などという言葉であっさり片付けられてしまいます。あらすじ紹介やアイデア段階の初期プロットとしては成立しても、物語とか小説というにはほど遠いものしか作れません。

もちろん「この文章を読んでみてよ。AIが出力したんだって!下手な人間より上手いよね!」という面白さはあるので、AIが出力した文章であるということを含めたエンターテイメントは成立するかもしれません。
しかし、このままでは文章の中身が「面白い」と思えるものにならないのです。

「AIのせいにするなよ。それはきみのプロンプトが悪いからだよ」

偉大なる先駆者の方々からはそう言われそうですが、実際にやってみると、たとえ4000字程度の短編であっても、汎用的に小説と呼べる文章を生成し続けるプロンプトというものはなく、結局は人間が細かく区切って誘導してやらないといけません。

こうなってしまうと、ほとんど人間がストーリーを考えて、思った文章をAIに出力させるためのプロンプトを考えて、出力された文章を読んでプロンプトを修正して……? やっぱりAIいる??というところにハマってしまうんですよね。(´;ω;`)

小説に特化システム

いちいち人間が先を考えながらプロンプトを修正し続けるぐらいなら、AIのべりすと や、Novel AI など、ChatGPTの登場以前からあるサービスを使った方が楽かもしれません。

例えば、ChatGPTの登場よりだいぶ前、AIのべりすとが話題になり始めた頃、筆者が作ったお話はこんな感じ。

【泣きながら捨てる桃の話】

むかしむかし、あるところにお爺さんとお婆さんがおりました。
お爺さんは山へ芝刈りに、お婆さんは川へ洗濯に行きました。「おーい」と声をかけても返事はありません。
しばらくすると川上から大きな桃がどんぶらこっこ、どんぶらこと流れてきました。
「これは良い桃だわい。持って帰ろう」
お爺さんは大きな桃を家に持ち帰り、早速切ってみることにしました。包丁を入れてみると思ったよりもずっと柔らかく、まるで水でも切るかのようです。そうして切り分けると中からはなんとも芳しい香りが漂ってきます。
「これなら食べられるなあ」
そこへ、お婆さんが帰ってきました。「ただいま帰りましたよ」
「ああ、お帰り。早かったね」
「ええ、このくらいの距離なら私にはお茶の子さいさいですよ」
「それは頼もしいなあ」
二人は早速桃を食べてみることにしました。するとどうでしょう。その味といったら! 口の中いっぱいに広がる果汁は甘く瑞々しく、噛めばシャキシャキとした歯ごたえとともに爽やかな酸味が広がります。お爺さんとお婆さんはあまりの美味しさにびっくり仰天してしまいました。
「ところでこれは何だろう?」と、お爺さんは言いました。「さあ? 一体なんでしょうかねえ?」と、お婆さんは答えました。
それからというもの、お爺さんの家は桃ばかり食べているようになりました。しかし、いくら食べても桃は一向に減る様子がなく、とうとう困り果ててしまいました。そこでお爺さんとお婆さんは相談をして、桃をどこかへ捨ててしまうことにしたのです。そして桃を捨てに行く道すがら、お爺さんはこう呟きました。
「それにしても惜しいことだ。町には飢餓で苦しんでいる子どもたちもいるというのに」それを聞いたお婆さんは涙を流しながら言いました。
「本当に可哀想なことですねえ。私たちのような老夫婦がこんなにも幸せだというのに……」
こうしてお爺さんとお婆さんは泣きながら桃を捨てて回りました。ところが不思議なことに、桃を捨てれば捨てるほど二人の家の前には桃が増えていき、しまいには立派な木になるほどになりました。
そこでお爺さんとお婆さんはその木を大切に育て上げ、毎年桃の実ができるたびに嬉しそうに食べるようになったということです。
めでたしめでたし。

「AIのべりすと」で作成したお話

結局、子供たちの飢餓はどうなるんだ!と思ったら、最後の「めでたしめでたし。」の行を手動で消して、続きを書かせます。運が良ければ、飢餓の話について言及されるかもしれません。

小説風の文章を作成することに特化したAIシステムで、AIに対して指示を出すプロンプトはなく、基本的にAIはそれまでに書いた文章の続きを作成するのみで、前から順番に書き進んでいきます。

使い方はわかりやすくて便利なのですが、もっと全体の話の流れをコントロールしたいというのが本音のところ。
どうにか、うまく盛り上げどころや落としどころを作る方法はないものかと考えてしまいます。

とはいえ、OpenAIのチャットシステム用にチューニングされたAIで小説を書くということは、例えば、Excelの図形描画機能を使って機械図面を書くようなもので、「出来なくはないけど、そういうもんじゃないよ」とか、「いやそれ、逆にしんどいだろ」というものなのかもしれません。

加えて、Excelの図形描画であれば、時間をかければ少々複雑な図面でも描き切ることができますが、生成AIの場合は、どんなに時間をかけてプロンプトをいじくりまわしても結局モノにならないことがあるので、かなりタチが悪いものかもしれません。

これは罠かもしれない

そう考えると文章生成に限らず生成AIというやつは、プロンプトをあれこれ試行させることによって、人間から大量の時間を奪い取っていきます。これはもう「プロンプトエンジニアリングの罠」といっていいかもしれません。

「AIがポンと出した絵を自分が描いたみたいに自慢しやがって!」と、何かにつけて批判の対象になっている画像生成AIですら、使ったことのない人が言うほど簡単に好みの画像は出てきません。

いま、生成AIによって、プロンプトエンジニアリングの罠にハマった世界中の人間から膨大な時間が奪い取られていると思うと、この生成AIブームは生産性を上げるどころが、むしろ大幅に下げている可能性があります。下手をすると、コロナ禍よりもヤバイかもしれません。

プロンプトエンジニアリングの罠をさらに巧妙にするシステム

そんなことを考えながらも、OpenAIの"gpt-3.5-turbo"と、"gpt-4"を使って、どうにか面白い小説を書く仕組みは作れないかと試行錯誤中です。

つまり、いまのところ自らプロンプトエンジニアリングの罠にハマり込みに行っているのですが、似たようなプロンプトを何度も書かなくていいように、Gradioで作業環境を整えつつ、底なし沼の底を手探りで探索中です。

前回からの主な変化点は下記の3点+αです。

  1. 追加設定を保存できるデータベース機能の追加

  2. 上書き保存ボタンの追加

  3. メモ機能の追加

  4. その他もろもろ、使い勝手の改善

追加設定データベース

追加設定データベース

詳細執筆タブで、いろんなプロンプトを試すのですが、似たような設定を書いたり消したりを繰り返すのが面倒なので、GradioのDataframeを使ってデータベースとして保存できるようにしました。

「追加設定へ送る」ボタンをクリックすると、詳細執筆タブの追加設定欄にコピーされます。

追加設定にコピー

追加設定でいろいろいじくりまわして「おっ、これ使えるかも」と思ったら、逆にデータベースにコピーもできます。

選択した設定をデータベースにコピー

マウスでコピーしたい部分を選択して「選択中の設定をDBに送る」ボタンをクリックするとデータベースにコピーされます。

これは結構便利で、何度も何度も似たようなプロンプトを書いたり消したりする手間が省けます。
それだけプロンプトを書いたり消したりしているということの証明でもあるのですが……

上書き保存ボタン

ロードボタンとセーブボタンに加えて、上書き保存ボタンをつけました。

上書き保存ボタン

どうでもいいような機能ですが、これがあるかないかで作業性が全然違います。

色が変わるよ

エディタ内の文章が編集されると色が変わって「セーブしたほうがよいのでは?」とお知らせ。

セーブするとファイル名を表示

一度セーブするとファイル名を表示し、以後、このボタンをクリックするたびに上書きセーブします。

何かするたびにセーブしたいのですが、そのたびにダイアログボックスが開くのは思いのほか面倒でした。
市販のワープロなどのアプリケーションはよく考えられているなと痛感します。

メモ機能

このプロンプトは効きそうだとか、もう少し話の展開をこうしたいとか、メモがあちこち散乱してしまいがちという超個人的な理由から、作業中のデータと一緒に保存できるメモ機能を付けました。

マークダウンでメモが残せます

もう、こんなもの機能でもなんでもないですが、これがまた、意外に便利。
GradioのCodeを "language='markdown', interactive=True" に設定しているだけですが、ミニエディタとして使えるし、マークダウン表記で表題を入れておくと折りたたむことができるので、いろんな使い方ができます。

その他もろもろ

その他、細々したボタンの動作や表示の設定を使い勝手に合わせてチマチマ修正しています。パパっと流れるならこれでいいけど、何度もやり直すならこうだよな……みたいな、使い勝手の部分は日々変わるので、それに合わせて都度修正しています。

とりあえず、こんなものになってはいますが、このままでは猛スピードでプロンプトエンジニアリングの罠にハマりに行くシステムでしかないので、何か次の一手を見つけて、「面白い小説が書けそうだ」という方向に向かっていきたいと思います。

おまけ(ChatGPTが人工無能を造る)

ChatGPTに人工無能のサンプルプログラムを作ってもらいました。

ChatGPTによる人工無能プログラム
import random

# ユーザーからの入力に対する返答を決定する関数
def get_response(input_text):
    responses = [
        "こんにちは!",
        "どうしてそう思うのですか?",
        "そうなんですね。",
        "興味深いですね。",
        "何か他にお話しすることはありますか?",
        "私はあなたの話を聞くのが好きです。",
        "それはとても興味深いです。",
        "それはあなたの人生にとって重要なことですか?",
        "すみません、もう一度言っていただけますか?",
        "私にも同じような経験があります。",
        "それは本当に素晴らしいですね!",
        "私はあなたの成功を祝福します。",
        "もう少し詳しく話していただけますか?",
        "それはとても重要な問題です。",
        "私はあなたがそれを達成できると信じています。",
    ]
    return random.choice(responses)

# チャットボットを起動する関数
def start_chatbot():
    print("チャットを開始します。終了するには\"bye\"と入力してください。")
    while True:
        input_text = input("あなた:")
        if input_text.lower() == "bye":
            print("チャットを終了します。")
            break
        else:
            response = get_response(input_text)
            print("Bot:" + response)

# チャットボットを起動
start_chatbot()

ええ~っ、ランダムに返事を返すだけって、ちょっとまって……
自分が人工知能だからって、人工無能をバカにし過ぎてますよね(笑)

頂いたサポートは今後の記事作成のために活用させて頂きます。