Документация

Маршрутизация

Router выбирает чекпойнт для каждого запроса и загружает свой Agent, когда он нужен для предсказания. Маршрутизатор по умолчанию направляет английский текст на английский чекпойнт, а остальные поддерживаемые языки — на многоязычный чекпойнт. Вы можете переопределить этот выбор, передать собственную языковую подсказку или явно выбрать чекпойнт typed-decisions.

Это руководство о выборе модели и жизненном цикле. Типы вопросов, которые принимает предсказание, см. в разделе Решения на основе схемы; обратные вызовы жизненного цикла — в разделе Hooks предсказаний.

Быстрый старт

from laya import Router

router = Router()

questions = {
    "department": {
        "type": "choice",
        "instructions": "Which department should handle this request?",
        "criteria": {
            "billing": "invoices, payments, refunds",
            "technical": "bugs, outages, system errors",
            "other": "everything else",
        },
    }
}

result = router.predict("We were billed twice. Please refund the duplicate charge.", questions)
print(result["answers"]["department"]["choice"])
print(result["routing"]["model"])

Создание Router() по умолчанию не загружает чекпойнты. predict() сначала маршрутизирует запрос, а затем при первом использовании загружает выбранный чекпойнт. Поэтому первое предсказание может занять больше времени, пока скачиваются файлы и инициализируется модель; последующие предсказания переиспользуют загруженный агент.

Как выбирается чекпойнт

Router.route(state, questions, ...) возвращает RouteDecision, не загружая чекпойнт и не запуская инференс. Решение содержит выбранную модель, понятную человеку причину и сведения об определении языка, когда использовалось встроенное определение.

Маршрутизация проверяет входные данные в таком порядке:

  1. model= напрямую выбирает чекпойнт.
  2. task= выбирает чекпойнт для указанной задачи.
  3. Если auto_task_detection=True, точное совпадение с одним из известных наборов ID вопросов typed-decisions выбирает typed-decisions.
  4. Распознанное значение lang= выбирает английский или многоязычный.
  5. Учитывается lang_guess= для отдельного вызова или настроенный lang_guess маршрутизатора.
  6. Встроенный анализ письменности и языка выбирает чекпойнт. Если надёжного языкового сигнала нет, маршрутизатор использует настроенный default (по умолчанию английский).

Побеждает первое подходящее правило. Например, model="multilingual" переопределяет lang="en". Недопустимые имена моделей вызывают ValueError, а не переходят к определению.

decision = router.route(
    "La aplicación se cierra cada vez que abro la configuración.",
    questions,
)
print(decision.model)   # multilingual
print(decision.reason)  # why that checkpoint was selected

RouteDecision совместим с dict, поэтому её поля также доступны по ключам вроде decision["model"] и decision["reason"]. Router.predict() включает то же решение под ключом "routing" результата.

Переопределение языковой маршрутизации

Используйте lang=, когда приложение уже знает язык запроса. Принимаются языковые теги вроде "en", "en-US" и "en_US.UTF-8". Английский маршрутизируется на english; другие распознанные языковые коды — на multilingual.

result = router.predict(state, questions, lang="de")
assert result["routing"]["model"] == "multilingual"

Если у приложения есть собственный определитель языка, передайте его результат как языковой код через lang_guess=. Вызываемый объект получает состояние и может вернуть код или None, чтобы воздержаться:

def detect_request_language(state):
    # Replace this with the application's detector.
    return "en" if "invoice" in str(state).lower() else None

router = Router(lang_guess=detect_request_language)

Воздержавшаяся подсказка не навязывает чекпойнт; маршрутизация переходит к следующему правилу. Это охватывает None, пустую строку и коды, которые не называют никакого языка (C, POSIX, C.UTF-8, und, zxx, mul) — именно то, что возвращает определитель, когда ему нечего сказать, поэтому воздержание не может молча привязать запросы к неверной модели.

Нераспознанная подсказка — это не воздержание. Любое другое значение, включая "xx", False и 0, читается как «не английский» и маршрутизируется на многоязычный чекпойнт. Так что определитель, возвращающий мусорный код вместо None, действительно выбирает чекпойнт; и если это важно, сопоставьте его неизвестный случай с None перед передачей дальше.

Встроенное определение — это лёгкая эвристика по письменности и языку, а не универсальная модель определения языка. Оно анализирует строковые значения в состояниях типа text, dict и list; ключи словаря игнорируются, потому что это часто английские имена полей. Короткий или неоднозначный текст может использовать чекпойнт по умолчанию. Для известных рабочих нагрузок явный язык или подсказка от приложения предсказуемее.

Выбор typed-decisions

Чекпойнт typed-decisions по умолчанию не выбирается автоматически. Выберите его явно:

result = router.predict(state, questions, model="typed-decisions")
# `task="typed_decisions"` is also accepted.

Либо задайте auto_task_detection=True. Тогда маршрутизатор проверяет, точно ли ID вопросов совпадают с одним из его известных рабочих процессов typed-decision. Он не выводит задачу из формулировки вопроса, а добавление посторонних ID вопросов мешает точному совпадению.

router = Router(auto_task_detection=True)

Проверка маршрутизации без загрузки моделей

Используйте route() для проверки одного решения или route_batch() для проверки последовательности. Ни один из методов не загружает чекпойнты, поэтому оба полезны для отладки правил маршрутизации до запуска инференса.

requests = [
    {"state": "Please refund the duplicate charge.", "questions": questions},
    {"state": "Necesito ayuda con mi factura.", "questions": questions},
]

decisions = router.route_batch(requests)
for decision in decisions:
    print(decision.model, decision.reason)

Каждому элементу route_batch() нужны state и questions; необязательные переопределения маршрутизации (model, task, lang и lang_guess) задаются для каждого элемента. Решения сохраняют порядок ввода.

Загрузка и память

По умолчанию маршрутизатор загружает чекпойнт при первой необходимости и держит резидентно не более двух агентов. Автоматической языковой маршрутизации обычно нужны только английский и многоязычный чекпойнты. Если запросы могут также выбирать typed-decisions, небольшое значение max_loaded может вытеснить другого агента и заставить загрузить его снова при следующей необходимости.

# Load only the checkpoints this process serves, before accepting requests.
router = Router()
router.preload(["english", "multilingual"])

print(router.loaded)  # currently resident checkpoint names
router.unload("multilingual")

Router(preload=True) предзагружает все настроенные чекпойнты. Предзагрузка поднимает лимит резидентных моделей, чтобы вместить запрошенный набор. Чтобы управлять рабочей нагрузкой из трёх чекпойнтов без предзагрузки, задайте max_loaded=3. Используйте unload(), чтобы освободить одного агента, или router.unload() — чтобы освободить всех. Маршрутизатор, используемый как менеджер контекста, выгружает своих агентов при выходе из блока:

with Router(preload=True) as router:
    result = router.predict(state, questions)

Также при создании маршрутизатора можно передать device="cpu", device="cuda" или другое поддерживаемое устройство PyTorch. Доступность и память определяют, какие устройства могут запускать данную модель.

Смешанные пакеты

predict_batch() принимает запросы с разными состояниями, моделями, языками и схемами вопросов. Сначала маршрутизатор принимает решение для каждого запроса, группирует работу по чекпойнту и совместимой схеме вопросов, а затем восстанавливает результаты в исходном порядке ввода.

requests = [
    {"state": "Please refund the duplicate charge.", "questions": questions},
    {"state": "Mi cuenta fue cobrada dos veces.", "questions": questions},
    {"state": "A third request", "questions": questions, "model": "typed-decisions"},
]

results = router.predict_batch(requests, batch_size=8)

Каждому запросу нужны state и questions; он также может включать model, task, lang или lang_guess. Запросы, разделяющие чекпойнт и схему вопросов, могут разделять один прямой проход пакета Agent. Разные схемы или чекпойнты обрабатываются в отдельных группах. batch_size ограничивает число состояний, передаваемых вместе агенту; результаты по-прежнему соответствуют порядку запросов.

Выбор точки входа

  • Используйте route() или route_batch(), когда нужно проверять решения без загрузки моделей.
  • Используйте predict() для одного запроса и predict_batch() для нескольких, возможно разнородных запросов.
  • Используйте Agent напрямую, когда приложение уже выбрало и загрузило один чекпойнт и не нуждается в автоматической маршрутизации.

Детали конструктора и методов см. в справочнике по API Router.