Тут две разные проблемы, и create_task решает только первую.
1. Колбэк должен отвечать сразу. Telegram ждёт answer() на callback_query несколько секунд, поэтому порядок такой: сразу await callback.answer() (можно с текстом «Запустил, это займёт время»), отредактировать сообщение в «⏳ Обрабатываю…» и запустить работу в фоне через asyncio.create_task(...). Ссылку на задачу сохраните (например, в set), иначе сборщик мусора может её прибить.
2. Ошибки «Failed to fetch updates … Request timeout» говорят о том, что блокируется сам event loop. Скорее всего, клиент к ИИ синхронный: requests, синхронный openai-клиент или тяжёлые вычисления. Пока он работает, aiogram не может даже забрать обновления, отсюда таймауты polling. Варианты:
— асинхронный клиент (AsyncOpenAI, httpx.AsyncClient);
— или обернуть синхронный вызов: result = await asyncio.to_thread(call_ai, prompt).
Когда фоновая задача закончится, отредактируйте то же сообщение через bot.edit_message_text(chat_id=..., message_id=...) и, если нужно, отправьте файл через send_document. Так в истории останется одно сообщение и файл, как вы хотите.
Прогресс-бар делается тем же редактированием сообщения. Только не чаще раза в 2–3 секунды, иначе получите flood control.
Если задачи будут идти часами, держать их внутри процесса бота уже рискованно: перезапуск бота их потеряет. Тогда выносите работу в очередь (arq, taskiq, Celery). Бот кладёт задачу и сохраняет chat_id и message_id, воркер выполняет её и по завершении сам редактирует сообщение через Bot API.