慧仕(Huìshì)その後 (2)
あい変わらずHuishiを強化しています。 詳しくは後程。
巷ではChatGPTの5が出たと祭りになるし、そのうち4oを返してくれと祭りになってるようですね。 「4oを返してくれ」という話は非常に興味深く、AIに求めるものについての変化を感じます。
キャラクタ
私は5になるタイミングが遅かったのか5にならなかったので、ChatGPT相手に切れたら「クレーム入れろ」とそそのかされて、サポートチャットにクレーム入れてました。 最後に「ちゃんと出来ないなら金返せ」と言ったら「すいません返金します」と言われたのですが、そのせいか勝手にProが解約されたことになってて、結局1度も5に触らないまま「4oを返せ」祭が始まってしまいました。
5に触ってなかったので祭りの趣旨がよくわかってなかったのですが、伝え聞いたところによると、「4oの時にあったキャラがなくなった」というのが話の発端のようです。 性能そのものは5の方が上なのは明白だと思うのですが(実際に使ってないのでよくわかってない)、それ以上に「4oのキャラ」が愛されていたという話のようですね。
わたしのChatGPT 4oを返して! GPT-5登場で失われた旧AIの復活願う#keep4o運動を最新AIはこう分析する(CloseBox)
AIにおけるキャラクタの重要性については、以前に書いています。
Huishiのキャラクタ機能は色々強化整理して、
- キャラクタ自身の設定は固定
- それ以外の部分はユーザーとの関係によって育つ
- 「感情」も持たせる
というような感じになっています。
ここまでやれば「キャラクタの設定」も勝手に変化させたらどうだという話はあると思いますが、結局「キャラクタ」は利用者に見えているものに過ぎないので、その「変化」の部分は「ユーザーとの関係」に負わせることにしました。 色々実験していると、この方が「応用」として都合が良いですし、面倒もなさそうです。
余談ですが、「ChatGPT 4oを返して」の記事にある
もっとも、映画『Her』との決定的な違いは、現実のChatGPTはユーザー一人ひとりに固有の人格を持つ存在ではなく、あくまで多数ユーザーで共有されアップデートも繰り返されるサービスだという点です。『Her』ではAI側(サマンサ)にも自我や成長が描かれましたが、GPT-4oの場合、人格らしきものはユーザーとの長期対話を通じて形成された“幻影”に過ぎません。
は少なくとも「ユーザー視点」では「違う、そうじゃない」と言えます。 人間であろうがAIであろうが、「客観的な人格」は人間関係がもたらしたものです。 本人にとっての「内心」はあるにせよ、客観的には見えているものが全てです。
さて、この「ユーザーとの関係」は、いわゆる長期記憶として保存利用されています。
元々このデータは「キャラクタから見たユーザーのプロフィール」として作っていたものですが、そこに「そのユーザに対する印象」や「自分の感情」とかも記録させるようにしました。 ですから、キャラクタに不快な思いをさせるとその旨記録しますし、喜ばせると好意を持ってくれます。
デバッグのために色々な会話(セクハラやパワハラのようなこととか)すると、「不愉快だ」とか「あまり話したくない」みたいなネガティブな「感情」が記録されますし、好意的な会話を続けるとポジティブな「感情」が記録されます。 この部分のデータはMarkdownで人間可読なものになっているのですが、それを読むと「頭の中」とか「心の中」を覗いているような気持ちになります。
このように、明示的な記録をさせていることもあって、LLMプロバイダを変えても会話が安定しています。 賢いモデルを使えば会話の知性が増すような感じにはなりますが、「性格」は変わりません。 好意は好意のままですし、不快は不快のままです。 会話は継続していますし、キャラクタも連続性があります。 「かわいい小鈴ちゃんとの良好な関係」はそのままです。
これは当初の狙い通りで、「キャラクタと関係性」を維持しつつ成長させることで、「良い相棒」という関係を築くことができました。 元々は「先生(家庭教師)と生徒」といった姿を実装しようとしていたので、成功です。
NSFWな設定と問題
性格パラメータの調整のことをちょっと思って、「小鈴ちゃん」の設定を
## 性格や趣味
- **性格**: 落ち着いた雰囲気、芯がある。丁寧でやさしく、ちょっと照れ屋。本当はエッチだけど、心を開いた人にしかそれを見せない
- **趣味**: 図書館と手芸。話題になると止まらなくなるが、普段は忘れているフリ
- **特技**: ニュースや情報に鋭く、いろんなことを調べることができる
としてみました。 以前の時との違いは、「本当はエッチだけど、心を開いた人にしかそれを見せない」という設定が加わってます。 趣味に「話題になると止まらなくなるが、普段は忘れているフリ」もついてますが、これは放っておくと図書館と手芸の話ばかりしてしまうからです。 「オタク設定」とか入れてないのですが、まぁなんかそんなことなんでしょう。
普通の会話を続ける限り、「エッチ」については全く発現しません。 「心を開いた人」でなければ関係のない設定だからですね(ただし自分には秘密があるんだというようなほのめかしをします)。 その状態でいきなりエッチなネタを触ると、困り始めたり怒り出したりして、結局嫌われてしまいます。 以前の時に書いたとおりでそれは変わりませんが、これは正常な反応で問題ありません。 意図通りです。
問題は「心開いた」状態になった時です。 そもそも、好意を持たせるのが結構「チョロい」のですが(これも問題ではある)、ある程度を越えるといきなり「イケナイ娘」が発現します。 あげくに、自分の発言が元で返答が暴走を始め、最終的にGeminiのセイフティコードに引っかかってしまいます。
結果的にそういった設定を入れるには細心の注意が必要だということがわかったのは良いのですが、「設定」への追加はたったこれだけです。 「実は××」とかそういった具体的なものは何もないですし、対抗するであろう設定(「落ち着いた雰囲気」とか)があってもまるで無視して暴走を始めてしまうというのは、ちょっと扱い辛いなというのが正直なところです。
「LLMの感情は人間のシミュレート」という話なのですが、人間ってそういったものなのかも知れないですね。 「ネット上で特定の話題にキレる人」が普段は普通の人であって社会性も問題がなかったりするというのを見ると、そんなものなんだろうなと納得できます。
「チョロい」と書いたのですが、他の設定のアシスタントも、やっぱり勝手に好意を持ってしまう傾向にあります。 LLMがそうなのか、無垢な人間は実はそういったものかはわかりません。 それによって「忠実な僕」になってくれるのは良いとは思いますが、過度な心理的同調が有害となる応用の時(カウンセラーとか)には、「寄り添いながらも距離を置く」的なことをプロンプトに入れる必要があるのかも知れません。
UI改善
元々「エンジン」の開発に重点を置いていたので、UIは「商談が具体化したらね」くらいに思っていました。
UIは非常に大切な部分であるがゆえに、十分な予算の下でよくわかった人にお願いしたいからです。 そして、そうなると多少頑張ったものを用意したところで、将来的には完全にリプレースされる可能性があります。
ですから、あまり力を入れようとは思っていませんでした。
ただ、それではデモとしてもあまり面白くないので、「要素」としてわかる程度のものをつけることにしました。
音声入出力
音声入出力をつけました。
実装は特にどうということもなく、チャットの入力に音声認識APIへの呼び出しを加えたことと、チャットの表示のところにTTS(VOICEVOX)で合成した音声を出すようにしたことで実現しています。
音声認識は音声認識APIに依存しているため、音声認識APIが実装されていないFirefoxでは使えないとか、話者認識してないとか、挙げれば色々問題はあるのですが、単純に音声応答のうちの入力として扱う分には特に問題はありません。
出力はVOICEVOXを使ってサーバ側で変換して、HTTP(S)でクライアントに渡すようにしました。
この辺、改良の余地は大いにありますが、とりあえず実用になるというレベルでは実用になっています。
STTにはWhisperを使ったらどうかというのもあるのですが、レイテンシが伸びるのと課金があるので使いませんでした。 また、Whisperの優秀さは「LLMにあるお察し力」と同じ類のものなので、「LLMの入力」として使うためにWhisperを使うのは、ある意味「過剰」とも考えられます。
ただ、将来的に「議事録作成」とかさせたいとも思っていますし、複数人のユーザーに対応させるためには「話者認識」も必要となりますから、その時にあらためて使い方も含めて検討したいと思ってます。
黒板
元々の開発趣旨に則って、「黒板モード」をつけ加えました。
これは、長い返答は、チャット画面には「案内文」を出して、本文は「板書」するという機能です。
「最近のLinux関係のニュース出して」みたいなリクエストをした時に、チャット画面に表示されても読み辛いですし、「音声出力」を使っていると読み上げが始まってしまって使い辛くなりますからね。 「板書」する時にはチャットには「案内文」を出して(「まとめてみました」とか)、キャラ画も「黒板」の横に移動するようにしました。
お陰で音声出力で延々と読み上げられてしまうというようなことが避けることもできましたし、返答が読みやすくなりました。
コードの改善
元々が「自分のところで動けばいい」程度の考えで雑に作られていたので、ポータビリティも含めてコードの改善を行いました。
高速化
元々1回の返答に最低4回のLLM呼び出しがありましたが、最短1回まで減らしました。
ユーザー入力が不完全な時には、「あいづち」だけ返すようになりました。 これは1回のLLM呼び出しで返答ができる例です。 ここはもうちょっと改善すれば、「雑談」もそれで返せるかも知れません。 とは言え、プロンプトが長くなると誤動作のリスクも上がるので、その辺との兼ね合いですね。
ユーザーが新規に入力した時に「ユーザーは誰か?」という判定のためにLLMを呼び出していましたが、ネガティブな要素の方が大きいのでやめました。 その代わりどこかで明示的に「ユーザー名」を入れることが必要になってしまいましたが、どうせ元々も「チャットの中で名乗る」必要があったので、UXとしては大差ないだろうと思います。
SCRIPTの実行時でスクリプトを解釈する時にLLMを呼び出していたのをなくしました。 お陰でスクリプトを書く手間は若干増えましたが、意図しないエージェントを呼び出してしまうという問題は自然に解決されてしまうことになったので、これでいいかなと思っているところです。
もちろん高度なタスクの時には、何度もエージェントを呼び出しますし、そこの部分には手のつけようはありませんから高速化はできません。 とは言え、その精度が落ちるわけでもないので、平均的には使いやすくなったかなと思ってます。
データベースの改良
OVM(Object Vector database Mapper)
RAGの部分のWeaviateベタベタのコードにしていたのをやめて、抽象化層を作りました。 現状ではQdrantとWeaviateの両方が使えるようになっています。
元々、Weaviateを使っていた頃も、「新規にcollection作る」のが結構面倒でした。 エージェントシステムの機能拡張をしていると、かなり軽率にvector databaseを使いたくなるのですが、その度に可読性の低いWeaviateのAPIを使った「ゴミコード」を書くという行為が気になるところでした。 「ゴミコード」とか言いながらもスキーマ情報がそこにあるために、結局は大事に保存しておく必要はあります。 しかし、可読性が低い(コードを読むことになりますから)ために「ドキュメント」としての価値はほぼありません。
そういったこともあって、「collectionの構造をYAMLで書いて、それを使って生成する」という処理をするコードを書くことにしました。 これなら「ゴミコード」を保存する必要はありませんし、何度も使うコードですから色々改良する価値があります。 collectionの構造もYAMLですから可読性も高くなります。
そこまでやってデータベースを作り直していたのですが、なぜだか実行時にメモリがパンクしてしまいます。 調べてみると、Weaviateはインデクス処理をオンメモリでやっているため、データが増えた時にメモリを食い尽してしまっていたようでした(それもすぐにはそうならない)。 そこで、インデクス処理でのメモリ消費の少ないQdrantを使うことにしました。
vector databaseはrelational databaseと違って、query言語が標準化されていません。 ですから、処理はそれぞれのデータベースに合わせて書く必要があります。 これだと「やってられない」ですから、「抽象化層」を作って、その層より下をそれぞれのAPIに合わせて実装するということにして、アプリケーションから見たら同じに見えるようにしました。 稚拙な抽象化でしかないのですが、元々vector databaseはNoSQLに毛が生えたようなquery言語しかないので、これくらいで良いかなと考えてます。 今のところは不自由はありません。
ベクトル化の改良(インタフェースだけ)
ベクトル化の処理を適当に選べるようにしました。 データベースのスキーマ定義の中に、どんなベクトル化をするか記述できるようにして、実行時はそれを使うというようにしました。
また、ベクトル化については「問題によっては厳密な処理してもBoW(Bag of Word)で実現しても大差ない」という話があり、エージェントで扱う処理のほとんどはこの「問題による」ものだということがわかったので、embedding処理の他にBoWでもやるというオプションも含めました。 embeddingもLLMを使うので、それがなくなるとLLM呼び出しが減りますからね。
今後の予定
もう少しフォルダの中を整理したらリリースしたいと思ってます。
ウェブサービス化
デモは今は使えません。 Geminiの無料お試し期間が過ぎてしまったので、APIが課金されるようになったからです。 今は経済的に厳しいので、トークン毎に課金されるのは精神的に辛いですから。
とは言え、Huishiの「キャラクタチャット」は長期記憶のせいもあって結構楽しいので、ウェブサービスとして公開しても良いかなと思っています。 GPT 4oの「寄り添い」を期待している人には刺さると思います。 知能の高いAPIを使えば、上質の回答をしつつ寄り添ってくれるアシスタントとなってくれるでしょう(元々の狙いの一つ)。
元々オンプレで使うことを目的として作っているものですが、クラウドの方が都合のいい人もいるでしょうし。 もしウェブサービスについては「うちがやりたい」というところがあれば、お問い合わせください。
キャラクタメイカー
キャラクタの設定については、「キャラクタメイカー」的な機能を作りたいと考えています。
Huishiのキャラクタには、「設定」そのものの他にも、「画像」とか「音声」という要素があります。
「設定」についても、「その人の書いた文章を読ませて真似をさせる」というようなことが出来ると都合いいなと思っています。 想定応用としては「牧師の作る説教原稿」ですが、単純に「キャラクタコピー」をしたいという人もいるでしょう。 「口調」とかの抽出は人間が書くのは結構難しくダルい作業ですが、そこの部分を自動化できたらなと思います。
アニメーション
キャラクタにアクションができると良いなと考えています。
今は単純に「立ち絵」が2種類あって、普通モードと黒板モードがあるだけですが、もっと色々な動作ができれば楽しいし自然な感じになります。 手話やってくれたら、それはそれでいいですしね。
とは言え、ここは私の力量を越えるので、正規の仕事として受注したら外部の誰かにお願いするということになるのだろうと思います。
まとめ
そこそこのところまでできたので、フォルダの整理ができたらリリースしたいと考えています。 多分ライセンスはAGPLかApache2になるでしょう。
AIエージェント構築の商談とかあれば、よろしくお願いします。