mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-11 14:22:12 +02:00
add more docs
Signed-off-by: Jenkins, Kenneth Alexander <kjenkins60@gatech.edu>
This commit is contained in:
parent
23e18cd562
commit
835acaa70e
94 changed files with 60854 additions and 1126 deletions
|
|
@ -1,114 +1,455 @@
|
|||
# Спецификация технической реализации JSONL для выходных данных запросов
|
||||
# Техническая спецификация формата вывода JSONL для запросов
|
||||
|
||||
## Обзор
|
||||
|
||||
Эта спецификация описывает реализацию формата выходных данных JSONL (JSON Lines) для ответов на запросы в TrustGraph. JSONL позволяет надежно извлекать структурированные данные из ответов LLM, решая критические проблемы, связанные с повреждением выходных JSON-массивов при достижении LLM лимитов токенов.
|
||||
Эта спецификация описывает реализацию формата вывода JSONL (JSON Lines) для ответов на запросы в TrustGraph. JSONL обеспечивает устойчивость к усечению при извлечении структурированных данных из ответов LLM, решая критические проблемы, связанные с повреждением выходных массивов JSON, когда ответы LLM достигают лимита токенов.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Эта реализация поддерживает следующие сценарии использования:
|
||||
|
||||
1. **Надежное извлечение при обрезании**: Извлечение действительных частичных результатов даже при обрезании ответа LLM в середине запроса
|
||||
2. **Масштабируемое извлечение**: Обработка извлечения множества элементов без риска полного сбоя из-за ограничений токенов
|
||||
3. **Извлечение нескольких типов**: Поддержка извлечения нескольких типов сущностей (определения, взаимосвязи, сущности, атрибуты) в одном запросе
|
||||
4. **Вывод, совместимый со стримингом**: Обеспечение возможности последующего стриминга/инкрементной обработки результатов извлечения
|
||||
1. **Извлечение, устойчивое к усечению**: Извлекайте допустимые частичные результаты, даже когда
|
||||
вывод LLM усекается в середине ответа.
|
||||
2. **Извлечение в больших масштабах**: Обрабатывайте извлечение большого количества элементов без риска
|
||||
полной сбоя из-за ограничений на количество токенов.
|
||||
3. **Извлечение данных разных типов**: Поддерживайте извлечение нескольких типов сущностей
|
||||
(определения, отношения, сущности, атрибуты) в одном запросе.
|
||||
4. **Вывод, совместимый со стримингом**: Обеспечьте возможность будущей потоковой/инкрементной
|
||||
обработки результатов извлечения.
|
||||
|
||||
## Цели
|
||||
|
||||
- **Совместимость с предыдущими версиями**: Существующие запросы, использующие `response-type: "text"` и `response-type: "json"`, продолжают работать без изменений
|
||||
- **Надежное извлечение при обрезании**: Частичные ответы LLM дают частичные валидные результаты вместо полного сбоя
|
||||
- **Валидация схемы**: Поддержка валидации JSON Schema для отдельных объектов
|
||||
- **Гибкость**: Поддержка различных сценариев извлечения, включая извлечение нескольких типов сущностей и использование стриминга
|
||||
**Обратная совместимость**: Существующие запросы, использующие `response-type: "text"` и
|
||||
`response-type: "json"`, продолжают работать без изменений.
|
||||
**Устойчивость к усечению**: Частичные выходные данные LLM приводят к частичным, но допустимым результатам,
|
||||
а не к полному сбою.
|
||||
**Проверка схемы**: Поддержка проверки JSON-схемы для отдельных объектов.
|
||||
**Дискриминированные объединения**: Поддержка выходных данных смешанных типов с использованием поля `type`
|
||||
в качестве дискриминатора.
|
||||
**Минимальные изменения API**: Расширение существующей конфигурации запросов с добавлением нового
|
||||
типа ответа и ключа схемы.
|
||||
|
||||
## Реализация
|
||||
## Обзор
|
||||
|
||||
* **Обработка 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\": \"<name>\", \"definition\": \"<definition>\"}",
|
||||
"response-type": "jsonl",
|
||||
"schema": {
|
||||
Сервис запросов поддерживает два типа ответов:
|
||||
|
||||
1. `response-type: "text"` - Необработанный текстовый ответ, возвращаемый как есть.
|
||||
2. `response-type: "json"` - JSON, полученный из ответа и проверенный на соответствие
|
||||
необязательной `schema`.
|
||||
|
||||
Текущая реализация в `trustgraph-flow/trustgraph/template/prompt_manager.py`:
|
||||
|
||||
```python
|
||||
class Prompt:
|
||||
def __init__(self, template, response_type = "text", terms=None, schema=None):
|
||||
self.template = template
|
||||
self.response_type = response_type
|
||||
self.terms = terms
|
||||
self.schema = schema
|
||||
```
|
||||
|
||||
### Текущие ограничения
|
||||
|
||||
Когда запросы извлечения требуют вывод в виде массивов JSON (`[{...}, {...}, ...]`):
|
||||
|
||||
**Повреждение из-за усечения**: Если языковая модель достигает лимита выходных токенов в середине массива,
|
||||
весь ответ становится недействительным JSON и не может быть проанализирован.
|
||||
**Анализ "все или ничего"**: Необходимо получить полный вывод перед анализом.
|
||||
**Нет частичных результатов**: Усеченный ответ дает нулевые полезные данные.
|
||||
**Ненадежно для больших извлечений**: Чем больше извлеченных элементов, тем выше риск сбоя.
|
||||
|
||||
Данная спецификация решает эти ограничения, вводя формат JSONL для
|
||||
запросов извлечения, где каждый извлеченный элемент является полным JSON-объектом на своей
|
||||
строке.
|
||||
|
||||
## Техническое проектирование
|
||||
|
||||
### Расширение типа ответа
|
||||
|
||||
Добавьте новый тип ответа `"jsonl"` наряду с существующими типами `"text"` и `"json"`.
|
||||
|
||||
#### Изменения конфигурации
|
||||
|
||||
**Новое значение типа ответа:**
|
||||
|
||||
```
|
||||
"response-type": "jsonl"
|
||||
```
|
||||
|
||||
**Интерпретация схемы:**
|
||||
|
||||
Существующий ключ `"schema"` используется как для `"json"`, так и для `"jsonl"` типов ответов.
|
||||
Интерпретация зависит от типа ответа:
|
||||
|
||||
`"json"`: Схема описывает весь ответ (обычно массив или объект).
|
||||
`"jsonl"`: Схема описывает каждую отдельную строку/объект.
|
||||
|
||||
```json
|
||||
{
|
||||
"response-type": "jsonl",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entity": { "type": "string" },
|
||||
"definition": { "type": "string" }
|
||||
},
|
||||
"required": ["entity", "definition"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Это позволяет избежать изменений в инструментах и редакторах конфигурации подсказок.
|
||||
|
||||
### Спецификация формата JSONL
|
||||
|
||||
#### Простое извлечение
|
||||
|
||||
Для подсказок, извлекающих один тип объекта (определения, отношения,
|
||||
темы, строки), вывод представляет собой один объект JSON на строку без обертки:
|
||||
|
||||
**Формат вывода подсказки:**
|
||||
```
|
||||
{"entity": "photosynthesis", "definition": "Process by which plants convert sunlight"}
|
||||
{"entity": "chlorophyll", "definition": "Green pigment in plants"}
|
||||
{"entity": "mitochondria", "definition": "Powerhouse of the cell"}
|
||||
```
|
||||
|
||||
**Контраст с предыдущим форматом JSON-массива:**
|
||||
```json
|
||||
[
|
||||
{"entity": "photosynthesis", "definition": "Process by which plants convert sunlight"},
|
||||
{"entity": "chlorophyll", "definition": "Green pigment in plants"},
|
||||
{"entity": "mitochondria", "definition": "Powerhouse of the cell"}
|
||||
]
|
||||
```
|
||||
|
||||
Если LLM обрезает текст после строки 2, формат массива JSON приводит к недействительному JSON,
|
||||
в то время как JSONL дает два допустимых объекта.
|
||||
|
||||
#### Извлечение данных смешанных типов (дискриминированные объединения)
|
||||
|
||||
Для запросов, извлекающих несколько типов объектов (например, определения и
|
||||
отношения, или сущности, отношения и атрибуты), используйте поле `"type"`
|
||||
в качестве дискриминатора:
|
||||
|
||||
**Формат вывода запроса:**
|
||||
```
|
||||
{"type": "definition", "entity": "DNA", "definition": "Molecule carrying genetic instructions"}
|
||||
{"type": "relationship", "subject": "DNA", "predicate": "located_in", "object": "cell nucleus", "object-entity": true}
|
||||
{"type": "definition", "entity": "RNA", "definition": "Molecule that carries genetic information"}
|
||||
{"type": "relationship", "subject": "RNA", "predicate": "transcribed_from", "object": "DNA", "object-entity": true}
|
||||
```
|
||||
|
||||
**Схема для дискриминированных объединений использует `oneOf`:**
|
||||
```json
|
||||
{
|
||||
"response-type": "jsonl",
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entity": {
|
||||
"type": "string",
|
||||
"description": "Имя сущности"
|
||||
},
|
||||
"definition": {
|
||||
"type": "string",
|
||||
"description": "Четкое определение сущности"
|
||||
}
|
||||
"type": { "const": "definition" },
|
||||
"entity": { "type": "string" },
|
||||
"definition": { "type": "string" }
|
||||
},
|
||||
"required": ["entity", "definition"]
|
||||
"required": ["type", "entity", "definition"]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": { "const": "relationship" },
|
||||
"subject": { "type": "string" },
|
||||
"predicate": { "type": "string" },
|
||||
"object": { "type": "string" },
|
||||
"object-entity": { "type": "boolean" }
|
||||
},
|
||||
"required": ["type", "subject", "predicate", "object", "object-entity"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Извлечение онтологии
|
||||
|
||||
Для извлечения онтологии на основе сущностей, связей и атрибутов:
|
||||
|
||||
**Формат вывода запроса:**
|
||||
```
|
||||
{"type": "entity", "entity": "Cornish pasty", "entity_type": "fo/Recipe"}
|
||||
{"type": "entity", "entity": "beef", "entity_type": "fo/Food"}
|
||||
{"type": "relationship", "subject": "Cornish pasty", "subject_type": "fo/Recipe", "relation": "fo/has_ingredient", "object": "beef", "object_type": "fo/Food"}
|
||||
{"type": "attribute", "entity": "Cornish pasty", "entity_type": "fo/Recipe", "attribute": "fo/serves", "value": "4 people"}
|
||||
```
|
||||
|
||||
### Детали реализации
|
||||
|
||||
#### Класс Prompt
|
||||
|
||||
Существующий класс `Prompt` не требует изменений. Поле `schema` используется повторно
|
||||
для JSONL, а его интерпретация определяется `response_type`:
|
||||
|
||||
```python
|
||||
class Prompt:
|
||||
def __init__(self, template, response_type="text", terms=None, schema=None):
|
||||
self.template = template
|
||||
self.response_type = response_type
|
||||
self.terms = terms
|
||||
self.schema = schema # Interpretation depends on response_type
|
||||
```
|
||||
|
||||
#### PromptManager.load_config
|
||||
|
||||
Изменения не требуются - существующая загрузка конфигурации уже обрабатывает
|
||||
ключ `schema`.
|
||||
|
||||
#### Разбор JSONL
|
||||
|
||||
Добавлен новый метод разбора ответов в формате JSONL:
|
||||
|
||||
```python
|
||||
def parse_jsonl(self, text):
|
||||
"""
|
||||
Parse JSONL response, returning list of valid objects.
|
||||
|
||||
Invalid lines (malformed JSON, empty lines) are skipped with warnings.
|
||||
This provides truncation resilience - partial output yields partial results.
|
||||
"""
|
||||
results = []
|
||||
|
||||
for line_num, line in enumerate(text.strip().split('\n'), 1):
|
||||
line = line.strip()
|
||||
|
||||
# Skip empty lines
|
||||
if not line:
|
||||
continue
|
||||
|
||||
# Skip markdown code fence markers if present
|
||||
if line.startswith('```'):
|
||||
continue
|
||||
|
||||
try:
|
||||
obj = json.loads(line)
|
||||
results.append(obj)
|
||||
except json.JSONDecodeError as e:
|
||||
# Log warning but continue - this provides truncation resilience
|
||||
logger.warning(f"JSONL parse error on line {line_num}: {e}")
|
||||
|
||||
return results
|
||||
```
|
||||
|
||||
#### Изменения в PromptManager.invoke
|
||||
|
||||
Расширить метод invoke для обработки нового типа ответа:
|
||||
|
||||
```python
|
||||
async def invoke(self, id, input, llm):
|
||||
logger.debug("Invoking prompt template...")
|
||||
|
||||
terms = self.terms | self.prompts[id].terms | input
|
||||
resp_type = self.prompts[id].response_type
|
||||
|
||||
prompt = {
|
||||
"system": self.system_template.render(terms),
|
||||
"prompt": self.render(id, input)
|
||||
}
|
||||
```
|
||||
* **Изменения в запросах**:
|
||||
|
||||
| ID запроса | Описание | Поле типа |
|
||||
|---|---|---|
|
||||
| `extract-definitions` | Извлечение всех сущностей и их определений из следующего текста. Выведите один JSON объект на строку. | Нет (один тип) |
|
||||
| `extract-relationships` | Извлечение взаимосвязей | Нет (один тип) |
|
||||
| `extract-topics` | Извлечение темы и определений | Нет (один тип) |
|
||||
resp = await llm(**prompt)
|
||||
|
||||
if resp_type == "text":
|
||||
return resp
|
||||
|
||||
if resp_type == "json":
|
||||
try:
|
||||
obj = self.parse_json(resp)
|
||||
except:
|
||||
logger.error(f"JSON parse failed: {resp}")
|
||||
raise RuntimeError("JSON parse fail")
|
||||
|
||||
if self.prompts[id].schema:
|
||||
try:
|
||||
validate(instance=obj, schema=self.prompts[id].schema)
|
||||
logger.debug("Schema validation successful")
|
||||
except Exception as e:
|
||||
raise RuntimeError(f"Schema validation fail: {e}")
|
||||
|
||||
return obj
|
||||
|
||||
if resp_type == "jsonl":
|
||||
objects = self.parse_jsonl(resp)
|
||||
|
||||
if not objects:
|
||||
logger.warning("JSONL parse returned no valid objects")
|
||||
return []
|
||||
|
||||
# Validate each object against schema if provided
|
||||
if self.prompts[id].schema:
|
||||
validated = []
|
||||
for i, obj in enumerate(objects):
|
||||
try:
|
||||
validate(instance=obj, schema=self.prompts[id].schema)
|
||||
validated.append(obj)
|
||||
except Exception as e:
|
||||
logger.warning(f"Object {i} failed schema validation: {e}")
|
||||
return validated
|
||||
|
||||
return objects
|
||||
|
||||
raise RuntimeError(f"Response type {resp_type} not known")
|
||||
```
|
||||
|
||||
### Затронутые запросы
|
||||
|
||||
Следующие запросы должны быть перенесены в формат JSONL:
|
||||
|
||||
| Идентификатор запроса | Описание | Тип поля |
|
||||
|-----------|-------------|------------|
|
||||
| `extract-definitions` | Извлечение сущностей/определений | Нет (один тип) |
|
||||
| `extract-relationships` | Извлечение отношений | Нет (один тип) |
|
||||
| `extract-topics` | Извлечение темы/определения | Нет (один тип) |
|
||||
| `extract-rows` | Извлечение структурированных строк | Нет (один тип) |
|
||||
| `agent-kg-extract` | Совместное извлечение определения и взаимосвязи | Да: `"definition"`, `"relationship"` |
|
||||
| `extract-with-ontologies` / `ontology-extract` | Извлечение на основе онтологий | Да: `"entity"`, `"relationship"`, `"attribute"` |
|
||||
| `agent-kg-extract` | Комбинированное извлечение определений + отношений | Да: `"definition"`, `"relationship"` |
|
||||
| `extract-with-ontologies` / `ontology-extract` | Извлечение на основе онтологии | Да: `"entity"`, `"relationship"`, `"attribute"` |
|
||||
|
||||
## Безопасность
|
||||
### Изменения API
|
||||
|
||||
* **Валидация входных данных**: Используется стандартная библиотека `json.loads()` для парсинга, что безопасно от возможных атак внедрением.
|
||||
* **Валидация схемы**: Используется `jsonschema.validate()` для проверки соответствия схемы.
|
||||
* **Отсутствие новых уязвимостей**: Разбор JSONL безопаснее, чем разбор JSON-массивов, из-за построчной обработки.
|
||||
#### Точка зрения клиента
|
||||
|
||||
## Производительность
|
||||
Разбор JSONL прозрачен для вызывающих API сервиса запросов. Разбор происходит
|
||||
на стороне сервера в сервисе запросов, и ответ возвращается через стандартное
|
||||
поле `PromptResponse.object` в виде сериализованного массива JSON.
|
||||
|
||||
* **Память**: Построчный разбор требует меньше памяти, чем загрузка всего JSON-массива.
|
||||
* **Задержка**: Производительность парсинга сопоставима с разбором JSON-массивов.
|
||||
* **Валидация**: Валидация объекта происходит для каждого объекта, что может привести к накладным расходам, но обеспечивает частичную валидацию при ошибках.
|
||||
Когда клиенты вызывают сервис запросов (через `PromptClient.prompt()` или аналогично):
|
||||
|
||||
**`response-type: "json"`** с схемой массива → клиент получает Python `list`
|
||||
**`response-type: "jsonl"`** → клиент получает Python `list`
|
||||
|
||||
С точки зрения клиента, оба возвращают идентичные структуры данных. Разница заключается только в том, как вывод LLM разбирается на стороне сервера:
|
||||
|
||||
|
||||
Формат массива JSON: Один вызов `json.loads()`; полностью завершается с ошибкой, если усечен
|
||||
Формат JSONL: Разбор построчно; дает частичные результаты, если усечен
|
||||
|
||||
Это означает, что существующий клиентский код, ожидающий список от запросов извлечения,
|
||||
не требует изменений при переносе запросов из формата JSON в формат JSONL.
|
||||
|
||||
#### Возвращаемое значение сервера
|
||||
|
||||
Для `response-type: "jsonl"` метод `PromptManager.invoke()` возвращает
|
||||
`list[dict]`, содержащий все успешно разобранные и проверенные объекты. Этот
|
||||
список затем сериализуется в JSON для поля `PromptResponse.object`.
|
||||
|
||||
### Обработка ошибок
|
||||
|
||||
Пустые результаты: Возвращает пустой список `[]` с предупреждением в журнале
|
||||
Частная ошибка разбора: Возвращает список успешно разобранных объектов с
|
||||
предупреждениями в журналах об ошибках
|
||||
Полная ошибка разбора: Возвращает пустой список `[]` с предупреждениями в журналах
|
||||
|
||||
Это отличается от `response-type: "json"`, который вызывает `RuntimeError` при
|
||||
ошибке разбора. Легкое поведение для JSONL намеренно, чтобы обеспечить
|
||||
устойчивость к усечению.
|
||||
|
||||
### Пример конфигурации
|
||||
|
||||
Полный пример конфигурации запроса:
|
||||
|
||||
```json
|
||||
{
|
||||
"prompt": "Extract all entities and their definitions from the following text. Output one JSON object per line.\n\nText:\n{{text}}\n\nOutput format per line:\n{\"entity\": \"<name>\", \"definition\": \"<definition>\"}",
|
||||
"response-type": "jsonl",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entity": {
|
||||
"type": "string",
|
||||
"description": "The entity name"
|
||||
},
|
||||
"definition": {
|
||||
"type": "string",
|
||||
"description": "A clear definition of the entity"
|
||||
}
|
||||
},
|
||||
"required": ["entity", "definition"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Соображения безопасности
|
||||
|
||||
**Проверка входных данных**: Разбор JSON использует стандартную `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 не работает
|
||||
### Юнит-тесты
|
||||
|
||||
## Вопросы
|
||||
Разбор JSONL с допустимыми входными данными.
|
||||
Разбор JSONL с пустыми строками.
|
||||
Разбор JSONL с блоками форматированного текста Markdown.
|
||||
Разбор JSONL с обрезанной последней строкой.
|
||||
Разбор JSONL со строками, содержащими недопустимый JSON.
|
||||
Проверка схемы с использованием `oneOf` для дискриминируемых объединений.
|
||||
Обратная совместимость: существующие `"text"` и `"json"` подсказки не изменены.
|
||||
|
||||
В настоящее время вопросов нет.
|
||||
### Интеграционные тесты
|
||||
|
||||
Комплексная извлечение данных с использованием подсказок JSONL.
|
||||
Извлечение данных с имитацией усечения (искусственно ограниченный ответ).
|
||||
Извлечение данных смешанных типов с использованием дискриминатора типов.
|
||||
Извлечение данных онтологии со всеми тремя типами.
|
||||
|
||||
### Тесты качества извлечения данных.
|
||||
|
||||
Сравнение результатов извлечения: формат JSONL против массива JSON.
|
||||
Проверка устойчивости к усечению: JSONL возвращает частичные результаты, в то время как JSON - нет.
|
||||
|
||||
## План миграции
|
||||
|
||||
### Этап 1: Реализация
|
||||
|
||||
1. Реализовать метод `parse_jsonl()` в `PromptManager`.
|
||||
2. Расширить `invoke()` для обработки `response-type: "jsonl"`.
|
||||
3. Добавить модульные тесты.
|
||||
|
||||
### Этап 2: Миграция подсказок
|
||||
|
||||
1. Обновить подсказку `extract-definitions` и конфигурацию.
|
||||
2. Обновить подсказку `extract-relationships` и конфигурацию.
|
||||
3. Обновить подсказку `extract-topics` и конфигурацию.
|
||||
4. Обновить подсказку `extract-rows` и конфигурацию.
|
||||
5. Обновить подсказку `agent-kg-extract` и конфигурацию.
|
||||
6. Обновить подсказку `extract-with-ontologies` и конфигурацию.
|
||||
|
||||
### Этап 3: Обновления для последующих этапов
|
||||
|
||||
1. Обновить любой код, использующий результаты извлечения, чтобы он мог обрабатывать возвращаемый тип списка.
|
||||
2. Обновить код, который категоризует извлечения смешанных типов, используя поле `type`.
|
||||
3. Обновить тесты, которые проверяют формат выходных данных извлечения.
|
||||
|
||||
## Открытые вопросы
|
||||
|
||||
На данный момент нет.
|
||||
|
||||
## Ссылки
|
||||
|
||||
* Реализация: `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`)
|
||||
Текущая реализация: `trustgraph-flow/trustgraph/template/prompt_manager.py`
|
||||
Спецификация JSON Lines: https://jsonlines.org/
|
||||
Схема JSON `oneOf`: https://json-schema.org/understanding-json-schema/reference/combining.html#oneof
|
||||
Связанная спецификация: Streaming LLM Responses (`docs/tech-specs/streaming-llm-responses.md`)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue