Alisa V Zadzerkalli
C++

Alisa V Zadzerkalli

Alisa v Zadzerkalli - C++で書かれたDiscordボット

GitHub|
image

Alisa v Zadzerkalli (ウクライナ語) - 鏡の国のアリス。鏡の向こう側の世界。そこへは意図的に行き、すべてが反転し、逆さまになり、間違っている。

«Ніколи не вгадаєш, ким станеш за хвилину.»
「一分後に自分が誰になっているかなんて、決して予測できない。」 - アリス、『アリス・イン・ワンダーランド』(Аліса в Країні Див)、ヴァレンティン・コルニエンコ訳、イヴァン・マルコヴィチ編、p. 53。

C++で書かれたDiscordボット。

機能

スラッシュコマンド

  • /ping - ゲートウェイとの往復レイテンシ
  • /leaderboard - Clube de Programação (UFFS) の順位表。クラブのvjudgeグループからスクレイピングし、解決済み問題数でランク付け

会話

彼女にメンションするか、メッセージ内で「alisa」または「obliterator」と言うと、彼女が応答する。返信はローカルで生成されない。アリスがコンテキストを組み立て、Providenceが思考を行う。

彼女が毎メッセージでモデルに提示するもの:

  • リーダーボード順の全クラブメンバー(ハンドル名、解決済み数、最終アクティブ時間)
  • 各メンバーが解決した問題の全リスト(ジャッジごと)
  • クラブ全体で最も頻繁に解決された10の問題

このコンテキストにより、彼女は誰もコマンドを書いていない質問に答えることができる。トップ3は誰か、彼らに共通する問題は何か、誰が沈黙しているか。モデルが推論を提供し、スクレイピングが事実を提供する。

クラブデータ

メンバーの状態は起動時にvjudgeから取得される。8つのワーカーからなる制限付きプールが使用され、各ワーカーはグループの担当分に対して1つの接続を保持する。各メンバーにつき2つのリクエストが必要:カウントとランクのためのプロフィールページ、問題リストのための解決詳細エンドポイント。

構成

  • main.cpp - エントリポイント
  • src/commands/ - スラッシュコマンドとディスパッチャ
  • src/members/ - クラブロスター、プロフィールと解決リストのスクレイピング
  • src/parser/ - lexborによるHTMLクエリ
  • src/network/ - 接続再利用を備えたHTTP
  • src/speech/ - Providenceリンクとプロンプト組み立て
  • src/onmessage/、src/onready/ - ゲートウェイイベントハンドラ
  • src/embeds/ - ハウスエンベッド
  • src/config/ - クラスター設定と共有ボット状態

返信の仕組み

メッセージハンドラは、ボットが見えるすべてのチャンネルのすべてのメッセージで起動する。ボットを除外し、ピングまたは「alisa」「obliterator」という単語で彼女に言及していないものを除外し、現在は著者を1人だけに制限している(そのIDはsrc/onmessageにハードコードされている)。生き残ったものには、モデルに何も尋ねる前に「Thinking...」と表示される即時エンベッドが投稿される。これにより、回答が遅い場合でも、チャンネルは彼女が質問を受け取ったことを確認できる。

回答自体は、http://127.0.0.1:8931 の /speech/deepthink/ へのPOSTであり、メッセージ、クラブ全体のコンテキスト、およびDiscordユーザー名を呼び出し元IDとして運ぶ。最大200秒待機する。返信はUTF-8文字境界で1990バイトに切り詰められ、切断がコードポイントの途中で発生しないようにする。その後、プレースホルダーエンベッドがその場で編集される。タイムアウト、拒否、または解析不能なボディはすべて、沈黙ではなく同じエンベッド内のテキストとして終了する。

Providenceは別のサービスであり、このリポジトリには含まれていない。そのポートで実行されていなくても、ボットは起動し、スラッシュコマンドに応答し、クラブをスクレイピングし続ける。ただ思考しなくなるだけだ。

Providenceが追加するもの

アリスは light true を送信する。これは安価な経路で、推論ノードが1つで分岐がない。このフラグを落とすと、同じエンドポイントは代わりに制限付き思考ツリーを実行する:深さ2、ノードごとに少なくとも2つのラベル付き分岐、各分岐は成功確率と追加・破壊する可能性の大きさでスコアリングされ、各ノードはサブプロセスとして生成されたネイティブシンカーによって生成される。その機構は、彼女が送信するすべてのメッセージで未使用のまま存在している。

また、質問が会話以上のものを必要とするかどうかを自分で判断する。必要な場合、分類器がメッセージを1つのコマンドとその引数にマッピングし、それを実行し、結果を最終回答に組み込む。現在のリスト:

  • プロット:言葉で説明する関数からの2D曲線または3D曲面
  • 代数:簡約化、展開、因数分解、変数について解く
  • 微積分:導関数、定積分と不定積分、極限
  • 行列:行列式、逆行列、固有値
  • 任意の式のLaTeXレンダリング
  • UFFS SIGAAポータル:現在の科目、スケジュール、今後の課題
  • UFFSレストラン:予約可能な食事と過去の実績。独自の認証情報を持つ実際のヘッドレスブラウザで駆動

これらの回答はすべて、散文の横に構造化フィールドを運ぶ。プロットやLaTeXレンダリングはbase64 PNGとして image の下に返され、ポータル読み取りはJSONとして data の下に返され、モデル自身の解説は response の下に並ぶ。アリスは response を読み、残りを捨てる。したがって、今日グラフを生成する質問は、誰も見ることのできないグラフについての文としてDiscordに届く。画像を添付ファイルとして送信することが、このボットが次に学ぶべき明らかなことだ。

アクセスはボット単位ではなく呼び出し元単位である。彼女は自分を discord と識別し、著者のユーザー名を識別する。Providenceはそのペアを照合し、知らない人を拒否する。それが彼女が逐語的に印刷する拒否だ。クラブメンバーを追加するということは、ここではなく、そちらに追加することを意味する。

ビルド

C++20コンパイラ、CMake 3.16以降、および3つのライブラリ(ゲートウェイ用のDPP、HTTP用のcpr、HTML用のlexbor)が必要。Archでは、Makefileがyayまたはparuを通じて不足しているものをインストールする。他の環境では、自分で先にインストールすること。

make deps      DPP、cpr、lexborがなければ取得
make           設定してbuild/にビルド
make run       .envを読み込み、バイナリを実行
make rebuild   build/を消去して最初からやり直す

ビルドには2つの意図的な点がある。デフォルトのビルドタイプはRelWithDebInfoで、並列コンパイルジョブは2に制限されている。DPPのヘッダーはテンプレートが多用されており、最適化されていないビルドはコンパイラプロセスごとに数ギガバイトを消費する。コアごとに1プロセスではマシンがダウンする。メモリに余裕がある場合は増やして、make JOBS=8 と指定する。

ソースはCONFIGURE_DEPENDSでグロブされるため、src/の下に新しいファイルを追加すると、CMakeListsを触らずに次のビルドで拾われる。

設定

ボットは環境からDISCORD_TOKENを読み取り、それ以外は何も読み取らない。リポジトリルートの.envに置くと、make run がそれをエクスポートする。または自分でエクスポートして build/alisa-v-zadzerkalli_core を直接実行する。彼女はデフォルトのインテントにメッセージコンテンツを加えて接続する。これは特権インテントなので、Discord開発者ポータルのアプリケーションで有効にしないと、メッセージハンドラは空文字列しか見ることができない。

Providenceキーは、ソケットの反対側のサービスのために.envに並んで置かれる。このバイナリはそれらを決して読み取らない。