Надеждно маршрутизиране на LLM API: изчакване, повторни опити и резервни модели без семантични регресии
Практическа архитектура за класифициране на неуспехите на LLM API, налагане на един бюджет за забавяне, избор на съвместими резервни модели, защита на страничните ефекти и валидиране на всеки приет отговор.
Резервната заявка не е успешна само защото друг модел е върнал HTTP 200. Замяната може да надхвърли първоначалния бюджет за забавяне, да пропусне задължителните JSON полета, да извика различен инструмент или да произведе отговор с съществено различна семантика. Надеждното LLM API маршрутизиране следователно изисква повече от подреден списък от модели: то изисква договор, класификатор на неуспехите, политика за ограничен опит и валидиране преди приемане.
Централното правило е просто: опитайте отново само когато неуспехът вероятно е временен и се върнете само когато следващият маршрут все още може да удовлетвори първоначалния договор за заявка.
Дефинирайте договора за маршрутизиране, преди да изберете модели
Започнете, като опишете какво трябва да предостави успешният отговор. Този договор за маршрутизиране трябва да бъде машинно четим и прикрепен към всеки клас на натоварване или заявка.
{
"workload": "invoice_extraction",
"modalities": ["text", "image"],
"max_input_tokens": 50000,
"requires_tools": false,
"structured_output": {
"required": true,
"schema_id": "invoice-v3",
"strict": true
},
"allowed_model_classes": ["document-extraction"],
"max_cost_usd": 0.08,
"deadline_ms": 8000
}
Договорът трябва да покрива необходимите модалности, капацитет на контекста, поддръжка на инструменти, поведение на структуриран изход, приемливи класове на модели, максимална цена и краен срок от край до край. Добавете специфични за приложението ограничения, където е необходимо, като например разрешени региони, минимална изходна дължина или необходима причина за завършване.
Препоръка: поддържайте отделни, тествани групи маршрути за обикновен текст, ограничен от схема изход, използване на инструменти, визия и заявки с дълъг контекст. Модел, който е приемлив резервен текст, не е автоматично приемлив резервен вариант за извикване на инструмент или въвеждане на изображение.
Класифицирайте грешката, преди да предприемете действие
Грешки при удостоверяване, неправилно формирани заявки, ограничения на скоростта и грешки на сървъра изискват различни отговори. Третирането на всеки неуспешен отговор като възможност за повторен опит губи капацитет и може да скрие дефекти.
| Клас на грешка | Примери | Действие по подразбиране |
|---|---|---|
| Постоянна неуспешна заявка | Невалидни идентификационни данни, неправилно формирани параметри, неподдържана функция | Спиране и връщане на ясна грешка |
| Несъвместимост на маршрута | Твърде голям контекст, неподдържано въвеждане на изображение, недостъпен режим на схема | Опитайте само съвместим маршрут |
| Преходна грешка при транспортиране | Нулиране на връзката, грешка на DNS, избрано изчакване | Повторен опит в рамките на оставащия бюджет |
| Неуспешен капацитет или скорост | HTTP 429, претоварена услуга, избрани 5xx отговора | Спазвайте съветите за повторен опит или използвайте здравословен резервен вариант |
| Невалиден успешен отговор | Неправилно образуван JSON, неизвестен инструмент, липсва задължително поле | Отхвърлете, след това опитайте отново или се върнете, ако правилата позволяват |
| Двусмислено изпълнение | Връзката е загубена, след като доставчикът може да е приел заявката | Дедупликация преди повторно възпроизвеждане |
Факт: неуспешните заявки с ограничена скорост все още могат да се зачитат спрямо ограниченията на доставчика. Следователно агресивните незабавни повторни опити могат да задълбочат дроселирането, вместо да го разрешат. Повторните опити също консумират допълнителен капацитет по време на прекъсване, а правилата за повторни опити на няколко приложни слоя могат да умножат произтичащото натоварване.
Препоръка: позволете на един слой да притежава повторни опити за генериране на модел. В типична архитектура шлюзът AI API е правилният собственик, защото вижда здравето на маршрута, историята на опитите, закъснението и разходите. Деактивирайте автоматичните повторни опити в клиенти от по-ниско ниво, където е възможно, или ги отчитайте изрично в същия бюджет за опити.
Изразходвайте един бюджет за латентност от край до край
Времената за изчакване на опит са недостатъчни. Три опита с изчакване от пет секунди могат да превърнат планирана операция от пет секунди в отговор от петнадесет секунди, преди да бъдат включени отлагането и валидирането.
Запишете абсолютен краен срок, когато заявката влезе в шлюза. Преди всеки опит изчислете оставащото време:
remaining = deadline - current_time
required = connect_allowance + generation_allowance + validation_allowance
if remaining < required:
stop_without_launching_another_attempt
За краен срок от осем секунди разумно първоначално разпределение може да резервира 300 ms за работа на шлюза и окончателно валидиране, да позволи до 4,5 секунди за основния маршрут и да запази приблизително 3,2 секунди за един резервен маршрут. Тези стойности са примерни, а не бенчмарк. Те трябва да бъдат получени от измерени разпределения на латентността за действителните доставчици, модели, региони и изходни размери.
Използване на ограничено експоненциално забавяне с трептене за преходни повторни опити:
delay = random(0, min(cap, base * 2^retry_index))
Подсказките на доставчика за повторен опит, като например стойност за повторен опит, трябва да имат предимство, когато се поберат в оставащия краен срок. Спрете след малък брой опити. Общата политика е един основен опит плюс един резервен, с незадължителен повторен опит по същия маршрут само за ранна грешка на връзката, която не може да генерира таксуван изход.
Компромис: последователният резервен вариант подобрява достъпността, но увеличава латентността на опашката. Паралелните или хеджираните заявки могат да намалят закъснението по време на забавяния, но те консумират повече капацитет и могат да наложат такси за множество успешни поколения. Хеджирането трябва да бъде ограничено до критични по отношение на забавянето работни натоварвания без странични ефекти с анулиране и контрол на разходите.
Избирайте резервни варианти по способности, а не по ранг
Резервната таблица трябва да кодира съвместимост, а не глобален ред на предпочитанията. Филтрирайте маршрутите на кандидатите спрямо договора, преди да вземете предвид здравето, закъснението или цената.
candidates = routes
.filter(supports_required_modalities)
.filter(context_limit >= estimated_input_size)
.filter(supports_required_tools)
.filter(supports_requested_schema_mode)
.filter(model_class in allowed_model_classes)
.filter(estimated_cost <= remaining_cost_budget)
.filter(not_temporarily_suppressed)
selected = rank(candidates, health, latency, cost)
Поддръжката на структуриран изход заслужава изрично тестване. Дори когато два маршрута рекламират ограничено от схема генериране, те може да поддържат различни JSON подмножества на схема или да интерпретират крайните случаи по различен начин. Моделите с възможности за инструменти също могат да се различават по избор на инструменти, конструкция на аргументи и поведение при паралелно извикване.
Факт: превключването на фамилии модели може да запази транспортната наличност, като същевременно променя стила, качеството на разсъждението, поведението на безопасността, токенизирането и избора на инструменти. HTTP успехът не е доказателство за семантична еквивалентност.
Прогноза: тъй като каталозите с модели се разширяват, политиките за производствено маршрутизиране все повече ще използват профили на възможности с версии и тестове за приемане, специфични за работното натоварване, вместо списъци със статични модели. Отнасяйте се към това като към посока на проектиране, а не като гаранция за поведението на доставчика.
Потвърдете отговора, преди да го приемете
Пуснете всеки отговор, включително основния отговор, през един и същ канал за приемане. Валидирането трябва да се извърши преди резултатът да бъде кеширан, таксуван вътрешно като успешен или предаден на изпълнител на инструмент.
- Потвърдете, че транспортирането е завършено и пликът с отговор може да бъде анализиран.
- Проверете причината за завършване и отхвърлете отрязването, когато се изисква пълен изход.
- Потвърдете структурирания изход спрямо оригиналната схема.
- Проверете задължителните полета, enum стойностите и инвариантите на приложението.
- Разрешаване само на регистрирани имена на инструменти и валидиране на аргументи срещу всяка схема на инструмента.
- Прилагайте семантични проверки, специфични за работното натоварване, където фалшивото приемане би било скъпо.
За извличане на фактури семантичните проверки може да изискват неотрицателна обща сума, поддържан код на валута и общи суми за редови позиции в рамките на изрично определен толеранс. За класификация изисквайте етикет от разрешения набор. За генериране на код може да е подходящ анализ или компилация. Тези проверки не доказват качеството, но предотвратяват третирането на предвидими нарушения на договора като успех.
Не поправяйте тихо всеки неправилно образуван отговор. Детерминистичната нормализация, като премахване на безобидни заобикалящи празни пространства, може да бъде приемлива. Отгатването на липсващи финансови полета или пренаписването на аргументи на инструмента променя значението на модела и трябва да предизвика отхвърляне или преглед от човек.
Отделни повторни опити за генериране от странични ефекти
Заявките за LLM обикновено използват HTTP POST, който по своята същност не е идемпотентен. По-важното е, че отговорът на модела може да инициира външно действие, като таксуване на метод на плащане, изпращане на съобщение, създаване на билет или модифициране на инфраструктура. Повторният опит за генериране и повторното възпроизвеждане на това действие са отделни решения.
Присвояване на идентификатор на операция на границата на приложението и идентификатор на опит за всяко извикване на модел. Запазване на състоянието на изпълнение на инструмента спрямо детерминистичен ключ, като например:
execution_key = operation_id + tool_name + canonical_arguments_hash
Преди да изпълните инструмент, проверете дали този ключ чака, завършен е или е неуспешен. Върнете запаметения резултат за завършено изпълнение, вместо да го стартирате отново. За операции, чиито аргументи могат законно да се променят, изисквайте одобрение на ниво приложение или нов идентификатор на операция.
Двусмислен таймаут изисква специална обработка. Ако връзката е неуспешна след предаване на заявка, шлюзът може да не знае дали е настъпило генериране. Поддържан от доставчика ключ за идемпотентност може да помогне, когато е наличен. В противен случай запишете резултата като неизвестен и приложете специфична за натоварването политика за повторение, вместо да приемете, че нищо не се е случило.
Потискане на нездравословни маршрути и разкриване на всеки опит
Прекъсвач на веригата или временно потискане на здравето не позволява на всяка нова заявка да преоткрива същия неуспешен маршрут. Отворете веригата след определена честота на грешки или праг на последователни откази, след което допуснете ограничени сонди в полуотворено състояние. Настройте праговете по маршрут и клас на отказ, така че неправилно формирана клиентска заявка да не може да направи здрав модел да изглежда недостъпен.
Записване на едно събитие на ниво заявка и едно събитие на опит. Полезните полета включват ID на операция, ID на опит, избран доставчик и модел, клас на грешка, код на състоянието, латентност, брой токени, прогнозна цена, резервна причина, резултат от валидиране, състояние на верига и краен резултат. Редактирайте или хеширайте подкани, изходи и аргументи на инструмента според изискванията им за чувствителност и запазване.
Полезните оперативни показатели включват резервен процент, опити за завършена заявка, процент на изчерпване на крайния срок, процент на отхвърляне при валидиране, двусмислени резултати, цена на приет отговор и забавяне по краен маршрут. Нарастващият HTTP процент на успеваемост, заедно с нарастващия процент на отхвърлени валидации, е предупреждение, че наличността на транспорт прикрива неуспешните договори.
Контролен списък за внедряване на продукция
- Дефиниране на версионен договор за маршрутизиране за всеки клас на натоварване.
- Съпоставете грешките на доставчика в постоянни, преходни, несъвместими, невалидни отговори и двусмислени категории.
- Изберете един собственик за повторен опит и ограничете общия брой опити.
- Разпространение на абсолютен краен срок чрез шлюз, клиент на доставчика, валидиране и изпълнение на инструмента.
- Изградете резервни групи с тествани възможности вместо една глобална верига от модели.
- Потвърдете схеми, извиквания на инструменти, причини за завършване и инварианти на домейни.
- Дедупликирайте страничните ефекти с клавиши за работа и изпълнение.
- Добавяне на потискане на маршрута с ограничени полуотворени сонди.
- Регистрирайте латентност на ниво опит, токени, цена, неуспехи и резултати от приемане.
- Изчакване за инжектиране, 429s, избрани грешки 5xx, неправилно образуван JSON, препълване на контекста и бавни успехи в етапа.
Започнете с основен маршрут и един съвместим резервен за едно работно натоварване с нисък риск. Сравнете качеството на приетия отговор, закъснението и цената, преди да разширите правилата. Целта не е възможно най-високият резервен процент. Това е ограничена система, която или връща отговор, удовлетворяващ оригиналния договор, или явно се проваля, преди да причини дублирана работа или семантична повреда.