@startuml "NTR Text Fragmentation Architecture" ' Использование CSS-стилей вместо skinparams ' Легенда legend Легенда | Цвет | Описание | | Зеленый | Модели данных | | Голубой | Стратегии чанкинга | | Красный | Основные компоненты | endlegend ' Разделение на пакеты package "models" { class LinkerEntity <> { + id: UUID + name: str + text: str + in_search_text: str | None + metadata: dict + source_id: UUID | None + target_id: UUID | None + number_in_relation: int | None + type: str + serialize(): LinkerEntity + {abstract} deserialize(data: LinkerEntity): Self } class Chunk <> extends LinkerEntity { + chunk_index: int | None } class DocumentAsEntity <> extends LinkerEntity { } note right of LinkerEntity Базовая сущность для всех элементов системы. in_search_text определяет текст, используемый при поиске, если None - данная сущность не должна попасть в поиск и используется только для вспомогательных целей. end note } package "chunking_strategies" as chunking_strategies { abstract class ChunkingStrategy <> { + {abstract} chunk(document: ParsedDocument, doc_entity: DocumentAsEntity): list[LinkerEntity] + dechunk(entities: list[LinkerEntity], links: list[LinkerEntity]): str } package "specific_strategies" { class FixedSizeChunkingStrategy <> extends chunking_strategies.ChunkingStrategy { + chunk(document: ParsedDocument, doc_entity: DocumentAsEntity): list[LinkerEntity] + dechunk(entities: list[LinkerEntity], links: list[LinkerEntity]): str } class SentenceChunkingStrategy <> extends chunking_strategies.ChunkingStrategy { + chunk(document: ParsedDocument, doc_entity: DocumentAsEntity): list[LinkerEntity] + dechunk(entities: list[LinkerEntity], links: list[LinkerEntity]): str } class NumberedItemsChunkingStrategy <> extends chunking_strategies.ChunkingStrategy { + chunk(document: ParsedDocument, doc_entity: DocumentAsEntity): list[LinkerEntity] + dechunk(entities: list[LinkerEntity], links: list[LinkerEntity]): str } } note right of ChunkingStrategy Базовая реализация dechunk сортирует чанки по chunk_index. Стратегии могут переопределить, если им нужна специфическая логика сборки end note } package "core" { class Destructurer <> { + __init__(document: ParsedDocument, strategy_name: str) + configure(strategy_name: str, **kwargs) + destructure(): list[LinkerEntity] } class InjectionBuilder <> { + __init__(entities: list[LinkerEntity], config: dict) + register_strategy(doc_type: str, strategy: ChunkingStrategy) + build(filtered_entities: list[LinkerEntity]): str - _group_chunks_by_document(chunks, links): dict } note right of Destructurer Основной класс библиотеки, используется для разбиения документа на чанки и вспомогательные сущности. В полученной конфигурации содержатся in_search сущности и множество вспомогательных сущностей. Предполагается, что первые будут отфильтрованы векторным или иным поиском, а вторые можно будет использовать для обогащения и сборки итоговой инъекции в промпт. end note note right of InjectionBuilder Класс-единая точка входа для сборки итоговой инъекции в промпт. Принимает в себя все сущности и конфигурацию в конструкторе, а в методе build принимает отфильтрованные сущности. Может частично делегировать сборку стратегиям для специфических типов чанкинга. end note } ' Композиционные отношения core.Destructurer --> chunking_strategies.ChunkingStrategy core.InjectionBuilder --> chunking_strategies.ChunkingStrategy ' Отношения между компонентами chunking_strategies.ChunkingStrategy ..> models ' Дополнительные отношения core.InjectionBuilder ..> models.LinkerEntity core.Destructurer ..> models.LinkerEntity @enduml