Сейчас мы используем классический механизм запрос-ответ.
А большинство ИИ API и в частности Напарник поддерживают stream (потоковый) режим, т.е. один запрос и несколько ответов, чтобы быстрее доставлять первую часть результата. Каждая часть приходит с префиксом "data: ".
Предлагаю
В обработчике ПриОтправкеЗапросаИИТ9 добавить флаг поддержки потокового режима
При включенном фаге вызывать обработчик ПриПолученииОтветаИИТ9 при получении 2-й части (чанка) и остальных частей отдельно вместе с указанием флага первой части, т.е. будет 1-2 вызова ПриПолученииОтветаИИТ9 на один ПриОтправкеЗапросаИИТ9
В обработчике ПриПолученииОтветаИИТ9 нужен флаг прерывания обработки ответа, т.к. я часто после первой порции знаю, что дальше нет смысла получать ответ.
0 0
ред. 07 ноября 2025 18:10
Недостаточно рейтинга для добавления отрицательного голоса. Шаблон будет скрыт из ваших результатов поиска.
Комментарии
tormozit #1, ред. 11 октября 2025 12:04
Делаю это в ИР. Сложная штука, если прорабатывать тщательно, а выигрыш дает не такой большой, как я ожидал. В 2000мс ответе первая часть приходит всегда на второй секунде, т.е. в лучшем случае где то максимум на 50% быстрее появляется первая строка ответа ИИ.
Вот текст HTML документа, используемого в ИР для фоновых HTTP запросов. Думаю его можно кинуть в ИИ и получить заготовку для реализации в C#
Ссылка скрыта
Отправку делаю так
Процедура ОтправитьЗапрос(Знач Адрес, Знач ТелоЗапросаСтрока, Знач Заголовки, Знач ЛиПотоковый = Ложь, Знач ЛиПроверочный = Ложь, знач МинИнтервалОтветов = 500) Экспорт
Если Не ирКэш.ДоступноБраузерWebKitЛкс() Тогда
Возврат;
КонецЕсли;
мЛиПроверочный = ЛиПроверочный;
ЗаголовкиМассив = Новый Массив;
Для Каждого ЗаголовкиЭлемент Из Заголовки Цикл
ЗаголовкиМассив.Добавить(Новый Структура("name,value", ЗаголовкиЭлемент.Ключ, ЗаголовкиЭлемент.Значение));
КонецЦикла;
ЗаголовкиТекст = ирОбщий.ОбъектВТекстЖСОНЛкс(ЗаголовкиМассив);
мНакопленныйОтвет = "";
мЛиПотоковый = ЛиПотоковый;
Если мЛиПотоковый Тогда
Браузер().sendStreamRequest(Адрес, ТелоЗапросаСтрока, ЗаголовкиТекст, МинИнтервалОтветов);
Иначе
Браузер().sendHttpRequest(Адрес, ТелоЗапросаСтрока, ЗаголовкиТекст);
КонецЕсли;
КонецПроцедуры
Обработку события от HTML документа в 1С делаю так
Процедура СлужебноеПолеХТМЛonclick(Элемент, pEvtObj) Экспорт
СтрокаСловаНапарника = СтрокаСловаНапарника();
Если СтрокаСловаНапарника.Слово = СтатусИИНеЗнает() Тогда
Возврат;
КонецЕсли;
ЛиПерваяЧасть = СтрокаСловаНапарника.Слово = СтатусИИДумает();
ЛиПоследняяЧасть = мФоновыйЗапросХттп.ЛиПотокЗавершен();
Если Истина
И Не ЛиПерваяЧасть
И Не ЛиПоследняяЧасть
Тогда
Возврат;
КонецЕсли;
ЧастьОтвета = мФоновыйЗапросХттп.ПрочитатьЧастьОтвета();
Если ЧастьОтвета = "" Тогда
Возврат;
КонецЕсли;
Отказ = Ложь;
Результат = ОбработатьОтветНапарника(ЧастьОтвета,, ЛиПерваяЧасть, ЛиПоследняяЧасть, Отказ);
Если Отказ Тогда
мФоновыйЗапросХттп.ОтменитьЗапрос();
Если ПустаяСтрока(Результат) И ЛиПерваяЧасть Тогда
Результат = СтатусИИНеЗнает();
КонецЕсли;
Если Не ЛиПоследняяЧасть Тогда
// Чтобы отправились заказанные метаданные
ОбработатьОтветНапарника("Конец:",, Ложь, Истина, Отказ);
КонецЕсли;
КонецЕсли;
Если ЛиСжиматьПустыеСтроки() Тогда
//УдалитьПустыеСтрокиВТекстеНапарника(Слово);
Если ПустаяСтрока(Результат) Тогда
Результат = "";
КонецЕсли;
КонецЕсли;
Если СтрокаСловаНапарника.Слово = СтатусИИНеЗнает() Тогда
// очень странная ситуация, как будто эти обработчики работают параллельно
Возврат;
КонецЕсли;
Если СтрокаСловаНапарника.Слово <> СтатусИИДумает() Тогда
Результат = СтрокаСловаНапарника.Слово + Результат;
ИначеЕсли ЗначениеЗаполнено(Результат) Тогда
Результат = СокрЛ(Результат);
КонецЕсли;
Если ПустаяСтрока(Результат) Тогда
Результат = СтатусИИНеЗнает();
КонецЕсли;
СтрокаСловаНапарника.Слово = Результат;
ЭлементыФормы.ТаблицаСлов.ОбновитьСтроки(ирОбщий.ЗначенияВМассивЛкс(СтрокаСловаНапарника));
ОбновитьОписаниеСлова();
КонецПроцедуры
Общая функция обработки частей ответа Напарника для Турбоконфа и ИР
Функция ОбработатьОтветНапарника(Знач ТекстОтвета, ТекстОбновления = "", Знач ЛиПерваяЧасть = Истина, Отказ = Ложь) Экспорт
Если ПустаяСтрока(ТекстОтвета) Тогда
Возврат "";
КонецЕсли;
ТекстОтвета = СокрЛ(ТекстОтвета);
Если Истина
И ирОбщий.СтрНачинаетсяСЛкс(ТекстОтвета, "Ошибка:")
И ирОбщий.СтрКончаетсяНаЛкс(ТекстОтвета, "401")
Тогда
СоединениеНапарника(, Истина);
Возврат "";
КонецЕсли;
Слово = "";
Отказ = Ложь;
ПрефиксЧастиОтвета = "data: ";
ЭлементыОбновления = Новый Массив;
Если ирОбщий.СтрНачинаетсяСЛкс(ТекстОтвета, "Ошибка:") Тогда
Слово = ТекстОтвета;
ИначеЕсли ирОбщий.СтрНачинаетсяСЛкс(ТекстОтвета, "Отмена:") Тогда
// Только для потокового режима
ИначеЕсли ирОбщий.СтрНачинаетсяСЛкс(ТекстОтвета, "Конец:") Тогда
// Только для потокового режима
ИначеЕсли ирОбщий.СтрНачинаетсяСЛкс(ТекстОтвета, ПрефиксЧастиОтвета) Тогда
...
КонецЕсли;
Возврат Слово;
КонецФункции
0
tormozit #4, ред. 03 ноября 2025 09:02
Обкатал. Работает стабильно. В среднем дает ускорение отображения ответа Напарника на 30%.
Основные функции в Обработка.ирФоновыйЗапросХттп.Макет.ФоновыйHTTPЗапрос. Оттуда генерируется событие onclick о приходе новой порции ответа.
#1, ред. 11 октября 2025 12:04
Делаю это в ИР. Сложная штука, если прорабатывать тщательно, а выигрыш дает не такой большой, как я ожидал. В 2000мс ответе первая часть приходит всегда на второй секунде, т.е. в лучшем случае где то максимум на 50% быстрее появляется первая строка ответа ИИ.
#2, 11 октября 2025 14:03
Сделал в ИР https://www.hostedredmine.com/issues/1007396
#3, ред. 03 ноября 2025 08:58
Вот текст HTML документа, используемого в ИР для фоновых HTTP запросов. Думаю его можно кинуть в ИИ и получить заготовку для реализации в C#
Ссылка скрыта
Отправку делаю так
Обработку события от HTML документа в 1С делаю так
Общая функция обработки частей ответа Напарника для Турбоконфа и ИР
#4, ред. 03 ноября 2025 09:02
Обкатал. Работает стабильно. В среднем дает ускорение отображения ответа Напарника на 30%.
Основные функции в Обработка.ирФоновыйЗапросХттп.Макет.ФоновыйHTTPЗапрос. Оттуда генерируется событие onclick о приходе новой порции ответа.
#5, 07 ноября 2025 18:10
Сделано в 6.6
bolsun изменил статус на Закрыто