跳到主要内容

QAnything 项目深度分析

· 阅读需 13 分钟
Wuji
AI Engineer

QAnything (Question and Answer based Anything) —— 网易有道开源的本地知识库问答系统 GitHub: https://github.com/netease-youdao/QAnything


一、项目概述

QAnything 是一个支持任意格式文件的本地知识库 RAG 问答系统。用户上传本地文件(PDF、Word、PPT、Excel、Markdown、图片、CSV、网页链接等),系统基于两阶段检索(Embedding + Rerank)+ LLM 生成,返回准确、可靠的问答结果。

核心特性:

  • 支持全程断网安装,保障数据安全
  • 跨语种问答(中英文自由切换)
  • 两阶段检索架构,解决大规模数据检索退化问题
  • 生产级高性能系统,可直接企业部署

二、技术栈全景

2.1 后端框架

组件技术选型用途
Web 框架Sanic (v23.6.0)异步 HTTP 服务,提供 REST API
LLM 应用框架LangChain (v0.0.351)文档加载、文本分割、Document 数据结构
LLM 推理Triton Inference Server + FasterTransformer / vLLM / HuggingFace Transformers大模型推理后端(三选一)
LLM 中间层FastChat (third_party/)提供 OpenAI 兼容 API 的 LLM 服务
Embedding 模型BCEmbedding (bce-embedding-base_v1)768 维向量编码,双语跨语种
Rerank 模型BCE Reranker (bce-reranker-base_v1)二阶段重排序
OCR 引擎PaddleOCR (v2.7.0.3) + PaddlePaddle-GPU (v2.5.2)图片/PDF 文字识别

2.2 数据存储

组件技术选型用途
向量数据库Milvus (v2.3.4)语义向量存储与检索(L2 距离)
全文检索Elasticsearch (v8.11.4)BM25 关键词检索(混合检索)
关系数据库MySQL元数据管理(知识库、文件状态、用户信息)
对象存储MinIOMilvus 的底层存储依赖
分布式协调etcd (v3.5.5)Milvus 的元数据协调

2.3 前端技术

组件技术选型
框架Vue 3 + TypeScript
UI 库Ant Design Vue
构建工具Vite (推断)
国际化中英文双语 (i18n)

2.4 文档处理

格式处理方式
PDFUnstructuredPaddlePDFLoader (PaddleOCR 增强)
Word (docx)UnstructuredWordDocumentLoader
PPT (pptx)UnstructuredPowerPointLoader
Excel (xlsx)pandas 转 CSV + CSVLoader
CSV自定义 CSVLoader
MarkdownUnstructuredFileLoader (elements 模式)
TXTTextLoader + ChineseTextSplitter
图片 (jpg/png)UnstructuredPaddleImageLoader (OCR)
Email (eml)UnstructuredEmailLoader
网页 (html)MyRecursiveUrlLoader

2.5 文本分割

工具用途
RecursiveCharacterTextSplitter (LangChain)二次分割,chunk_size=400 tokens
ChineseTextSplitter中文专用分句器,sentence_size=100
ZhTitleEnhance可选的中文标题加强(标题+正文拼合)

三、系统架构

3.1 整体架构图

┌─────────────────────────────────────────────────────────────────────┐
│ 用户层 (User Layer) │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ Web 前端 │ │ REST API 客户端 │ │
│ │ (Vue3/TS) │ │ (curl/SDK) │ │
│ │ :5052 │ │ :8777 │ │
│ └──────┬───────┘ └────────┬─────────┘ │
└─────────┼─────────────────────┼────────────────────────────────────┘
│ │
┌─────────┼─────────────────────┼────────────────────────────────────┐
│ └─────────┬───────────┘ │
│ API Gateway │
│ ┌─────────┴───────────┐ │
│ │ Sanic API Server │ (qanything_server/sanic_api.py) │
│ │ :8777 │ │
│ └─────────┬───────────┘ │
│ │ │
│ ┌──────────────┼──────────────────────────────┐ │
│ │ │ 核心业务层 (Core Layer) │ │
│ │ ┌─────────┴───────────┐ │ │
│ │ │ LocalDocQA │ (核心问答引擎) │ │
│ │ │ + LocalFile │ (文件处理引擎) │ │
│ │ └──┬──────┬──────┬────┘ │ │
│ │ │ │ │ │ │
│ └───────┼──────┼──────┼────────────────────────┘ │
│ │ │ │ │
│ ┌────────┼──────┼──────┼─────────────────────────────────┐ │
│ │ │ Connector 连接器层 │ │
│ │ │ │ │ │ │
│ │ ┌─────┴──┐ ┌─┴────┐ ┌┴───────┐ ┌──────────┐ │ │
│ │ │Embedding│ │ LLM │ │Milvus │ │ MySQL │ │ │
│ │ │Connector│ │Conn. │ │Client │ │ Client │ │ │
│ │ └─────┬──┘ └─┬────┘ └┬───────┘ └──────────┘ │ │
│ │ │ │ │ ┌──────────┐ │ │
│ │ │ │ │ │ES Client │ │ │
│ │ │ │ │ │(BM25) │ │ │
│ │ │ │ │ └──────────┘ │ │
│ └────────┼──────┼───────┼────────────────────────────────┘ │
│ │ │ │ │
└────────────┼──────┼───────┼────────────────────────────────────────┘
│ │ │
┌────────────┼──────┼───────┼────────────────────────────────────────┐
│ 服务层 │ │ │ (Dependent Server Layer) │
│ │ │ │ │
│ ┌─────────┴──┐ ┌─┴──────────┐ ┌─────────┐ ┌──────┐ ┌──────────┐ │
│ │Triton Server│ │FastChat/ │ │ Milvus │ │MySQL │ │ ES │ │
│ │(Embedding │ │vLLM/HF │ │:19530 │ │:3306 │ │ :9200 │ │
│ │ +Rerank) │ │(LLM推理) │ │ │ │ │ │ │ │
│ └────────────┘ └────────────┘ └─────────┘ └──────┘ └──────────┘ │
│ ┌────────────┐ │
│ │OCR Server │ (PaddleOCR, :8010) │
│ └────────────┘ │
│ ┌────────────┐ │
│ │Rerank Server│ (BCE Reranker, :8776) │
│ └────────────┘ │
└────────────────────────────────────────────────────────────────────┘

3.2 Docker 容器编排

Docker Compose 定义了以下 6 个服务:

docker-compose-linux.yaml
├── etcd (milvus-etcd-local) -- Milvus 协调服务
├── minio (milvus-minio-local) -- Milvus 对象存储
├── standalone (milvus-standalone-local) -- Milvus 向量数据库
├── elasticsearch (es-container-local) -- ES 全文检索
├── mysql (mysql-container-local) -- MySQL 元数据库
└── qanything_local (qanything-container-local) -- 主业务容器
├── Sanic API Server (:8777)
├── Nginx 前端 (:5052)
├── OCR Server (:8010)
├── Rerank Server (:8776)
├── LLM Server Entrypoint (:36001)
└── Triton Inference Server (:10001)

四、模块设计详解

4.1 API 服务层 (qanything_server/)

文件: sanic_api.py + handler.py

基于 Sanic 框架的异步 REST API 服务,提供以下接口:

接口方法功能
/api/local_doc_qa/new_knowledge_basePOST新建知识库
/api/local_doc_qa/upload_filesPOST上传文件到知识库
/api/local_doc_qa/upload_weblinkPOST上传网页链接
/api/local_doc_qa/local_doc_chatPOST知识库问答(核心接口)
/api/local_doc_qa/list_knowledge_basePOST列出所有知识库
/api/local_doc_qa/list_filesPOST列出知识库中的文件
/api/local_doc_qa/delete_filesPOST删除文件
/api/local_doc_qa/delete_knowledge_basePOST删除知识库
/api/local_doc_qa/rename_knowledge_basePOST重命名知识库
/api/local_doc_qa/get_total_statusPOST获取所有知识库状态
/api/local_doc_qa/clean_files_by_statusPOST按状态清理文件

设计要点:

  • 请求体最大支持 400MB(大文件上传)
  • CORS 全开放(Access-Control-Allow-Origin: *
  • 支持 local / online 两种运行模式
  • 文件上传后异步处理(asyncio.create_task),立即返回 file_id

4.2 核心问答引擎 (core/)

文件: local_doc_qa.py

LocalDocQA 是整个系统的核心类,串联了 RAG 的全部流程:

class LocalDocQA:
def __init__(self):
self.llm # LLM 实例 (ZiyueLLM / OpenAILLM)
self.embeddings # Embedding 实例 (YouDaoLocalEmbeddings)
self.top_k = 100 # 一阶段检索返回数量
self.chunk_size = 800 # 上下文片段最大长度
self.milvus_kbs # Milvus 客户端列表(缓存)
self.milvus_summary # MySQL 元数据管理器

关键方法:

  1. init_cfg(mode) — 初始化 Embedding、LLM、MySQL 连接
  2. create_milvus_collection(user_id, kb_id, kb_name) — 创建知识库(Milvus Collection + Partition)
  3. insert_files_to_milvus(user_id, kb_id, local_files) — 文件入库流程
  4. get_source_documents(queries, milvus_kb) — 一阶段向量检索
  5. rerank_documents(query, source_documents) — 二阶段重排序
  6. reprocess_source_documents(...) — Token 预算裁剪
  7. generate_prompt(query, source_docs, prompt_template) — Prompt 组装
  8. get_knowledge_based_answer(...) — 端到端问答(流式/非流式)

4.3 文件处理引擎 (core/local_file.py)

文件: local_file.py

LocalFile 类负责文件的解析、分块和 Embedding:

文件上传 → 保存到本地磁盘

根据文件类型选择 Loader

文本分割 (ChineseTextSplitter → RecursiveCharacterTextSplitter)

生成 Embedding 向量

写入 Milvus + ES

支持的文件类型和对应 Loader:

.pdf → UnstructuredPaddlePDFLoader (OCR 增强)
.docx → UnstructuredWordDocumentLoader
.pptx → UnstructuredPowerPointLoader
.xlsx → pandas 转 CSV → CSVLoader
.csv → CSVLoader
.md → UnstructuredFileLoader (elements 模式)
.txt → TextLoader + ChineseTextSplitter
.jpg/png → UnstructuredPaddleImageLoader (OCR)
.eml → UnstructuredEmailLoader
html → MyRecursiveUrlLoader

文本分割策略:

  • 第一级:ChineseTextSplitter(按中文标点分句,sentence_size=100)
  • 第二级:RecursiveCharacterTextSplitter(chunk_size=400 tokens)

4.4 向量数据库层 (connector/database/milvus/)

文件: milvus_client.py

Milvus Collection Schema:

字段类型说明
chunk_idVARCHAR(64)主键,格式 {file_id}_{idx}
file_idVARCHAR(64)文件 ID
file_nameVARCHAR(640)文件名
file_pathVARCHAR(640)文件路径
timestampVARCHAR(64)时间戳
contentVARCHAR(4000)文本内容
embeddingFLOAT_VECTOR(768)768 维向量

索引配置:

  • 索引类型:IVF_FLAT(本地)/ GPU_IVF_FLAT(在线)
  • 距离度量:L2(欧氏距离)
  • nlist:2048
  • 搜索参数:nprobe=256

多租户设计:

  • 每个 user_id 对应一个 Milvus Collection
  • 每个 kb_id 对应一个 Partition
  • 支持跨知识库查询(多 Partition 检索)

文档扩展(expand_cand_docs):

  • 检索到的 chunk 会向前后各扩展 200 个 chunk
  • 直到总长度达到 CHUNK_SIZE (800 chars)
  • 按 file_id 分组并行处理

4.5 混合检索层 (connector/database/milvus/es_client.py)

文件: es_client.py

在 Milvus 向量检索的基础上,增加 Elasticsearch BM25 关键词检索:

查询 → Milvus 向量检索 (top_k=100) ──┐
→ ES BM25 检索 (size=50) ──┤

结果合并 + 去重

expand_cand_docs

Rerank 重排序

ES 索引命名规则: {user_id}++{kb_id}

4.6 LLM 连接器层 (connector/llm/)

系统支持多种 LLM 后端:

后端场景
ZiyueLLMTriton + FasterTransformer本地默认(单卡/双卡)
OpenAICustomLLMFastChat (OpenAI 兼容 API)本地自定义模型 (hf/vllm)
OpenAILLMOpenAI API云端模式
ZiyueLLM本地推理服务 (:36001)流式/非流式生成

LLM 配置参数:

  • token_window: 4096(上下文窗口)
  • max_token: 300-512(最大生成长度)
  • temperature: 0.6(本地)/ 0(OpenAI)
  • history_len: 2(历史对话轮数)

4.7 Embedding 连接器层 (connector/embedding/)

架构:

YouDaoLocalEmbeddings

EmbeddingClient (gRPC → Triton Server)

BCEmbedding (bce-embedding-base_v1)

768 维向量输出
  • 通过 Triton Inference Server 的 gRPC 接口调用
  • 支持批量处理(batch_size=16)
  • 多线程并发请求

4.8 依赖服务层 (dependent_server/)

服务端口技术功能
OCR Server:8010Sanic + PaddleOCR图片/PDF 文字识别
Rerank Server:8776Sanic + BCE Reranker二阶段重排序
LLM Server Entrypoint:36001Sanic + Triton ClientLLM 推理中转
Embedding/Rerank Triton:10001Triton Inference Server模型推理引擎

4.9 前端 (front_end/)

Vue 3 + TypeScript + Ant Design Vue 构建的 Web UI:

  • 知识库管理(创建/删除/重命名)
  • 文件上传与管理
  • 多知识库选择问答
  • 流式对话展示
  • 中英文国际化

五、RAG 流程与模块对应

5.1 完整 RAG Pipeline

以下是 QAnything 的完整 RAG 流程,标注了每个步骤对应的代码模块:

═══════════════════════════════════════════════════════════════
阶段一:文档索引(离线/上传时)
═══════════════════════════════════════════════════════════════

用户上传文件


┌─────────────────────────────────────────┐
│ [1] 文件保存 │ ← handler.py: upload_files()
│ 保存到 QANY_DB/content/{user_id}/ │
└────────────────┬────────────────────────┘

┌─────────────────────────────────────────┐
│ [2] 文档解析 │ ← local_file.py: split_file_to_docs()
│ 根据文件类型选择 Loader │
│ PDF → PaddleOCR │ ← ocr_server.py
│ 图片 → PaddleOCR │
│ 其他 → LangChain Loaders │
└────────────────┬────────────────────────┘

┌─────────────────────────────────────────┐
│ [3] 文本分割 │ ← ChineseTextSplitter (一级)
│ ChineseTextSplitter → 分句 │ RecursiveCharacterTextSplitter (二级)
│ RecursiveCharacterTextSplitter → 分块│ chunk_size=400 tokens
└────────────────┬────────────────────────┘

┌─────────────────────────────────────────┐
│ [4] 向量编码 │ ← embedding_for_local.py
│ BCEmbedding → 768维向量 │ embedding_client.py (Triton gRPC)
│ 批量处理,batch_size=16 │
└────────────────┬────────────────────────┘

┌─────────────────────────────────────────┐
│ [5] 存储入库 │ ← milvus_client.py: insert_files()
│ Milvus: 向量 + 元数据 │ es_client.py (混合检索时同步写入 ES)
│ ES: 文本内容 (BM25 索引) │ mysql_client.py: 元数据 + 状态管理
│ MySQL: 文件状态 (gray→green/red) │
└─────────────────────────────────────────┘


═══════════════════════════════════════════════════════════════
阶段二:检索增强生成(在线/查询时)
═══════════════════════════════════════════════════════════════

用户提问


┌─────────────────────────────────────────┐
│ [6] Query 向量编码 │ ← embedding_for_local.py
│ BCEmbedding → 768维查询向量 │
└────────────────┬────────────────────────┘

┌─────────────────────────────────────────┐
│ [7] 一阶段检索:向量检索 │ ← milvus_client.py: search_emb_async()
│ Milvus L2 距离检索, top_k=100 │
│ 阈值过滤: score <= 1.1 │
│ │
│ [7b] 混合检索(可选) │ ← es_client.py: BM25 检索
│ ES BM25 检索, size=50 │ parse_es_batch_result() 合并去重
│ 向量结果 + BM25 结果合并 │
└────────────────┬────────────────────────┘

┌─────────────────────────────────────────┐
│ [8] 文档去重与扩展 │ ← milvus_client.py: deduplicate_documents()
│ 去重 (page_content) │ expand_cand_docs()
│ 向前后扩展到 CHUNK_SIZE (800 chars) │
└────────────────┬────────────────────────┘

┌─────────────────────────────────────────┐
│ [9] 二阶段检索:Rerank 重排序 │ ← local_doc_qa.py: rerank_documents()
│ 调用 Rerank Server (:8776) │ rerank_server.py
│ BCE Reranker 重打分 │ rerank_server_backend.py
│ 过滤 score < 0.35 的结果 │
│ 按 score 降序排列 │
└────────────────┬────────────────────────┘

┌─────────────────────────────────────────┐
│ [10] Token 预算裁剪 │ ← reprocess_source_documents()
│ 总预算 = token_window │
│ - max_token │
│ - offcut_token │
│ - query_tokens │
│ - history_tokens │
│ - template_tokens │
│ 按序填充文档,超出则截断 │
└────────────────┬────────────────────────┘

┌─────────────────────────────────────────┐
│ [11] Prompt 组装 │ ← generate_prompt()
│ PROMPT_TEMPLATE: │
│ "参考信息:{context} │
│ 我的问题或指令:{question} │
│ 请根据上述参考信息回答..." │
└────────────────┬────────────────────────┘

┌─────────────────────────────────────────┐
│ [12] LLM 生成 │ ← llm_for_local.py: generatorAnswer()
│ 流式/非流式生成 │ llm_for_openai_api.py
│ 返回答案 + 引用来源 │ llm_server_entrypoint.py
└─────────────────────────────────────────┘

5.2 RAG 核心设计亮点

(1) 两阶段检索架构

一阶段 (Embedding) 二阶段 (Rerank)
┌──────────────────┐ ┌──────────────────┐
│ 向量语义检索 │ →→→ │ 精排重排序 │
│ top_k=100 │ │ 过滤 score<0.35 │
│ L2 距离, IVF_FLAT │ │ BCE Reranker │
│ 解决召回率问题 │ │ 解决准确率问题 │
└──────────────────┘ └──────────────────┘
  • 一阶段用 Embedding 模型做粗召回,保证高召回率
  • 二阶段用 Reranker 模型做精排,保证高准确率
  • 数据越多,两阶段优势越明显(解决检索退化问题)
向量检索 (Milvus) + 关键词检索 (ES BM25)

结果合并去重

expand_cand_docs 扩展上下文
  • Milvus: 语义相似度检索(理解"意思")
  • ES BM25: 关键词精确匹配(理解"关键词")
  • 两者互补,提升召回质量

(3) 文档扩展 (Context Window Expansion)

检索到的 chunk 不是孤立返回的,而是向前后扩展:

  • 检索到 chunk_id=50,会尝试扩展到 [48, 49, 50, 51, 52]
  • 直到总长度达到 CHUNK_SIZE (800 chars)
  • 保证返回给 LLM 的上下文是连贯完整的

(4) Token 预算管理

可用 Token = token_window(4096)
- max_token(300~512) # 生成预留
- offcut_token(50) # 安全余量
- query_tokens # 问题本身
- history_tokens # 历史对话
- template_tokens # Prompt 模板

确保不会超出模型的上下文窗口限制。


六、项目目录结构

QAnything/
├── README.md / README_zh.md # 项目文档
├── run.sh / close.sh # 启动/关闭脚本
├── docker-compose-linux.yaml # Docker 编排 (Linux)
├── docker-compose-windows.yaml # Docker 编排 (Windows)
├── requirements.txt # Python 依赖
├── .env # 环境变量配置

├── qanything_kernel/ # 核心业务代码
│ ├── configs/
│ │ └── model_config.py # 全局配置(端口、阈值、Prompt 模板等)
│ │
│ ├── core/ # 核心逻辑
│ │ ├── local_doc_qa.py # 问答引擎(RAG 主流程)
│ │ └── local_file.py # 文件处理引擎(解析+分块+Embedding)
│ │
│ ├── connector/ # 外部服务连接器
│ │ ├── database/
│ │ │ ├── milvus/
│ │ │ │ ├── milvus_client.py # Milvus 向量数据库客户端
│ │ │ │ └── es_client.py # Elasticsearch BM25 客户端
│ │ │ └── mysql/
│ │ │ └── mysql_client.py # MySQL 元数据管理
│ │ ├── llm/
│ │ │ ├── llm_for_local.py # 本地 LLM (Triton/FasterTransformer)
│ │ │ ├── llm_for_fastchat.py # FastChat LLM (OpenAI 兼容)
│ │ │ ├── llm_for_openai_api.py # OpenAI API LLM
│ │ │ └── base/ # LLM 基类 (BaseAnswer, AnswerResult)
│ │ └── embedding/
│ │ ├── embedding_client.py # Embedding Triton 客户端
│ │ ├── embedding_for_local.py # 本地 Embedding 封装
│ │ └── embedding_for_online.py# 在线 Embedding
│ │
│ ├── dependent_server/ # 依赖的独立服务
│ │ ├── llm_for_local_serve/
│ │ │ ├── llm_server_entrypoint.py # LLM 中转服务 (:36001)
│ │ │ ├── modeling_qwen.py # Qwen 模型封装
│ │ │ └── template.py # 对话模板
│ │ ├── ocr_serve/
│ │ │ └── ocr_server.py # OCR 服务 (:8010)
│ │ └── rerank_for_local_serve/
│ │ ├── rerank_server.py # Rerank 服务 (:8776)
│ │ └── rerank_server_backend.py # Rerank 后端实现
│ │
│ ├── qanything_server/ # API 服务层
│ │ ├── sanic_api.py # Sanic 应用 + 路由注册
│ │ └── handler.py # API 处理函数
│ │
│ └── utils/ # 工具类
│ ├── custom_log.py # 日志工具
│ ├── general_utils.py # 通用工具函数
│ ├── loader/ # 文档加载器
│ │ ├── pdf_loader.py # PDF 加载器 (PaddleOCR)
│ │ ├── csv_loader.py # CSV 加载器
│ │ ├── image_loader.py # 图片加载器 (OCR)
│ │ └── my_recursive_url_loader.py # 网页加载器
│ └── splitter/ # 文本分割器
│ ├── chinese_text_splitter.py # 中文分句器
│ └── ZhTitleEnhance.py # 标题增强

├── front_end/ # 前端代码
│ ├── src/
│ │ ├── App.vue # 根组件
│ │ ├── main.ts # 入口文件
│ │ ├── components/ # Vue 组件
│ │ ├── store/ # 状态管理 (Pinia)
│ │ ├── language/ # 国际化 (en/zh)
│ │ └── utils/ # 工具函数
│ └── package.json

├── third_party/ # 第三方依赖
│ ├── FastChat/ # LLM 服务框架
│ └── es/ # ES 插件

├── assets/ # 资源文件
│ └── custom_models/ # 自定义模型目录

├── QANY_DB/ # 数据目录
│ └── content/ # 上传的文件存储

└── logs/ # 日志目录
└── debug_logs/ # 调试日志

七、关键配置参数

# model_config.py 中的核心配置

# 检索参数
VECTOR_SEARCH_TOP_K = 100 # 一阶段检索返回数量
VECTOR_SEARCH_SCORE_THRESHOLD = 1.1 # L2 距离阈值(归一化后)
CHUNK_SIZE = 800 # 单段上下文最大字符数
SENTENCE_SIZE = 100 # 分句长度

# LLM 参数
STREAMING = True # 默认流式输出
LLM_HISTORY_LEN = 3 # 历史对话轮数

# Prompt 模板
PROMPT_TEMPLATE = """参考信息:
{context}
---
我的问题或指令:
{question}
---
请根据上述参考信息回答我的问题或回复我的指令。
前面的参考信息可能有用,也可能没用,你需要从我给出的参考信息中选出与我的问题最相关的那些,
来为你的回答提供依据。回答一定要忠于原文,简洁但不丢信息,不要胡乱编造。
我的问题或指令是什么语种,你就用什么语种回复,
你的回复:"""

# 混合检索
HYBRID_SEARCH = True # 启用 ES BM25 混合检索
ES_BM25_SEARCH_SIZE = 50 # BM25 检索返回数量

# 中文标题增强
ZH_TITLE_ENHANCE = False # 默认关闭

八、总结

QAnything 是一个设计完整的生产级 RAG 系统,其核心优势在于:

  1. 两阶段检索:Embedding 粗召回 + Rerank 精排,解决大规模数据检索退化问题
  2. 混合检索:向量语义检索 + BM25 关键词检索,语义与精确匹配互补
  3. 文档扩展:检索到的 chunk 自动扩展上下文窗口,保证 LLM 获得完整信息
  4. Token 预算管理:精确控制输入 LLM 的 token 数量,避免截断
  5. 多格式支持:统一的 Loader 抽象层,支持 10+ 种文件格式
  6. 多后端 LLM:支持 FasterTransformer / vLLM / HuggingFace / OpenAI API
  7. 生产级部署:Docker Compose 一键部署,支持 GPU 多卡

整体架构清晰,模块职责分明,是一个值得学习和参考的 RAG 系统实现。