
Alisa v Zadzerkalli (українською) — Аліса в Задзеркаллі. Світ по той бік дзеркала, куди ти потрапляєш навмисно, і все відображене, перевернуте й неправильне.
«Ніколи не вгадаєш, ким станеш за хвилину.»
"You can never guess who you'll become in a minute." — Аліса, у
Аліса в Країні Див, пер. Валентин Корнієнко, ред. Іван Малкович, с. 53.
Бот для Discord, написаний на C++.
Можливості
Слеш-команди
- /ping — час обробки запиту до шлюзу
- /leaderboard — таблиця лідерів Clube de Programação (UFFS), отримана з
групи клубу на vjudge та відсортована за кількістю розв'язаних задач
Розмова
Згадайте її, або напишіть alisa чи obliterator у повідомленні — і вона відповість.
Відповідь не генерується локально. Аліса збирає контекст, а Providence думає.
Що вона передає моделі в кожному повідомленні:
- кожного члена клубу, у порядку таблиці лідерів, з їхнім нікнеймом, кількістю
розв'язаних задач і часом останньої активності - повний список задач, розв'язаних кожним учасником, за кожною платформою
- десять найчастіше розв'язуваних задач у всьому клубі
Цей контекст дозволяє їй відповідати на питання, для яких ніхто не писав команду.
Хто в топ-3, які задачі вони мають спільні, хто замовк. Модель забезпечує
міркування, скрейпер — факти.
Дані клубу
Стан учасників отримується з vjudge під час запуску через обмежений пул із
восьми робітників, кожен із яких тримає одне з'єднання для своєї частини групи.
Кожен учасник коштує два запити: сторінка профілю для кількості та рейтингу,
і кінцева точка деталей розв'язків для списку задач.
Структура
- main.cpp — точка входу
- src/commands/ — слеш-команди та диспетчер
- src/members/ — склад клубу, скрейпинг профілів і списків розв'язків
- src/parser/ — запити до HTML через lexbor
- src/network/ — HTTP із повторним використанням з'єднань
- src/speech/ — зв'язок із Providence і збірка підказок
- src/onmessage/, src/onready/ — обробники подій шлюзу
- src/embeds/ — стандартний embed
- src/config/ — налаштування кластера та спільний стан бота
Як відбувається відповідь
Обробник повідомлень прокидається на кожне повідомлення в кожному каналі, який
бачить бот. Він відкидає ботів, відкидає все, що не згадує її через пінг або
слова alisa чи obliterator, а зараз також відкидає всіх авторів, окрім одного,
чий ID захардкоджений у src/onmessage. Усе, що виживає, отримує миттєвий embed
із текстом Thinking..., опублікований до того, як модель отримає запит, щоб
канал бачив, що вона прийняла питання, навіть якщо відповідь буде повільною.
Сама відповідь — це POST до Providence на http://127.0.0.1:8931 на
/speech/deepthink/, що несе повідомлення, весь контекст клубу та ім'я
користувача Discord як ідентичність викликача. Він чекає до 200 секунд.
Відповідь обрізається до 1990 байтів на межі символу UTF-8, щоб обрізання
ніколи не потрапило в середину кодової точки, а потім embed-заглушка
редагується на місці. Таймаут, відмова або нерозбірливе тіло — усе
завершується текстом у тому ж embed, а не мовчанням.
Providence — це окремий сервіс, якого немає в цьому репозиторії. Якщо він
не запущений на цьому порту, бот все одно стартує, відповідає на слеш-команди
та скрейпить клуб — він просто перестає думати.
Що додає Providence
Аліса надсилає light true, що є дешевим шляхом: один вузол міркування без
розгалужень. Якщо прибрати цей прапорець, та сама кінцева точка запускає
обмежене дерево думок: глибина два, щонайменше дві позначені гілки на вузол,
кожна оцінюється за ймовірністю успіху та за тим, скільки потенціалу вона
додає чи знищує, і кожен вузол генерується нативним мислителем, запущеним як
підпроцес. Цей механізм простоює на кожному повідомленні, яке вона надсилає.
Вона також сама вирішує, чи потребує питання більше, ніж розмови. Якщо так,
класифікатор зіставляє повідомлення з однією командою та її аргументом,
виконує її та вбудовує результат у фінальну відповідь. Що зараз у цьому списку:
- побудова графіків: 2D-крива або 3D-поверхня з функції, яку ви описуєте словами
- алгебра: спрощення, розкладання, факторизація, розв'язок змінної
- математичний аналіз: похідні, визначені та невизначені інтеграли, границі
- матриці: визначник, обернена матриця, власні значення
- рендеринг будь-якого виразу у форматі LaTeX
- портал UFFS SIGAA: поточні дисципліни, розклад, майбутні завдання
- ресторан UFFS: які страви відкриті для бронювання та як минули попередні,
керується через справжній headless-браузер із власними обліковими даними
Кожна з цих відповідей несе структуровані поля поруч із прозою. Графік або
LaTeX-рендер повертається як base64 PNG під полем image, читання порталу
повертається як JSON під полем data, а власний коментар моделі розміщується
поруч під полем response. Аліса читає response і викидає решту, тому сьогодні
питання, що створює графік, доходить до Discord як речення про графік, який
ніхто не бачить. Надсилання зображення як вкладення — це очевидна наступна
річ, якої цей бот має навчитися.
Доступ надається за викликачем, а не за ботом. Вона ідентифікує себе як
discord та ім'я автора, а Providence зіставляє цю пару та відмовляє будь-кому,
кого не знає, — це та відмова, яку вона друкує дослівно. Додавання члена клубу
означає додавання його там, а не тут.
Збірка
Потрібен компілятор C++20, CMake 3.16 або новіший, і три бібліотеки: DPP для
шлюзу, cpr для HTTP, lexbor для HTML. На Arch Makefile встановлює відсутні
через yay або paru. На будь-якій іншій системі встановіть їх самостійно.
make deps завантажити DPP, cpr і lexbor, якщо їх немає
make налаштувати та зібрати в build/
make run завантажити .env, потім запустити бінарник
make rebuild стерти build/ і почати заново
Дві речі в збірці навмисні. Тип збірки за замовчуванням — RelWithDebInfo,
а кількість паралельних процесів компіляції обмежена двома. Заголовки DPP
досить шаблонні, що неоптимізована збірка коштує кілька гігабайт на кожен
процес компілятора, а один процес на ядро звалить машину. Дайте більше, коли
маєте пам'ять: make JOBS=8.
Джерела збираються через CONFIGURE_DEPENDS, тому новий файл у src/
підхоплюється наступною збіркою без змін у CMakeLists.
Конфігурація
Бот читає DISCORD_TOKEN із середовища та більше нічого. Покладіть його в .env
у корені репозиторію, і make run експортує його за вас, або експортуйте самі
та запустіть build/alisa-v-zadzerkalli_core безпосередньо. Вона підключається
з інтентами за замовчуванням плюс вміст повідомлень, що є привілейованим
інтентом, тому увімкніть його для застосунку в порталі розробника Discord,
інакше обробник повідомлень бачитиме лише порожні рядки.
Ключі Providence зберігаються поруч у .env для сервісу на іншому кінці сокета.
Цей бінарник їх ніколи не читає.
