# Спецификация технической реализации JSONL для выходных данных запросов ## Обзор Эта спецификация описывает реализацию формата выходных данных JSONL (JSON Lines) для ответов на запросы в TrustGraph. JSONL позволяет надежно извлекать структурированные данные из ответов LLM, решая критические проблемы, связанные с повреждением выходных JSON-массивов при достижении LLM лимитов токенов. Эта реализация поддерживает следующие сценарии использования: 1. **Надежное извлечение при обрезании**: Извлечение действительных частичных результатов даже при обрезании ответа LLM в середине запроса 2. **Масштабируемое извлечение**: Обработка извлечения множества элементов без риска полного сбоя из-за ограничений токенов 3. **Извлечение нескольких типов**: Поддержка извлечения нескольких типов сущностей (определения, взаимосвязи, сущности, атрибуты) в одном запросе 4. **Вывод, совместимый со стримингом**: Обеспечение возможности последующего стриминга/инкрементной обработки результатов извлечения ## Цели - **Совместимость с предыдущими версиями**: Существующие запросы, использующие `response-type: "text"` и `response-type: "json"`, продолжают работать без изменений - **Надежное извлечение при обрезании**: Частичные ответы LLM дают частичные валидные результаты вместо полного сбоя - **Валидация схемы**: Поддержка валидации JSON Schema для отдельных объектов - **Гибкость**: Поддержка различных сценариев извлечения, включая извлечение нескольких типов сущностей и использование стриминга ## Реализация * **Обработка JSONL**: Метод `parse_jsonl` парсит входные данные JSONL построчно, обрабатывая ошибки при обнаружении невалидного JSON. Он возвращает список словарей, где каждый словарь представляет собой успешно обработанный объект. * **Обработка JSON**: Метод `parse_json` парсит входные данные JSON, используя стандартную библиотеку `json`. Он возвращает объект Python, соответствующий структуре JSON. * **Валидация схемы**: Функция `validate` проверяет, соответствует ли объект заданным требованиям JSON Schema. * **Формат вывода**: Метод `PromptManager.invoke` возвращает список словарей Python, где каждый словарь представляет собой успешно обработанный объект. * **Обработка ошибок**: * Если входные данные JSONL не валидны или результат обрезания, метод возвращает пустой список (`[]`). * Если при валидации схемы произошла ошибка, метод возвращает пустой список (`[]`) и выводит предупреждающие сообщения в лог. * Если произошла ошибка парсинга JSON, метод выводит ошибку и выбрасывает исключение. * **Совместимость**: * Клиентский код, ожидающий список в качестве результата извлечения, не требует изменений при переходе на JSONL. * Формат вывода для `response-type: "json"` (массив) и `response-type: "jsonl"` (список) одинаковый: Python `list` * **API изменения**: * **Клиентская перспектива**: Разбор JSONL выполняется на стороне сервера в сервисе запросов, и результат возвращается через стандартное поле `PromptResponse.object` в виде сериализованного JSON-массива. * **Формат возвращаемого значения**: Для `response-type: "jsonl"`, метод `PromptManager.invoke()` возвращает `list[dict]`, содержащий все успешно обработанные объекты. Этот список сериализуется в JSON для поля `PromptResponse.object`. * **Обработка ошибок**: * Пустой результат: возвращает пустой список `[]` с сообщением в логе * Частичная ошибка парсинга: возвращает список успешно обработанных объектов с сообщениями об ошибках * Полная ошибка парсинга: возвращает пустой список `[]` с сообщениями об ошибках * **Пример конфигурации**: ```json { "prompt": "Извлеките все сущности и их определения из следующего текста. Выведите один JSON объект на строку.\n\nТекст:\n{{text}}\n\nФормат вывода на строку:\n{\"entity\": \"\", \"definition\": \"\"}", "response-type": "jsonl", "schema": { "type": "object", "properties": { "entity": { "type": "string", "description": "Имя сущности" }, "definition": { "type": "string", "description": "Четкое определение сущности" } }, "required": ["entity", "definition"] } } ``` * **Изменения в запросах**: | ID запроса | Описание | Поле типа | |---|---|---| | `extract-definitions` | Извлечение всех сущностей и их определений из следующего текста. Выведите один JSON объект на строку. | Нет (один тип) | | `extract-relationships` | Извлечение взаимосвязей | Нет (один тип) | | `extract-topics` | Извлечение темы и определений | Нет (один тип) | | `extract-rows` | Извлечение структурированных строк | Нет (один тип) | | `agent-kg-extract` | Совместное извлечение определения и взаимосвязи | Да: `"definition"`, `"relationship"` | | `extract-with-ontologies` / `ontology-extract` | Извлечение на основе онтологий | Да: `"entity"`, `"relationship"`, `"attribute"` | ## Безопасность * **Валидация входных данных**: Используется стандартная библиотека `json.loads()` для парсинга, что безопасно от возможных атак внедрением. * **Валидация схемы**: Используется `jsonschema.validate()` для проверки соответствия схемы. * **Отсутствие новых уязвимостей**: Разбор JSONL безопаснее, чем разбор JSON-массивов, из-за построчной обработки. ## Производительность * **Память**: Построчный разбор требует меньше памяти, чем загрузка всего JSON-массива. * **Задержка**: Производительность парсинга сопоставима с разбором JSON-массивов. * **Валидация**: Валидация объекта происходит для каждого объекта, что может привести к накладным расходам, но обеспечивает частичную валидацию при ошибках. ## Стратегия тестирования * **Юнит-тесты**: * Разбор JSONL с валидными данными * Разбор JSONL с пустыми строками * Разбор JSONL с маркерами markdown * Разбор JSONL с обрезаными последними строками * Разбор JSONL с невалидным JSON * Валидация схемы с использованием `oneOf` * Совместимость: существующие запросы `"text"` и `"json"` не изменяются * **Интеграционные тесты**: * Извлечение с JSONL-запросами * Симулированное обрезание ответа LLM (искусственно ограниченный ответ) * Извлечение нескольких типов сущностей с использованием поля типа * Извлечение на основе онтологий * **Тесты качества извлечения**: * Сравнение результатов извлечения: JSONL vs JSON * Проверка на надежное извлечение при обрезании: JSONL дает частичные результаты, где JSON не работает ## Вопросы В настоящее время вопросов нет. ## Ссылки * Реализация: `trustgraph-flow/trustgraph/template/prompt_manager.py` * Спецификация JSON Lines: https://jsonlines.org/ * Спецификация JSON Schema `oneOf`: https://json-schema.org/understanding-json-schema/reference/combining.html#oneof * Связанная спецификация: Streaming LLM Responses (`docs/tech-specs/streaming-llm-responses.md`)