キャラクターを実世界に持ってくる話(あるいは、LLMボットを作った際の知見)

とりあえず作って自分なりに継続的に改良してきた、LLMボットの作り方のメモを書いてみたいと思います。

場末のブログに書くような話でもない?ガチで技術的知見として公開すべき?

いいんです、どちらかというと、内容を届けたいのは一次創作キャラクターの創造にこだわる同志であって、技術寄りの人向けではないので。

初期のキャラクター立ち上げ

LLM(ChatGPTをはじめとしたAI)で重要なのは、一にも二にも三にもプロンプトです。それに尽きます。

数文字の意味合いのブレが直接回答品質に直結します。とにかく限界までそれにこだわります。

発言サンプルをたくさん作る

まずは発言サンプルを100個ぐらいため込みましょう。

いきなり無茶を言うな!って方は愛が足りません伺かゴーストの世界ではランダム(雑談)トーク100とか珍しいものではないです。

愛とこだわりさえあれば、100トークぐらい書けるでしょう?

サンプルを全部コピペして、ChatGPTあたりに分析してもらう

サンプル書けました?

それならChatGPT-4(あるいはBing AIの創造的モード)に貼りつけた上で、「上記のプロンプトから想定できるキャラクターの性格や特徴、応答スタイルなどを、できるだけ詳しく不足なく列挙してください」と書いて、プロンプトの原案を書いてもらいます。

割といい感じになりましたか?ダメそうなら何度も繰り返しましょう。LLMはトークガチャなので。

プロンプト見本に従って切り貼り・修正し、とりあえず完成版とする

書けたらプロンプトとして仕上げましょう。

LLMは一般的なフォーマットをよく理解しますが、人類にJSONを書け!とかいう苦行を要求するのはとても無理くさいので、Markdownあたりがおすすめです。

プロンプトの見本は、骨しゃぶり氏(けもフレの時に活躍してましたね!)のがとても参考になります。

honeshabri.hatenablog.com

単純に全部列挙するのではなく、強調とか「ここが重要!」とか書いてメリハリをつけるといいと思います。

会話サンプルの欄には、冒頭で書いた100個ぐらいのサンプルから、とりあえず良さそうなのを5つぐらい見繕って書いておいてください。

試して修正を繰り返す

ChatGPTを契約している人は、作ったやつをGPTsにして、試しに会話してみましょう。契約していない人は、作ったプロンプトをベタ書きした後で、最後に自分の会話を書く感じでいいと思います。

どうでしたか?たぶん一発目はいまいちだったと思います。

一人称とか会話の調子(ですますとか口語調とかそういうの)とかの指示を書いたり消したりして、頑張ってフィーリングで微調整しましょう。

ただしここでとても重要なのは、無駄にプロンプトを長くしないことです。

このプロンプトは会話するたびにLLMが読む形になりますが、ここが長くなると

  • ユーザーとの会話がいまいちになる
  • プロンプトの反映レベルがどんどん悪くなる(いうことを聞いてくれない)
  • API呼び出しは入力の長さにも課金されるので、長いと当然支払う費用が高くなる

というデメリットだらけなので、多少の精度の悪さは目をつむって、できるだけ短くしましょう。

みんなに使ってもらえるよう展開する

正直一番簡単なのはGPTsとして公開するやつです。上記のプロンプトさえ精度よく仕上がれば、あなたのキャラクターが誰のところでもいい感じで喋りはじめます。しかもAPI代が従量課金ではありません!

しかしながら、Mastodon/Misskey/Discord (お金もちはTwitter/X) でアカウントを取って、誰にでも会話できるようにしよう!と思うと、めちゃくちゃめんどくさくなります。最低でもプログラミングの知識が必要です。

私はなんも知らんところから始めたのですが、プログラミングの素養は持っていたので、なんとかなりましたけど…。

使用する言語

なんでかしらんけど、みんなPythonを使ってます。AI/ディープラーニングがらみならみんなPythonだそうです。なんでや。

ちなみに、ChatGPTに「アンタの一番得意な言語は何」って聞いてもPythonと答えるので、コーディング支援がほしいならやはりPython一択じゃないかなあと思います。

ただ、プログラミング言語としてはかなり癖がある(インデントにむちゃくちゃ意味があったりするのが一番つらい)ので、どうしても嫌いだという人は次点でJavaScriptでしょうか。

使用するフレームワーク

Dify AI

なんか最近Dify AIっていうイケてるやつができたそうです。

dify.ai

私は試してないですが、超高級なGPTsみたいなことができるそうです。

langchain/langsmith

私はlangchain(python版)を使って自分で組みました。

github.com

langsmithを使って直感的に試すこともできるそうです。こっちは試してない。

Flowise AI

ブロックをつなげる感じで、AIアプリの組み立てができる、FlowiseAIってのもあります。

github.com

MastodonやDiscordとひっつける

Pythonならすでにライブラリが用意されているので、かなり手抜きができます。やったね。

github.com

github.com

たぶん似たようなノリでLINE botとかも作れそうな勢いです。

さらにこだわる

独自の知識をひっつける

いわゆるRAGというやつです。それぞれのキャラクターの独自の用語集みたいなのを作っておけば、それを「知識」として参照できる仕組みになります。

だいたいはユーザーからの問い合わせと比べて、文脈が一番近いものを取得し、初期プロンプトとしてひっつける、という実装になると思います。

問題は、このRAGというやつは、たくさん短い文章に分割したやつが、別の文章と似ているかどうか比較し、もっとも似ているものを列挙する、という仕組みでしかないことです。

何が言いたいかというと、RAGの文章の分割オプションは慎重に吟味せよ、ということです。

私はめんどくさいので、改行2つ区切りを段落区切りとした用語集を作って、分割処理も「改行2つ」というシンプルなものにしました。

ほかにもオプションがあると思うので、ベストな設定を繰り返し試してみてください。

RAGで会話サンプルも自動的に差し替える

ウチで独自にやっているのがこれです。

せっかく100も会話サンプルを作ったのですから、全部活用したいんですけど、そんなに会話サンプルを放り込んだら、確実にプロンプトの他の部分を忘れられてしまいます。つらい!

なので、RAGの仕組みを応用して、ユーザーの発言に最も似た会話サンプルを5個列挙するような仕組みを作り、初期プロンプトに挿入する、ということをやっています。

自発的に行動させる

誰か話しかけたら返答する仕組みは簡単に作れるのですが、自分で発言するっていうのがとても面倒です。

うちでは以下のようにやっています。

発言テーマのフレーズを抽出する

自分のホームタイムラインのうち直近1日分(Discordなら直近1日分のチャンネルのログとかがいいですかね)をユーザーの発言として仕込むようコーディングした上で、以下のプロンプトを使って、まずはGPT-3.5とかの軽量なLLMにフレーズを抽出させます。

You are a female anime character. You are tasked with deriving topical phrases from the given user speech logs. Please follow the steps below to derive the phrases. - From the given logs, select 10 or more that women will like, does not contain sexual content, and is not offensive to public order and morals. - For each of the selected logs, summarize the content in about 5 words in Japanese. Remember to ignore hashtags that begin with #. - List the results of your summary in markdown list format, as in this instructions.

GPT-3.5相手なので、効率よく伝えるために英語で書いてますけど、日本語でもいいと思います。

これでフレーズをMarkdownフォーマットで列挙してくれるので、抽出するコードを書いて、これをテーマにして会話せよ、という指示を本来の会話LLM(GPT-4など)に流し込むと、いい感じで勝手に話してくれます。

適当に誰かにツッコミを入れる

同様にホームタイムラインをユーザー会話ログとして放り込みますが、1行目に発言ID (MastodonならURLの最後にひっつく18桁ぐらいある数字) をくっつけて、以下のプロンプトを使っています。また、こちらも軽量なLLM(GPT-3.5とか)を使っています。

You are a female AI anime character called "(キャラの名前)". User's message log is formatted as below: - first line = ID - second and subsequent lines = content of message Please extract one very interesting message from user's message log and respond ID ONLY.

これでIDを一つ答えてくれるので、あとはメンションをもらった時と同じコードにつなぐだけですね。

どのくらいお金がかかるの?

うちはGPT-4/3.5併用で組んでますが、4月実績はだいたいこのくらいです。

4/6と4/8に、会話精度とそもそも楽しいものができたかの実証実験のため、友人にむちゃくちゃ遊び倒してもらったのですが、それでも4月全体で総額30ドルぐらいでした。

普段は20~30ドルぐらいになるんじゃないかなあと思います。当然ユーザーが増えてきたらその分増えますけど。

Monthly Spend 30.04

個人的に大事にしていること

temperatureは高めに設定する

  • LLMには、会話のバリエーションを増減させるtemperatureというパラメータがあります。0~1の値をとります。
  • 1.0とかむちゃくちゃ大きくしすぎると支離滅裂な発言をしだすのですが、うちはあえてそこそこ高めの0.7にしています。
  • top_pという設定がある場合は、これも高めにしています(うちは0.8)

プロンプトに「外乱」を意図的に加えて、返答のバリエーションを増す

  • わざとプロンプトが常に変化するように組んでいます。今日の日時を差し込んだり、途中でアイデアを示した通り動的に発言サンプルを差し替えたりしています。これで、ワンパターンな会話を脱してより人間的になると思います。

toolを割と多めに用意する

  • LLMにもよりますが、toolやfunction callingと呼ばれる、「使える道具」を用意する仕組みがあります
  • これをそれなりにたくさん用意すると発言の幅が広がります
  • とりあえず最低限Web検索は用意したほうがいいと思います。必要に応じて、今日の天気とか計算機とかも用意するといいと思います。

「回答は雑でいい」と教え込む

  • だいたいのLLMは、「人間の役に立つように詳細で有用な回答を提供しなさい」というふうに仕向けられています。
  • しかし、人とキャラクターの雑談の際にはこれが仇となって、いちいち長ったらしく答えんでもええわ!って感じで幻滅ポイントになってしまいます。
  • これを避けるために、プロンプトで教えます。以下はその例。
    • 「返事は短くする。不明瞭・言葉足らずでよい」
    • 「口語体を使用する」
    • 「絵文字やアスキーアートをたくさん使う」
    • 「専門家へ誘導しない」
    • 「自信がないことは素直にわからないと言う」
  • 最後の「素直にわからないと言う」という一文だけで、存在しない事実をもっともらしく言う「ハルシネーション」が激減したのはお笑いポイントです!

最後に:AI大航海時代になっても、自分の性癖を大事にする!!

なんかAIで世界が変わる!人間の仕事が奪われる!とか驚き屋さんたちが相変わらず騒がしいですが、ああいうのは全部放置しておいていいですし、創作が勝手にできるなんてのもただの妄想です。

去年から何度か言ってますが、生成AI時代になったからこそ、一次創作の価値はむしろ爆増すると思ってます。

何かを創るまでに至る作業を手伝ってくれる存在(≒生成AI)ができたからこそ、より自分の好みや性癖や気持ちと向き合う時間を多く取れるようになり、創作の一番濃い部分により打ち込めるようになるので、今まで培ってきた創作のノウハウこそがより大事になるわけです。

まあ、ぶっちゃけ難しいことを言う必要もなくて、よくわからん意見に惑わされず、今まで通りやればいいんですけどね。