# 图图RAG:为什么矢量搜索断开于 Corpus 水平

<datetime class="hidden">2025-12-26T12:00</datetime>

<!-- category -- ASP.NET, Semantic Search, ONNX, Qdrant, Machine Learning, Vector Search, RAG -->
您的 RAG 系统非常擅长“ 需要” 问题 : 检索几个相关块, 合成一个答案 。 它与两种常见的查询类型相对应 :

- **预警**:“这本法典的主要主题是什么?”
- **连接连接**:“ X 在不同文档中与 Y 有何关联?”

任何部分都无法回答,它们需要 **+ 集群+链接**.

**这里的矢量搜索失败的原因 :**

- 它排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列,排在一列 **独立独立** 与查询相似
- 具有相关性,而非 **全球覆盖**
- 嵌入式捕捉“ 听起来相似的东西” 而不是“ 连接到什么的东西” 。

你可以用催化和后处理来强迫它, 但你最终会重建一个图形形的解决方案。

**关键的洞察力:** GraphRAG 更改检索单元。 对于文体问题, 您不希望“ 顶K 类似块块 ” ; 您想要 **连接连连的概念界** (及其摘要),所以模型看到的是结构,而不是碎片。

[图图RAG](https://microsoft.github.io/graphrag/) 来自微软研究公司 [纸张](https://arxiv.org/pdf/2404.16130) 可供调用 [开放源实施](https://github.com/microsoft/graphrag)它保持矢量对具体问题的搜索,但增加了知识图和社区摘要,以便进行人身推理。

## 不使用 Gragrag 时

在潜入之前,让我们先弄清楚 什么时候这太过分了:

- **小文档集** (在~50文档下):仅使用矢量搜索
- **只有"我该如何"的问题**: Gragrag帮不上忙
- **统一内容** (无实体种类):没有图表结构可加以利用
- **成本限制**:索引化需要许多LLLM电话

如果您的用户仅询问特定问题,请与 [语义搜索](/blog/semantic-search-with-onnx-and-qdrant)。当用户需要时,图形RAG会闪耀 *大全图*这是比销售商建议的要小的观众

# 一. 导言 导言 导言 导言 导言 导言 一,导言 导言 导言 导言 导言 导言

**系列导航:** 这是RAG系列第6部分:

- [第1部分:起源和基本要点](/blog/rag-primer) - 历史、动机和核心概念
- [第2部分:建筑和内部](/blog/rag-architecture) - 技术深层潜水
- [第3部分:在实务中协助通知书](/blog/rag-practical-applications) - 建立实际系统
- [第4a部分:ONNX和Qdrant执行](/blog/semantic-search-with-onnx-and-qdrant) - CPU友好语义搜索
- [第4b部分:语义搜索行动](/blog/semantic-search-in-action) - 头型、混合搜索和UI
- [第5部分:混合搜索和自动插入](/blog/rag-hybrid-search-and-indexing) - 生产一体化
- **第6部分:图表** (本条) - 用于了解人身知识的知识图表

在整个系列中,我们建造了越来越先进的RAG系统。我们从基本的矢量搜索开始,添加了混合关键字+语义检索和集成自动索引。但所有这些方法都有一个基本的限制:它们发现 **相似的块块**,而不是 **连接概念**用于 *基本体层* 问题(主题涉及许多文件)需要结构。

**建议路径 :** 如果您已经有基于 Qdrant 的本地搜索工作( 如我们一样) , 原型用 Python 侧车验证值, 保留矢量供本地搜索, 并为全球/ DRIFT 查询添加一个轻量级图表 。 只有验证用户提出这些问题后, 才会使用“ 完整的 GrapRAG ” 。

[TOC]

# 纯矢矢量 RAG 问题

让我用一个具体的例子来告诉你我的意思。

## 矢量 ROAG 做得很好

**问题:** "我如何使用HTMX与阿尔卑斯山Js?"

**矢量 RAG 进程 :**

1. 隐藏着问题: `[0.234, -0.891, 0.567, ...]`
2. 在 Qdrant 中查找相似的块
3. 返回关于 HTMX 和 Alpine.js 的顶K 匹配
4. LLM 合成这些块的答案

这是因为问题和有关内容是 **字义相似**嵌入式捕捉到这种相似性。

```csharp
// 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 角斗

**问题:** “我写的主要技术是什么? 它们彼此之间有何关系?”

**矢量 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..."
```

它提到多克、波斯格里斯QL、HTMX、ONNX... 但没有对它们进行分组或解释它们是如何连接的。 你得到的碎片,而不是洞察力。

问题:这个问题需要 **和关系理解** 横跨整个体体。 您需要 :

- 查明提到的所有技术
- 理解哪些是一起使用
- 将它们合并为协调一致的主题

光靠矢量相似性并不能给你这个。 如果您试图用提示来补上这个, 你最终会重新生成一个图表 。

# 输入图图RAG

[图图RAG](https://microsoft.github.io/graphrag/) 是微软研究的解决方案 解决这个问题。 [图图RAG 纸张](https://arxiv.org/pdf/2404.16130) 查明了基准RAG处理不当的两种查询类型(RAG处理不当)。**文 谋 智 谋 智 谋** 和 **连接连接**并建立了一个专门解决这些问题的系统。

GragRAG不是仅仅嵌入块块,而是建造 **知识图** 能够捕捉实体及其关系,然后以摘要将其分组成社区。

## 图图RAG如何工作

**管道一眼看一眼:**

- **索引:** · 实体/关系 
- **查询 :** Global=社区摘要 * DRIFT = 路径+摘要

GrapRAG在RAG输油管线上增加了几个部件,分为三类:

1. **采掘** (实体+关系)
2. **图图构建** (知识图存储)
3. **B. 摘要概述** (社区检测+等级)

```mermaid
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:知识图建设

所有实体和关系组成图表:

```mermaid
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:社区探测(Leiden Algorithm)

缩略 [Leiden算法](https://arxiv.org/pdf/1810.08473.pdf) 聚集群将密集的节点连接到社区。这很重要,因为它给了你 *稳定* 组群将总结和检索; 社区将成为全球查询的检索单位。

- **社区1 1**(HTMX、Alpine.js、尾风)
- **社区2 2 社区2**“集装箱基础设施”(纸箱、作曲、PostgreSQL、Qdrant)
- **社区3 3**“RAG管道”(ONNX、内嵌、Qdrant、RAG)

注意Qdrant如何出现在两个社区:它连接基础设施和AI/ML。

### 步骤5:社区摘要

法学硕士为各个层次的每个社区编写摘要:

```
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."
```

## 查询模式

图示RAG提供三种查询模式,每个模式为不同的问题类型优化:

### 全局搜索

**最佳用于:** "主要主题是什么?" "总结关键主题"

使用社区摘要(而非个别块)回答感知问题:

```
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 搜索

**最佳用于:** "X和Y有什么关系?" "比较A和B"

DRIFT 搜索(灵活轨迹动态原因和推断), [如Greagrag docs中所述](https://microsoft.github.io/graphrag/query/drift_search/),将本地搜索与社区背景结合起来。它仍然使用LLM推理法对检索到的结构环境进行推理(而不是魔形图形推理),但结构有助于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."
```

# 将图图RAG与我们目前的系统进行比较

让我们将 Gragrag 概念映射到我们已有的概念上 `Mostlylucid.SemanticSearch`:


|-----------|---------------|---------------------|
| **内嵌** * ONNX(全-MiniLM-L6-V2) * *相同(或 OpenAI) * * * * * NONX(全-MiniLM-L6-V2) *
| **矢量存储** Qdrant Qdrant / LanceDB
| **开采实体** * 无 * * LLM-电源提取 * * * * * 无 * LLM-help 提取 * * * * LLM-help 提取 * * * LLM-help 提取 * * * 无 * LLM-help 提取 * * LLM-production *
| **知识图图** 
| **社区探测** 无 Leiden 算法
| **查询: 特定** | `SemanticSearchService.SearchAsync()` 本地搜索  地方搜索  地方搜索  地方搜索
| **查询:全球** 不支持 @ globalSearch @

我们目前的执行程序 **本地搜索** " 图表 " 将增加: **全局搜索** 和 **DRIFT 搜索** 能力。

```csharp
// 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);
}
```

# 执行方法

将GreagRAG加入现有系统有三种方式。

## 备选办法1:皮松侧面车(建议勘探)

运行 Microsoft 的 GrapRAG 单独服务 :

```yaml
# 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
```

```csharp
// 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;
    }
}
```

**专业:** 使用微软的战斗测试实施, 快速到原型
**关节 :** Python依赖性、LLM费用,用于索引编制、跨过程通信

## 备选2:.NET原生(生产路径)

构建 C# 中的关键组成部分。 BERT 的提取和 Ollama 模式 [DocSummamer 缩写器](/blog/docsummarizer-tool) 在这里也做类似的工作。

### 开采实体

要求 LLM 识别 *事项* 每个块中每个块(实体)的结构化实体,而不是自由形式专题:

```csharp
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 产出 *会* 间断。 这不是可选的硬化。 您需要 :

- **计划受制约的一代** (奥拉马 `format: json`, OpenAI 函数调用)
- **与修理环重试** (发现JSON畸形,请LLM修理它)
- **后退提取** (共同实体类型的区域模式)

LLMs是概率性的; 你的抽取管道不能是。

### 关系采掘

一旦有实体,请问专卖局长,它们是如何连接的:

```csharp
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核心”、“ASP.NET”和“顶部核心”应该是相同的节点。

```csharp
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();
}
```

要认真使用,请考虑嵌入实体的重复:如果两个实体的名称有类似的嵌入,它们可能是一样的。

**生产疼痛点** (GraphRAG的值取决于图表质量):

- **同义词/别名表格**:维护金字塔名称和已知化名
- **关系方案控制**:为防止幻影关系类型而限制允许的上游
- **信心评分+计分**:并非所有已建立的关系都同样可靠
- **递增再索引**:当文档更新时,您需要修补图形,而不是重建它

### 图图 Traversal

查找相关实体是一项广域第一搜索:

```csharp
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();
}
```

### 社区探测

这是连接组件基线, **否** Leiden 优化模块化( 高级内部连接、 稀少的外部连接) 。 为了正确实施, 使用图表库或移植算法 。

```csharp
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;
}
```

### 社区总结

每个社区都得到一个描述其主题的概要。 这就是全球搜索的力量:

```csharp
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 查询添加轻量级图形层 。

### 查询分类

首先,先看看这是什么样的问题:

```csharp
// 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;
}
```

### 本地搜索( 增强)

使用现有的矢量搜索,可选用图表上下文加以丰富:

```csharp
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));
}
```

### 全球搜索(新能力)

减少社区摘要的地图(不需要矢量搜索):

```csharp
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 搜索(同步查询)

将本地结果与社区背景相结合,

```csharp
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.");
}
```

# 成本和绩效的考虑

与纯病媒RAG相比,GragraG具有重大的权衡。

## 费用指数化 费用

实体/关系提取成本因模型、迅速设计和块体大小的不同而差别很大。 **每块一两通LLM电话** 加上要求社区摘要的呼声数量较少。


|-----------|------------|----------|
| **嵌入** 一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通电话,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通,一通
| **实体/关系** * 1-2LLM电话/Chunk * 
| **社区总结** * 1个LLM呼叫/社区 *

对于每块有5块(共5 000块)的1,000个博客文章,仅以矢量为主的指数化基本上只是嵌入成本。 GraphRAG增加了数千个LLM,要求提取和总结。 准确成本在很大程度上取决于您的模型选择和快速效率;使用本地模型(Ollama with llama3.2或类似模型)完全消除API成本,这是推荐的实验方法。

## 询问费用

查询类型  矢量 RAG  图RAG 本地  图RAG Global
|------------|------------|----------------|-----------------|
| **矢量搜索** 呼叫 呼叫 呼叫 0 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫 呼叫
| **横跨图图** 0 1-2 查询 -0
| **LLLM电话** 1+1+1+1+++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Global Search 每个查询费用更高, 但是它回答本地搜索根本无法回答的问题。 您也可以隐藏全局的答案, 并且只在程序更改时才能刷新这些答案 。

## 图图RAG 失败模式

GragraG不是魔法,小心:

- **抽取错误**:LLM女士错失实体或幻觉关系
- **实体别名**“ASP.NET Core”与“ASP.NET”与“顶部”成为单独的节点。
- **图图漂移**:当 docs 更新文档时,图形会变得老化
- **社区摘要逐渐过时**:当实体改变时,摘要不会自动更新

实体正常化是最大的实际痛苦 你需要:

- Canonical 名称+别名
- 案件重复和标标点正常化
- 以任择嵌入为基础的实体重复

# 结合我们的博客搜索

以下是Greagrag如何加强博客现有的语义搜索:

## 目前流动

```
User types in search → SemanticSearchService → Qdrant → Results
```

## 强化流动

分类路径查询不同的搜索策略。 **全局查询** - 注意从不触及矢量存储处:

```mermaid
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..."
```

比较此比 **本地查询**,它将矢量搜索与图表背景相结合,以便找到更丰富的答案:

```mermaid
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..."
```

关键区别是:全球查询汇总社区摘要(公司级主题),而地方查询则检索实体关系丰富的具体部分。

> **更简单的备选办法:** GrapRAG在很大程度上仍然是一个研究工具 -- -- 实体提取、图形构建和社区探测,这增加了相当的复杂性和LLM成本。 **BERT 嵌入 + BM25 关键字匹配** 工作效果更好。 这就是 [来源来源于Cody](https://sourcegraph.com/blog/how-cody-understands-your-codebase) 用于代码情报,以及什么用途 [DocSummamer 缩写器](/blog/docsummarizer-part3) 用于文档汇总。 模式: 混合检索处理关联性; LLM 处理 *组装*,而不是 *决策决策*。你得到80%的福利金 与20%的复杂程度。

## 执行差距

API是直截了当的:对查询进行分类, 向合适的处理人发送路径 :

```csharp
[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
    };
}
```

矢量搜索和图形搜索互为补充。使用矢量查询“我该如何回答”问题,使用“主题是什么”问题的图表。

# 结论 结论 结论 结论 结论

GrapraG 将RAG从“ 找到相似的块块” 扩大到“ 了解知识结构 ” 。 它不是矢量搜索的替代品; 它是一种增强功能, 使得新的查询类型得以使用 。

**GragraG补充说:**

- 实体和关系提取
- 知识图图建设
- 社区探测和等级摘要
- 全球寻找感知问题
- DRIFT 搜索连接推理

**何时使用:**

- 您有大量的文档收藏
- 用户询问“主题是什么”类型问题
- 你的内容有明确的实体和关系
- 您想要自动表面连接

**执行路径 :**

1. 首先, 问: 您真的需要这个吗 ? BERT + BB25 混合检索处理大部分使用的案例 。
2. 如果是,带有 Python 侧车的原型,以验证值
3. 构建. NET 本地端, 如果成本/ 时间关系重要的话
4. 使用当地LLMs(阿鲁沙)控制索引编制费用

## 资源资源资源 资源资源资源 资源资源 资源资源

**图例 :**

- [图图RAG文档](https://microsoft.github.io/graphrag/) - 微软的官方文件
- [图图G GitHub](https://github.com/microsoft/graphrag) - 源代码和实例
- [图图RAG 纸张](https://arxiv.org/pdf/2404.16130) - 原始研究论文
- [Leiden Algorithm 纸张](https://arxiv.org/pdf/1810.08473.pdf) - 社区检测算法

**RAG系列:**

- [第1部分:RAG起源和基本要点](/blog/rag-primer)
- [第2部分:RAG建筑和内部](/blog/rag-architecture)
- [第3部分:在实务中协助通知书](/blog/rag-practical-applications)
- [第4部分:使用 ONNX 和 Qdrant 进行语义搜索](/blog/semantic-search-with-onnx-and-qdrant)
- [第5部分:混合搜索和自动插入](/blog/rag-hybrid-search-and-indexing)

**简易替代品(BERT+BM25):**

- [DocSummamer化器第 3 部分](/blog/docsummarizer-part3) - 混合检索,不使用图表间接费用
- [源代码 Cody 建筑](https://sourcegraph.com/blog/how-cody-understands-your-codebase) - 混合生产搜索