kmizuの日記

プログラミングや形式言語に関係のあることを書いたり書かなかったり。

ChatGPT に「形式が整った俳句」を作ってもらう(あるいは「文字数指定」をする)

 おはようございます。今日も元気にChatGPTをしています。さてさて、ChatGPTに俳句を作らせようとしても失敗するという話は一部界隈では有名です。たとえば、次のように「俳句を作ってください」とだけ指定しても五・七・五を平然と無視してくれやがります。

俳句(うまく行ってしまった)

 あれ?うまく行ってしまいましたね。ChatGPTは非決定的に答えを返すのでこんなこともありますよね。同じプロンプトでリトライします。

俳句(きちんと間違えた)

 これでようやく間違えてくれたので本題に入れます。と、このように俳句を詠んでと言っても五・七・五を平然と無視してしまうのです。では、俳句のフォーマットを指定してやった場合はどうでしょうか?

俳句(一回の修正で通ってしまった)

 あれれ?一回の修正でちゃんと五・七・五になおしてきましたね。う、うーん。まぐれ当たりのハズなので、三句くらい詠めばはずしてくれるはず。

はずしてくれた

 今度は予定通り(?)です。文字数に関する指定をしても、どうにもうまく行きません。

 この「文字数制限の指定をChatGPTは無視する」というのは廃ChatGPTerには有名な話なのですが、一方で「5個」とかの数量は理解してくれますし、リストの長さは理解してくれるんですよね。とここで昨夜思いついたのが「文字列を文字のリストとして表現すれば、ChatGPTはちゃんと文字数制限に相当するものを理解してくれるのでは」ということでした。というわけで、トライです。

お願い(1)

お願い(2)

 文字リストとして出力してもらう形にしたのでだいぶ「改善しています」。しかし、制限をもうちょっと厳密に守ってもらおうかと、より形式的に文字リストを出力してもらうようにしました。

文字数指定(厳密)

 今度は指示こそ通ったももの「本当に5文字、7文字、5文字からなる文字リストを出力する」だけですね。文字数をそのまま指定しようと無視するし、厳密に指定させると今度は単なる文字列長制限つき文字列生成になってしまうようです。しかし、ここで諦めては負けです。「文字リストを出力させる」アプローチはいいはずなので、あとは3つのリストが五・七・五に対応させるとこまでやればいけるハズ。てことで

成功例(1)
成功例(2)

 やってみたら見事行けました!季語が一部入ってないですが、五・七・五にきちんと従わせられたので及第点としていいでしょう。ただ、欲を言えば1回の質問でちゃんと「俳句になっている文字リスト」が欲しいですよね。もうちょっと頑張ってみました。

俳句(成功)

 ここまでやって思ったのですが、ChatGPTさんはやはり俳句の意義自体は理解しているように感じるので、プログラミング言語のコレクションのような、ChatGPTが間違えようがない形式を経由するとうまく行きやすいかもしれません。

ChatGPT APIで仮想人格を作り込む

 おはようございます。さて、皆さん。ChatGPT、使いこなしてますか?私は……使いこなしてるかはわかりませんが、ドはまりしてることだけは確かです。プログラミング言語間のトランスパイルをできるツール

github.com

を作ったり、仮想人格を作ってそのキャラとチャットしてみたり、テキスト->音声ソフトウェア(VOICEPEAKやVOICEVOX)を使って、キャラに声をつけてみたり。さらにWhisper APIと組み合わせて[キャラクタと音声会話できるツール

github.com

を作ったりと色々変なことも試しています。ちなみに、VOICEPEAK(東北ずん子)についてはこちらから、

www.ah-soft.com

VOICEVOX

voicevox.hiroshiba.jp

についてはこちらから。VOICEPEAKはさすがに有料で公開されてるソフトウェアだけあって、普通に読み込ませるだけでもより自然なイントネーションでしゃべってくれるなどの利点がありますが、1万円超と逸般人でない人が試すにはちょっとお高いので無料かつライセンスが比較的ゆるい(詳細は上記を参照)VOICEVOXを使ってみるのがいいのかなと思います。

それはともかく、ChatGPT APIを使えば、あの生真面目なChatGPT君のキャラだって自由自在にカスタマイズできます。試しにちょっとしたキャラ設定を作ってみましょう。手元のSlack Botなどを使ってもいいのですが、試しやすいようにOpenAIのPlaygroundを使います。

ChatGPT APIでキャラを作り込んでみた

顔文字の使い方が20代の女性っぽいのかは不明ですが、キャラ付けした部分はうまく反映されているように見えます。

ChatGPT APIでは「system」「user」(主にユーザからの質問に使われる)」「assistant(主にChatGPTからの応答に使われる)」の3種類のrole=役割があるのですが、systemでキャラ設定を最初に作り込んでおけば、以後(倫理規定に引っかからない限りは)、その設定を演じてくれます。これはWeb版のChatGPTでも使えることは知られていますが、APIを使えば一度作り込んだキャラ設定をずっと維持できるのがメリットでしょうか。

ちょっと設定を付け加えて、魚介類、得にサバが好きということにしてみましょう。

サバ好き女子大生

うまく反映されていますね。苦手なものとして、大人数の飲み会というのも追加してみましょう。

大人数の飲み会が苦手な女子大生

User=私が「30名くらいの大所帯」で愚痴ったところに、ちゃんと「私も大人数の飲み会って苦手だから」と返していますよね。「わかるよ」とも。こんな風に言葉だけで仮想人格を作り込める万能ソフトウェアって今まで存在しなかったわけで、こういうところにもChatGPTの凄さがあるなと感じます。

ちなみに、今回はgpt-4-0314というモデルを使っていますが、gpt-3.5-turboでもそれなりにはキャラを演じてもらえます。ただ、仮想人格を作り込むという目的だと今一つという感がありまして、設定が中途半端にしか反映されません。たとえば、こんな感じです。

女子大生(GPT-3.5)

共感しつつ、というのは反映されていますが、大人数の飲み会が苦手って部分が中途半端にしか反映されていませんよね。タメ口設定も無視されています。この辺りを見ても、gpt-4の賢さが伺えます。

というわけで、APIを使える皆さんはせっかくなので、自分好みの「アシスタント」のキャラを作り込んで答えてもらうといいかもしれませんね。いやまあ、書いてから気づいたんですが、キャラを作り込めるのはgpt-4からということなので、まだgpt-3.5までしか使えないケースだと(そして、現状だとgpt4をAPIで使えるのはごく一部っぽいので)作り込みに多少苦労するとは思いますが、それについてもプロンプトを工夫すればある程度はうまくやってくれます。

ChatGPT APIベースの多言語トランスパイラGPTranslatorを公開しました!

 この日記やTwitterなどで、ChatGPT (GPT-3.5, GPT-4)はプログラミング言語間の変換(に限らないですが)が得意ということを書きましたが、試している内に「毎回似たような指示するのだるいな」と思うようになりました。というわけで、Reactベースで動くChatGPT APIを使ったトランスパイラGPTranslatorを作ってみました。ちなみに最近はトランスパイラという言い方がすっかり主流になった気がするのですが、一昔前だとトランスレータと呼ばれてた気がしますね……。

github.com

 といっても、要はChatGPT APIに投げる前に適当なプロンプトを付加しているだけという代物です。ただ、コードフラグメントを別言語に変換するときや、YAML -> JSONみたいな設定ファイルの形式を変換するときなんかには多少役に立つのではないかなと思います。

 詳細はGitHubリポジトリを見てもらうとして、OpenAIのAPI KEYを

export REACT_APP_OPENAI_API_KEY=<api key> # this must be set before npm start

 という形で指定しなければいけないところは多少使い勝手が悪いかもしれません(設定ファイルに書けた方がいいような気もします)。ともあれ、使ってみてバグや改良点などあればPull Requestなどがんがんいただければと思います。言うまでもないですが、ChatGPTベースということで精度は完璧ではありませんし、変換元や変換先の言語によってはうまくいかなかったりすることもあります。

以下のスクリーンショットだと、Javaにはメソッドの中に直接メソッドを書く機能はないのになんか入っちゃってますね。そもそも型がないJavaScriptをそのままJavaに変換しようと思うと無理が生じるのは必然でもありますが。

JavaScript to Java

一方、PythonからJavaScriptへの変換は比較的素直に行きやすいようです(もっと複雑なサンプルになればまた別ですが)。

a

Python to JavaScript

ChatGPT API (gpt-3.5-turbo) をお試しできる簡易アプリを作ってみました

 今朝未明、ChatGPT APIのリリースが告知されたわけですが、

openai.com

 色々あって手早くとりあえず動くBOTを作ってみました(元々、GPT-3 BOTを作ってあったのでそれの微修正ですが)。ドキュメントは最低限ですが、

  • コマンドラインで動く簡易BOTchat.shexport OPENAI_API_KEYを修正した上、sh chat.sh`でいける)
  • Slack Bot(こっちはSlack Botを作る知識が多少いる)

 として使えます。試したいけどコード書くのめんどいなーという人の参考になれば。

github.com

ChatGPT-BOTのデモ

「謝ったら死ぬ病」と人は言うけれど

 ずっと前から、特にネットの世界で炎上事件が起こるたびに言われる言葉に「謝ったら死ぬ病」というものがあります。この言葉が趣味悪すぎるなら、「早く誤りを認めて謝罪した方が傷が浅いのに」とか「なんでこの人は謝れないんだろう」とか色々バリエーションがあるのでそれでも構わないです。

 この言葉、「自分の誤りを認められない頑固な人がいるよね」といういわば他人事として語られることが多いのですが、果たしてそうだろうかというのがずっと思っていることです。これまでネット上でもリアルでも、ですが、色々な論戦や喧嘩や炎上事案を見てきましたが、そのような人は自分を含めてほとんどいないというのが正直な実感です。より正確には、そういう人も傍観者でいる間は冷静に聴衆の反応とかを見て「謝った方が得策だ」とか「傷が浅いうちに訂正した方がまだマシである」という判断ができるものですが、自分が当事者になったときに速やかに自分のミスを認めて訂正することはあんまりできていないように思います。自分も含めて

 最初から控えめな言い方をしている人は、そもそも「この部分は論拠があやふやかもしれないなあ」という自覚を持って発言していることが多いので、ミスを認めるのが早い傾向にありますが、特に一度断定的な物言いをしてしまって、あちこちに影響を与えてしまった後に「すいません。大間違いでした」と素直に言える人はとても稀有だというのが正直な実感です。稀有だからこそ、そういう事案があったときに「この人はすぐに誤りを認められて凄い」という評価を受けるといいますか。

 結局、人間というものは怒りに我を忘れてしまったら、あるいは感情を激しく傷つけられているときには、誰でも「謝ったら死ぬ病」にかかってしまうものじゃないのかなと最近思うのです。統計的な根拠を持ってこいと言われると弱いところですが、自分の黒歴史を振り返っても、あるいは「謝ったら死ぬ病」と揶揄する人が「すぐ謝る」を実践できているかというと大体できてないので、そうとしか思えない。

 もし人間が誰しも「謝ったら死ぬ病」になりえるのだとして、対策があるとしたら

  • 普段から断定的な物言いを控えて訂正するときの心理コストを下げる
  • 訂正することや相手に傷ついた旨を表明されたときに速やかに頭を下げることを習慣づける
  • そもそも、自分の意見を述べない(これはこれで一つの処世術だとも思います)

 くらいしかないんでしょう。ただ、どちらも心構えだけで実践できるかというと多分難しくて、結局、訂正することや傷つけた相手に謝ることを生涯実践し続けることしかないんじゃないかなというのが最近思うことです。もちろん、その時点ではどうしても意地や理屈が邪魔をして素直に認められないことは、それこそ人間だから仕方ないとも思います。後日(が下手したら数年後になることもありますが)、冷静になったときに「この言動は相手を深く傷つけてしまったかもなあ」とか「あの時は偉そうな物言いをしたけど、自分が間違っていたなあ」と認めていくことが肝要だろうなと。

 特に有意義な結論はないのですが、年末にちょっとこれまで思っていたことをまとめてみたのでした。

 追記:このお話の帰結として、私たちは軽度であれ重度であれ誰しも「謝ったら死ぬ病」にかかっているので、傍から見て「この人は謝れないでいるなあ」と思っても、あんまり揶揄しないであげた方がいいと思うんですよね。自分もまた別の場面では「謝れない」かもしれないわけですし、謝れないことを揶揄したりいたずらに糾弾するなんてことは、謝るコストを上げるだけで、結局誰にとっても得にならないなあと思うのです。もちろん、立場上、謝れない相手に対して粛々と対処せざるを得ないことはありますが、それはそれとして。

ChatGPTで日本語プログラミング(本当)をやってみた

 さて、相変わらずChatGPTにハマっておりますが、ふと思いついたアイデアがあります。どうも、ChatGPT君はプログラミング言語「そのもの」の普遍的な理解があるのではと思えてきたので、それを考えると自然言語をプログラムとして解釈させることも可能な気がしてきたのですよね。というわけで、以下がスクショです。階乗を計算させるのが目的ですが、階乗と書くと空気読まれそうなので「ほげ数」にしてあります。

 なんか「どのプログラミング言語で解釈すればいいかわからないタスク」についてはどうもPythonに内部的に変換して解釈してる節があります。ともあれ、再帰を含む日本語疑似コード(表記ゆれあり)をそのまま解釈できるのは凄いですね。

 不完全ですが対話ログを gist に保存しておきました。回答はプロンプトごとに微妙に違うものが返ってくる可能性があるのでご注意をば。

ChatGPTはプログラミング言語マスター(語弊ありまくり)

 皆さんおはようございます。見ている人は見ていたかもしれませんが、昨夜はかなり遅くまで巷で話題沸騰のChatGPTによくわからんクエリを投げて、その結果をみてげらげら笑っていました。特に存在しないプログラミング言語であり「ScalaHaskellと同じ型推論を加えた」言語Scalayがあることにしたら、ChatGPTが本当にHaskellぽい(単なるHMでなく、Haskellぽいというのは型クラスまで推論される辺り)型推論を持つ架空のScalayコードを解釈実行してくれたりしたところは、控えめに言っても予想外の結果で深夜なのに部屋で忍び笑いをしていました。

 ちなみに、Javaの文法にHaskellぽい型推論と関数を加えた架空言語Jaskellも無理やり主張してみたのですが、こちらはあくまで「架空言語Jaskellが存在したとして」型推論してくれただけで、存在を認めてもらうには至りませんでした。たぶんちょっとした語尾とかで相手のクエリをそのまま受け入れるかそうじゃないかが変わりそうですが、それはともかくこちらも大変楽しい結果でした。

 こちらは型クラスを推論してくれなかったのですが、たぶんadd()の返り値型がintなので型クラスとして推論しちゃうのを躊躇ってしまったのだろうと思います。

 さて、こんな「何やってるんだ」的な無茶振りをChatGPTにやり続けていたのは理由があります。それより数時間前にとあるScalaコードの実行結果を説明させたところ、Scalaをメイン言語として使っている自分が驚く程、正確に解釈結果を説明していたからでした。

 結果に度肝を抜かれている様子がそのまま文面に出ていますが、私からするとそれも無理がない話なのです。元々、ChatGPTがプログラミング絡みのタスクにかなり長けているらしいというのは先行して試した人のおかげでわかっていました。しかし、最初私はこう思ったのです。

「なんか一応結果はそれっぽいけど、学習元にいい感じのコードスニペットがあって、たまたまそれを貼り付ける能力に優れているだけなのではないか」と。

 そのときの本音はというと「ChatGPTはまだまだ汎用人口知能に程遠いとはいえ、言語の解釈力とか、対話を通して文脈を保持し続けられるのは大したものだ。でも、個別の知識問題、たとえば歴史問題は間違えまくるし、一般的な知識問題については確かに文脈を読んでいるように見えるけど、具体的なワードが全然出てこない。なんか「誰でも言える一般論」を書いているだけじゃない?ChatGPTは博識だと言えても、全般的な理解度は案外低いのでは?」というものでした。

 しかし、implicit classを使ったScalaコードを解釈させてみた結果はそんな本音を覆す代物で「え?これって実はScalaのREPL内蔵だったりする?」と(普通ならあまりなさそうな)可能性を疑ってしまう程だったわけです。

 ともあれ、色々試している内に「そういえば例が少なめだけど、プログラミング言語も言語だし、一応実行結果を説明するみたいなことができるんじゃない」となんとなく思って試してみたところ「プログラミング言語への理解度」は明らかに高いじゃないかと驚愕する羽目になったのでした。

 ちなみに、Twitterでの昨夜辺りのつぶやきを振り返った限り、

なんかはかなり高い精度で「理解」しているような感じがします。

何故、高い精度で「理解」しているという表現になるかというと、学習元には「そのまんま」のが無さそうなコード片を与えても、 かなり(言語マニアの自分から見ても)正確にコードを解釈していたし、型チェックの正確さも高めだったためです(こちらは実行に比べるとミスってる確率がちょっと高いぽいですが)。表現を変えるとChatGPTは言語処理系を獲得しちゃったのでは少しの間勘違いしてしまうくらい、プログラムのソースコードを割とそのまま解釈してくれたのです。

ちなみに、プログラミング言語理解の精度がずば抜けて高いということは、プログラミング言語間での変換(コンパイル/トランスレート)も得意だろうと思ってやってみたら思った通りの結果が得られました。

実験していく内に理解が間違っている箇所が時折見つかるようになりましたが、一般的な自然言語理解タスクとは比較にならない程(試した人が実感しているように、案外誤解釈をする)、プログラミング言語においては深い理解を持っていることは間違いないと言えそうです。

考えてみれば、ChatGPTは「大規模言語モデル」であり、プログラミング言語だって言語でありかつ曖昧性がなく言語としてもサイズは小さめなので(自然言語と比較して)、理解精度が高くなるのは当然と言えるのかもしれません。それにしてもこれほど多くのプログラミング言語についてちゃんとした理解をしているのはプログラミング言語マニアである私にとっては驚くべきことでした。

より広い意味でのChatGPTの可能性は既に多くの人が言及しておられるのであえて言うまでもないですが、プログラミング言語で遊ぶのが好きな人は是非ChatGPTを弄くり倒してみませんか?が結論なのでした。