Pull to refresh

Comments 10

Результат работы примера выглядит хуже чем старый способ с банальным редактированием сообщения раз в пару секунд.

Ну тут пример показывает, как реализуется механизм лишь. Всякие гэпы я на рандом воткнул. Новый метод на самом деле очень хорош, теперь нативнее все выглядит, нежели простое редактирование.

full_text += chunk - не самый лучший способ работы со строками. Хотя, если текст не очень большой, то ладно.

Это правда, поэтому это не повторяйте за мной!) Там конечно можно спорить, при каких объемах это плохо, но не будем

Там больше зависит от того, какого размера будут добавляемые куски. В не старых версиях CPython есть оптимизации, благодаря которым место под строку выделяется с запасом и при небольших размерах добавляемой строки и отсутствии дополнительных ссылок на эту строку, добавляемое записывается прямо на свободное резервное место, новая строка не создаётся. Но это детали реализации, на которые не всегда можно полагаться. )

Верно, в новых версиях вроде добавляли инплэйс обновление. Но нафиг его, помним, что стринга имутабельна, и делаем через io)

StringIO, либо банальный list с последующим string.join (примерно так же фактически устроен StringBuilder в C#).

Отличная статья! Сам недавно реализовывал стриминг для Telegram-бота на Cloudflare Workers, и возникли мысли по поводу подхода.

В статье используется sendMessageDraft → финальный sendMessage. Но есть альтернативный подход — редактирование существующего сообщения через editMessageText:

  1. Бот создаёт "думаю..." сообщение через sendMessage

  2. По мере получения чанков от LLM — редактирует это же сообщение через editMessageText

  3. В конце — финальное редактирование с полным текстом

Плюсы такого подхода:

  • Сообщение в истории чата остаётся ОДНИМ (а не черновик + новое сообщение)

  • Не нужно два API-вызова в конце

  • Работает и для длинных ответов с разбивкой на несколько частей

Минусы:

  • Нужно вручную показывать "печатает" через sendChatAction('typing')

  • Требуется HTML-форматирование (проблемы с незакрытыми тегами при стриминге)

  • Лимит Telegram: ~1 editMessageText в секунду

Для коротких сообщений (без стриминга) можно использовать Markdown напрямую (без HTML), а для длинных — HTML + балансировка тегов.

Интересно мнение автора: какой подход лучше для ботов с длинными ответами, которые нужно разбивать на части?

Посмотреть live-реализацию можно в боте @Vika_talk_Bot — там используется подход с editMessageText, стриминг + разбивка на части, Markdown для коротких сообщений (без стрима) и HTML для длинных.

Минус не мой, но старый метод через редактирование обсуждался выше в комментариях, плюс похоже вы просто рекламируете своего бота. За это видимо и минус.

А, то есть, раз уже выше писали, то мне это обсуждать нельзя, да?:)
А как насчёт ответа на вопрос? Технической дискуссии, так сказать? Вы же не вникали в написанное, я так вижу.

У нас есть длинный текст, например 10 тысяч символов от нейросети, его нужно передать в телеграм, а там ограничение в 4096 символа. Решение: режем на заведомо более мелкие куски (я режу по 3500).

Проблема: при нарезке мы часто портим входную разметку Markdown! (что, кстати вы в своих комментариях выше вообще никто не отобразил), и Телеграм возвращает ошибку 400. Можно делать анализ тегов кусков текста, проходя каждую часть валидатором, можно просто отдавать в html, попутно просто вырезав все теги перед разрезанием на части. Я сделал так: пытаемся отправить маркдаун, а html как запасной путь.

Но это в случае отправки разрезанными кусками, где у нас есть власть над текстом. В случае же стриминга предложенная схема замены черновика на замену текста отлично подходит для того, что влезает в 1 сообщение. А в случае замены стрима на 5 кусках на финальные обработанные части мы должны обновлять все 5 частей. А если мы их по-другому нарежем, ну, так получится? Или нам надо тоже сохранять все 5 частей в память и их все заменять? :) Думаю над этим:)

Понимаете, надо сразу думать про то, что нам потом придётся резать текст.

Автор просто не рассматривал длинные ответы.

Проблема остаётся:

  • Черновик → sendMessage (НОВОЕ сообщение)

  • Если текст > 4096 — снова резать на куски

  • Но это уже новые сообщения, не черновик!

    Подход через editMessageText — более универсальный, хоть и сложнее. Особенно для длинных ответов с разбивкой.


А насчёт "рекламы" бота, который ничего не продаёт - вы, верно, шутите, мистер CrazyElf.
Особенно учитывая по самые уши залепленный рекламой сайт habr.com.
Если у вас есть другой бот, где можно в натуре посмотреть метод стриминга через редактирование, можете его написать :)

Sign up to leave a comment.

Articles