芋出し画像

Blueskyに爆誕したおしゃべりロボ「プルスカちゃん」の技術的な解説をするよ

Blueskyにお絶賛皌働䞭のおしゃべりロボ「プルスカちゃん」に぀いお技術解説したす。プログラミングっお楜しいね〜


前眮き

シロむは今でこそむンタヌネット芞人 äž»ã«å¿ƒç†å­Šã‚„哲孊の本を曞く仕事をしおいたすが、元々はIT゚ンゞニア出身です。

ゞャンルは䜕であれ、私は自分が面癜そうだず思ったものを圢にしおいくのが奜きなんですよね。プログラミングのスキルだっお、元々は10代の頃の趣味のゲヌム制䜜で身に぀けたものですから、別に職業䞊の必芁などに迫られなくおも、攟っおおけば奜き勝手に䜕かを䜜っお遊んでいる人間のような気がしたす。

それで先日、Blueskyに「プルスカちゃん」ずいうアカりントをお遊びで䜜成したした。プルスカちゃんの裏偎では、フォロワヌが盎近に投皿した文章を孊習した䞊で、それを真䌌た「䞀応日本語っぜい」文章をランダムに生成し、定期的に投皿するずいうプログラムが動いおいたす。

迷子 犬 柎犬 どうでもいい事で独自のリズムに䜜り倉えるこずがあるずいうから、明日はハンドドリップも詊しおみるずこんなに歩いたのよ。

— プルスカちゃん (@purupurusky.bsky.social) 2025-04-27T03:57:27.359Z

ワンマンがありたヌヌヌヌヌヌヌヌす でヌヌヌヌす

— プルスカちゃん (@purupurusky.bsky.social) 2025-05-03T07:14:31.494287+00:00

このプルスカちゃんの誕生をシロむのメむンアカりントで告知した際、もしかしたら「どういう仕組みになっおいるのか詳しく知りたい」ずいう方もいるかもしれないな ずいう気がしたので、せっかくだから簡単に解説蚘事を曞くこずにしたした。

マルコフ連鎖ずいうアむデアに぀いお

この手のプログラムずしおは、おそらく倚くの方が旧Twitterの有名アカりント「しゅうたい君」を真っ先に連想するのではないかず思いたす。アむデアの盗甚ず思われるずちょっず悲しいので、この点を最初に説明しおおきたす。

実は、このような文章生成のアむデアは盞圓叀くから存圚するものです。プルスカちゃんの文章生成の仕組みを支えおいるのはマルコフ連鎖ず呌ばれる確率論の話で、この抂念が䞖に出たのがい぀なのかは私も詳しく知りたせんが、名前の掲げられた数孊者のアンドレむ・マルコフの生没幎が 1856幎-1922幎であるこずを蚘しおおけばひずたず十分でしょう。

私が10代の頃生成AIもスマホもないに接しおいた「20幎前のむンタヌネット」䞊にも、マルコフ連鎖による文章生成ずいうのは普通に存圚しおいた情報でしたし、ある皋床の奜奇心のあるプログラマの人ならば、ハフマン笊号デヌタ圧瞮やミニマックス法ゲヌム理論ずいったアルゎリズムず同じく、「面癜そうだな」「自分でもやっおみるか」ず興味をそそられるような察象の䞀぀だったものず思いたす。

先述の「しゅうたい君」は、スマホずSNSが爆発的に普及した2010幎代のネット瀟䌚でたたたた有名になったものです。そしお、みなさんが認識しおいるであろう「しゅうたいっぜいさ」ずは、おそらくあのアカりントが「狙っおそのように個性的に蚭蚈されおいた」からではなく、マルコフ連鎖ずいう仕組みで生成された文章が本質的に持぀意倖性の面癜さによるものず考えられたす。実際、少しばかりのプログラミングの心埗のある人であれば、あの「しゅうたいっぜいさ」は非垞にシンプルな実装によっおすぐに再珟が可胜なものです。

さお、前眮きはここたでにしお、本題の解説ぞず進みたしょう。正盎、数孊的に厳密な話は私の専門倖になるので、ここではそういう正確さは眮いおおいお、「どうしお読み蟌んだテキストから新しいおしゃべりが生み出せるのか」をざっくり説明しおいきたいず思いたす。

もしかしたら、専門家の人が読むず「マルコフ連鎖」ずいう甚語の䜿い方自䜓に「頭痛が痛い」的なおかしさを感じるかもしれたせんが、どうぞご容赊ください 

文章生成の仕組み

1. 孊習のステップ

たず、孊習元ずしお入力された文章が次のようなものだったずしたす。ささやかな日蚘の断片みたいなむメヌゞです。

明日こそは晎倩になっおほしいなあ。 䞭略 ずころで、カントリヌマアムにこれ以䞊小さいサむズになっおほしいず思っおる人いる

䞋準備ずしお、日本語を「最小限の意味を持぀たずたり」に分割するずいう凊理を行う必芁がありたす。このたずたりを「トヌクン」ず呌びたす。

たずえば、「明日は 」で始たる文章があったずしたら、「明日」ず「は」は分割可胜ですね。しかし、「明日」を「明」ず「日」に分割するず、単語ずしおの意味をなさなくなっおしたうので、この2文字は分割したせん。「明日」は2文字で1トヌクン、「は」は1文字で1トヌクンになりたす。

こういった調子で先の䟋文をトヌクンに分割しおみるず、以䞋のような圢になりたす。

明日 / こそ / は / 晎倩 / に / なっお / ほしい / なあ / 。 /  䞭略 / ずころで / 、 / カントリヌマアム / に / これ / 以䞊 / 小さい / サむズ / に / なっお / ほしい / ず / 思っおる / 人 / いる / 

次に、元々のマルコフ連鎖ずいうのは「ある状態の次にはどのような状態が取られうるか」を考えるものなのですが、今回のプルスカちゃんの䟋では「盎前の2぀のトヌクンの次には、どのようなトヌクンが珟れうるか」に泚目したす。

぀たり、䟋文を「孊習する」ずいう過皋で、具䜓的に以䞋のような情報を埗おいるずいうこずです。最初の2行だけは文頭凊理のため䟋倖的ですが、3行目以降はすべお「盎前の2トヌクンず次のトヌクン」に泚目しおいる点を確認したしょう

・文章の先頭には「明日」が珟れうる
・「明日」の次には「こそ」が珟れうる
・「明日 / こそ」の次には「は」が珟れうる
・「こそ /  は」の次には「晎倩」が珟れうる
・「は / 晎倩」の次には「に」が珟れうる
・「晎倩 / に」の次には「なっお」が珟れうる

  以䞋略

実は、芁点はたったのこれだけです。これだけわかっおいれば、次の生成ステップぞず進むこずができたす。

䞀応補足しおおくず、プルスカちゃんは正確には「A/Bの次にはCやDが珟れうる」ではなく「A/Bの次にCやDが珟れる確率」ずいう圢で孊習しおいお、このあずのランダム生成にもその確率の重みが反映されおいたす。今回は説明を簡単にするために、「珟れうる」ずいう情報だけで解説しおいたすが、この情報だけでも実際にちゃんず動くものは䜜れたす。

孊習はここたでで終わったので、次に考えるのはランダム生成のステップです。

2. 生成のステップ

たず、「文章の先頭に珟れうるトヌクン」ずしおは「明日」が孊習枈みなので、ここでは最初に「明日」を生成するものずしたす。ランダムな生成ずはいっおも、基本は「孊習デヌタで出おきたパタヌンをなぞる」ずいう動きを取りたす。

今回の䟋では、元々の孊習デヌタに「明日」のあずに続くトヌクンは「こそ」しかなく、「晎倩」ずいったトヌクンも他の䜿い方をされおいなかったものずしお、生成結果の最初のほうは先述の䟋文ず同䞀になったものずしたしょう。以䞋が生成途䞭の文章です。

明日こそは晎倩になっおほしい

ここで、「ほしい」の次に生成されるトヌクンを考えたす。孊習枈みの䟋文を思い出しおみるず、そこには「明日こそは晎倩になっおほしいなあ」ず「カントリヌマアムにこれ以䞊小さいサむズになっおほしいず思っおる人いる」ずいう文章が含たれおいたしたね。

倪字で匷調したように、「なっお / ほしい」ずいうトヌクンの流れがどちらの文章にも存圚しおいたすね。぀たり、この2぀のトヌクンの盎埌に珟れる新しいトヌクンずしおは、耇数のパタヌンが孊習枈みだずいうこずです。そこで、生成の流れは以䞋の2パタヌンに分岐しうるこずになりたす。

【パタヌンA】 明日こそは晎倩になっおほしいなあ
【パタヌンB】 明日こそは晎倩になっおほしいず

ここで、仮にランダムな遞択がパタヌンBぞず進んだずするず、孊習枈みの䟋文の䞭には存圚しなかった意味を持぀文章が生成されうるこずがわかりたす。次のような流れになるでしょう。

明日こそは晎倩になっおほしいず
     ↓
明日こそは晎倩になっおほしいず思っおる
     ↓
明日こそは晎倩になっおほしいず思っおる人
     ↓
明日こそは晎倩になっおほしいず思っおる人いる
     ↓
明日こそは晎倩になっおほしいず思っおる人いる

おわかりでしょうか。「2トヌクンのセット→次の1トヌクン」ずいう組み合わせ自䜓は孊習枈みのパタヌンをそのたたに利甚しおいたすが、このパタヌンに埓っおトヌクン生成の連鎖を行っおいくず、最終的には䟋文のどこにも存圚しなかった意味を持぀文章が埗られるずいうこずです。

これは短くお単玔な䟋なので、生成された文章が䟋文の2箇所に由来しおいるずいうこずはすぐにわかりたすね。しかし、孊習枈みの文章が十分に長いものであれば、3トヌクンの組み合わせは数䞇通りかそれ以䞊ずいった膚倧な数になりたす。そこから生成される文章は、元々の䟋文をたったく想像できない、思いがけないような意倖な内容ずなる可胜性が出おくるずいうわけです。

ポむントずしお、生成された新しい文章がどれほど意倖なものであったずしおも、それを再びトヌクンに分割しお「3トヌクンの流れ」に限っおチェックすれば、そのパタヌンは元々の孊習デヌタに必ず1床は珟れおいるずいう点がありたす。逆に、孊習デヌタに含たれない3トヌクンの流れは決しお生成されたせん。

぀たり、孊習デヌタが自然な日本語であれば、生成された文章に「をを」ずいうひらがなの䞊びが出おきたりだずか、文末が「もしくは。」ずいう圢で終わっおしたうようなこずは基本的にないずいうこずです。仮にマルコフ連鎖ずいう考え方を知らずに、囜語蟞曞に茉っおいる名詞や接続詞をランダムに出力し続けるだけのプログラムを組んだずしたら、おそらく今挙げたような䞍自然な文字の䞊びが頻繁に発生しおしたうこずになるでしょう。その生成結果は「挢字やひらがなが䞊んでいるのに、党然日本語っぜくは芋えない」文章になりたす。

この「䞀぀ひず぀の語句の前埌だけは自然な流れなのだけど、党䜓ずしおは予想倖の方向に流れ着く文章が生成される」ずいう点こそが、マルコフ連鎖の考え方に基づいた文章生成の面癜さであるず蚀えたす。

仕組みの解説はここたでで、次は実装のお話になりたす。

実装䞊の技術的な話

䜕で曞かれおいるのか

プルスカちゃんはPythonで曞かれおいたす。2025幎珟圚では特に付蚘する必芁はないかもしれたせんが、3.x系のほうですちなみに2.xは2020幎にサポヌト終了。補助的にシェルスクリプトも少し䜿っおいたす。

Pythonは  ずいうか、珟代的な蚀語では圓たり前のこずなのですが、リストや蟞曞ずいったデヌタ構造をたるで敎数の足し匕きのような軜いノリで扱える点は本圓に助かりたす。私が新卒で入った䌚瀟はメヌカヌの゜フトりェア郚門、぀たり組み蟌み系の分野でしお、そこで䜿っおいたのはC蚀語C++ではなくだったので、䜕をするにも「そのデヌタはメモリ䞊にどう配眮されおいるのか」を意識しなければいけないようなめんどくささがありたした。

技術畑の人はご存知かず思いたすが、日本語の自然蚀語凊理ずいうのは本来かなり倧倉なものです。真っ先に挙げられる性質ずしお、日本語の文章は英文ず異なり、単語間のスペヌスのような区切りがデヌタ䞊存圚しおいないずいう点がありたす。機械的に「区切りず芋なしおほが間違いない」ず蚀えるのは、句読点などの蚘号くらいしかありたせん。

たずえば「すもももももももものうち」ずいう文字列があったずき、日本で生たれ育った人であればこれが「すもも / も / もも / も / もも / の / うち」ずいうトヌクンで成り立っおいるずいうこずは知っおいたすね。しかし、これは蚀葉遊びずしお有名だから知っおいるだけで、玔粋な日本語の理屈のみで「どうしおこのようなトヌクンの分割ずしお綺麗に解釈できたのか」を説明するのは、おそらく日本語ネむティブであっおも困難でしょう。

コンピュヌタにずっおの日本語が「区切りなしにベタッず䞊んだマルチバむト文字の連続」でしかないずいう点を考えるず、コンピュヌタから芋た「こんにちは、今日はいい倩気ですね」ずいう文章は「ももももも、もももももももももも」ずさほど倉わらないず蚀っおしたっおもいいかもしれたせん。

もちろん、「こんにちは」の文章は「ももももも」の文章ほど「自然な日本語ずしお解釈できるトヌクン分割䜍眮の組み合わせ数」が倚くはないので、これはやや極端な比喩ですが、少なくずも日本語ネむティブが盎感的か぀ノヌタむムで「ここで区切られおいる」ず刀断できる文章でも、その盎感的な刀断プロセスをコンピュヌタのロゞカルな動きに萜ずし蟌むのは簡単ではなさそうだずいうこずです。

で、肝心の「どうしお実際にそういうトヌクン分割ができおいるのか」ですが、プルスカちゃんではPythonで䜿える圢態玠解析噚のJanomeを䜿甚しおいたす。このラむブラリの䞭身がどうなっおいるのかは私もマゞでよくわかっおいないのですが䞭に劖粟さんがいるのかな、トヌクン分割ずいう仕事はJanomeさんぞの䞞投げです。Janomeさんのようなオヌプン゜ヌスのラむブラリが存圚しなければ、プルスカちゃんのようなお遊びはたず生たれなかったでしょう。

たた、Blueskyに投皿された内容を孊習するためのテキスト取埗、そこからプルスカちゃんずしお生成した文章の自動的・定期的な投皿に぀いおは、AT Protocol SDKによっお行うこずができたした。この蟺はBlueskyがオヌプンなSNSを暙抜しおくれおいるおかげです。

珟状のXやThreadsなどのSNSの堎合、API等に課金せずにこういう仕組みを実装するこずはおそらく䞍可胜だず思いたす。やっおおよかったBluesky

どのように運甚されおいるのか

普通に消費者ずしお暮らしおいるずきは特に意識しないものですが、私たちがスマホやパ゜コンを通じお䜕かのサヌビスを䜿うずきっお、必ず䞖界のどこかにそのシステムを動かし続けおいるサヌバが存圚するのですよね。

シロむは個人で仕事をしおいお、さすがに垞時動きっぱなしのサヌバなどは所有しおいないので、自分のMacBook Airの裏偎で勝手にシェルスクリプトが走っおいるような状態にしおいたす。レンタルサヌバ的なものを䜿っおもいいのですが、プルスカちゃんは元々お遊びで生たれたものですし、毎月のサヌバ代を支払うためには私の曞いた本が毎月毎月毎月毎月たくさん売れおくれなければなりたせん。たすけお〜

そこで代替案ずなったMacBook Airですが、私は぀い最近お金もないのにM4のモデルを新しく賌入しおいお、叀いM1は予備のマシンずいう扱いにしおいたす。このM1のほうをディスプレむを閉じた状態でもスリヌプしないように蚭定しお、郚屋の隅っこで音もなく皌働しおもらっおいる状態にしおいたす。消費電力はそんな倧したこずないはず 。

むメヌゞ的には、時刻チェックず数十分間のsleepを亀互に行う無限ルヌプの入ったシェルスクリプトを走らせおおいお、指定された時間䞀日に数回の発蚀タむミングになるたびにメむンのPythonプログラムを呌び出しおいる圢です。単玔ですね。

ずいう感じで、運甚ずいっおも「予備のノヌトで垞時スクリプトを走らせおいるだけだよ」ずいう話でした。

終わりに

以䞊、プルスカちゃんの解説蚘事でした

みなさんも䜕か新しいものを芋たずき、「どういう仕組みで動いおいるのだろう」ずいう疑問を持぀こずはないでしょうか。こういう気持ちっお、別に技術者や衚珟者ずしお倧切だずいう話に限らなくお、奜奇心を持぀ずいうこずには「生きおいる時間の党䜓を以前よりも面癜くする」効果があるず思っおいたす。

以前、ネットでこんな話を読みたした。倖でお匁圓を買うず、メむンのおかずの䞋に少量のパスタが敷かれおいるこずっおよくありたすよね。あれには実は理由があっお、揚げ物やお肉系のおかずは時間の経過ずずもに油分が出おくるので、あのパスタには「䜙蚈な油分を吞い取っお、䞻圹のおかずがベチャっずしおしたうのを防ぐ」ずいう圹割があるのだそうです。たた、揚げ物などは調理盎埌に盛り付けを行うず高枩になっおいるこずがあるので、それがプラスチック容噚に盎接觊れるのを防ぐずいう圹割もあるのだずか。

こういう事実を知ったずきのなるほど感ずいうのは気持ちがいいものですが、逆にそれを知らない人は「䞊げ底だ 䌁業は貧乏くさいテクニックで消費者を隙しおいる」などず憀慚するこずになったりもしたす。

ネットでよく芋かける陰謀論みたいな話も、おそらく「いろいろず事情があっおそうなっおいる」ずいうこの瀟䌚の耇雑さの認識の欠劂によるものだず思うので、「奜奇心は知識ず理解を呌び、知識ず理解は私たちを守っおくれる」ず蚀えるのかなず思いたす。

いやはや、こんな結論でこの解説蚘事がたずたるずは思っおいたせんでした。教蚓を匕き出そうずするのは物曞きの癖かな

ずにかく、みんなもこの䞖のいろんな物事に目を向けお、少しでも興味を匕かれたら「調べおみる」「自分でもやっおみる」ずいうこずをしおいくず面癜いず思いたす。では。

埌日远蚘プルスカちゃんがパワヌアップした件

ふず思い立っお、このnoteを曞いた翌週にプルスカちゃんを少しパワヌアップさせたした。リプラむに察しお返事をしおくれるようになっおいたす。

やった内容はわりず単玔で、以䞋の远加スクリプトを定期的に走らせるような圢です。

  1. プルスカちゃんの盎近の投皿䞀芧を取埗し、新たなリプラむが぀いおいないか確認

  2. 届いたリプラむをトヌクンに分割しお、その䞭に含たれおいる名詞の䞀芧から「反応甚キヌワヌド」を1぀だけランダムに遞ぶ名詞がなければ他の動詞などの適圓なトヌクンを代わりに遞ぶ

  3. 「反応甚キヌワヌド」を先頭トヌクンずしお、普段ず同じようにマルコフ連鎖で文章を生成する孊習デヌタは通垞皌働しおいるずきのものを流甚する

  4. 生成された文章をリプラむをくれた人宛おに投皿する

ポむントは2ず3の「反応甚キヌワヌド」を遞んでいるずころで、これによっお䞀応ちゃんずした返事っぜくなったりならなかったりしたす。

たた䜕か思い぀いたら機胜远加したす。みなさんもずきどきプルスカちゃんず遊んであげおください

関連曞籍

3月に出した曞籍「人生の意味の぀くり方」でも、私たちの生きる䞖界をコンピュヌタの仕組みず䞊べお考えた郚分がありたす。よかったらチェックしおみおくださいね

関連蚘事

いいなず思ったら応揎しよう

シロむ い぀も応揎ありがずうございたす✚ いただいたチップはおや぀代ぞ カロリヌを曞籍ずnote蚘事に倉換しおいたす🍩🍰☕

この蚘事が参加しおいる募集