От разнородных данных к онтологическому графу через формализацию и фильтрацию - Towareesh/OntoC4Designer GitHub Wiki

1. Сбор и предобработка данных

Источники:

graph LR
    A[Jira] --> F[Структуризатор]
    B[GitLab] --> F
    C[Notion] --> F
    D[User History] --> F
    E[Интервью] --> F

Этап структуризации:

  • Инструменты: SpaCy + Custom NLP Pipelines
  • Действия:
    def preprocess(raw_data):
        # Нормализация текста
        text = normalize(raw_data)  # "фикс_бага_123 -> Исправить ошибку декодирования"
        
        # Сегментация по источникам
        source_tag = detect_source(raw_data.metadata) 
        
        # Разбивка на атомарные утверждения
        statements = split_into_atomic_statements(text)
        
        return {
            "source": source_tag, 
            "statements": statements,
            "entities": extract_entities(text)
        }
    

2. Формализация через ML

Процесс типизации:

graph TD
    A[Неструктурированный текст] --> B(ML-Классификатор)
    B --> C{Тип}
    C -->|FR| D[Формальное описание]
    C -->|NFR| E[Подтип: Security/Performance/etc]
    C -->|Constraint| F[Техническое ограничение]
    D --> G[База формализованных требований]
    E --> G
    F --> G

Пример вывода ML:

{
  "original": "Система должна обрабатывать 10К RPS",
  "formalized": {
    "type": "NFR",
    "subtype": "Performance",
    "metrics": [
        {"name": "throughput", "value": 10000, "unit": "RPS"}
    ],
    "source": "jira-REQ-123"
}

3. Онтологический граф C4

Структура онтологий:

graph TD
    META["**Метаонтология (ISO 21838)**<br>- Component<br>- Interface<br>- Relation"] 
    
    DOMAIN["**Доменные онтологии**<br>- SystemSoftware<br>- AppSoftware<br>- Tooling"]
    
    SUB["**Субдоменные онтологии**<br>- Security<br>- Scalability<br>- Compliance"]
    
    C4["**C4-Концепты**<br>- Person<br>- System<br>- Container<br>- Component"]
    
    META --> DOMAIN
    DOMAIN --> SUB
    SUB --> C4

Особенности:

  • Каждый C4-элемент представлен как вершина графа
  • Связи = ребра с типами отношений:
    • dependsOn
    • implements
    • constrains
    • conflictsWith

4. Механизм фильтрации графа

Ключевая инновация: Динамическое отключение вершин на основе формализованных требований

Принцип работы:

class OntologyFilter:
    def __init__(self, ontology_graph, requirements):
        self.graph = ontology_graph
        self.reqs = requirements
        
    def apply_filters(self):
        # Шаг 1: Отключение нерелевантных доменов
        if not self.has_system_software_reqs():
            self.graph.disable_domain("SystemSoftware")
            
        # Шаг 2: Активация/деактивация вершин
        for node in self.graph.nodes:
            if self.is_node_required(node):
                node.activate()
            else:
                node.deactivate()  # Скрываем из визуализации
                
        # Шаг 3: Проверка целостности
        self.validate_connections()
        
    def is_node_required(self, node):
        # Правило 1: Соответствие требованиям
        if node.matches_requirements(self.reqs):
            return True
            
        # Правило 2: Обязательные зависимости
        if any(parent.is_active for parent in node.critical_parents):
            return True
            
        return False

5. Визуализация результата

Фильтрованный граф:

graph TD
    A[Пользователь] --> B[Web-приложение]
    B --> C[AuthService]
    C --> D[Database]
    
    style A fill:#9f9,stroke:#333
    style B fill:#9f9,stroke:#333
    style C fill:#9f9,stroke:#333
    style D fill:#9f9,stroke:#333
    
    %% Отключенные элементы
    E[LegacySystem]:::disabled
    F[MessageQueue]:::disabled
    
    classDef disabled fill:#fdd,stroke-dasharray:5,5

Что отображается:

  • Только вершины, для которых выполнены условия:
    1. Прямое упоминание в требованиях
    2. Критическая зависимость от активных элементов
    3. Обязательные системные компоненты (например, БД для авторизации)

Пример сквозного процесса

Входные данные:

[
  {"text": "Поддержка 5000+ одновременных пользователей", "source": "jira/PERF-1"},
  {"text": "Аутентификация через OAuth2.0", "source": "gitlab/AUTH-5"},
  {"text": "Запрет использования облачных БД", "source": "constraint/security-7"}
]

После формализации:

[
  {"type": "NFR", "subtype": "Scalability", "target": 5000, "unit": "users"},
  {"type": "FR", "component": "AuthService", "interface": "OAuth2.0"},
  {"type": "Constraint", "category": "Security", "rule": "no-cloud-db"}
]

Фильтрация графа:

  1. Активируются:

    • Load Balancer (из Scalability)
    • AuthService (из FR)
    • OnPremiseDatabase (из Constraint)
  2. Отключаются:

    • CloudDatabase
    • BasicAuthModule
    • LegacyAuthGateway

Итоговый граф:

graph LR
    U[Пользователь] --> LB[Load Balancer]
    LB --> A[AuthService]
    A --> DB[(On-Premise DB)]
    
    %% Отключенные элементы
    CDB[(Cloud DB)]:::disabled
    style CDB stroke-dasharray:5,5

Преимущества подхода

  1. Автоматическая релевантность: Граф всегда соответствует актуальным требованиям
  2. Консистентность: Невозможно получить противоречивую архитектуру
  3. Трассируемость: Каждая вершина связана с породившими её требованиями
  4. Адаптивность: Изменения требований = автоматическое обновление графа
  5. Визуальная ясность: Только нужные элементы без "информационного шума"

Техническая реализация:

  • Backend: Python + RDFLib + NetworkX
  • ML: SpaCy + Scikit-learn
  • Визуализация: D3.js + GraphViz
  • Хранение онтологий: OWL/RDF в GraphDB
graph LR
    A[Источники данных] --> B[Структуризатор]
    B --> C[ML-Классификатор]
    C --> D[Формальные требования]
    D --> E[Онтологический движок]
    E --> F[Фильтрованный граф]
    F --> G[Визуализатор]

Этот подход создает "живую" архитектурную модель, где граф становится динамическим отражением проекта, а не статичным артефактом.