向量数据库与 RAG 实践指南:从原理到 Pinecone Demo 完整搭建
本文介绍大模型局限性、向量数据库、RAG 架构、检索优化,并以
c0616.py为例,手把手完成一个基于 Pinecone 的语义检索 Demo。
目录
- 大模型局限性
- [RAG 解决方案](#RAG 解决方案)
- 向量数据库基础
- 向量数据库选型
- 离线索引优化
- 在线检索优化
- [企业级 RAG 架构](#企业级 RAG 架构)
- [Pinecone 实战:c0616.py Demo 从零搭建](#Pinecone 实战:c0616.py Demo 从零搭建)
- 总结
一、大模型局限性
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(记录) | 一条知识片段,通常包含 id 和 text |
四、向量数据库选型
国内
- 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
- 打开 app.pinecone.io 注册账号
- 进入 API Keys → 创建 Key
- 复制形如
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 下载失败 | 代理端口错误 | 检查 ~/.condarc 中 proxy_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 → 最终答案