--- layout: default title: "Происхождение данных во время извлечения: Исходный слой" parent: "Russian (Beta)" --- # Происхождение данных во время извлечения: Исходный слой > **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta. ## Обзор Этот документ содержит заметки о происхождении данных во время извлечения для будущих работ по спецификации. Происхождение данных во время извлечения фиксирует "исходный слой" - откуда данные были получены изначально, как они были извлечены и преобразованы. Это отличается от происхождения данных во время запроса (см. `query-time-provenance.md`), которое фиксирует логику работы агента. ## Описание проблемы ### Текущая реализация В настоящее время происхождение данных работает следующим образом: Метаданные документа хранятся в виде RDF-триплетов в графе знаний. Идентификатор документа связывает метаданные с документом, поэтому документ отображается как узел в графе. Когда связи (отношения/факты) извлекаются из документов, связь `subjectOf` связывает извлеченную связь с исходным документом. ### Проблемы текущего подхода 1. **Повторная загрузка метаданных:** Метаданные документа группируются и загружаются повторно при каждой партии триплетов, извлеченных из этого документа. Это неэффективно и избыточно - одни и те же метаданные передаются как "груз" с каждым результатом извлечения. 2. **Поверхностное происхождение данных:** Текущая связь `subjectOf` связывает факты только с верхним уровнем документа. Нет информации о цепочке преобразований - с какой страницы был получен факт, из какого фрагмента, какой метод извлечения был использован. ### Желаемое состояние 1. **Загрузка метаданных один раз:** Метаданные документа должны быть загружены один раз и привязаны к узлу верхнего уровня документа, а не повторяться с каждой партией триплетов. <<<<<<< HEAD 2. **Разветвленная структура данных о происхождении:** Захватите полную цепочку преобразований от исходного документа через все промежуточные артефакты до извлеченных фактов. Например, преобразование PDF-документа: ======= 2. **Разветвленная структура происхождения данных:** Захватите полную цепочку преобразований от исходного документа через все промежуточные артефакты до извлеченных фактов. Например, преобразование PDF-документа: >>>>>>> 82edf2d (New md files from RunPod) ``` PDF file (source document with metadata) → Page 1 (decoded text) → Chunk 1 → Extracted edge/fact (via subjectOf) → Extracted edge/fact → Chunk 2 → Extracted edge/fact → Page 2 → Chunk 3 → ... ``` <<<<<<< HEAD 3. **Унифицированное хранилище:** Граф происхождения хранится в той же базе знаний, что и извлеченные знания. Это позволяет запрашивать происхождение так же, как и знания, прослеживая связи обратно по цепочке от любого факта к его точному источнику. ======= 3. **Унифицированное хранилище:** Граф происхождения хранится в той же базе знаний, что и извлеченные знания. Это позволяет запрашивать происхождение так же, как и знания, прослеживая связи вверх по цепочке от любого факта к его точному источнику. >>>>>>> 82edf2d (New md files from RunPod) 4. **Стабильные идентификаторы:** Каждый промежуточный артефакт (страница, фрагмент) имеет стабильный идентификатор в виде узла в графе. 5. **Связь родитель-потомок:** Производные документы связаны с их родительскими документами до самого верхнего уровня, используя согласованные типы отношений. 6. **Точное определение источника факта:** Отношение `subjectOf` на извлеченных связях указывает на непосредственный родительский элемент (фрагмент), а не на верхний документ. Полное происхождение восстанавливается путем прохода по графу. ## Случаи использования ### UC1: Определение источника в ответах GraphRAG **Сценарий:** Пользователь выполняет запрос GraphRAG и получает ответ от агента. **Процесс:** 1. Пользователь отправляет запрос агенту GraphRAG. 2. Агент извлекает соответствующие факты из базы знаний для формирования ответа. <<<<<<< HEAD 3. В соответствии со спецификацией происхождения во время запроса, агент сообщает, какие факты внесли вклад в ответ. ======= 3. В соответствии со спецификацией происхождения для запросов, агент сообщает, какие факты послужили основой для ответа. >>>>>>> 82edf2d (New md files from RunPod) 4. Каждый факт связан с его исходным фрагментом через граф происхождения. 5. Фрагменты связаны со страницами, страницы связаны с исходными документами. **Результат для пользователя:** Интерфейс отображает ответ LLM вместе с указанием источника. Пользователь может: <<<<<<< HEAD Увидеть, какие факты подтверждают ответ. Переходить от фактов к фрагментам, страницам и документам. Просматривать исходные документы для проверки утверждений. Понимать, откуда в документе (на какой странице, в каком разделе) произошел факт. ======= Увидеть, какие факты послужили основой для ответа. Переходить от фактов к фрагментам, страницам и документам. Просматривать исходные документы для проверки утверждений. Понимать, откуда в документе (на какой странице, в каком разделе) произошел тот или иной факт. >>>>>>> 82edf2d (New md files from RunPod) **Преимущество:** Пользователи могут проверять ответы, сгенерированные ИИ, по сравнению с первичными источниками, что повышает доверие и позволяет проводить проверку фактов. ### UC2: Отладка качества извлечения <<<<<<< HEAD Факт кажется неверным. Проследите обратно через фрагмент, страницу и документ, чтобы увидеть исходный текст. Это была ошибка извлечения, или исходный документ был неверным? ### UC3: Инкрементное повторное извлечение Исходный документ обновлен. Какие фрагменты/факты были получены из него? Отмените и перезапустите только эти, а не перерабатывайте все. ### UC4: Удаление данных / Право на забвение Исходный документ должен быть удален (GDPR, юридические требования и т.д.). Найдите и удалите все производные факты, пройдя по графу. ### UC5: Разрешение конфликтов Два факта противоречат друг другу. Проследите оба обратно к их источникам, чтобы понять, почему, и решить, кому доверять (более авторитетному источнику, более свежему и т.д.). ======= Факт кажется неверным. Проследите по цепочке от фрагмента к странице и документу, чтобы увидеть исходный текст. Была ли это ошибка извлечения, или исходный текст был неверным? ### UC3: Инкрементное повторное извлечение Исходный документ был обновлен. Какие фрагменты/факты были получены из него? Отмените и перегенерируйте только эти, а не перерабатывайте все. ### UC4: Удаление данных / Право на забвение Исходный документ должен быть удален (GDPR, юридические требования и т.д.). Пройдите по графу, чтобы найти и удалить все производные факты. ### UC5: Разрешение конфликтов Два факта противоречат друг другу. Проследите оба факта до их источников, чтобы понять причину и решить, кому доверять (более авторитетному источнику, более свежему и т.д.). >>>>>>> 82edf2d (New md files from RunPod) ### UC6: Взвешивание авторитетности источника Некоторые источники более авторитетны, чем другие. Факты могут быть взвешены или отфильтрованы на основе авторитетности/качества исходных документов. ### UC7: Сравнение конвейеров извлечения Сравните результаты, полученные с использованием различных методов/версий извлечения. Какой экстрактор выдал лучшие факты из одного и того же источника? ## Точки интеграции ### Библиотекарь Компонент "библиотекарь" уже предоставляет хранение документов с уникальными идентификаторами документов. Система отслеживания происхождения интегрируется с существующей инфраструктурой. #### Существующие возможности (уже реализовано) **Связывание документов "родитель-потомок":** Поле `parent_id` в `DocumentMetadata` - связывает дочерний документ с родительским документом. <<<<<<< HEAD Поле `document_type` - значения: `"source"` (оригинальный) или `"extracted"` (производный). ======= Поле `document_type` - значения: `"source"` (исходный) или `"extracted"` (производный). >>>>>>> 82edf2d (New md files from RunPod) API `add-child-document` - создает дочерний документ с автоматическим `document_type = "extracted"`. API `list-children` - извлекает все дочерние документы родительского документа. Каскадное удаление - удаление родительского документа автоматически удаляет все дочерние документы. **Идентификация документов:** Идентификаторы документов задаются клиентом (не генерируются автоматически). Документы индексируются по составному ключу `(user, document_id)` в Cassandra. Объектные идентификаторы (UUID) генерируются внутренне для хранения двоичных данных. **Поддержка метаданных:** Поле `metadata: list[Triple]` - тройки RDF для структурированных метаданных. `title`, `comments`, `tags` - основные метаданные документа. `time` - метка времени, `kind` - MIME-тип. **Архитектура хранения:** Метаданные хранятся в Cassandra (пространство ключей `librarian`, таблица `document`). Содержимое хранится в хранилище двоичных данных MinIO/S3 (контейнер `library`). Интеллектуальная доставка контента: документы размером менее 2 МБ встраиваются, более крупные документы передаются потоком. #### Основные файлы `trustgraph-flow/trustgraph/librarian/librarian.py` - Основные операции "библиотекаря". `trustgraph-flow/trustgraph/librarian/service.py` - Сервисный процессор, загрузка документов. `trustgraph-flow/trustgraph/tables/library.py` - Хранилище таблиц Cassandra. `trustgraph-base/trustgraph/schema/services/library.py` - Определения схемы. <<<<<<< HEAD #### Необходимые улучшения ======= #### Проблемы, требующие решения >>>>>>> 82edf2d (New md files from RunPod) "Библиотекарь" имеет необходимые компоненты, но в настоящее время: 1. Связывание "родитель-потомок" ограничено одним уровнем - отсутствуют вспомогательные функции для обхода многоуровневых графов. 2. Отсутствует стандартная терминология для типов отношений (например, `derivedFrom`, `extractedFrom`). <<<<<<< HEAD 3. Метаданные происхождения (метод извлечения, уверенность, позиция фрагмента) не стандартизированы. ======= 3. Метаданные происхождения (метод извлечения, достоверность, позиция фрагмента) не стандартизированы. >>>>>>> 82edf2d (New md files from RunPod) 4. Отсутствует API запросов для прослеживания полной цепочки происхождения от факта до исходного источника. ## Проектирование сквозного потока Каждый процессор в конвейере следует последовательной схеме: Получает идентификатор документа от предыдущего этапа. Извлекает содержимое из "библиотекаря". Создает дочерние артефакты. Для каждого дочернего элемента: сохраняет в "библиотекаре", создает связь в графе и передает идентификатор на следующий этап. ### Потоки обработки Существуют два потока в зависимости от типа документа: #### Поток обработки документов PDF ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ Librarian (initiate processing) │ │ 1. Emit root document metadata to knowledge graph (once) │ │ 2. Send root document ID to PDF extractor │ └─────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ PDF Extractor (per page) │ │ 1. Fetch PDF content from librarian using document ID │ │ 2. Extract pages as text │ │ 3. For each page: │ │ a. Save page as child document in librarian (parent = root doc) │ │ b. Emit parent-child edge to knowledge graph │ │ c. Send page document ID to chunker │ └─────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ Chunker (per chunk) │ │ 1. Fetch page content from librarian using document ID │ │ 2. Split text into chunks │ │ 3. For each chunk: │ │ a. Save chunk as child document in librarian (parent = page) │ │ b. Emit parent-child edge to knowledge graph │ │ c. Send chunk document ID + chunk content to next processor │ └─────────────────────────────────────────────────────────────────────────┘ │ ▼ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ Post-chunker optimization: messages carry both chunk ID (for provenance) and content (to avoid librarian round-trip). Chunks are small (2-4KB). ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ Knowledge Extractor (per chunk) │ │ 1. Receive chunk ID + content directly (no librarian fetch needed) │ │ 2. Extract facts/triples and embeddings from chunk content │ │ 3. For each triple: │ │ a. Emit triple to knowledge graph │ │ b. Emit reified edge linking triple → chunk ID (edge pointing │ │ to edge - first use of reification support) │ │ 4. For each embedding: │ │ a. Emit embedding with its entity ID │ │ b. Link entity ID → chunk ID in knowledge graph │ └─────────────────────────────────────────────────────────────────────────┘ ``` #### Поток текстовых документов Текстовые документы пропускают этап извлечения из PDF и сразу поступают в компоновщик: ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ Librarian (initiate processing) │ │ 1. Emit root document metadata to knowledge graph (once) │ │ 2. Send root document ID directly to chunker (skip PDF extractor) │ └─────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ Chunker (per chunk) │ │ 1. Fetch text content from librarian using document ID │ │ 2. Split text into chunks │ │ 3. For each chunk: │ │ a. Save chunk as child document in librarian (parent = root doc) │ │ b. Emit parent-child edge to knowledge graph │ │ c. Send chunk document ID + chunk content to next processor │ └─────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ Knowledge Extractor │ │ (same as PDF flow) │ └─────────────────────────────────────────────────────────────────────────┘ ``` Полученный ориентированный ациклический граф (DAG) имеет на один уровень меньше: ``` PDF: Document → Pages → Chunks → Triples/Embeddings Text: Document → Chunks → Triples/Embeddings ``` Дизайн учитывает оба варианта, поскольку компонент, разделяющий текст на части, обрабатывает входные данные универсально - он использует любой идентификатор документа, который он получает, в качестве родительского, независимо от того, является ли это исходным документом или страницей. ### Схема метаданных (PROV-O) Метаданные происхождения используют онтологию W3C PROV-O. Это обеспечивает стандартный словарь и позволяет в будущем осуществлять подпись/аутентификацию результатов извлечения. #### Основные концепции PROV-O | Тип PROV-O | Использование в TrustGraph | |-------------|------------------| | `prov:Entity` | Документ, страница, фрагмент, тройка, вложение | | `prov:Activity` | Экземпляры операций извлечения | | `prov:Agent` | Компоненты TG (извлечение PDF, компонент, разделяющий текст на части и т.д.) с версиями | #### Отношения PROV-O | Предикат | Значение | Пример | |-----------|---------|---------| | `prov:wasDerivedFrom` | Сущность, полученная из другой сущности | Страница была получена из документа | | `prov:wasGeneratedBy` | Сущность, сгенерированная действием | Страница была сгенерирована действием извлечения PDF | | `prov:used` | Действие, использующее сущность в качестве входных данных | Действие извлечения PDF использовало документ | | `prov:wasAssociatedWith` | Действие, выполненное агентом | Действие извлечения PDF было связано с tg:PDFExtractor | #### Метаданные на каждом уровне **Исходный документ (генерируется Librarian):** ``` doc:123 a prov:Entity . doc:123 dc:title "Research Paper" . doc:123 dc:source . doc:123 dc:date "2024-01-15" . doc:123 dc:creator "Author Name" . doc:123 tg:pageCount 42 . doc:123 tg:mimeType "application/pdf" . ``` **Страница (сгенерирована извлечением из PDF):** ``` page:123-1 a prov:Entity . page:123-1 prov:wasDerivedFrom doc:123 . page:123-1 prov:wasGeneratedBy activity:pdf-extract-456 . page:123-1 tg:pageNumber 1 . activity:pdf-extract-456 a prov:Activity . activity:pdf-extract-456 prov:used doc:123 . activity:pdf-extract-456 prov:wasAssociatedWith tg:PDFExtractor . activity:pdf-extract-456 tg:componentVersion "1.2.3" . activity:pdf-extract-456 prov:startedAtTime "2024-01-15T10:30:00Z" . ``` <<<<<<< HEAD **Раздел (выдан разделителем):** ======= **Раздел (выдан Компоновщиком):** >>>>>>> 82edf2d (New md files from RunPod) ``` chunk:123-1-1 a prov:Entity . chunk:123-1-1 prov:wasDerivedFrom page:123-1 . chunk:123-1-1 prov:wasGeneratedBy activity:chunk-789 . chunk:123-1-1 tg:chunkIndex 1 . chunk:123-1-1 tg:charOffset 0 . chunk:123-1-1 tg:charLength 2048 . activity:chunk-789 a prov:Activity . activity:chunk-789 prov:used page:123-1 . activity:chunk-789 prov:wasAssociatedWith tg:Chunker . activity:chunk-789 tg:componentVersion "1.0.0" . activity:chunk-789 tg:chunkSize 2048 . activity:chunk-789 tg:chunkOverlap 200 . ``` <<<<<<< HEAD **Жирный шрифт (вывод Knowledge Extractor):** ======= **Жирный шрифт (выделен извлечением знаний):** >>>>>>> 82edf2d (New md files from RunPod) ``` # The extracted triple (edge) entity:JohnSmith rel:worksAt entity:AcmeCorp . # Subgraph containing the extracted triples subgraph:001 tg:contains <> . subgraph:001 prov:wasDerivedFrom chunk:123-1-1 . subgraph:001 prov:wasGeneratedBy activity:extract-999 . activity:extract-999 a prov:Activity . activity:extract-999 prov:used chunk:123-1-1 . activity:extract-999 prov:wasAssociatedWith tg:KnowledgeExtractor . activity:extract-999 tg:componentVersion "2.1.0" . activity:extract-999 tg:llmModel "claude-3" . activity:extract-999 tg:ontology . ``` <<<<<<< HEAD **Встраивание (хранится в векторной базе данных, а не в тройной базе данных):** ======= **Встраивания (хранятся в векторной базе данных, а не в тройной базе данных):** >>>>>>> 82edf2d (New md files from RunPod) Встраивания хранятся в векторной базе данных вместе с метаданными, а не в виде RDF-троек. Каждая запись встраивания содержит: | Поле | Описание | Пример | |-------|-------------|---------| | vector | Вектор встраивания | [0.123, -0.456, ...] | | entity | URI узла, который представляет встраивание | `entity:JohnSmith` | | chunk_id | Исходный фрагмент (происхождение) | `chunk:123-1-1` | | model | Используемая модель встраивания | `text-embedding-ada-002` | | component_version | Версия компонента TG | `1.0.0` | <<<<<<< HEAD Поле `entity` связывает встраивание с графом знаний (URI узла). Поле `chunk_id` предоставляет информацию о происхождении, указывающую на исходный фрагмент, что позволяет проследить путь до исходного документа. ======= Поле `entity` связывает встраивание с графом знаний (URI узла). Поле `chunk_id` предоставляет информацию о происхождении, указывающую на исходный фрагмент, что позволяет проследить путь вверх по DAG к исходному документу. >>>>>>> 82edf2d (New md files from RunPod) #### Расширения пространства имен TrustGraph Пользовательские предикаты в пространстве имен `tg:` для метаданных, специфичных для извлечения: | Предикат | Область | Описание | |-----------|--------|-------------| | `tg:contains` | Подграф | Указывает на тройку, содержащуюся в этом подграфе извлечения | | `tg:pageCount` | Документ | Общее количество страниц в исходном документе | | `tg:mimeType` | Документ | MIME-тип исходного документа | | `tg:pageNumber` | Страница | Номер страницы в исходном документе | <<<<<<< HEAD | `tg:chunkIndex` | Фрагмент | Индекс фрагмента внутри родительского фрагмента | ======= | `tg:chunkIndex` | Фрагмент | Индекс фрагмента внутри родительского элемента | >>>>>>> 82edf2d (New md files from RunPod) | `tg:charOffset` | Фрагмент | Смещение символов в родительском тексте | | `tg:charLength` | Фрагмент | Длина фрагмента в символах | | `tg:chunkSize` | Действие | Настроенный размер фрагмента | | `tg:chunkOverlap` | Действие | Настроенное перекрытие между фрагментами | | `tg:componentVersion` | Действие | Версия компонента TG | | `tg:llmModel` | Действие | LLM, используемый для извлечения | | `tg:ontology` | Действие | URI онтологии, используемой для управления извлечением | | `tg:embeddingModel` | Действие | Модель, используемая для встраиваний | | `tg:sourceText` | Утверждение | Точный текст, из которого была извлечена тройка | | `tg:sourceCharOffset` | Утверждение | Смещение символов внутри фрагмента, где начинается исходный текст | | `tg:sourceCharLength` | Утверждение | Длина исходного текста в символах | #### Начальная загрузка словаря (для каждой коллекции) <<<<<<< HEAD Граф знаний является онтологически нейтральным и изначально пуст. При первом добавлении данных о происхождении PROV-O в коллекцию словарь должен быть инициализирован с помощью RDF-меток для всех классов и предикатов. Это обеспечивает удобочитаемое отображение в запросах и пользовательском интерфейсе. ======= Граф знаний является онтологически нейтральным и изначально пуст. При записи данных о происхождении PROV-O в коллекцию в первый раз словарь должен быть инициализирован с помощью меток RDF для всех классов и предикатов. Это обеспечивает удобочитаемое отображение в запросах и пользовательском интерфейсе. >>>>>>> 82edf2d (New md files from RunPod) **Классы PROV-O:** ``` prov:Entity rdfs:label "Entity" . prov:Activity rdfs:label "Activity" . prov:Agent rdfs:label "Agent" . ``` **Предикаты PROV-O:** ``` prov:wasDerivedFrom rdfs:label "was derived from" . prov:wasGeneratedBy rdfs:label "was generated by" . prov:used rdfs:label "used" . prov:wasAssociatedWith rdfs:label "was associated with" . prov:startedAtTime rdfs:label "started at" . ``` **Предикаты TrustGraph:** ``` tg:contains rdfs:label "contains" . tg:pageCount rdfs:label "page count" . tg:mimeType rdfs:label "MIME type" . tg:pageNumber rdfs:label "page number" . tg:chunkIndex rdfs:label "chunk index" . tg:charOffset rdfs:label "character offset" . tg:charLength rdfs:label "character length" . tg:chunkSize rdfs:label "chunk size" . tg:chunkOverlap rdfs:label "chunk overlap" . tg:componentVersion rdfs:label "component version" . tg:llmModel rdfs:label "LLM model" . tg:ontology rdfs:label "ontology" . tg:embeddingModel rdfs:label "embedding model" . tg:sourceText rdfs:label "source text" . tg:sourceCharOffset rdfs:label "source character offset" . tg:sourceCharLength rdfs:label "source character length" . ``` <<<<<<< HEAD **Примечания по реализации:** Этот механизм начальной загрузки словаря должен быть идемпотентным, то есть его можно безопасно запускать несколько раз без создания дубликатов. Его можно запускать при первой обработке документа в коллекции или как отдельный этап инициализации коллекции. #### Происхождение подраздела (желательно) Для более детальной информации о происхождении полезно записывать, из какой именно части фрагмента была извлечена тройка. Это позволяет: ======= **Примечания по реализации:** Этот начальный набор словаря должен быть идемпотентным - его можно безопасно запускать несколько раз без создания дубликатов. Его можно запускать при первой обработке документа в коллекции или как отдельный этап инициализации коллекции. #### Происхождение под-фрагментов (желательно) Для более детальной информации о происхождении, было бы полезно записывать, из какой именно части фрагмента была извлечена тройка. Это позволяет: >>>>>>> 82edf2d (New md files from RunPod) Выделять точный исходный текст в пользовательском интерфейсе Проверять точность извлечения по отношению к исходному тексту Отлаживать качество извлечения на уровне предложений **Пример с отслеживанием позиции:** ``` # The extracted triple entity:JohnSmith rel:worksAt entity:AcmeCorp . # Subgraph with sub-chunk provenance subgraph:001 tg:contains <> . subgraph:001 prov:wasDerivedFrom chunk:123-1-1 . subgraph:001 tg:sourceText "John Smith has worked at Acme Corp since 2019" . subgraph:001 tg:sourceCharOffset 1547 . subgraph:001 tg:sourceCharLength 46 . ``` **Пример с выделением текста (альтернативный):** ``` subgraph:001 tg:contains <> . subgraph:001 prov:wasDerivedFrom chunk:123-1-1 . subgraph:001 tg:sourceRange "1547-1593" . subgraph:001 tg:sourceText "John Smith has worked at Acme Corp since 2019" . ``` **Соображения по реализации:** Извлечение на основе LLM может не всегда предоставлять информацию о позициях символов. <<<<<<< HEAD Можно запросить LLM, чтобы он возвращал исходное предложение/фразу вместе с извлеченными тройками. ======= Можно запросить LLM, чтобы она возвращала исходное предложение/фразу вместе с извлеченными тройками. >>>>>>> 82edf2d (New md files from RunPod) Альтернативно, можно выполнить постобработку для сопоставления извлеченных сущностей с исходным текстом. Компромисс между сложностью извлечения и детализацией происхождения. Может быть проще реализовать с использованием структурированных методов извлечения, чем с использованием LLM для извлечения в свободной форме. <<<<<<< HEAD Это обозначено как перспективное направление - сначала следует реализовать базовое отслеживание происхождения на уровне фрагментов, а отслеживание подфрагментов следует рассматривать как улучшение в будущем, если это будет возможно. ### Двухуровневая модель хранения Граф происхождения строится постепенно по мере прохождения документов через конвейер: | Хранилище | Что хранится | Назначение | |-------|---------------|---------| | Библиотекарь | Содержимое документа + ссылки "родитель-потомок" | Извлечение содержимого, каскадное удаление | | Граф знаний | Ребра "родитель-потомок" + метаданные | Запросы происхождения, атрибуция фактов | Оба хранилища поддерживают одну и ту же структуру графа. Библиотекарь хранит содержимое, а граф хранит отношения и обеспечивает возможности запросов для обхода. ======= Это обозначено как перспективное направление - сначала следует реализовать базовое отслеживание происхождения на уровне фрагментов, а отслеживание подфрагментов следует рассматривать как улучшение в будущем, если это возможно. ### Двухуровневая модель хранения Граф происхождения строится постепенно по мере прохождения документов по конвейеру: | Хранилище | Что хранится | Назначение | |-------|---------------|---------| | Библиотекарь | Содержимое документа + ссылки родитель-потомок | Извлечение содержимого, каскадное удаление | | Граф знаний | Ребра родитель-потомок + метаданные | Запросы происхождения, атрибуция фактов | Оба хранилища поддерживают одну и ту же структуру графа. Библиотекарь хранит содержимое, а граф хранит отношения и обеспечивает возможность выполнения запросов для обхода графа. >>>>>>> 82edf2d (New md files from RunPod) ### Основные принципы проектирования 1. **Идентификатор документа как единица потока данных** - Процессоры передают идентификаторы, а не содержимое. Содержимое извлекается из библиотеки, когда это необходимо. <<<<<<< HEAD 2. **Отправка данных только в исходной точке** - Метаданные записываются в граф только один раз при начале обработки, а не повторяются далее по цепочке. ======= 2. **Однократная отправка данных в источнике** - Метаданные записываются в граф один раз при начале обработки, а не повторяются далее по цепочке. >>>>>>> 82edf2d (New md files from RunPod) 3. **Единый шаблон для процессоров** - Каждый процессор следует одному и тому же шаблону: прием/извлечение/создание/сохранение/отправка/передача. 4. **Постепенное построение графа** - Каждый процессор добавляет свой уровень в граф. Полная цепочка происхождения строится постепенно. 5. **Оптимизация после разбиения на фрагменты** - После разбиения на фрагменты сообщения содержат как идентификатор, так и содержимое. Фрагменты небольшие (2-4 КБ), поэтому включение содержимого позволяет избежать ненужных обращений к библиотеке, сохраняя при этом происхождение с помощью идентификатора. ## Задачи реализации ### Изменения в библиотеке #### Текущее состояние Инициирует обработку документа, отправляя идентификатор документа первому процессору. Нет подключения к хранилищу тройных данных - метаданные добавляются к результатам извлечения. <<<<<<< HEAD `add-child-document` создает одноуровневые ссылки "родитель-потомок". ======= `add-child-document` создает одноуровневые ссылки родитель-потомок. >>>>>>> 82edf2d (New md files from RunPod) `list-children` возвращает только непосредственные потомки. #### Необходимые изменения **1. Новый интерфейс: Подключение к хранилищу тройных данных** Библиотекарь должен напрямую отправлять ребра метаданных документа в граф знаний при начале обработки. Добавить клиент/публикатор хранилища тройных данных в сервис библиотеки. При инициации обработки: отправлять метаданные корневого документа в виде ребер графа (один раз). **2. Словарь типов документов** <<<<<<< HEAD Стандартизировать значения `document_type` для дочерних документов: ======= Стандартизировать значения `document_type` для документов-потомков: >>>>>>> 82edf2d (New md files from RunPod) `source` - исходный загруженный документ. `page` - страница, извлеченная из источника (PDF и т.д.). `chunk` - текстовый фрагмент, полученный из страницы или источника. #### Краткое описание изменений интерфейса | Интерфейс | Изменение | |-----------|--------| | Хранилище тройных данных | Новый исходящий канал - отправка ребер метаданных документа | | Инициация обработки | Отправка метаданных в граф перед передачей идентификатора документа | <<<<<<< HEAD ### Изменения в извлечении данных из PDF ======= ### Изменения в извлечении PDF >>>>>>> 82edf2d (New md files from RunPod) #### Текущее состояние Получает содержимое документа (или потоковую передачу больших документов). Извлекает текст из страниц PDF. Передает содержимое страницы в компоновщик. Не взаимодействует с библиотекой или хранилищем тройных данных. #### Необходимые изменения **1. Новый интерфейс: Клиент библиотеки** <<<<<<< HEAD Извлечение данных из PDF должно сохранять каждую страницу как дочерний документ в библиотеке. Добавить клиент библиотеки в сервис извлечения данных из PDF. ======= Извлечение PDF должно сохранять каждую страницу как документ-потомок в библиотеке. Добавить клиент библиотеки в сервис извлечения PDF. >>>>>>> 82edf2d (New md files from RunPod) Для каждой страницы: вызвать `add-child-document` с parent = идентификатор корневого документа. **2. Новый интерфейс: Подключение к хранилищу тройных данных** <<<<<<< HEAD Извлечение данных из PDF должно отправлять ребра "родитель-потомок" в граф знаний. ======= Извлечение PDF должно отправлять ребра родитель-потомок в граф знаний. >>>>>>> 82edf2d (New md files from RunPod) Добавить клиент/публикатор хранилища тройных данных. Для каждой страницы: отправлять ребро, связывающее документ страницы с родительским документом. **3. Изменить формат вывода** Вместо прямой передачи содержимого страницы, передавайте идентификатор документа страницы. Chunker будет извлекать содержимое из хранилища, используя идентификатор. #### Краткое описание изменений интерфейса | Интерфейс | Изменение | |-----------|--------| | Хранилище | Новый исходящий поток - сохранение дочерних документов | | Тройной магазин | Новый исходящий поток - генерация связей родитель-потомок | | Сообщение вывода | Изменение с содержимого на идентификатор документа | <<<<<<< HEAD ### Изменения Chunker ======= ### Изменения в Chunker >>>>>>> 82edf2d (New md files from RunPod) #### Текущее состояние Получает содержимое страницы/текста Разбивает на фрагменты Передает содержимое фрагмента обработчикам на последующих этапах Не взаимодействует с хранилищем или тройным магазином #### Необходимые изменения **1. Изменение обработки входных данных** Вместо содержимого получайте идентификатор документа, извлекайте из хранилища. Добавьте клиент хранилища в сервис Chunker Извлекайте содержимое страницы, используя идентификатор документа **2. Новый интерфейс: Клиент хранилища (запись)** Сохраняйте каждый фрагмент как дочерний документ в хранилище. Для каждого фрагмента: вызывайте `add-child-document` с parent = идентификатор документа страницы **3. Новый интерфейс: Подключение к тройному магазину** Генерируйте связи родитель-потомок для графа знаний. Добавьте клиент/публикатор тройного магазина Для каждого фрагмента: генерируйте связь, связывающую документ фрагмента с документом страницы **4. Изменение формата вывода** Передавайте как идентификатор документа фрагмента, так и содержимое фрагмента (оптимизация после обработки фрагмента). Обработчики на последующих этапах получают идентификатор для отслеживания происхождения + содержимое для работы #### Краткое описание изменений интерфейса | Интерфейс | Изменение | |-----------|--------| | Сообщение ввода | Изменение с содержимого на идентификатор документа | | Хранилище | Новый исходящий поток (чтение + запись) - извлечение содержимого, сохранение дочерних документов | | Тройной магазин | Новый исходящий поток - генерация связей родитель-потомок | | Сообщение вывода | Изменение с содержимого только на идентификатор + содержимое | <<<<<<< HEAD ### Изменения Knowledge Extractor ======= ### Изменения в Knowledge Extractor >>>>>>> 82edf2d (New md files from RunPod) #### Текущее состояние Получает содержимое фрагмента Извлекает тройки и вложения <<<<<<< HEAD Передает в тройной магазин и хранилище вложений ======= Отправляет в тройной магазин и хранилище вложений >>>>>>> 82edf2d (New md files from RunPod) `subjectOf` отношение указывает на верхний уровень документа (а не на фрагмент) #### Необходимые изменения **1. Изменение обработки входных данных** <<<<<<< HEAD Получайте идентификатор фрагмента вместе с содержимым. ======= Получайте идентификатор документа фрагмента вместе с содержимым. >>>>>>> 82edf2d (New md files from RunPod) Используйте идентификатор фрагмента для отслеживания происхождения (содержимое уже включено в соответствии с оптимизацией) **2. Обновление отслеживания происхождения тройками** Связывайте извлеченные тройки с фрагментом (а не с верхним уровнем документа). Используйте реификацию для создания связи, указывающей на связь `subjectOf` отношение: тройка → идентификатор документа фрагмента Первое использование существующей поддержки реификации **3. Обновление отслеживания происхождения вложениями** Связывайте идентификаторы сущностей вложений с фрагментом. Генерируйте связь: идентификатор сущности вложения → идентификатор документа фрагмента #### Краткое описание изменений интерфейса | Интерфейс | Изменение | |-----------|--------| | Сообщение ввода | Ожидается идентификатор фрагмента + содержимое (а не только содержимое) | | Тройной магазин | Используйте реификацию для отслеживания происхождения тройки → фрагмент | <<<<<<< HEAD | Отслеживание происхождения вложениями | Свяжите идентификатор сущности → идентификатор фрагмента | ======= | Отслеживание происхождения вложений | Свяжите идентификатор сущности → идентификатор фрагмента | >>>>>>> 82edf2d (New md files from RunPod) ## Ссылки Отслеживание происхождения во время запроса: `docs/tech-specs/query-time-provenance.md` Стандарт PROV-O для моделирования происхождения Существующие метаданные источника в графе знаний (требуется аудит)