# 建立您的博客“-”部分的 “9:”文档存取

<!--category-- AI, LLM, Docling, RAG, C#, AI-Article, mostlylucid.blogllm -->
<datetime class="hidden">2025-12-15T22:45</datetime>

欢迎使用 {9! 在前几部分中 < , > we' _已经建立了一个强大的RAG系统, 可以处理标记的博客日志, 通过语义嵌入@.}来搜索它们。 现在是时候扩展我们的能力了 **弯曲** - 是一个强大的文件处理库, 可以摄取 PDFs, DOCX}, 和其他格式@, 使我们的律师GPT真正包罗万象的 GPT=.

> 这是我自己编辑的A )Q MS K3Q 同一声音 同样的实用性 ,Q 一样

这不是我对博客“(it's all markdown{),_BARBAR_'D ”的需要,而是为了完成我所认为的“IMSK3}*d 展示了如何轻松地将文件接收能力添加到您的RAG管道中的<.♪这特别有用

[TOC]

## 为何文件接收事项

目前为止,我们的GPT律师只能理解 标记文件@. @ that'}对于一个博客来说是罚款的。 但真正的-#World知识库含有\:}

- **PDF 合同** -法律工作的命脉
- **单词文档** @- 简况 , 动议, 信件
- **PowPoint 演示** -客户阵列 @,个案摘要
- **扫描文件** 需要OCR的旧纪录
- **HTML 页** 网络内容 @,}在线资源

如果我们想让我们的系统像一个真正的法律 AI助理... ...MSKK0 它需要消费 所有这些这些 这些>.

## 什么是多林?

[弯曲](https://github.com/docling-project/docling) 是一个来自 IBM 的 Open-源文件处理工具包, 从 IBMA}. 想象一下它是文档的通用翻译@- 你喂它一个 PDF\ , Word docMS K4 或Powerpoint, 它吐出干净{, 结构化标记_.

为何标记@? @ @ 因为' @ @ 因为我们现有的管道已经理解了我们的现有管道 @ ! @ weMS K3} 我们已经建立了块状的 ,} 嵌入了生成+,* 和矢量存储以显示标记下调内容@ .# 通过将一切转换为标记首字母@ I, @ 我们可以再利用所有的基础设施 #.}

**什么样的控制器 : ***

- PDF提取 ( 本地和扫描 通过OCR)
- DOCX和DOC文件
- PPPTX演示
- HTML 页
- 带有文本的图像@(_via OCR)}

**是什么使得它特别 :**

- 保存文档结构@(_heatings @,}列出,}表格_)}
- 处理复杂的布局 @ (_ molti-}{collumn\ MS K2 混合内容@)
- 桌面提取实际上有效 @ ( @ 不像许多 PDF 剖析器@ MS K1 @ {
- 没有发送到外部服务的数据

## 以服务方式运行文档

Python 库*,}但团队提供 [文档服务](https://github.com/docling-project/docling-serve) -AREST API 包装纸 我们可以从 C#.调用 这是最清洁的融合路径

### 开始服务处

最简单的方式就是通过 Docker : 运行 docling

```bash
docker run -p 5001:5001 quay.io/docling-project/docling-serve
```

您现在有一个文档转换 API 正在运行 `http://localhost:5001`.

想要与它交互式地玩“?”启用“UIQ:”

```bash
docker run -p 5001:5001 -e DOCLING_SERVE_ENABLE_UI=1 quay.io/docling-project/docling-serve
```

其后访问 `http://localhost:5001/ui` 来拖放文档并查看结果@.}

### 选择正确的图像

按您的硬件提供多个容器图像@: @%

@|_ 图像@|_ 使用案例|}大小{|}
|-------|----------|------|
| `docling-serve` -=YTET -伊甸园字幕组=- 翻译:
| `docling-serve-cpu` |+Smaller+,+CPU=- 仅限 @|+Q~4.4+GB#|+%
| `docling-serve-cu126` -=YTET -伊甸园字幕组=- 翻译:
| `docling-serve-cu128` -=YTET -伊甸园字幕组=- 翻译:

如果您正在做重 OCR 工作 @(_scanned documents@),} GPU 图像值为额外大小 @ .} 对于数字+-#native PDFs 和Word docs,} CPU is freedQ. *

### 添加到 docker 撰写器

用于生产 @,+在您现有的堆叠中添加 docling@:

```yaml
services:
  docling:
    image: quay.io/docling-project/docling-serve:latest
    ports:
      - "5001:5001"
    volumes:
      - docling_cache:/root/.cache
    restart: unless-stopped
```

缓存量很重要 @ -% docling 在第一次运行时下载 ML 模型, 而您不想要在每次容器重新启动后重新装入\ MS K3@ docking\ k4}

## 打印 API

在潜入 C# 代码@ , @ let\ '}让我们理解我们和什么人合作

### 从 URL 转换文档

```bash
curl -X POST 'http://localhost:5001/v1/convert/source' \
  -H 'Content-Type: application/json' \
  -d '{
    "sources": [{"kind": "http", "url": "https://example.com/contract.pdf"}],
    "options": {"to_formats": ["md"]}
  }'
```

### 上传本地文件

```bash
curl -X POST 'http://localhost:5001/v1/convert/file' \
  -F 'files=@contract.pdf'
```

两个返回的 JSON 包含已转换的标记@ , 以及像页面计数和检测到的文件类型@ MPK1\ 这样的元数据

### 密钥选项

- **`to_formats`**:}您想要什么样的输出 ? `md` @ (_ 标记@ MS K1} `json` (squated),或 `text` (palin)
- **`ocr`**@ : 启用@ MS K1 discable OCR *% ( 默认=: 已启用} @ MPK4
- **`table_mode`**: `fast` 或 `accurate` 表格质量贸易速度

## 与C#整合

由于文件是一个REST服务@,整合是直截了当的 HTTP 调用}{.}_此处>'这是一种方法_:}*

### 建立 docling 客户端

我们需要一个处理 HTTP 通讯的服务 :

```csharp
public class DoclingClient
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl;

    public DoclingClient(HttpClient httpClient, string baseUrl = "http://localhost:5001")
    {
        _httpClient = httpClient;
        _baseUrl = baseUrl;
    }

    public async Task<string?> ConvertFromUrlAsync(string documentUrl)
    {
        var request = new
        {
            sources = new[] { new { kind = "http", url = documentUrl } },
            options = new { to_formats = new[] { "md" } }
        };

        var response = await _httpClient.PostAsJsonAsync(
            $"{_baseUrl}/v1/convert/source", request);

        if (!response.IsSuccessStatusCode)
            return null;

        var result = await response.Content.ReadFromJsonAsync<DoclingResponse>();
        return result?.Document?.MarkdownContent;
    }

    public async Task<string?> ConvertFileAsync(string filePath)
    {
        using var content = new MultipartFormDataContent();
        using var fileStream = File.OpenRead(filePath);
        content.Add(new StreamContent(fileStream), "files", Path.GetFileName(filePath));

        var response = await _httpClient.PostAsync(
            $"{_baseUrl}/v1/convert/file", content);

        if (!response.IsSuccessStatusCode)
            return null;

        var result = await response.Content.ReadFromJsonAsync<DoclingResponse>();
        return result?.Document?.MarkdownContent;
    }
}
```

关键洞察力=:}我们得到的标记回溯@,}它直接插进我们现有的输油管 200)}.

### 2.喂到现有管道

记住我们从“ 4?” 部件接收的输入管道。 它需要标记@ MS K1 @ 块, it,# 生成嵌入@ I,} 和在Qdrant\ .}( 我们只需要添加 docling 作为新的输入源@:)

```csharp
public async Task ProcessDocumentAsync(string filePath)
{
    // Step 1: Convert to markdown with Docling
    var markdown = await _doclingClient.ConvertFileAsync(filePath);
    
    if (string.IsNullOrEmpty(markdown))
    {
        _logger.LogError("Failed to convert {File}", filePath);
        return;
    }

    // Step 2: Parse the markdown (reuse existing code!)
    var document = _markdownParser.ParseFromContent(markdown, Path.GetFileName(filePath));

    // Step 3: Chunk it (reuse existing code!)
    var chunks = _chunker.ChunkDocument(document);

    // Step 4: Generate embeddings (reuse existing code!)
    await _embedder.GenerateEmbeddingsAsync(chunks);

    // Step 5: Store in vector database (reuse existing code!)
    await _vectorStore.UpsertChunksAsync(chunks);
}
```

看看我们需要多少新代码 我们需要什么 ? 围绕标记建造一条管道的美好之处 就是任何新的输入格式 只要需要一个转换器

### 3. 处理不同文档类型

不同的文档可能需要不同处理@: @%

```csharp
public async Task ProcessDocumentAsync(string filePath, string[] categories)
{
    var extension = Path.GetExtension(filePath).ToLower();
    
    // Scanned PDFs need OCR, which is slower
    var useOcr = extension == ".pdf" && await IsScannedPdfAsync(filePath);
    
    var markdown = await _doclingClient.ConvertFileAsync(filePath, new ConvertOptions
    {
        EnableOcr = useOcr,
        TableMode = extension == ".xlsx" ? "accurate" : "fast"
    });

    // ... rest of pipeline
}
```

## 业绩考量

文档转换为 @ ' @ t即时@ MS K1 @ here @ I' @ sits what to expect @ MPK3}

|文档类型 @| 典型时间@|
|--------------|--------------|
@| 简单PDF(1-5page_) |2-5秒@|#
@|#Complicate PDF #(20+#page\ )}|> @MS K4#秒 @|#
| 扫描 PDF 用 OCR | @ MS K2 秒@|
|+Word 文档 * @|_Q#\ MS K2_秒@|}
|+Powerpoint @|+#5-30_秒@|

**生产提示@:**

1. **进程不同步** - 唐' t 文档转换区块 @. 在背景中排队文档和进程@.}

2. **缓存结果** - 存储已转换的标记@ MS K1 如果文档已经 @ ' t 更改了\ (} check file hash), dono{'t recover=.}

3. **运行 OCR 使用 GPU** -如果你处理了大量扫描文档... ...#,, CUDA 图像是 @5-10x faster_.@

4. **可能时跳过OCR** - Digital-Native PDFs doMS K2t 需要 OCR.docling 自动-DetectsMSQ5,但您可以强制它关闭已知的数字源@.

## 自动文档监视

查看新文档的文件夹@: @%

```csharp
public class DocumentWatcher : BackgroundService
{
    private FileSystemWatcher _watcher;

    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _watcher = new FileSystemWatcher("/documents/incoming")
        {
            Filters = { "*.pdf", "*.docx", "*.pptx" }
        };

        _watcher.Created += async (s, e) => 
        {
            await Task.Delay(1000); // Wait for file to finish writing
            await _ingestionService.ProcessDocumentAsync(e.FullPath);
        };

        _watcher.EnableRaisingEvents = true;
        return Task.CompletedTask;
    }
}
```

在文件夹@ ,中丢弃一个 PDF, 它会自动被转换为 @ MS K1 brokeed\ , 嵌入@ MOSK3 并成为可搜索的@ MPK4

## 启用什么

我们的律师GPT现在可以 :了

- **入门客户合同** @- 上传 PDF, 询问关于具体条款的问题
- **横跨书状搜索** {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}
- **参考研究论文** - 添加学术性 PDF 到您的知识库
- **处理遗留文件** 这些旧的扫描记录

关键洞察力是文档格式只是一个输入问题@. 一旦一切都被标记下来\, 我们的语义搜索 {'#t care where the内容来自_.

## 摘要摘要

我们的GPT:律师 增加了文件接收量

1. **弯曲** 将 PDFs @ , DOCX,PPTX 转换为清除标记
2. **文档服务** 我们可以从C#呼叫 将它包装在API中
3. **我们现有的管道** 处理所有从那里开始的一切 @ - @ 不需要更改

这是围绕共同格式构建的能量 =.}新输入类型很容易添加\;}核心情报保持原样

## 系列导航

- [部分: 1:_ 导言 _&建筑](/blog/building-a-lawyer-gpt-for-your-blog-part1)
- [部分@2:GPU 设置 @&CUDA 在 CQ#](/blog/building-a-lawyer-gpt-for-your-blog-part2)
- [“3: 理解嵌入器”部分](/blog/building-a-lawyer-gpt-for-your-blog-part3)
- [建立接收管道](/blog/building-a-lawyer-gpt-for-your-blog-part4)
- [窗口客户端](/blog/building-a-lawyer-gpt-for-your-blog-part5)
- [6:地方LLM整合部分](/blog/building-a-lawyer-gpt-for-your-blog-part6)
- [内容生成 *&}快速工程](/blog/building-a-lawyer-gpt-for-your-blog-part7)
- [生产部署](/blog/building-a-lawyer-gpt-for-your-blog-part8)
- ***% 9:}文档按下停放摄取** 校对:Soup

## 资源资源资源 资源和资源资源资源

- [吉特胡卜岛](https://github.com/docling-project/docling)
- [GitHub 医生服务](https://github.com/docling-project/docling-serve)
- [(arXivMS K1](https://arxiv.org/abs/2501.17887)
- [API 文件](http://localhost:5001/docs) “(”当本地运行时“)”