向量数据库与 RAG(Retrieval-Augmented Generation)实践指南

向量数据库与 RAG 实践指南:从原理到 Pinecone Demo 完整搭建

本文介绍大模型局限性、向量数据库、RAG 架构、检索优化,并以 c0616.py 为例,手把手完成一个基于 Pinecone 的语义检索 Demo。


目录

  1. 大模型局限性
  2. [RAG 解决方案](#RAG 解决方案)
  3. 向量数据库基础
  4. 向量数据库选型
  5. 离线索引优化
  6. 在线检索优化
  7. [企业级 RAG 架构](#企业级 RAG 架构)
  8. [Pinecone 实战:c0616.py Demo 从零搭建](#Pinecone 实战:c0616.py Demo 从零搭建)
  9. 总结

一、大模型局限性

1. 缺乏领域特定知识

  • 无法掌握企业私有数据
  • 无法理解内部业务文档

2. 容易产生幻觉

  • 超出知识范围时可能编造答案

3. 无法获取最新知识

  • 模型训练完成后知识固定

4. 预训练数据不可修改

  • 错误知识难以修复
  • 过时知识难以及时删除

二、RAG 解决方案

RAG(Retrieval-Augmented Generation,检索增强生成)的核心思想:

text 复制代码
先检索,再生成

完整流程:

text 复制代码
用户问题
    ↓
知识库检索
    ↓
相关知识片段
    ↓
Prompt 增强
    ↓
LLM 生成答案

本文 Demo(c0616.py)实现了其中 「知识库检索」 这一环:把文本写入 Pinecone,按问题做语义搜索,返回最相关的知识片段。接入 ChatGPT 生成答案,则是下一步扩展。


三、向量数据库基础

Embedding(向量嵌入)

Embedding 是把文本转换成一串数字(向量),让计算机能按「意思相近」来比较和搜索:

text 复制代码
文本
 ↓
Embedding Model
 ↓
向量(如 1024 或 3072 维浮点数)

语义越接近的文本,向量在空间中距离越近,因此可以做语义搜索,而不只是匹配相同关键词。

常见 Embedding 模型

模型 特点
OpenAI text-embedding-3-large 3072 维,英文表现强,需自行调用 OpenAI API
multilingual-e5-large 1024 维,多语言友好,Pinecone 可托管
BGE-M3 中英文效果好,开源可自部署
GTE / M3E 中文场景常用

本 Demo 选用 multilingual-e5-large:Pinecone 集成索引可直接传文本,无需单独部署 Embedding 服务。

三个核心概念

概念 含义
Index(索引) 向量数据库的「表」,存放所有向量
Namespace(命名空间) 索引内的逻辑分区,用于隔离不同业务数据
Record(记录) 一条知识片段,通常包含 idtext

四、向量数据库选型

国内

  • Milvus
  • Zilliz Cloud
  • 腾讯云 VectorDB

国外

  • Pinecone(本文选用)
  • PGVector
  • Redis
  • FAISS
  • Elasticsearch

Pinecone 的优势在于:托管服务、上手快、支持集成 Embedding,适合快速验证 RAG 检索链路。


五、离线索引优化

离线索引指写入知识库之前的优化,决定「存什么、怎么存」。

Embedding 模型优化

根据语言和业务场景选择模型。中文知识库优先考虑多语言或中文专用模型(如 multilingual-e5-large、BGE-M3)。

Chunk 切分优化

长文档不宜整段入库,推荐切分策略:

text 复制代码
每段约 500 字
+
100 字 Overlap(重叠,避免语义被截断)

Doc2Query

将文档自动转换为问题,用「问题」去匹配用户的「问题」,提升召回率:

text 复制代码
文档:MyBatis 一级缓存是 SqlSession 级缓存

生成问题:
- MyBatis 一级缓存是什么?
- MyBatis 一级缓存原理是什么?

本 Demo 的 RECORDS 中 vec4、vec5 即对应离线与在线优化相关知识点。


六、在线检索优化

在线检索指用户提问之后的优化,决定「怎么搜、搜什么」。

Query Rewrite(问题改写)

text 复制代码
用户问题
 ↓
LLM 改写
 ↓
向量检索

示例:

text 复制代码
原始:若依框架怎么实现数据权限控制?
改写:若依框架部门数据权限实现原理

Hybrid Search(混合检索)

结合多种检索方式,再融合结果:

text 复制代码
Vector Search(向量检索)
      ↘
       结果融合(Rerank / 加权)
      ↗
BM25 Search(全文检索)

还可叠加标签检索、图谱检索等。

HyDE(Hypothetical Document Embeddings)

text 复制代码
用户问题
 ↓
LLM 生成「假答案」文档
 ↓
对假文档做 Embedding
 ↓
向量检索
 ↓
召回真实文档

本 Demo 的 RECORDS 中 vec4 涵盖了上述在线优化思路。


七、企业级 RAG 架构

将离线与在线优化组合,形成完整企业级链路:

text 复制代码
用户问题
    ↓
Query Rewriting
    ↓
HyDE
    ↓
多路召回
  ↙      ↘
向量检索  BM25
  ↘      ↙
结果融合
    ↓
Reranking
    ↓
LLM 回答

最佳实践全景:
#mermaid-svg-gv65UVkbZQyItIN9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gv65UVkbZQyItIN9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gv65UVkbZQyItIN9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gv65UVkbZQyItIN9 .error-icon{fill:#552222;}#mermaid-svg-gv65UVkbZQyItIN9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gv65UVkbZQyItIN9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gv65UVkbZQyItIN9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gv65UVkbZQyItIN9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gv65UVkbZQyItIN9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gv65UVkbZQyItIN9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gv65UVkbZQyItIN9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gv65UVkbZQyItIN9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gv65UVkbZQyItIN9 .marker.cross{stroke:#333333;}#mermaid-svg-gv65UVkbZQyItIN9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gv65UVkbZQyItIN9 p{margin:0;}#mermaid-svg-gv65UVkbZQyItIN9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gv65UVkbZQyItIN9 .cluster-label text{fill:#333;}#mermaid-svg-gv65UVkbZQyItIN9 .cluster-label span{color:#333;}#mermaid-svg-gv65UVkbZQyItIN9 .cluster-label span p{background-color:transparent;}#mermaid-svg-gv65UVkbZQyItIN9 .label text,#mermaid-svg-gv65UVkbZQyItIN9 span{fill:#333;color:#333;}#mermaid-svg-gv65UVkbZQyItIN9 .node rect,#mermaid-svg-gv65UVkbZQyItIN9 .node circle,#mermaid-svg-gv65UVkbZQyItIN9 .node ellipse,#mermaid-svg-gv65UVkbZQyItIN9 .node polygon,#mermaid-svg-gv65UVkbZQyItIN9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gv65UVkbZQyItIN9 .rough-node .label text,#mermaid-svg-gv65UVkbZQyItIN9 .node .label text,#mermaid-svg-gv65UVkbZQyItIN9 .image-shape .label,#mermaid-svg-gv65UVkbZQyItIN9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-gv65UVkbZQyItIN9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gv65UVkbZQyItIN9 .rough-node .label,#mermaid-svg-gv65UVkbZQyItIN9 .node .label,#mermaid-svg-gv65UVkbZQyItIN9 .image-shape .label,#mermaid-svg-gv65UVkbZQyItIN9 .icon-shape .label{text-align:center;}#mermaid-svg-gv65UVkbZQyItIN9 .node.clickable{cursor:pointer;}#mermaid-svg-gv65UVkbZQyItIN9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gv65UVkbZQyItIN9 .arrowheadPath{fill:#333333;}#mermaid-svg-gv65UVkbZQyItIN9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gv65UVkbZQyItIN9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gv65UVkbZQyItIN9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gv65UVkbZQyItIN9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gv65UVkbZQyItIN9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gv65UVkbZQyItIN9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gv65UVkbZQyItIN9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gv65UVkbZQyItIN9 .cluster text{fill:#333;}#mermaid-svg-gv65UVkbZQyItIN9 .cluster span{color:#333;}#mermaid-svg-gv65UVkbZQyItIN9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gv65UVkbZQyItIN9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gv65UVkbZQyItIN9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-gv65UVkbZQyItIN9 .icon-shape,#mermaid-svg-gv65UVkbZQyItIN9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gv65UVkbZQyItIN9 .icon-shape p,#mermaid-svg-gv65UVkbZQyItIN9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gv65UVkbZQyItIN9 .icon-shape .label rect,#mermaid-svg-gv65UVkbZQyItIN9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gv65UVkbZQyItIN9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gv65UVkbZQyItIN9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gv65UVkbZQyItIN9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 企业文档
Chunk 切分
Embedding
Pinecone
用户问题
Query Rewrite
向量检索
Top K 知识片段
Prompt 组装
GPT-4
最终答案

第八章的 Demo 实现了上图中的 C → D → G → H 段。


八、Pinecone 实战:c0616.py Demo 从零搭建

8.1 实现目标

构建一个可运行的私人知识库检索 Demo:

text 复制代码
RAG 知识片段(文本)
    ↓
Embedding(Pinecone 自动完成)
    ↓
写入 Pinecone
    ↓
用户提问
    ↓
语义检索(返回 Top K)
    ↓
(扩展)拼接 Prompt → GPT 回答

8.2 项目结构

text 复制代码
pythonProject1/
├── .env              # API Key(勿提交 git)
├── .env.example      # 环境变量模板
├── .gitignore
├── env_config.py     # 从 .env 加载密钥
└── c0616.py          # 主 Demo 脚本

8.3 阶段一:准备 Python 环境

bash 复制代码
# 创建并激活 conda 环境
conda create -n py310 python=3.10 -y
conda activate py310

# 安装依赖
pip install pinecone python-dotenv

# 验证
python -c "import pinecone; print(pinecone.__version__)"

若 conda 下载失败,检查 ~/.condarc 代理配置。不要把 API Key 写入 ~/.zshrc ,应使用项目级 .env 文件。

8.4 阶段二:注册 Pinecone 并获取 API Key

  1. 打开 app.pinecone.io 注册账号
  2. 进入 API Keys → 创建 Key
  3. 复制形如 pcsk_... 的 Key

8.5 阶段三:配置项目密钥

创建 .env 文件:

bash 复制代码
PINECONE_API_KEY=your-pinecone-api-key

创建 env_config.py

python 复制代码
import os
from pathlib import Path
from dotenv import load_dotenv

_ENV_PATH = Path(__file__).resolve().parent / ".env"
load_dotenv(_ENV_PATH)


def get_api_key(name: str) -> str:
    value = os.environ.get(name, "").strip()
    if not value:
        raise ValueError(f"请在 {_ENV_PATH} 中设置 {name}")
    return value

创建 .gitignore

text 复制代码
.env
__pycache__/
.idea/

8.6 阶段四:验证 Pinecone 连接

python 复制代码
from pinecone import Pinecone
from env_config import get_api_key

pc = Pinecone(api_key=get_api_key("PINECONE_API_KEY"))
print("已有索引:", [i.name for i in pc.list_indexes()])

能打印索引列表即表示连接成功。

8.7 阶段五:理解集成索引

本 Demo 使用 集成 Embedding 索引 ,只需传 text,Pinecone 用 multilingual-e5-large 自动完成向量化:

类型 写入方式 适用场景
普通索引 自行生成向量,调用 upsert 使用 OpenAI 等外部 Embedding
集成索引 直接传 text,调用 upsert_records 快速上手,Pinecone 托管 Embedding

核心配置:

python 复制代码
INDEX_NAME = "0616clanguage-ii"
NAMESPACE = "0616clanguage-namespace"
EMBED_MODEL = "multilingual-e5-large"

创建集成索引的代码(索引不存在时自动执行):

python 复制代码
pc.create_index_for_model(
    name=INDEX_NAME,
    cloud="aws",
    region="us-east-1",
    embed={
        "model": EMBED_MODEL,
        "field_map": {"text": "text"},
        "write_parameters": {"input_type": "passage"},
        "read_parameters": {"input_type": "query"},
    },
)

8.8 阶段六:准备知识库数据

Demo 内置 6 条 RAG 相关知识片段:

python 复制代码
RECORDS = [
    {"id": "vec1", "text": "从 Pinecone 获取指定的索引将 Prompt 转换为向量数据,从向量数据库提取相似数据将提取的数据与 Prompt 重新构建输入,发送给 ChatGPT,ChatGPT 整理内容后输出结果"},
    {"id": "vec2", "text": "向量的相似度原理以及设计、向量数据库架构原理以及设计、Embedding Model 原理以及选型、向量数据库应用性能优化、向量数据库应用治理、向量数据库 Ops."},
    {"id": "vec3", "text": "将私人数据转换为向量数据,并写入到向量数据库中根据 Prompt 从向量数据库中提取相似数据结合相似数据重新组装 Prompt,让 ChatGPT 生成回答"},
    {"id": "vec4", "text": "在线检索更多优化用户问题改写,使用改写的问题召回多路召回,结合全文检索的结果把问题编造成"假"文档,使用"假"文档召回"},
    {"id": "vec5", "text": "离线索引更多优化针对文档特性(语言、内容)选择 Embedding 模型更有针对性的文档分段模型文档转问题,用问题召回"},
    {"id": "vec6", "text": "文档检索增强(Retrieval Augmented Generation)利用提前构建好的知识库,通过检索与 Query 相关的知识片段来增强大模型回答效果."},
]

QUERY_TEXT = "Tell me about the RAG"
id 对应章节
vec1 RAG 基本流程
vec2 向量数据库基础(第三章)
vec3 RAG 私人知识库
vec4 在线检索优化(第六章)
vec5 离线索引优化(第五章)
vec6 RAG 定义

8.9 阶段七:完整代码(c0616.py

python 复制代码
import time
from pinecone import Pinecone
from env_config import get_api_key

INDEX_NAME = "0616clanguage-ii"
NAMESPACE = "0616clanguage-namespace"
EMBED_MODEL = "multilingual-e5-large"

RECORDS = [
    {"id": "vec1", "text": "从 Pinecone 获取指定的索引将 Prompt 转换为向量数据,从向量数据库提取相似数据将提取的数据与 Prompt 重新构建输入,发送给 ChatGPT,ChatGPT 整理内容后输出结果"},
    {"id": "vec2", "text": "向量的相似度原理以及设计、向量数据库架构原理以及设计、Embedding Model 原理以及选型、向量数据库应用性能优化、向量数据库应用治理、向量数据库 Ops."},
    {"id": "vec3", "text": "将私人数据转换为向量数据,并写入到向量数据库中根据 Prompt 从向量数据库中提取相似数据结合相似数据重新组装 Prompt,让 ChatGPT 生成回答"},
    {"id": "vec4", "text": "在线检索更多优化用户问题改写,使用改写的问题召回多路召回,结合全文检索的结果把问题编造成"假"文档,使用"假"文档召回"},
    {"id": "vec5", "text": "离线索引更多优化针对文档特性(语言、内容)选择 Embedding 模型更有针对性的文档分段模型文档转问题,用问题召回"},
    {"id": "vec6", "text": "文档检索增强(Retrieval Augmented Generation)利用提前构建好的知识库,通过检索与 Query 相关的知识片段来增强大模型回答效果."},
]

QUERY_TEXT = "Tell me about the RAG"


def ensure_integrated_index(pc: Pinecone) -> None:
    """确保存在带集成 embedding 的索引。"""
    if pc.has_index(INDEX_NAME):
        desc = pc.describe_index(INDEX_NAME)
        if desc.embed is None:
            raise ValueError(
                f"索引 {INDEX_NAME} 未配置集成 embedding。\n"
                "请在 Pinecone 控制台删除后重试,或修改 INDEX_NAME。"
            )
        print(f"使用已有索引: {INDEX_NAME}")
        return

    print(f"正在创建集成 embedding 索引: {INDEX_NAME} ...")
    pc.create_index_for_model(
        name=INDEX_NAME,
        cloud="aws",
        region="us-east-1",
        embed={
            "model": EMBED_MODEL,
            "field_map": {"text": "text"},
            "write_parameters": {"input_type": "passage"},
            "read_parameters": {"input_type": "query"},
        },
    )
    print(f"索引 {INDEX_NAME} 创建完成")


def upsert_records(index, records: list[dict]) -> None:
    response = index.upsert_records(namespace=NAMESPACE, records=records)
    print(f"已写入 {response.record_count} 条记录到 namespace: {NAMESPACE}")


def search_records(index, query_text: str, top_k: int = 3):
    return index.search(
        namespace=NAMESPACE,
        top_k=top_k,
        inputs={"text": query_text},
    )


def print_results(results) -> None:
    print(f"\n查询: {QUERY_TEXT}\n")
    for hit in results.result.hits:
        text = hit.fields.get("text", "") if hit.fields else ""
        print(f"  id={hit.id}  score={hit.score:.4f}")
        print(f"  text={text}\n")


def main() -> None:
    pc = Pinecone(api_key=get_api_key("PINECONE_API_KEY"))
    ensure_integrated_index(pc)
    index = pc.Index(INDEX_NAME)
    upsert_records(index, RECORDS)
    time.sleep(2)
    results = search_records(index, QUERY_TEXT)
    print_results(results)


if __name__ == "__main__":
    main()

8.10 代码结构说明

text 复制代码
c0616.py
├── 配置常量          INDEX_NAME / NAMESPACE / EMBED_MODEL / RECORDS / QUERY_TEXT
├── ensure_integrated_index()   检查或创建集成索引
├── upsert_records()            写入知识片段
├── search_records()            语义搜索,返回 top_k
├── print_results()             打印 id、score、text
└── main()                      串联完整流程

8.11 执行流程

#mermaid-svg-1QAvQao7eUCtInD5{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1QAvQao7eUCtInD5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1QAvQao7eUCtInD5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1QAvQao7eUCtInD5 .error-icon{fill:#552222;}#mermaid-svg-1QAvQao7eUCtInD5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1QAvQao7eUCtInD5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1QAvQao7eUCtInD5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1QAvQao7eUCtInD5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1QAvQao7eUCtInD5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1QAvQao7eUCtInD5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1QAvQao7eUCtInD5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1QAvQao7eUCtInD5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1QAvQao7eUCtInD5 .marker.cross{stroke:#333333;}#mermaid-svg-1QAvQao7eUCtInD5 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1QAvQao7eUCtInD5 p{margin:0;}#mermaid-svg-1QAvQao7eUCtInD5 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1QAvQao7eUCtInD5 .cluster-label text{fill:#333;}#mermaid-svg-1QAvQao7eUCtInD5 .cluster-label span{color:#333;}#mermaid-svg-1QAvQao7eUCtInD5 .cluster-label span p{background-color:transparent;}#mermaid-svg-1QAvQao7eUCtInD5 .label text,#mermaid-svg-1QAvQao7eUCtInD5 span{fill:#333;color:#333;}#mermaid-svg-1QAvQao7eUCtInD5 .node rect,#mermaid-svg-1QAvQao7eUCtInD5 .node circle,#mermaid-svg-1QAvQao7eUCtInD5 .node ellipse,#mermaid-svg-1QAvQao7eUCtInD5 .node polygon,#mermaid-svg-1QAvQao7eUCtInD5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1QAvQao7eUCtInD5 .rough-node .label text,#mermaid-svg-1QAvQao7eUCtInD5 .node .label text,#mermaid-svg-1QAvQao7eUCtInD5 .image-shape .label,#mermaid-svg-1QAvQao7eUCtInD5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-1QAvQao7eUCtInD5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1QAvQao7eUCtInD5 .rough-node .label,#mermaid-svg-1QAvQao7eUCtInD5 .node .label,#mermaid-svg-1QAvQao7eUCtInD5 .image-shape .label,#mermaid-svg-1QAvQao7eUCtInD5 .icon-shape .label{text-align:center;}#mermaid-svg-1QAvQao7eUCtInD5 .node.clickable{cursor:pointer;}#mermaid-svg-1QAvQao7eUCtInD5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1QAvQao7eUCtInD5 .arrowheadPath{fill:#333333;}#mermaid-svg-1QAvQao7eUCtInD5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1QAvQao7eUCtInD5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1QAvQao7eUCtInD5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1QAvQao7eUCtInD5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1QAvQao7eUCtInD5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1QAvQao7eUCtInD5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1QAvQao7eUCtInD5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1QAvQao7eUCtInD5 .cluster text{fill:#333;}#mermaid-svg-1QAvQao7eUCtInD5 .cluster span{color:#333;}#mermaid-svg-1QAvQao7eUCtInD5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1QAvQao7eUCtInD5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1QAvQao7eUCtInD5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-1QAvQao7eUCtInD5 .icon-shape,#mermaid-svg-1QAvQao7eUCtInD5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1QAvQao7eUCtInD5 .icon-shape p,#mermaid-svg-1QAvQao7eUCtInD5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1QAvQao7eUCtInD5 .icon-shape .label rect,#mermaid-svg-1QAvQao7eUCtInD5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1QAvQao7eUCtInD5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1QAvQao7eUCtInD5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1QAvQao7eUCtInD5 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否

启动 main
读取 PINECONE_API_KEY
ensure_integrated_index
索引是否存在?
create_index_for_model
验证 embed 配置
pc.Index 连接索引
upsert_records 写入 6 条
等待 2 秒
search_records 语义搜索
print_results 输出 top 3

对应业务含义:

text 复制代码
读取知识文档(RECORDS)
      ↓
Embedding(Pinecone + multilingual-e5-large 自动完成)
      ↓
写入 Pinecone(upsert_records)
      ↓
用户提问(QUERY_TEXT)
      ↓
Query 向量化 + 相似度检索(search)
      ↓
返回 Top K 结果
      ↓
(扩展)拼接 Prompt → GPT 生成回答

8.12 运行 Demo

bash 复制代码
conda activate py310
cd pythonProject1
python c0616.py

成功输出示例:

text 复制代码
使用已有索引: 0616clanguage-ii
已写入 6 条记录到 namespace: 0616clanguage-namespace

查询: Tell me about the RAG

  id=vec6  score=0.xxxx
  text=文档检索增强(Retrieval Augmented Generation)...

  id=vec1  score=0.xxxx
  text=从 Pinecone 获取指定的索引...

  id=vec3  score=0.xxxx
  text=将私人数据转换为向量数据...

查询 "Tell me about the RAG" 时,vec6(RAG 定义)通常排在最前,说明语义检索生效。

8.13 常见问题

问题 原因 解决
请设置环境变量 PINECONE_API_KEY 未配置 .env 复制 .env.example.env 并填写
Integrated inference is not configured 对普通索引使用了 upsert_records 使用集成索引 0616clanguage-ii
conda 下载失败 代理端口错误 检查 ~/.condarcproxy_servers
搜索结果为空 namespace 不一致 写入与查询使用同一 namespace
Key 更换不生效 ~/.zshrc 中有旧 export 注释 .zshrc 中的 Key,改用 .env

九、总结

推荐企业级 RAG 技术栈

层级 推荐方案
Embedding multilingual-e5-large、BGE-M3
Vector DB Pinecone、Milvus
Rerank BGE-Reranker-v2
LLM GPT、Claude、DeepSeek、Qwen

本文 Demo 覆盖了什么

  • 理论:大模型局限、RAG 流程、向量库基础、离线与在线优化、企业级架构
  • 实战:从环境准备到 c0616.py 完整可运行的 Pinecone 语义检索 Demo

下一步扩展

c0616.py 检索结果基础上,将 Top K 知识片段与用户问题组装为 Prompt,调用 GPT 生成最终答案,即完成完整 RAG 闭环:

text 复制代码
search 结果 + 用户问题 → Prompt → GPT → 最终答案

参考链接