
现代 RAG 机器人的工作方式
良好的 RAG 流水线不仅仅是”把文档放进向量数据库”。基本流程如下:| 步骤 | 发生的事情 |
|---|---|
| Load | 读取本地 Markdown、文本或 reStructuredText 文件 |
| Chunk | 将长文档拆分为重叠的部分 |
| Embed | 使用 Venice 嵌入将 chunk 转换为向量 |
| Store | 将向量和源元数据保存在 Qdrant 中 |
| Retrieve | 嵌入用户的问题并运行向量搜索 |
| Re-rank | 使用 cross-encoder 重新评分最佳候选 |
| Answer | 将最佳上下文与引用说明一起发送到 Venice 聊天模型 |
安装依赖项
我们将使用 OpenAI Python SDK,因为 Venice 暴露了 OpenAI 兼容的 API。我们还将使用支持 FastEmbed 的 Qdrant Python 客户端:requirements.txt:
选择模型
创建一个名为rag_bot.py 的文件,然后从添加导入、数据结构、API URL 和模型名称开始:
base_url 和 API 密钥来迁移。
您可以使用以下命令列出可用的 Venice 模型:
创建 Venice 和 Qdrant 客户端
为嵌入和聊天补全创建一个 OpenAI 兼容的 Venice 客户端:| 模式 | 何时使用 |
|---|---|
QdrantClient(":memory:") | 快速本地演示和测试 |
QdrantClient(path="./qdrant_data") | 本地持久化存储 |
QdrantClient(url=..., api_key=...) | 远程或托管 Qdrant 集群 |
加载和分块文档
在本教程中,我们将让机器人摄取本地文件或文件夹。从.md、.rst 和 .txt 文件开始:
1000 字符的起始 chunk 大小加 150 字符的重叠对于混合 Markdown 和文本文档是一个良好的默认值。较小的 chunk 可以提高精度。较大的 chunk 可以保留更多上下文。正确的设置通常取决于您存储的文档类型。
使用 Venice 嵌入文档
有了 chunk 后,我们批量嵌入它们:在 Qdrant 中存储向量
在插入点之前,使用正确的向量大小创建 Qdrant 集合。知道向量大小最简单的方法是嵌入第一批,然后使用len(embeddings[0])。
source、chunk_index 和内容派生的确定性 UUID。这使得对未更改 chunk 的重复摄取具有幂等性。
检索候选 chunk
在问题时间,机器人嵌入用户的问题并向 Qdrant 请求顶级向量匹配:limit 是候选数量。它通常应该高于您计划发送给模型的 chunk 数量,因为下一步将对它们进行重新排序。一个良好的默认值是检索 8 个候选并将最佳 4 个发送到聊天模型。
使用 FastEmbed 重新排序
现在我们添加使检索感觉更智能的部分。- 用向量搜索检索更大的候选集。
- 在本地仅重新排序这些候选。
- 将顶部几个 chunk 发送到语言模型。
candidate_k=8 和 top_k=4。如果正确的来源经常在附近但未进入最终上下文,则增加 candidate_k。
使用 Venice 聊天补全回答
选择上下文后,用源编号格式化它:运行机器人
将各部分组装成脚本后,将其保存为rag_bot.py。简单的首次运行可以使用一些内置示例文档,以便您在摄取自己的文件之前验证流水线:
有用的 CLI 选项
将主要的检索旋钮作为 CLI 选项暴露,以便您可以在不编辑代码的情况下调整机器人:| 选项 | 默认值 | 控制内容 |
|---|---|---|
--candidate-k | 8 | 要重新排序的向量搜索结果数 |
--top-k | 4 | 发送到聊天模型的重新排序 chunk 数 |
--chunk-size | 1000 | 重叠前的最大 chunk 大小 |
--chunk-overlap | 150 | 相邻 chunk 之间重复的字符 |
--embedding-batch-size | 32 | 每个 Venice 嵌入请求的 chunk 数 |
--qdrant-path | 未设置 | 本地持久化 Qdrant 存储路径 |
--qdrant-url | 未设置 | 远程 Qdrant URL |
--skip-ingest | false | 查询现有集合而不重新加载文档 |
--recreate-collection | false | 删除并重建 Qdrant 集合 |
隐私注意事项
对于私有 RAG 设置,请单独考虑每一层:| 层 | 隐私考虑 |
|---|---|
| Venice 嵌入 | 文档 chunk 被发送到 Venice 以创建向量 |
| Venice 聊天 | 检索到的上下文被发送到 Venice 以回答问题 |
| Qdrant 本地 | 向量和 payload 留在您的机器上 |
| Qdrant 远程 | 向量和 payload 存储在 Qdrant 服务器运行的位置 |
| FastEmbed 重排序器 | 模型可用后重新排序在本地运行 |
需要预先处理的常见错误
| 症状 | 通常意味着什么 | 该做什么 |
|---|---|---|
Set VENICE_API_KEY before running this example. | 环境变量缺失 | 在运行脚本之前导出 VENICE_API_KEY |
Document path does not exist | 传递给 --docs 的路径错误 | 检查文件或文件夹路径 |
| 空检索结果 | 未摄取任何内容,或正在查询错误的集合 | 移除 --skip-ingest 或确认 --collection 和 --qdrant-path |
| Qdrant 向量大小错误 | 集合使用不同的嵌入模型创建 | 更改嵌入模型后重建集合 |
| 首次重排序缓慢 | FastEmbed 可能正在下载或初始化 cross-encoder | 让首次运行完成,后续运行应该更快 |
接下来去哪里
一旦您让基线运行起来,最高影响的改进通常是:- 添加针对 PDF、HTML、工单或内部 wiki 页面的文档特定加载器。
- 存储更丰富的元数据,如标题、标头、日期、所有者和 URL。
- 在实际问题上调整
candidate_k、top_k、chunk 大小和重叠。 - 添加评估问题,以便您可以衡量更改前后的检索质量。
- 流式传输最终的 Venice 聊天补全以获得更好的交互式聊天体验。