Конвейер пакетной обработки
Описание
Конвейер пакетной обработки — это JSON-конфигурация, которая определяет, как будут обрабатываться документы в пакете. Конвейер описывает последовательность шагов: классификацию страниц, распознавание полей, NLP-извлечение данных, постобработку и валидацию результатов.
Конвейер представляет собой дерево шагов. Корневой шаг — классификация — определяет тип каждой страницы, а дочерние шаги обрабатывают страницы в зависимости от результата классификации.
Классификация (SmartOCR или NLP)
├── Класс «Счёт-фактура» → Распознавание (SmartOCR) → Извлечение NLP → ...
├── Класс «Паспорт» → Распознавание (SmartOCR)
└── Класс «Договор» → Извлечение NLPСтруктура конвейера
{
"documentDefinitions": [ ... ],
"notClassifiedDefinition": { ... },
"steps": [ ... ]
}| Поле | Описание |
|---|---|
steps | Корневые шаги конвейера (обычно один шаг классификации). Не может быть пустым |
documentDefinitions | Правила группировки страниц в документы |
notClassifiedDefinition | Настройки для нераспознанных страниц |
Шаги конвейера
Каждый шаг (PackagePipelineStep) содержит:
| Поле | Описание | Обязательное |
|---|---|---|
id | Уникальный идентификатор шага (3–50 символов). Не может повторяться во всём дереве | Да |
routingKey | Ключ маршрутизации — указывает, какой агент обработает шаг | Да |
meta | Тип шага: компонент и его подтип | Да |
classCondition | Точное имя класса — шаг выполнится только для страниц этого класса | Нет |
classConditionRegex | Регулярное выражение для фильтрации по классу | Нет |
classify | Параметры классификации (для шагов классификации) | Для классификации |
recognition | Параметры распознавания (для шагов распознавания) | Для распознавания |
nlp | Параметры NLP (для шагов NLP) | Для NLP |
nextSteps | Дочерние шаги, выполняемые после текущего | Нет |
Мета-информация (meta)
{
"meta": {
"component": "SmartOCR",
"smartOcrType": "Classification"
}
}| Поле | Значения |
|---|---|
component | "SmartOCR" или "NLP" |
smartOcrType | "Classification" или "Recognition" (только для SmartOCR) |
nlpType | "Extraction" или "Classification" (только для NLP) |
Для SmartOCR-шагов указывайте smartOcrType и не указывайте nlpType.
Для NLP-шагов — наоборот.
Классификация
Классификация — первый шаг конвейера. Определяет тип каждой страницы документа.
Классификация через Умный OCR
{
"id": "classify",
"routingKey": "ocr-clas-a1b2",
"meta": { "component": "SmartOCR", "smartOcrType": "Classification" },
"classify": {
"fallback": "Unknown",
"postProcessing": [],
"classesConfidenceThreshold": {
"Invoice": 0.8,
"Passport": 0.7
}
},
"nextSteps": [ ... ]
}| Поле | Описание |
|---|---|
classify.fallback | Класс, присваиваемый странице, если модель не смогла определить тип |
classify.classesConfidenceThreshold | Минимальная уверенность для каждого класса (0–1). Если уверенность ниже порога, страница получает класс fallback |
classify.postProcessing | Правила постобработки результатов классификации |
Классификация через NLP
Языковая модель используется для классификации вместо Умного OCR. В nlp.schema перечисляются допустимые классы.
{
"id": "classify-nlp",
"routingKey": "nlp-clas-a3k2",
"meta": { "component": "NLP", "nlpType": "Classification" },
"classify": { "fallback": "Unknown" },
"nlp": {
"addImage": true,
"schema": ["Паспорт", "Договор", "Другое"],
"promptBuilder": {
"addUnifiedText": false,
"addAnswer": false,
"addRawAnswer": false
},
"temperature": 0.0,
"minP": 0.1,
"responseLength": 1024
},
"nextSteps": [ ... ]
}NLP-агенты классификации разворачиваются с предварительно настроенными
промптами. В конвейере достаточно указать schema — список допустимых
классов. Не указывайте prependPrompt для классификации — это вызовет
конфликт со встроенным промптом агента.
Маршрутизация по классу (classCondition) #class-routing
Дочерние шаги обрабатывают только определённые классы документов. Маршрутизация настраивается через поля:
| Поле | Описание | Пример |
|---|---|---|
classCondition | Точное совпадение имени класса (с учётом регистра) | "Invoice" |
classConditionRegex | Регулярное выражение (синтаксис C# Regex) | "^Invoice.*" |
Если оба поля указаны, применяется логика И — оба условия должны совпасть. Если ни одно не указано, шаг выполняется для всех документов.
Пример — распознавание запускается только для страниц, классифицированных как Invoice:
{
"id": "recognize-invoice",
"routingKey": "ocr-rec-struct-c3d4",
"meta": { "component": "SmartOCR", "smartOcrType": "Recognition" },
"classCondition": "Invoice",
"recognition": {},
"nextSteps": []
}Распознавание (SmartOCR Recognition)
Извлекает поля из страницы с помощью структурированного OCR.
{
"id": "recognize-invoice",
"routingKey": "ocr-rec-struct-c3d4",
"meta": { "component": "SmartOCR", "smartOcrType": "Recognition" },
"classCondition": "Invoice",
"recognition": {
"postProcessing": [],
"validations": [],
"cellPostProcessing": [],
"cellValidations": [],
"overrideClassIfEmpty": null,
"overrideFields": [],
"fieldsConfidenceThreshold": {
"INN": 0.5,
"TotalAmount": 0.4
}
},
"nextSteps": []
}| Поле | Описание |
|---|---|
fieldsConfidenceThreshold | Минимальная уверенность для каждого поля (0–1) |
overrideClassIfEmpty | Присвоить указанный класс, если страница не была классифицирована |
overrideFields | Список полей, которые при повторном распознавании заменяют существующие значения |
Извлечение через NLP #nlp-extraction
Извлекает поля из документа с помощью языковой модели. В schema указываются имена извлекаемых полей.
{
"id": "extract-contract",
"routingKey": "nlp-extr-4bo9",
"meta": { "component": "NLP", "nlpType": "Extraction" },
"classCondition": "Contract",
"recognition": {},
"nlp": {
"addImage": true,
"schema": ["Номер договора", "Дата", "Контрагент", "Сумма"],
"promptBuilder": {
"addUnifiedText": false,
"addAnswer": false,
"addRawAnswer": false
},
"temperature": 0.0,
"minP": 0.1,
"responseLength": 1024
},
"nextSteps": []
}Параметры NLP
| Поле | Описание | По умолчанию |
|---|---|---|
addImage | Передать изображение страницы модели | — |
schema | Имена полей для извлечения | — |
temperature | Случайность ответа (0–2). Для извлечения рекомендуется 0.0 | 0.0 |
minP | Минимальная вероятность токена (0–1) | 0.1 |
responseLength | Максимальное количество токенов в ответе | 1024 |
Управление промптом (promptBuilder)
promptBuilder управляет данными, которые передаются в промпт языковой модели:
| Поле | Описание |
|---|---|
addUnifiedText | Включить текст, распознанный на предыдущих шагах (OCR) |
addAnswer | Включить ответы предыдущих NLP-шагов |
addRawAnswer | Включить сырые ответы предыдущих NLP-шагов |
prependPrompt | Текст, добавляемый перед данными |
appendPrompt | Текст, добавляемый после данных |
fieldsByConditions | Включить конкретные OCR-поля, отобранные по условиям |
NLP-агенты разворачиваются с предварительно настроенными промптами. По
умолчанию достаточно указать schema и источник данных (addImage или
addUnifiedText). Используйте prependPrompt / appendPrompt только когда
нужно дополнить стандартное поведение.
Для NLP-шага обязательно должен быть указан хотя бы один источник данных:
addImage, prependPrompt, addAnswer, addRawAnswer, addUnifiedText,
fieldsByConditions или appendPrompt.
Цепочка OCR → NLP
OCR распознаёт структурированные поля, затем NLP уточняет или извлекает дополнительные данные на основе OCR-результатов:
{
"id": "recognize-invoice",
"routingKey": "ocr-rec-struct-u3v4",
"meta": { "component": "SmartOCR", "smartOcrType": "Recognition" },
"classCondition": "Invoice",
"recognition": {},
"nextSteps": [
{
"id": "refine-invoice-nlp",
"routingKey": "nlp-extr-w5x6",
"meta": { "component": "NLP", "nlpType": "Extraction" },
"recognition": {
"overrideFields": ["PaymentTerms", "Notes"]
},
"nlp": {
"addImage": false,
"promptBuilder": {
"addUnifiedText": true,
"addAnswer": false,
"addRawAnswer": false
},
"schema": ["PaymentTerms", "Notes", "DeliveryAddress"],
"temperature": 0.0,
"minP": 0.1,
"responseLength": 1024
}
}
]
}В данном примере:
- NLP-шаг не имеет
classCondition— он выполняется для всех документов, дошедших до него через родительский шаг addUnifiedText: trueпередаёт OCR-текст в промпт моделиrecognition.overrideFieldsуказывает, какие существующие поля NLP-шаг имеет право перезаписать
Постобработка (postProcessing) #post-processing
Постобработка модифицирует значения полей после извлечения. Доступна в classify.postProcessing и recognition.postProcessing.
{
"recognition": {
"postProcessing": [
{
"conditions": { "fieldKey": "INN" },
"modifyRules": {
"text": {
"regexPattern": "[^0-9]",
"replacement": ""
}
}
},
{
"conditions": {
"fieldKeyRegex": "Date.*",
"minConfidence": 0.3
},
"modifyRules": {
"text": {
"regexPattern": "(\\d{2})\\.(\\d{2})\\.(\\d{4})",
"replacement": "$3-$2-$1"
}
}
}
]
}
}Условия отбора полей (conditions)
Все условия опциональны. Если указано несколько — применяется логика И.
| Поле | Описание |
|---|---|
fieldKey | Точное совпадение имени поля |
fieldKeyRegex | Регулярное выражение для имени поля |
text | Точное совпадение текста |
textRegex | Регулярное выражение для текста |
minConfidence | Минимальная уверенность (0–1) |
maxConfidence | Максимальная уверенность (0–1) |
jsonPathCondition | Условие по JSONPath: { "jsonPath": "$.field", "valueRegex": "\\d+" } |
Правила модификации (modifyRules)
Ключ правила — "field" (имя поля) или "text" (текст поля). Значение — объект с regexPattern и replacement.
Примеры:
- Удалить все нецифровые символы из ИНН:
"regexPattern": "[^0-9]","replacement": "" - Переформатировать дату из ДД.ММ.ГГГГ в ГГГГ-ММ-ДД:
"regexPattern": "(\\d{2})\\.(\\d{2})\\.(\\d{4})","replacement": "$3-$2-$1"
Валидация (validations) #validations
Валидация проверяет извлечённые поля и устанавливает флаг isValid. Доступна в recognition.validations.
{
"recognition": {
"validations": [
{
"conditions": { "fieldKey": "INN" },
"validations": [{ "textRegex": "^\\d{10}$|^\\d{12}$" }]
},
{
"conditions": { "fieldKey": "TotalAmount" },
"validations": [
{ "textRegex": "^[\\d\\s,.]+$" },
{ "minConfidence": 0.4 }
]
}
]
}
}conditions— отбирает поля для валидации (те же условия, что и в постобработке)validations[]— массив правил. Все правила должны пройти, чтобы поле получилоisValid = true- Доступные правила:
textRegex,text,minConfidence,maxConfidence,fieldKey,fieldKeyRegex,jsonPathCondition
Результат: поле получает isValid = true, если все правила выполнены, false — если хотя бы одно не выполнено. Поля, не попавшие под conditions, сохраняют isValid = null.
Постобработка выполняется до валидации. Валидация проверяет уже модифицированные значения.
Постобработка ячеек таблиц (cellPostProcessing) #cell-post-processing
Модифицирует текст ячеек в табличных полях. Использует двухуровневую фильтрацию: сначала отбирает поля (conditions), затем ячейки внутри них (cellConditions).
{
"recognition": {
"cellPostProcessing": [
{
"conditions": { "fieldKey": "invoice_table" },
"cellConditions": {
"columnHeader": "Сумма",
"textRegex": "^\\s*\\d"
},
"modifyRule": { "regexPattern": "\\s", "replacement": "" }
}
]
}
}Условия отбора ячеек (cellConditions)
| Поле | Описание |
|---|---|
rowIndex | Индекс строки |
columnIndex | Индекс столбца |
columnHeader | Точное совпадение текста ячейки в строке 0 того же столбца |
columnHeaderRegex | Регулярное выражение для заголовка столбца |
textRegex | Регулярное выражение для текста ячейки |
minConfidence / maxConfidence | Диапазон уверенности ячейки (0–1) |
Валидация ячеек таблиц (cellValidations) #cell-validations
Аналогична cellPostProcessing, но вместо модификации устанавливает cell.isValid.
{
"recognition": {
"cellValidations": [
{
"conditions": { "fieldKey": "invoice_table" },
"cellConditions": { "columnHeaderRegex": "(Сумма|Итого)" },
"rules": [{ "textRegex": "^\\d+[.,]\\d{2}$", "minConfidence": 0.7 }]
}
]
}
}Постобработка ячеек выполняется до валидации ячеек, поэтому валидация проверяет уже модифицированный текст.
Определения документов (documentDefinitions) #document-definitions
Определяют, как классифицированные страницы группируются в логические документы.
{
"documentDefinitions": [
{
"title": "Invoice",
"titleClasses": ["Invoice", "Invoice-alt"],
"isPdfGenerated": true
},
{
"title": "Passport",
"titleClasses": ["Passport"],
"isPdfGenerated": false
}
]
}| Поле | Описание |
|---|---|
title | Название документа (обязательное) |
titleClasses | Классы, обозначающие титульную страницу документа (обязательное, не пустое) |
isPdfGenerated | Генерировать PDF из страниц документа после обработки. По умолчанию: false |
Когда система встречает страницу с классом из titleClasses, она начинает новый документ. Последующие страницы (до следующей титульной) включаются в тот же документ.
Неклассифицированные страницы
{
"notClassifiedDefinition": {
"isPdfGenerated": true
}
}Страницы, не попавшие ни в один класс, группируются в отдельный объект NotClassified.
Интерпретация результатов #results
После обработки пакет содержит структуру processing со следующими данными:
Документ (PackageDocumentDto)
| Поле | Описание |
|---|---|
id | Идентификатор документа |
title | Название документа (из documentDefinitions) |
classConfidence | Уверенность классификации |
pages | Массив страниц документа |
items | Распознанные данные документа (объединение постраничных данных) |
isPdfCreated | PDF готов к скачиванию |
warnings | Предупреждения при обработке |
stepIds | Идентификаторы шагов, обработавших документ |
Поле документа (PackageDocumentDtoItem)
| Поле | Описание |
|---|---|
field | Имя поля |
confidence | Уверенность распознавания (0–1) |
coordinates | Координаты области на изображении (minX, minY, maxX, maxY) |
text | Распознанный текст (для скалярных полей) |
cells | Ячейки таблицы (для табличных полей) |
rawTable | Автоматически генерируемое представление: rawTable[столбец][строка] = текст |
isValid | Результат валидации: null — не валидировалось, true — пройдена, false — не пройдена |
Поле является либо скалярным (text заполнен, cells отсутствует), либо табличным (cells заполнен, text отсутствует, rawTable генерируется автоматически).
Ячейка таблицы (PackageDocumentDtoItemCell)
| Поле | Описание |
|---|---|
row | Индекс строки |
column | Индекс столбца |
text | Текст ячейки |
confidence | Уверенность распознавания |
isValid | Результат валидации ячейки |
Страница документа
Каждая страница (PackageDocumentPageDto) содержит:
| Поле | Описание |
|---|---|
class | Класс, присвоенный при классификации |
classConfidence | Уверенность классификации |
indexInPackage | Порядковый номер страницы в пакете |
file | Информация о файле страницы (для скачивания изображения) |
rawResult | Сырые результаты: items (поля), unifiedText (объединённый текст), nlp (ответ NLP) |
Ошибки обработки
Массив errors содержит информацию об ошибках:
| Поле | Описание |
|---|---|
stepId | Идентификатор шага, на котором произошла ошибка |
fileIds | Идентификаторы файлов, затронутых ошибкой |
errorMsg | Описание ошибки |
Ключи маршрутизации
Ключ маршрутизации (routingKey) связывает шаг конвейера с конкретным агентом. Формат: {тип}-{случайный_суффикс}.
| Тип шага | Префикс | Пример |
|---|---|---|
| OCR-классификация | ocr-clas- | ocr-clas-275i |
| OCR-распознавание | ocr-rec-struct- | ocr-rec-struct-71ui |
| NLP-извлечение | nlp-extr- | nlp-extr-4bo9 |
| NLP-классификация | nlp-clas- | nlp-clas-a3k2 |
Ключ маршрутизации создаётся и копируется в Портале при настройке навыка или проекта.
Полный пример конвейера
Конвейер классифицирует документы через SmartOCR, распознаёт счета-фактуры (с постобработкой и валидацией) и извлекает данные из договоров через NLP:
{
"documentDefinitions": [
{ "title": "Invoice", "titleClasses": ["Invoice"], "isPdfGenerated": true },
{
"title": "Contract",
"titleClasses": ["Contract"],
"isPdfGenerated": true
}
],
"notClassifiedDefinition": { "isPdfGenerated": false },
"steps": [
{
"id": "classify",
"routingKey": "ocr-clas-a1b2",
"meta": { "component": "SmartOCR", "smartOcrType": "Classification" },
"classify": {
"fallback": "Unknown",
"classesConfidenceThreshold": { "Invoice": 0.8, "Contract": 0.7 }
},
"nextSteps": [
{
"id": "recognize-invoice",
"routingKey": "ocr-rec-struct-c3d4",
"meta": { "component": "SmartOCR", "smartOcrType": "Recognition" },
"classCondition": "Invoice",
"recognition": {
"postProcessing": [
{
"conditions": { "fieldKey": "INN" },
"modifyRules": {
"text": { "regexPattern": "[^0-9]", "replacement": "" }
}
}
],
"validations": [
{
"conditions": { "fieldKey": "INN" },
"validations": [{ "textRegex": "^\\d{10}$|^\\d{12}$" }]
},
{
"conditions": { "fieldKey": "TotalAmount" },
"validations": [
{ "textRegex": "^[\\d\\s,.]+$" },
{ "minConfidence": 0.4 }
]
}
],
"fieldsConfidenceThreshold": { "INN": 0.5 }
}
},
{
"id": "extract-contract",
"routingKey": "nlp-extr-e5f6",
"meta": { "component": "NLP", "nlpType": "Extraction" },
"classCondition": "Contract",
"recognition": {},
"nlp": {
"addImage": true,
"schema": ["Номер договора", "Дата", "Контрагент", "Сумма"],
"promptBuilder": {
"addUnifiedText": false,
"addAnswer": false,
"addRawAnswer": false
},
"temperature": 0.0,
"minP": 0.1,
"responseLength": 1024
}
}
]
}
]
}