Я не проверял, но как выше написал, я не думаю, что в раннере гитхаба можно запустить мощную модель, которая сможет более-менее хорошо обработать большой diff.
ИИ анализирует diff и оставляет комментарии по коду
Улетает diff, а также название и описание PR. На данный момент это всё. Как отвечал выше, в будущем планирую реализовать передачу в контекст прошлых комментариев при дополнении PR'а, чтобы ответ не повторялся.
используются ли RAGи
RAG не используется, но подумаю над этим.
Как подбирались промпты, и какие они сейчас?
Промпты сейчас не в лучшем виде, они есть в репозитории. Пока, что они на русском и с зашитым ответом на русском, впоследствии реализую систему кастомных промптов и расширю имеющиеся.
Есть ли ограничения по языкам программирования?
Всё ограничивается используемым ИИ-провайдером и моделью. Если подключите локальную дообученную для питона, то будет не лучшая идея давать ей условную Java.
Локальный запуск LLM для ревью прямо внутри раннера гитхаба
Сомневаюсь, что у раннера гитхаба хватит для этого мощностей, но идея запускать проект в воркфлоу тоже есть, с подключением к ИИ на стороне.
Не использовал SonarQube, но как я понимаю он для статического анализа кода.
Сомневаюсь, что он может распознать, например, неэффективный код, с чем вполне может справится ИИ. А для статических проверок вполне хватает pre-commit.
Про RSGI не могу ничего сказать. Он ещё очень молод, поэтому и скуден. Интересно будет наблюдать за его развитием, как со стороны применения в Python, так и в самом Rust
А вот этот бенчмарк говорит, что uWSGI самый медленный (впрочем, насколько можно верить бенчмарку девятилетней давности, не знаю — но мне до сих пор интересно, что не так с этим бенчмарком)
RSGI не применяется в джанге, это отмечено в статье. Granian работает по WSGI, однако, даже в работе синхронно он обеспечивает производительность сопоставимую с ASGI. После реверс прокси идёт именно веб-сервер, у него есть свои задержки выполнения, это сравнение также есть в статье. Если брать значения "в лоб", у granian в шесть раз лучше показать задержки выполнения, а затем уже да, идёт джанга. И вот этого достаточно, чтобы повысить отзывчивость сайта. Преимущества в RPS проявят себя со временем при росте посещаемости. Gunicorn'а у меня никогда не было, я сразу использовал uWSGI и заменил его на Granian, вместо обвзяки Django Cannels + uvicorn.
Полтора года назад писал подобного бота на стриме без ии!)) Так и не дошли руки его доработать и превратить во что-то интересное) Правда вместо библиотеки докер использовал прописанные команды, зато есть БДшка со списком избранных команд и возможность выполнять пользовательские команды)
class CommandsRobot(ModelConfig):
"""Класс с командами для робота"""
# Другой код
stop: str
def is_command(self, command: str) -> bool:
"""Есть ли команда в командах"""
return command in self.model_dump().values()
Тут у тебя при каждом обращении будет происходить сериализация текущего объекта класса, что не очень хорошо в плане производительности. Куда лучше завести отдельное поле которое один раз создаётся из дампа, а потом через property выдаёт из него значение. Либо уйти от Pydantic-Settings к Dynaconf, который один раз сериализует конфиг в объект настроек и можно будет получать доступ к словарям и вложенным элементам.
В моём случае он хранит кортежи со статус-кодами и сообщениями, что делает ответы читаемыми и структурированными.
class FormResponse(Enum):
"""Класс для формирования ответа"""
NOT_FOUND_COMMAND = (404, 'Unknown command!')
OK_COMMAND = (200, 'Command executed')
SERVER_ERR = (500, 'Internal Server Error!')
@property
def response(self) -> dict[str, int | str]:
"""Словарь для формирования ответа серверу"""
return {
'status': self.value[0],
'message': self.value[1]
}
Сугубо моё мнение, но использовать тапл как значение энума не лучшая идея и проблема такого использования прямо отражается в методах класса - неявное индексирование. Если тебе в другом месте понадобится использровать только текст команды или его код, будешь делать [0] или [1], что плохо с точки зрения явности. Я бы заменил весь класс на DictEnum и прописал конкретные ключи или, если хочешь остаться на кортежах, тогда NamedTuple в качестве значений. Это сильно повысит читаемость кода и использование значений вне методов класса.
Это можно вынести наружу цикла while, иначе как я писал выше, каждый раз будет происходить сериализация класса с командами в JSON и выборкой из него. При том, что во время работы приложения класс не будет меняться.
Я тестировал пока только на трёх провайдерах (которые реализованы в проекте): OpenAI, GigaChat от Сбера и YandexGPT.
От OpenAI использую модель
gpt-4.1-mini
, она достаточно дешева и выдаёт достойные комментарии. Их можно посмотреть в закрытых PR репозитория.GigaChat на стандартной модели выдаёт крайне посредственные и ограниченные комментарии.
YandexGPT тестировал на стандартной модели
yandexgpt
. Результат не совсем дотягивает до OpenAI, но вполне достойный.Думаю, что подбирать модели буду в последствии, когда реализую других провайдеров и наведу порядок в промптах.
Да, поддерживается. У меня развёрнута своя Gitea, и все тесты проводил на ней, а потом уже на Github)
Я не видел)
Я не проверял, но как выше написал, я не думаю, что в раннере гитхаба можно запустить мощную модель, которая сможет более-менее хорошо обработать большой diff.
Ответ есть в статье:
Улетает diff, а также название и описание PR. На данный момент это всё. Как отвечал выше, в будущем планирую реализовать передачу в контекст прошлых комментариев при дополнении PR'а, чтобы ответ не повторялся.
RAG не используется, но подумаю над этим.
Промпты сейчас не в лучшем виде, они есть в репозитории. Пока, что они на русском и с зашитым ответом на русском, впоследствии реализую систему кастомных промптов и расширю имеющиеся.
Всё ограничивается используемым ИИ-провайдером и моделью. Если подключите локальную дообученную для питона, то будет не лучшая идея давать ей условную Java.
Сомневаюсь, что у раннера гитхаба хватит для этого мощностей, но идея запускать проект в воркфлоу тоже есть, с подключением к ИИ на стороне.
Только в контексте diff'а открытого PR. Сохранение истории, а именно учёт предыдущих комментариев тоже в планах реализовать.
Не использовал SonarQube, но как я понимаю он для статического анализа кода.
Сомневаюсь, что он может распознать, например, неэффективный код, с чем вполне может справится ИИ. А для статических проверок вполне хватает pre-commit.
Перманентно)
Как и весь граниан по большому счёту =)
Granian также можно вызывать из кода:
https://github.com/emmett-framework/granian?tab=readme-ov-file#embedding-granian-in-your-project
Про RSGI не могу ничего сказать. Он ещё очень молод, поэтому и скуден. Интересно будет наблюдать за его развитием, как со стороны применения в Python, так и в самом Rust
https://github.com/zauberzeug/nicegui/discussions/3039
RSGI не применяется в джанге, это отмечено в статье. Granian работает по WSGI, однако, даже в работе синхронно он обеспечивает производительность сопоставимую с ASGI. После реверс прокси идёт именно веб-сервер, у него есть свои задержки выполнения, это сравнение также есть в статье. Если брать значения "в лоб", у granian в шесть раз лучше показать задержки выполнения, а затем уже да, идёт джанга. И вот этого достаточно, чтобы повысить отзывчивость сайта. Преимущества в RPS проявят себя со временем при росте посещаемости. Gunicorn'а у меня никогда не было, я сразу использовал uWSGI и заменил его на Granian, вместо обвзяки Django Cannels + uvicorn.
Думаю, что опробую его в связке с FastAPI и изучу тему тестирования нагрузочного, чтобы примерно представлять производительность
Улучшился отклик сайта, и в перспективе он будет обрабатывать большое количество запросов лучше и стабильнее чем uWSGI
Ну на раст прям не факт, но вот то, что библиотеки используют его под капотом для ускорения мне определённо нравится
Полтора года назад писал подобного бота на стриме без ии!)) Так и не дошли руки его доработать и превратить во что-то интересное) Правда вместо библиотеки докер использовал прописанные команды, зато есть БДшка со списком избранных команд и возможность выполнять пользовательские команды)
Если интересно, расприватил репо: https://git.pressanybutton.ru/proDream/serverbot
P.S. В клиенте тг на пк, в экспериментальных настройках можно включить отображение id в профиле пользователя и боты будут не нужны)
Интересная статья, но есть несколько замечаний:
Тут у тебя при каждом обращении будет происходить сериализация текущего объекта класса, что не очень хорошо в плане производительности. Куда лучше завести отдельное поле которое один раз создаётся из дампа, а потом через property выдаёт из него значение. Либо уйти от Pydantic-Settings к Dynaconf, который один раз сериализует конфиг в объект настроек и можно будет получать доступ к словарям и вложенным элементам.
Сугубо моё мнение, но использовать тапл как значение энума не лучшая идея и проблема такого использования прямо отражается в методах класса - неявное индексирование. Если тебе в другом месте понадобится использровать только текст команды или его код, будешь делать [0] или [1], что плохо с точки зрения явности. Я бы заменил весь класс на
DictEnum
и прописал конкретные ключи или, если хочешь остаться на кортежах, тогда NamedTuple в качестве значений. Это сильно повысит читаемость кода и использование значений вне методов класса.Это можно вынести наружу цикла while, иначе как я писал выше, каждый раз будет происходить сериализация класса с командами в JSON и выборкой из него. При том, что во время работы приложения класс не будет меняться.
Посмотрел, штука интересная. Она скорее как альтернатива заббиксу, не только мониторить состояния, но им собирать метрику.
Скорее всего, речь про актуальную ветку 1.x и использование SQLIte. В бете второй версии есть поддержка внешней MariaDB.
Из документации:
Не понял, при чём тут Касперский.
Буквально только что, вышло обновление для aiogram с поддержкой нововведений Bot API 9.2.
Обновиться можно командой
pip install -U aiogram