
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/ — фірмовий ембед
- src/config/ — налаштування кластера та спільний стан бота
Як відбувається відповідь
Обробник повідомлень прокидається на кожне повідомлення в кожному каналі, який
бачить бот. Він відкидає ботів, відкидає все, що не згадує її через пінг або
слова alisa чи obliterator, а також наразі відкидає всіх авторів, крім одного,
чий ID захардкоджений у src/onmessage. Усе, що виживає, отримує негайний ембед
з текстом Thinking..., опублікований до того, як модель щось запитають, щоб
канал бачив, що вона прийняла питання, навіть якщо відповідь повільна.
Сама відповідь — це POST до Providence на http://127.0.0.1:8931 на
/speech/deepthink/, що несе повідомлення, весь контекст клубу та ім'я
користувача Discord як ідентичність викликача. Він чекає до 200 секунд.
Відповідь обрізається до 1990 байтів на межі символу UTF-8, щоб обрізання
ніколи не потрапило в середину кодової точки, а потім ембед-заглушка
редагується на місці. Таймаут, відмова або нерозбірливе тіло — усе
завершується текстом у тому самому ембеді, а не мовчанням.
Providence — це окремий сервіс, і його немає в цьому репозиторії. Без нього,
що працює на цьому порту, бот все одно запускається, відповідає на слеш-команди
та скрейпить клуб, він лише перестає думати.
Що додає Providence
Аліса надсилає light true, що є дешевим шляхом: один вузол міркування і без
розгалужень. Приберіть цей прапорець — і та сама кінцева точка запускає
обмежене дерево думок замість цього: глибина два, щонайменше дві позначені
гілки на вузол, кожна оцінюється за ймовірністю успіху та за тим, скільки
потенціалу вона додає чи знищує, і кожен вузол генерується нативним мислителем,
запущеним як підпроцес. Цей механізм просто лежить невикористаним у кожному
повідомленні, яке вона надсилає.
Він також сам вирішує, чи потребує питання більше, ніж розмови. Якщо так,
класифікатор зіставляє повідомлення з однією командою та її аргументом,
виконує її та вбудовує результат у фінальну відповідь. Що зараз у цьому списку:
- побудова графіків, 2D-крива або 3D-поверхня з функції, яку ви описуєте словами
- алгебра, спрощення, розкладання, факторизація, розв'язок для змінної
- математичний аналіз, похідні, визначені та невизначені інтеграли, границі
- матриці, визначник, обернена матриця, власні значення
- рендеринг будь-якого виразу як LaTeX
- портал UFFS SIGAA, поточні дисципліни, розклад, майбутні завдання
- ресторан UFFS, які прийоми їжі відкриті для бронювання і як минулі
пройшли, керований через справжній безголовий браузер із власними обліковими даними
Кожна з цих відповідей несе структуровані поля поруч із прозою. Графік або
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 для сервісу на іншому кінці сокета.
Цей бінарник ніколи їх не читає.
