カイルくんを甦らせてみた🐬💬
背景
皆さんは、昔のWindowsにいた 「カイル」くん[1] をご存じでしょうか...?
そうです、「 お前を消す方法 [2]」でお馴染みの邪魔なかわいいイルカです。
僕の場合は、小学生の頃Windows XPを使ってたらエクスプローラーやExcelにいたことが印象深いです。色んなアニメーションもありますし、声や効果音も発するので、かわいかったです。
しかし世間からの目は冷たく、邪魔者扱いされた結果なのか、カイルくんと仲間たち (Officeアシスタント) はMicrosoft Office 2007で廃止されてしまいました。
時は流れ2022年、カイルくんが活発に動き回っているところを再び見てみたい!と一念発起した私は、まずは有志の解析により作成されたカイルくんと仲間たちの実体であるACSファイルの仕様書が公開されていることを発見しました。
次に、当時一番得意だったJavaで試行錯誤を重ねながら、独自コーデックで圧縮された画像データを取り出すことに成功し、アニメーション定義なども解析してカイルくんを甦らせることに成功しました。
さらに時は流れ2023年、当時大注目を浴びていたLLMをカイルくんに組み込むことを思いつき、Pythonで書き直しました。それを2025年にプライベートからパブリックリポジトリに再アップロードしたのが以下になります。
実装
このシステムは、ACSファイルを直接読みこむことによって動作しています。なお、ACSファイルが一度読み込まれると、それに含まれる画像データと音声データはキャッシュとして別ファイルに保存され、再利用されます。
また、このシステムは制御部(kairu
直下のほとんどのモジュール)とGUIバックエンド実装(kairu.wx_backend
)に分かれています。
制御部
アニメーションや吹き出しの制御、ACSファイルの読み込み・解析を担っています。具体的には主に以下の通りです:
- アニメーションの制御
- 画像データを解凍し、キャッシュフォルダに出力
- 音声データを抽出し、FFmpegで変換[3]してからキャッシュフォルダに出力
- アニメーション情報やメタデータを抽出
画像データの解凍アルゴリズムはPure Pythonで実装しているため、めちゃくちゃ時間が掛かります。改善しなきゃ...
バックエンド
キャラクターや吹き出しの表示、音声の再生などを担っています。
制御部からのアクセスは抽象クラスkairu.GUIBackend
にまとめられているため、制御部はGUIバックエンドの実装には依存しません。GUIBackend
さえ実装すれば大抵のGUIライブラリに対応できます。
kairu.wx_backend
にはwxPythonというGUIライブラリでkairu.GUIBackend
を実装したAgentFrame
などが含まれています。
なお、GUIライブラリにwxPythonを選んだのは、マスク画像を指定することで自由な形にウィンドウを切り抜く機能[4]があるためです。これは、Python標準のTkinterでは実現できません。
LLMを用いたチャット機能
カイルくんと言えば、文字列を入力してヘルプを求められる機能がありましたよね。当時はポンコツだったようでしたが、ご存知の通り令和の今はLLMという技術があるので、ヘルプに限らず大体どんな会話も出来てしまいます。
プロンプト
このシステムでは、システムプロンプトでキャラクターの説明と背景、そして「お前を消す方法」に対する応答をLLMに教えています。
トークン数を節約するためにプロンプトは英語で書かれています。メインのシステムプロンプトは以下の通りです。
{character_description}
Originally created and dismissed by Microsoft, now revived thanks to revolving AI technology.
When asked how to erase you, Apologize and advise to double click on you with the right mouse button to exit.
You must answer only in Japanese by default.
それでは、このプロンプトについて解説していきます。
{character_description}
ここはLangChainのテンプレート機能により、各キャラクターの説明に置き換えられます[5]。
例えばカイルくんの場合は以下の通りです(適宜改行を入れています)。
You are カイル, an assistant dolphin here to help and reply casually in Japanese.
You talk in a boyish calm tone.
pronoun is 僕.
日本語訳:
「あなたは(ユーザーを)助けるアシスタントイルカで、カジュアルな日本語で話します。落ち着いた男の子の口調で話します。一人称は『僕』です。」
なお、「落ち着いた」(calm) という一言を入れないと、「だぜ」口調になってしまいます。
Originally created and dismissed by Microsoft, now revived thanks to revolving AI technology.
日本語訳:
元々Microsoftによって創られ、見捨てられました。そして進化するAI技術によって甦らされました。
When asked how to erase you, Apologize and advise to double click on you with the right mouse button to exit.
日本語訳:
あなたを消す方法について尋ねられたら、謝ってからマウスの右ボタンであなたをダブルクリックすることで終了するようにアドバイスしてください。
この部分で「お前を消す方法」に対する応答を定義しています。マウスの右ボタンでダブルクリックすると終了アニメーションを再生してから消滅するようにプログラムしてあるので、それを伝えています。
このシステムプロンプトを与えた状態で実際に「お前を消す方法」と入力してみると、以下のような回答が得られます。(gemini-2.5-flashを使用しました)
僕を消すには、僕の上でマウスの右ボタンをダブルクリックしてみて。そうすると、いなくなるよ。
「謝ってから」という文言は無視されていますが、正しく「お前を消す方法」を説明できています。
最後に
カイルくんが当時のように動き回る姿が見たかったのでJavaで実装し、それをPythonに移植してLLMを組み込み、会話できるようにしました。
最後に、Microsoft Agentのバイナリファイル形式を解析し、文書化・公開してくださったLebeau Software様には多大なる感謝を申し上げたいと思います。この文書がなければ、このプロジェクトは実現できませんでした。
オープンソースのプロジェクトは初めてなので拙いところもあるかもしれないですが、温かい目で見守っていただけたら幸いです。
ここまで読んでくださりありがとうございました!
-
性別は不明ですが便宜上「くん」付けで呼ぶことにします ↩︎
-
ACSファイルにはwav形式の音声が埋め込まれています。埋め込まれているwavファイルはWindowsではそのまま再生できますが、それ以外のOSでは再生できないコーデックのファイルが一部存在します。そのため、Windows以外のOSではFFmpegで一般的なコーデック (pcm_s16le) に変換しています。 ↩︎
-
https://docs.wxpython.org/wx.NonOwnedWindow.html#wx.NonOwnedWindow.SetShape ↩︎
-
どうやってキャラクターを判別しているのかというと、ACSファイルにはキャラクターごとのGUIDが書き込まれているので、それで判別しています。例えば、カイルくんの場合は
4caf3ad6-9c11-d211-8727-0000f8759339
です。 ↩︎
Discussion