Перейти к содержанию

Шаблоны загрузки

Шаблон загрузки — таблица XLSX или CSV, в которую человек вносит записи одного вида базы знаний: номенклатуру, лицензии, договоры, активы или собственный вид компании. Шаблоны не пишутся руками: генератор строит их из схемы вида любого включённого пакета онтологии, и тот же код проверяет заполненную таблицу перед планом загрузки. Статья для администраторов базы знаний и авторов пакетов онтологии. Обоснование — TAI-ADR-0056 (решение 2).

Как получить шаблон

Скилл knowledge.template@1 (побочных эффектов нет) возвращает файл прямо в выходе — contentBase64, имя файла и media type:

Вход Что значит
pack пакет вида: company@1, procurement@2, tenant:<имя>@<версия>
kind вид
profile значение профиля вида, например sro
format xlsx (по умолчанию) или csv
packs другие включённые пакеты — виды концов связей и профили (default@1…)
definitions описания пакетов, которых нет среди встроенных (пакет арендатора)

Выход: templateVersion, filename (<вид>.<формат>), mediaType, contentBase64, columns[] — {field, header, required, type, hint}. Неизвестный пакет или вид — ошибка kind_not_found.

python3 tools/knowledge.py template --pack company@1 --kind offering --out offering.xlsx
python3 tools/knowledge.py template --pack company@1 --kind credential \
    --packs procurement@2 --profile sro --out sro.xlsx

Формат — по расширению --out (.csv или XLSX). Ничего не пишет в платформу.

Из чего строится шаблон

Колонки идут в таком порядке:

Колонки Откуда Поле колонки
ключ плейсхолдеры шаблона naturalKey вида, которые не являются атрибутами и не <source>: offering:<source>:<id> → колонка «Код» key.<часть>
атрибуты JSON Schema атрибутов вида и профилей: заголовок — title, подсказка — description, проверка — type, format, enum, pattern, minimum/maximum, maxLength; обязательность — required attributes.<имя>
связи связи пакетов, у которых вид стоит в fromKinds: заголовок — title связи, значение — ключи связанных записей links.<связь>
  • Заголовок колонки ключа: id и slug — «Код», key — «Ключ», иначе имя плейсхолдера (vehicle:<vin> → «vin»).
  • У вида без шаблона ключа ключ — атрибут inn (так у legal_entity) или колонка «Ключ».
  • Профили. Профиль без when добавляет атрибуты ко всем сущностям вида — так company@1 описывает legal_entity пакета default. Профиль с when выбирается явно значением profile: credential с profile: sro получает колонки членства в СРО из procurement@2, а атрибут условия (memberOf) — постоянное значение.
  • Версия шаблона — <пакет>/<вид>, с профилем — <пакет>/<вид>#<атрибут>=<значение> (например company@1/offering).

Типы колонок

Тип Из схемы Как заполнять
string type: string текст; проверяются pattern, enum, maxLength
number, integer type: number, integer число; пробелы и запятая как десятичный разделитель допустимы
boolean type: boolean да/нет, true/false, 1/0, +/-
date type: string, format: date ГГГГ-ММ-ДД или ДД.ММ.ГГГГ; дата ячейки Excel тоже принимается
list type: array несколько значений через «;» (разделитель меняет уточнение); каждое проверяется items.pattern
object type: object имя=значение; имя=значение или JSON-объект
key колонка ключа уникальный код записи в источнике: по нему повторная загрузка узнаёт запись

Колонка связи — ключ связанной записи: полный (с префиксом ключа вида конца, например unit:1c:NORTH или ИНН организации) или короткий, если в ключе вида конца один плейсхолдер кроме <source>: короткий G-1 в колонке «Группа» дополнится по шаблону group:<source>:<id> с источником этой таблицы. Ключи записей другого источника указывайте полностью. У связи cardinality: many — несколько ключей через «;».

Коды из ячеек Excel не портятся: число 62.01 остаётся строкой 62.01, целое 796 — 796.

Файл шаблона

Лист Что на нём
«Данные» строка заголовков (* у обязательных), строка-пример, выпадающие списки для колонок с enum (если значения короче 250 символов), закреплённая первая строка
«Инструкция» название и описание вида, текст уточнения, правила заполнения, таблица колонок: обязательность, тип, подсказка; версия шаблона
_meta (скрыт) версия шаблона и поля колонок — по ним загрузчик сопоставляет таблицу даже с переименованными заголовками

UTF-8 с BOM, разделитель «;»: строка заголовков (* у обязательных) и строка-пример.

Строку-пример удалите

Пример на листе «Данные» — подсказка, а не запись. Удалите его перед загрузкой, иначе он станет записью базы знаний.

Уточнение шаблона пакетом

Пакет может уточнить подачу шаблона данными — файл templates/<вид>.yaml в интеграции пакета, форма — packages/schema/v1/knowledge-template.schema.json. Уточнение меняет заголовки, порядок, подсказки и примеры; колонок сверх схемы вида оно не добавляет.

Поле Что задаёт
pack, kind к какому виду относится (company@1, offering)
title название шаблона
instructions текст листа «Инструкция» перед описанием колонок (до 4000 символов)
columns[] порядок колонок: field (key, title, attributes.<имя>, links.<связь>), header, hint, example, separator; не перечисленные идут после в порядке схемы
examples[] до пяти строк-примеров: поле → значение
forbiddenColumns[] запрещённые заголовки сверх общего списка персональных данных

Уточнение номенклатуры, которое поставляется с company@1:

pack: company@1
kind: offering
title: Номенклатура
instructions: >-
  Одна строка — одна позиция: товар, работа или услуга. Код — из вашей учётной системы:
  по нему повторная загрузка узнаёт позицию. Коды ОКПД2 — через «;».
columns:
  - {field: key, header: Код, hint: "Код позиции в учётной системе"}
  - {field: attributes.name, header: Наименование}
  - {field: attributes.type, header: Тип}
  - {field: attributes.okpd2, header: ОКПД2, example: "62.01.11.000"}
  - {field: attributes.unit, header: Единица (ОКЕИ), example: "796"}
  - {field: attributes.unitName, header: Единица, example: "шт"}
  - {field: attributes.description, header: Описание}
  - {field: links.item_of, header: Группа}
examples:
  - {key: "SKU-001", name: "Разработка программного обеспечения", type: service, okpd2: "62.01.11.000"}

Проверка таблицы

Заполненную таблицу проверяет тот же код, что строит план загрузки (knowledge.import_plan@1), и локальная команда:

python3 tools/knowledge.py check --file offering.xlsx --pack company@1 --kind offering
{
  "status": "invalid",
  "pack": "company@1",
  "kind": "offering",
  "templateVersion": "company@1/offering",
  "rows": 120,
  "entities": 118,
  "relations": 118,
  "errors": [
    {"row": 14, "code": "enum", "message": "«товар» — допустимо: product, work, service", "column": "Тип"},
    {"row": 37, "code": "duplicate_key", "message": "ключ offering:template:offering:SKU-7 уже был в строке 12"}
  ],
  "errorsTotal": 2,
  "columns": ["Код", "Наименование", "Тип", "ОКПД2", "…"]
}

status: ok — можно загружать, invalid — есть ошибки, empty — записей нет. Код выхода команды — 0 только при ok. Показывается до 50 ошибок, всего — в errorsTotal.

Чтение файла. XLSX — лист «Данные» или первый; CSV — UTF-8 (с BOM или без) или cp1251, разделитель «;», «,» или табуляция (тот, которого больше в строке заголовков). Пустые строки пропускаются. Колонки сопоставляются по листу _meta, иначе по заголовку (без * и без учёта регистра) или по имени поля.

Ошибки — с номером строки листа и заголовком колонки:

code Когда
required нет обязательной колонки (строка 1), пусто в обязательной колонке, не из чего собрать ключ
type значение не того типа: не число, не «да/нет», не объект
format не подходит pattern, не дата
enum значение не из списка
unknown_column колонки нет в шаблоне
duplicate_key ключ уже был в другой строке
personal_data запрещённая колонка или значение, похожее на персональные данные
kind_not_found пакета или вида нет
file_unreadable файл не читается как XLSX или CSV

Строка с ошибкой в снимок не идёт, а план по таблице с ошибками не строится (см. Загрузка таблицы).

Персональные данные

Колонки с персональными данными физических лиц запрещены в любом шаблоне. Заголовок, содержащий одно из слов списка, — ошибка personal_data в строке 1, и таблица дальше не проверяется:

фио, фамилия, имя сотрудника, отчество, паспорт, снилс, дата рождения, адрес проживания, домашний адрес, телефон, мобильный, e-mail, email, электронная почта — плюс forbiddenColumns уточнения.

Каждое строковое значение проверяет страж skill-sdk: значение, похожее на ФИО, СНИЛС, паспорт, телефон или e-mail, — ошибка строки «похоже на персональные данные». Роли людей в базе знаний — вид role с атрибутом platformRole, а не ФИО.

Исключение — атрибут, который пакет онтологии явно пометил x-personal-data: allowed: значения такой колонки страж не проверяет, но ИИ их не заполняет и в промпт не получает.

Пример: свой вид арендатора

Перевозчику нужно вести транспорт со страховкой — такого вида в company@1 нет. Описание пакета арендатора:

name: acme-logistics
version: 1
scope: tenant
extends: ["company@1"]
description: Транспорт перевозчика
kinds:
  - kind: vehicle
    title: Транспортное средство
    naturalKey: "vehicle:<vin>"
    searchable: {fields: [model]}
    attributes:
      type: object
      required: [plate]
      properties:
        plate: {type: string, title: Госномер}
        model: {type: string, title: Модель}
        capacityKg: {type: number, title: "Грузоподъёмность, кг"}
        insurer: {type: string, title: Страховщик}
        validFrom: {type: string, format: date, title: Страховка с}
        validUntil: {type: string, format: date, title: Страховка до}
relations:
  - {relation: assigned_to, title: Подразделение, fromKinds: [vehicle], toKinds: [org_unit]}
expiry:
  - {kind: vehicle, role: fleet-manager, leadDays: 14}
  1. Проверка описания — схема, конфликты имён с включёнными пакетами, шаблон по каждому виду:

    python3 tools/knowledge.py pack-check --file vehicles.pack.yaml
    
  2. Шаблон — пакет арендатора не встроен, поэтому его описание передаётся --definition:

    python3 tools/knowledge.py template --pack tenant:acme-logistics@1 --kind vehicle \
        --packs company@1 --definition vehicles.pack.yaml --out vehicles.csv
    

    Колонки: vin * (ключ из плейсхолдера), «Госномер *», «Модель», «Грузоподъёмность, кг», «Страховщик», «Страховка с», «Страховка до», «Подразделение» (связь assigned_to).

  3. Заполненная таблица:

    vin *;Госномер *;Модель;Грузоподъёмность, кг;Страховщик;Страховка с;Страховка до;Подразделение
    XTA000001;А123ВС77;Газель;1500;Страховщик А;2026-01-01;2026-12-31;unit:1c:NORTH
    XTA000002;В456ОР77;Валдай;3500;Страховщик Б;04.10.2025;03.10.2026;unit:1c:NORTH
    

    Даты в двух форматах принимаются обе; ключ записи — vehicle:XTA000001.

  4. Регистрация, включение и загрузка — после согласия человека: pack-register, pack-enable со всем набором пакетов дерева, затем import-start с --definition vehicles.pack.yaml (см. База знаний компании).

  5. Сроки. У вида есть validUntil, а в expiry — роль fleet-manager и 14 дней: чтобы правило knowledge-expiry напоминало о страховке, пакет добавляется в его вход packs, описание — в definitions (см. Истечение сроков).

См. также