GraphRAG: Чому векторний пошук розривається на рівні Corpus (Українська (Ukrainian))

GraphRAG: Чому векторний пошук розривається на рівні Corpus

Friday, 26 December 2025

//

20 minute read

Ваша система RAG є чудовою у питаннях " needle ": отримання декількох відповідних шматків і синтезу даних. У програмі передбачено два типових типи запитів:

  • Відтворення пам'яті"Яка головна тема на цьому корпусі?"
  • З' єднаний"Як Х відносяться до Y через різні документи?"

На них не відповідає жодна частинка. coveres + collectioning + linkage.

Чому не вдається виконати векторний пошук:

  • Коштовності. незалежно за подібною до запиту
  • Подібність є дуже важливою, але ні загальне покриття
  • Вбудовані вловлюють "які звуки схожі," а не "що з'єднується з тим, що"

Ви можете присилувати це за допомогою стимуляції та остаточної обробки, але врешті-решт ви відбудуєте графічне рішення.

Головне розуміння: GraphRAG змінює модуль отримання. Для питань з корпуса вам не потрібні " ті самі шматки ," вам потрібні пов'язані поняття спільноти (і їх резюме), таким чином модель бачить структуру, а не фрагменти.

GraphRAG походить з Microsoft Research's папір і доступний як Реалізація з відкритим кодомВін продовжує пошук конкретних питань, але додає графік знань та суспільні підсумки для міркування про корпус-рівень.

Якщо не використовувати GraphRAG

Перед тим, як пірнати всередину, давайте прояснимо, коли це перевершить:

  • Набори маленьких документів (під ~50 документами): просто використовувати векторний пошук
  • Тільки питання "Як я": GraphRAG не допоможе
  • Однорідний вміст (без різноманітності сутностей): не існує структури графіка для використання
  • Коефіцієнт вартості: Для індексування потрібно багато викликів LLM

Якщо ваші користувачі задають лише конкретні питання, тримайтеся Семантичний пошук. GraphRAG світить, якщо користувачі потребують даних велика картинкаІ це менша аудиторія, ніж пропонують продавці.

Вступ

Навігація серією: Це частина 6 серії RAG:

Протягом цієї серії ми створили все складніші системи RAG, ми почали з базового векторного пошуку, додали гібридне ключове слово+семантичне отримання і інтегроване автоіндексування. подібні шматки, не з' єднані концепції. for Корпус- рівень Вам потрібна структура запитань (теми, що вміщають багато документів).

Рекомендований шлях: Якщо ви вже працювали з локальним пошуком на основі Qdrant (так само, як і у нас), прототип з трамвайом Python для перевірки значення, утримуйте вектори для локального пошуку і додайте невибагливий графік для запитів на загальні/ DRIFT. Підіть " Повноцінну GraphRAG " лише після того, як ви доведете, що користувачі задають ці питання.

Проблема з чистим векторним RAG

Давайте я покажу вам конкретний приклад.

Що добре робить векторний RAG

Питання: "Як мені використати HTMX з альпійськими.js?"

Векторний процес RAG:

  1. Вбудувати питання: [0.234, -0.891, 0.567, ...]
  2. Знайти подібні шматки у Qdrant
  3. Return top- K- matchs about HTMX and Billian.js
  4. Програма для синтезу LLM відповідає з цих шматків

Це працює, тому що питання та зміст мають значення семантично подібнаВбудовування вловлює цю подібність.

// This is what our current SemanticSearchService does
var embedding = await _embeddingService.GetEmbeddingAsync(query);
var results = await _qdrantService.SearchAsync(
    collectionName: "blog_posts",
    queryVector: embedding,
    limit: 10
);
// Returns chunks about HTMX, Alpine.js, frontend patterns

Векторна боротьба

Питання: "Які основні технології я пишу і як вони пов'язані?"

Що повертає вектор RAG:

Result 1: "HTMX makes it easy to add AJAX to your pages..."
Result 2: "Docker Compose orchestrates multiple containers..."
Result 3: "PostgreSQL's full-text search is surprisingly capable..."
Result 4: "Alpine.js provides reactive state management..."

Він згадує Докера, PostgreSQL, HTMX, ONNX... але не згруповує їх і не пояснює як вони з'єднуються.

Проблема: це питання вимагає агрегація і розуміння відносин по всему корпусу.

  • Визначити всі згадані технології
  • Зрозуміти, які використовуються разом
  • Згрупувати їх у зв' язані теми

Подібність вектора одна не дасть вам цього результату. Якщо ви спробуєте латати її за допомогою запиту, ви завершите оновлення графіка.

Введіть GraphRAG

GraphRAG Microsoft Research's розв'язання цієї проблеми. Папір GraphRAG ідентифіковано два типи запитів, які не працюють з baseline RAG (feeling і з' єднання) і створив систему, яка б доручала їм завдання.

Замість вбудовування шматків, GraphRAG будує a графік знання що захоплює об'єкти і їх взаємозв'язки, а потім об'єднує їх у спільноти з резюме.

Як працює GraphRAG

Лінія труби на перший погляд:

  • Індексування: Шматки → об'єкти/реляція → Діаграма → Суспільства → Узагальнення
  • Запит: Локальний =} г. +Грубний =завершення спільноти} ЦИФТ = шляхи + Узагальнення

GraphRAG додає декілька компонентів у каналі SRAG, впорядкований за трьома категоріями:

  1. Витягання (міста + взаємозв' язки)
  2. Збирання графів (Зберігання графів)
  3. Сумарналізація (виявлення спільноти + ієрархія)
flowchart TB
    subgraph "Traditional RAG (What We Have)"
        A[Documents] --> B[Chunks]
        B --> C[Embeddings]
        C --> D[Vector Store]
    end

    subgraph "GraphRAG Additions"
        B --> E[Entity Extraction]
        E --> F[Relationship Extraction]
        F --> G[Knowledge Graph]
        G --> H[Community Detection]
        H --> I[Community Summaries]
    end

    subgraph "Query Time"
        J[User Query] --> K{Query Type?}
        K -->|Specific| L[Local Search]
        K -->|Global| M[Global Search]
        K -->|Hybrid| N[DRIFT Search]

        D --> L
        G --> L
        I --> M
        G --> N
        I --> N
    end

    style E stroke:#f9f,stroke-width:2px
    style H stroke:#bbf,stroke-width:2px
    style I stroke:#9f9,stroke-width:2px

Крок 1: Видобування сутності

LLM читає кожен шматок і екстракт Елементи (Те, що обговорюється)

Chunk: "Docker Compose makes it easy to define multi-container applications.
        I use it with PostgreSQL for my blog's database layer."

Extracted Entities:
- Docker Compose (technology)
- PostgreSQL (database)
- blog (project)
- database layer (concept)

Крок 2: Видобування зв'язків

Те саме LLM визначає, як пов' язані між собою елементи:

Relationships:
- Docker Compose --[used_with]--> PostgreSQL
- blog --[has_component]--> database layer
- PostgreSQL --[implements]--> database layer

Крок 3. Будівництво графів знання

Всі об' єкти і зв' язки формують графік:

graph LR
    subgraph "Frontend Cluster"
        HTMX[HTMX]
        Alpine[Alpine.js]
        Tailwind[Tailwind CSS]
    end

    subgraph "Infrastructure Cluster"
        Docker[Docker]
        Compose[Docker Compose]
        Postgres[PostgreSQL]
        Qdrant[Qdrant]
    end

    subgraph "AI/ML Cluster"
        ONNX[ONNX Runtime]
        Embeddings[Embeddings]
        RAG[RAG]
    end

    HTMX -->|used_with| Alpine
    HTMX -->|styled_by| Tailwind
    Alpine -->|styled_by| Tailwind

    Docker -->|orchestrated_by| Compose
    Compose -->|runs| Postgres
    Compose -->|runs| Qdrant

    ONNX -->|generates| Embeddings
    Embeddings -->|stored_in| Qdrant
    RAG -->|uses| Embeddings
    RAG -->|uses| Qdrant

    style HTMX stroke:#f9f
    style Docker stroke:#bbf
    style RAG stroke:#9f9

Крок 4: Виявлення спільноти (Леден Алгоритм)

The Алгоритм Лейдена скупчення щільно з' єднаних вузлів у спільноті. стабільний Групи, щоб підсумувати і отримати; спільноти стають вашими одиницями отримання для глобальних запитів.

  • Суспільство 1: "Frontend Stack" (HTMX, Billian.js, Tailwain)
  • Суспільство 2: "Contain Infraструктура" (Docker, Compose, PostgreSQL, Qdrant)
  • Суспільство 3: "Прокрутка RAG" (ONNX, Вмонтовані, QDrant, RAG)

Зауважте, як Qdrant з'являється у двох спільнотах: це мости інфраструктури і AI/ML.

Крок 5. Суспільство

LLM створює резюме для кожної громади на кожному рівні ієрархії:

Community 1 Summary (Frontend Stack):
"The frontend approach combines HTMX for server-driven interactivity
with Alpine.js for client-side state management, styled using Tailwind CSS.
This stack prioritizes HTML-first development with minimal JavaScript,
focusing on progressive enhancement over SPA complexity."

Community 2 Summary (Container Infrastructure):
"The blog runs on Docker Compose, orchestrating PostgreSQL for persistent
storage, Qdrant for vector search, and the ASP.NET Core application.
This containerized architecture enables consistent local development
and production deployment."

Режими запиту

GraphRAG складається з трьох режимів запиту, кожен з яких оптимізовано для різних типів питань:

Загальний пошук

Найкраще для: "Які основні теми?" - "Розміряй ключові теми."

Використовує підсумки спільноти (не окремих шматків) для відповіді на питання, що викликають сенсацію:

Query: "What technologies does this blog cover most?"

Process:
1. Retrieve all community summaries
2. Map: Ask LLM to extract technology themes from each summary
3. Reduce: Combine partial answers into final response

Response:
"The writing centres on three technology clusters:
1. **Frontend Development** - HTMX, Alpine.js, Tailwind CSS for minimal-JS web UIs
2. **AI/ML Infrastructure** - RAG pipelines, ONNX embeddings, vector search with Qdrant
3. **DevOps/Containerization** - Docker, PostgreSQL, ASP.NET Core deployment"

Локальний пошук

Найкраще для: "Як мені налаштувати X?" "Яким є Y?"

Об' єднує граф, фокусований на елементі з традиційним векторним пошуком:

Query: "How do I use Qdrant with ONNX embeddings?"

Process:
1. Identify entities in query: Qdrant, ONNX, embeddings
2. Retrieve graph neighborhood around those entities
3. Also retrieve vector-similar chunks
4. Combine into rich context for LLM

Response includes:
- Direct relationships (ONNX generates embeddings stored in Qdrant)
- Related entities (all-MiniLM-L6-v2 model, cosine similarity)
- Specific code examples from vector-retrieved chunks

DRIFT пошук

Найкраще для: "Як Х відносяться до Y?" - "Порівняйте А і Б."

DRIFT- пошук (Dynamic Dinking and Inference with Flexible Traversal), як описано у документації GraphRAG, об' єднує локальний пошук з контекстом спільноти. Він все ще використовує LM логічні аргументи над отриманим структурним контекстом (не магічним обчисленням), але структура допомагає LLM бачити зв' язки, які він пропускає з плоскими шматками.

Query: "How do the frontend and backend technologies connect?"

Process:
1. Start with entities: HTMX, ASP.NET Core
2. Traverse graph to find connection paths
3. Include community summaries for context
4. Generate answer showing the full picture

Response:
"HTMX makes requests to ASP.NET Core endpoints, which query PostgreSQL
and Qdrant. The connection flows through the API layer, where endpoints
return HTML fragments that HTMX swaps into the DOM. Alpine.js handles
client-side state for interactive components like search typeahead."

Порівнюючи GraphRAG з нашою сучасною системою

Давайте нанесемо GraphRAG концепції до того, що ми вже маємо. Mostlylucid.SemanticSearch:

♪00} Поточна система} GraphRAG} |-----------|---------------|---------------------| | Вбудовані Д_ Д. Х. (all-MiniLM-L6- v2)}Те (або OpenAI) | Сховище векторів ♪ Qdance} Qdent / LanceDB} | Видобування сутності ♪ None ♪ LLM- permission ♪ | Графік знання ♪ None} Діаграма бази даних / in- memmory} | Виявлення громади Алгоритм "Немає" | Запит: специфічний | SemanticSearchService.SearchAsync() ♪ Local Sear ♪ | Запит: загальний } Не підтримується} Глобальний пошук}

Поточна реалізація керує Локальний пошук добре. GraphRAG додасть Загальний пошук і DRIFT пошук Можливості.

// What we have today (Local Search equivalent)
public async Task<List<SearchResult>> SearchAsync(string query, int limit = 10)
{
    var embedding = await _embeddingService.GetEmbeddingAsync(query);
    return await _qdrantService.SearchAsync("blog_posts", embedding, limit);
}

// What GraphRAG would add
public async Task<string> GlobalSearchAsync(string query)
{
    // 1. Retrieve community summaries (not chunks)
    var summaries = await _graphService.GetCommunitySummariesAsync();

    // 2. Map: Extract relevant themes from each summary
    var partialAnswers = await Task.WhenAll(
        summaries.Select(s => _llm.ExtractThemesAsync(query, s))
    );

    // 3. Reduce: Combine into final answer
    return await _llm.SynthesizeAsync(query, partialAnswers);
}

Наближається впровадження

Існує три способи додати GraphRAG до існуючої системи.

Варіант 1: Сторонна машина Python (рекомендовано для Exploration)

Запустити Microsoft' GraphRAG як окрему службу:

# docker-compose.graphrag.yml
services:
  graphrag:
    build:
      context: ./graphrag
    volumes:
      - ./data/input:/app/input
      - ./data/output:/app/output
    environment:
      - OPENAI_API_KEY=${OPENAI_API_KEY}

  graphrag-api:
    build:
      context: ./graphrag-api
    ports:
      - "8001:8000"
    depends_on:
      - graphrag
// GraphRagClient.cs - Call from ASP.NET Core
public class GraphRagClient
{
    private readonly HttpClient _http;

    public GraphRagClient(HttpClient http)
    {
        _http = http;
        _http.BaseAddress = new Uri("http://graphrag-api:8000");
    }

    public async Task<string> GlobalSearchAsync(string query)
    {
        var response = await _http.PostAsJsonAsync("/query/global", new { query });
        var result = await response.Content.ReadFromJsonAsync<GraphRagResponse>();
        return result.Answer;
    }

    public async Task<string> LocalSearchAsync(string query)
    {
        var response = await _http.PostAsJsonAsync("/query/local", new { query });
        var result = await response.Content.ReadFromJsonAsync<GraphRagResponse>();
        return result.Answer;
    }
}

Прос: Використовувати реалізацію битви Microsoft, швидко для прототипу Збори: Залежність від Python, вартість LLM для індексування, обміну міжпроцесорами

Варіант 2:. NET рідний (Дорожній шлях)

Створити ключові компоненти у C#. Шаблони видобування на основі BERT і Ollama з DocSummarizer так само й тут.

Видобування сутності

Запитувати LLM, щоб ідентифікувати речі (міста) для кожного шматка об' єктів, що структуруються, а не теми вільної форми:

public async Task<List<Entity>> ExtractEntitiesAsync(string chunk)
{
    var prompt = $"""
        Extract entities from this text. Return JSON array.
        Types: technology, concept, project, person, organization
        Text: {chunk}
        Format: [{{"name": "Docker", "type": "technology"}}]
        """;

    var response = await _ollama.GenerateAsync(prompt);
    return JsonSerializer.Deserialize<List<Entity>>(response);
}

Вимоги для виробництва: Вивід LLM JSON will break. Це не є обов' язковим затвердженням. Вам потрібен такий:

  • Покоління, пов' язане з схемою (Ольяма) format: jsonДзвінок функції OpenAI)
  • Повторні петлі з перепочинком (виявлення неправильно сформованого JSON, попросити LLM виправити його)
  • Незахищене видобування (набір шаблонів для спільних типів сутностей)

LLM є пробабілістичним; ваш трубопровод не повинен бути.

Видобування зв'язків

Після того, як у вас з' являться об' єкти, запитайте LLM, як вони з' єднуються:

public async Task<List<Relationship>> ExtractRelationshipsAsync(
    string chunk, List<Entity> entities)
{
    var names = string.Join(", ", entities.Select(e => e.Name));
    var prompt = $"""
        Given entities: {names}
        Extract relationships. Return JSON array.
        Text: {chunk}
        Format: [{{"source": "Docker", "target": "PostgreSQL", "rel": "runs"}}]
        """;

    return JsonSerializer.Deserialize<List<Relationship>>(
        await _ollama.GenerateAsync(prompt));
}

Сховище графіка з нормалізації сутності

Найбільший практичний біль - псевдоніми сутностей: " ASP. NET Core ," " ASP. NET " і " aspnetcore " мають належати до одного вузла. Просте нормалізація допомагає:

public class KnowledgeGraph
{
    private readonly Dictionary<string, Entity> _entities = new();
    private readonly List<Relationship> _relationships = new();

    public void AddEntity(Entity entity)
    {
        var key = Normalise(entity.Name);  // "ASP.NET Core" → "aspnetcore"
        _entities[key] = entity;
    }

    private string Normalise(string name) =>
        name.ToLowerInvariant().Replace(".", "").Replace("-", "").Trim();
}

Для серйозного використання розгляньте дебдуляцію сутностей, засновану на вбудовуваннях: якщо назви двох сутностей мають подібні вбудовування, то вони, ймовірно, однакові.

Продукти з болем. (Станота графа залежить від якості графіка):

  • Таблиці синонімів: підтримувати канонічні назви та відомі псевдоніми
  • Керування схемою взаємозв' язку: Межа дозволяла наперед розподіляти типи галюцинацій
  • Оцінка довіри + Обрізання: Не всі виділені зв'язки однаково надійні
  • Нарощувальне переекспонування: під час оновлення документів вам слід латати графік, а не перезібрати його

Граф Traversal

Пошук пов' язаних об' єктів - це перший пошук з шириною:

public List<Entity> GetNeighbors(string entityName, int depth = 1)
{
    var result = new HashSet<Entity>();
    var queue = new Queue<(string Name, int Depth)>();
    queue.Enqueue((Normalise(entityName), 0));

    while (queue.Count > 0)
    {
        var (name, d) = queue.Dequeue();
        if (d >= depth) continue;

        // Find all entities connected to this one
        var neighbours = _relationships
            .Where(r => Normalise(r.Source) == name || Normalise(r.Target) == name)
            .SelectMany(r => new[] { r.Source, r.Target });

        foreach (var neighbour in neighbours)
            if (_entities.TryGetValue(Normalise(neighbour), out var entity))
                if (result.Add(entity))
                    queue.Enqueue((Normalise(neighbour), d + 1));
    }
    return result.ToList();
}

Виявлення громади

Це базова лінія з'єднаних партнерів, неDescription of a condition. Do not translate key words (# V1S #, # V1 #,) full Leiden. Лейден оптимізує модульність (довгі внутрішні з' єднання, далекі зовнішні). Для належної реалізації, скористайтеся бібліотекою графів або портуйте алгоритм.

public List<Community> DetectCommunities(KnowledgeGraph graph)
{
    // Connected components: group everything reachable together
    var visited = new HashSet<string>();
    var communities = new List<Community>();

    foreach (var entity in graph.GetAllEntities())
    {
        if (visited.Contains(entity.Name)) continue;
        
        // BFS to find all connected entities
        var community = new Community();
        var queue = new Queue<string>();
        queue.Enqueue(entity.Name);

        while (queue.Count > 0)
        {
            var name = queue.Dequeue();
            if (!visited.Add(name)) continue;
            community.Entities.Add(graph.GetEntity(name));
            foreach (var neighbor in graph.GetNeighbors(name, depth: 1))
                queue.Enqueue(neighbor.Name);
        }
        communities.Add(community);
    }
    return communities;
}

Сумарна сума громади

Кожна спільнота отримує резюме щодо своєї теми. Саме це і є призначенням пункту меню Загальні результати пошуку:

public async Task<string> SummarizeCommunityAsync(Community community)
{
    var entities = string.Join("\n", 
        community.Entities.Select(e => $"- {e.Name}: {e.Description}"));
    
    var prompt = $"""
        Summarize what unites these concepts (2-3 sentences):
        {entities}
        """;

    return await _ollama.GenerateAsync(prompt);
}

Варіант 3: Гібрид (Прагматична середня земля)

Рекомендуємо вам це зробити, якщо у вас вже є робочий векторний пошук. Тримайте Qdrant для локального пошуку, додайте невибагливий шар графу для запитів Global/ DRIFT.

Класифікація запиту

По-перше, визначте, що це за питання:

// WARNING: Toy heuristic for illustration only.
// In production, use a classifier prompt or few-shot rules and log misroutes.
private QueryMode ClassifyQuery(string query)
{
    var q = query.ToLowerInvariant();
    
    if (q.Contains("main theme") || q.Contains("summarize") || q.Contains("what topics"))
        return QueryMode.Global;
    
    if (q.Contains("relate") || q.Contains("connect") || q.Contains("compare"))
        return QueryMode.Drift;
    
    return QueryMode.Local;
}

Локальний пошук (покращений)

Використовувати існуючий векторний пошук, за бажання, збалансований з контекстом графу:

private async Task<string> LocalSearchAsync(string query)
{
    // Existing semantic search (what we have today)
    var chunks = await _semanticSearch.SearchAsync(query, limit: 10);

    // NEW: Enrich with related entities from graph
    var entities = await _graphService.ExtractEntitiesFromQueryAsync(query);
    var related = await _graphService.GetEntityContextAsync(entities);

    return await _llm.GenerateAsync(query, FormatContext(chunks, related));
}

Загальний пошук (Нова можливість)

Усунення карти через резюме спільноти (не потрібен векторний пошук):

private async Task<string> GlobalSearchAsync(string query)
{
    var summaries = await _graphService.GetAllCommunitySummariesAsync();

    // Map: Extract relevant info from each community
    var partials = await Task.WhenAll(
        summaries.Select(s => _llm.ExtractRelevantInfoAsync(query, s)));

    // Reduce: Combine into final answer
    return await _llm.SynthesizeAsync(query, partials.Where(p => !string.IsNullOrEmpty(p)));
}

Пошук DRIFT (концентраційні запити)

Об' єднати локальні результати з контекстом спільноти для питань " Як X пов' язано з Y ":

private async Task<string> DriftSearchAsync(string query)
{
    var localResults = await LocalSearchAsync(query);
    
    var entities = await _graphService.ExtractEntitiesFromQueryAsync(query);
    var communities = await _graphService.GetCommunitiesForEntitiesAsync(entities);
    var themes = string.Join("\n", communities.Select(c => c.Summary));

    return await _llm.GenerateAsync(
        $"Question: {query}\n\nDetails:\n{localResults}\n\nBroader themes:\n{themes}",
        systemPrompt: "Synthesize the details with the thematic context.");
}

Обмірковування вартості і швидкодії

GraphRAG має значні компроміси у порівнянні з чистим векторним RAG.

Координати

Витрати на видобування сутностей та реляцію значно відрізняються за моделями, швидким дизайном і розміром шматка. Як грубе збільшення порядку, припускається: один або два виклики LLM на шматок плюс менша кількість викликів для суспільних узагальнень.

ДІТЧІЧНА ТЕРРАГІЯ |-----------|------------|----------| | Вмонтовані 1 call/chunk | Видобування сутності/ об' єднання ♪ None} 1-2 LLM calls/chunk} | Сумарна сума громади ♪ None} 1 LLM call/comunity}

Загалом для корпусів у 1000 блогах, кожен з яких складається з 5 шматків (5 000 шматків), індексування лише для вектора - це, по суті, витрати на вбудовування. GraphG додає тисячі викликів LLM для видобування і узагальнення. Точна вартість залежить від вашого вибору моделі і негайної ефективності; використання локальних моделей (Ollama з ламою 3. 2 або подібною) повністю усуває вартість API, яка є рекомендованим підходом до експериментування.

Вартість запиту

} PAH TOG GraphRAG локальний GraphRAG global} |------------|------------|----------------|-----------------| | Векторний пошук 1 call * 1 call = 0 ceps ♪ | Графопочервоний + 0 * 1-2 + 0} | Виклики LLM + 1 (карта) + 1 (відновлення)

Загальний пошук дорожчий за кожен запит, але він відповідає на питання, які локальні результати пошуку просто неможливі. Крім того, ви можете кешувати загальні відповіді і відновлювати їх, лише якщо зміни у кодуванні.

Режими помилок GraphRAG

GraphRAG - це не магія. Обережно:

  • Помилки видобування: LLM пропускають сутності або галюцинативні відносини
  • ПсевдонімиXLIFF mark type: " ASP. NET Core " проти " ASP. NET " і " aspnetcore " стають окремими вузлами
  • Граф- дрейф: Під час оновлення документів графік може стати застарілим
  • Підсумки суспільства стають застарілими: Сумки не повторюються автоматично, коли об' єкти змінюються

Нормалізація сутності - це найбільший практичний біль.

  • Канонічні назви + альтернативні назви
  • Нормалізація з урахуванням регістру і пунктуації
  • Дебдуляція об' єкта, заснованого на вбудовуваннях

Інтеграція з нашим пошуком блогу

Ось як GraphRAG може покращити існуючий семантичний пошук блогу:

Поточний потік

User types in search → SemanticSearchService → Qdrant → Results

Розширений потік

Маршрути маршрутів класифікаторів надсилають запити до різних стратегій пошуку. Ось як: global query потоки води - зауважте, що він ніколи не торкається сховища векторів:

sequenceDiagram
    participant U as User
    participant API as Search API
    participant C as Query Classifier
    participant G as Global Search
    participant KG as Knowledge Graph

    U->>API: "What topics does this blog cover?"
    API->>C: Classify query
    C-->>API: QueryMode.Global

    API->>G: GlobalSearch(query)
    G->>KG: GetCommunitySummaries()
    KG-->>G: [Frontend, Infrastructure, AI/ML]
    G->>G: MapReduce over summaries
    G-->>API: Synthesized answer

    API-->>U: "The blog covers three main areas..."

Порівняти це з a локальний запит, який поєднує векторний пошук з контекстом графіка для багатших відповідей:

sequenceDiagram
    participant U as User
    participant API as Search API
    participant C as Query Classifier
    participant L as Local Search
    participant Q as Qdrant
    participant KG as Knowledge Graph

    U->>API: "How do I use HTMX?"
    API->>C: Classify query
    C-->>API: QueryMode.Local

    API->>L: LocalSearch(query)
    L->>Q: Vector search
    Q-->>L: Relevant chunks
    L->>KG: GetEntityContext("HTMX")
    KG-->>L: Related: Alpine.js, Tailwind, ASP.NET
    L-->>API: Answer with rich context

    API-->>U: "HTMX is used with Alpine.js for..."

Різниця між ключовими питаннями: загальна сукупність запитів про спільноту (теми рівня corpus), а локальні запити отримують окремі шматки, збагачені зв' язками сутностей.

Проста альтернатива: GraphRAG все ще є дослідницьким інструментом: видобування сутностей, побудови графів і виявлення спільноти додає до нього значні складності і вартість LLM. У більшості випадків, Вбудовування ERT + ключові слова BM25 Это то, что работает лучше. Коді джерела використовується для роботи з кодовим інтелектом, і що DocSummarizer використовується для резюме документів. Шаблон: гібридне отримання роботи з релевантністю; інструмент керування LLM компіляція, не прийняття рішеньВи отримаєте 80% прибутку з 20% складності.

Впровадження ескізу

Програмний інтерфейс простий: класифікувати запит, маршрут до відповідного обробника:

[HttpGet("api/search")]
public async Task<IActionResult> Search([FromQuery] string q, [FromQuery] string mode = "auto")
{
    if (mode == "auto")
        mode = ClassifyQuery(q);

    // global/local return synthesised answers; default returns raw search results
    return mode switch
    {
        "global" => Ok(await _graphRag.GlobalSearchAsync(q)),  // synthesised answer
        "local" => Ok(await SearchWithGraphContext(q)),        // answer with citations
        _ => Ok(await _semanticSearch.SearchAsync(q))          // raw ranked results
    };
}

Векторний пошук і пошук у графах доповнюють один одного. Використовуйте вектори для питань " як я " і графіки " для питань " які теми ."

Висновки

GraphRAG розширює RAG від " знайти подібні шматки " до " розуміння структури знання ." Це не заміна для векторного пошуку; це покращення, яке вмикає нові типи запитів.

Що GraphRAG додає:

  • Сутність і взаємозв'язок
  • Побудова графу знань
  • Виявлення спільноти і ієрархічні резюме
  • Глобальний пошук запитань, що викликають сенсацію
  • ДРІФТ У пошуках об'єднуючих міркувань

Коли ним користуватися:

  • У вас є значна збірка документів
  • Користувачі задають питання типу " які теми "
  • Ваш зміст має чіткі об'єкти та зв' язки
  • Ви хочете автоматично налаштувати з' єднання

Шлях впровадження:

  1. По - перше, запитайте себе: чи вам насправді це потрібно? БЕРТ + BM25 гібридних механізмів для отримання даних більшості випадків використання
  2. Якщо так, прототип з Python для перевірки значення
  3. Створити. NET рідне, якщо матерія/ вартість вартості
  4. Використовувати локальні LLM (Ollama) для керування витратами індексування

Ресурси

Офіціальний GraphRAG:

Серія RAG:

Проста альтернатива (BERT + BM25):

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.