Skip to content

Pinecone详解 ​

版本基线:本文基于 LangChain 1.x,向量库使用官方独立集成包,更新于 2026-09。

概述 ​

Pinecone是全托管的云原生向量数据库,专为机器学习应用设计。它以零运维、自动扩展和易用性著称,是快速上线生产环境的理想选择。

核心特点 ​

特性说明
全托管零运维,无需管理基础设施
自动扩展根据负载自动扩展资源
低延迟毫秒级查询响应
高可用99.95% SLA保证
易用性简洁的API,快速上手
安全SOC2认证,数据加密

安装与配置 ​

创建账号 ​

  1. 访问 pinecone.io 注册账号
  2. 创建API密钥
  3. 创建索引(Index)

Python客户端安装 ​

bash
# 包名已从 pinecone-client 更名为 pinecone
pip install pinecone

# LangChain 集成包(1.x 起为官方独立集成包)
pip install langchain-pinecone

初始化配置 ​

python
import os
from pinecone import Pinecone

# 新版 SDK:不再使用 pinecone.init(),改为实例化 Pinecone 客户端
pc = Pinecone(api_key=os.environ["PINECONE_API_KEY"])

# 查看索引列表
print(pc.list_indexes())

核心API详解 ​

1. 索引管理 ​

python
import os
from pinecone import Pinecone, ServerlessSpec

pc = Pinecone(api_key=os.environ["PINECONE_API_KEY"])

# 创建索引(新版默认推荐 Serverless)
pc.create_index(
    name="documents",
    dimension=768,           # 向量维度
    metric="cosine",         # 距离度量: cosine, euclidean, dotproduct
    spec=ServerlessSpec(
        cloud="aws",
        region="us-east-1"
    )
)

# 列出所有索引
indexes = pc.list_indexes()
print(f"索引列表: {indexes}")

# 获取索引信息
index_info = pc.describe_index("documents")
print(f"维度: {index_info.dimension}")
print(f"度量: {index_info.metric}")

# 删除索引
pc.delete_index("documents")

2. 连接索引 ​

python
# 连接到索引
index = pc.Index("documents")

# 获取索引统计
stats = index.describe_index_stats()
print(f"向量数量: {stats.total_vector_count}")
print(f"维度: {stats.dimension}")

3. 数据操作 ​

python
import numpy as np

# 插入数据
index.upsert(
    vectors=[
        {
            "id": "doc1",
            "values": np.random.random(768).tolist(),
            "metadata": {
                "text": "这是第一篇文档",
                "source": "web",
                "year": 2023
            }
        },
        {
            "id": "doc2",
            "values": np.random.random(768).tolist(),
            "metadata": {
                "text": "这是第二篇文档",
                "source": "book",
                "year": 2022
            }
        }
    ]
)

# 批量插入
def batch_upsert(index, vectors, batch_size=100):
    """批量插入向量"""
    for i in range(0, len(vectors), batch_size):
        batch = vectors[i:i+batch_size]
        index.upsert(vectors=batch)
        print(f"已插入 {min(i+batch_size, len(vectors))}/{len(vectors)}")

# 删除向量
index.delete(ids=["doc1", "doc2"])

# 按命名空间删除
index.delete(delete_all=True, namespace="ns1")

4. 查询操作 ​

python
import numpy as np

# 向量查询
query_vector = np.random.random(768).tolist()

results = index.query(
    vector=query_vector,
    top_k=5,
    include_values=False,
    include_metadata=True
)

# 遍历结果
for match in results.matches:
    print(f"ID: {match.id}")
    print(f"分数: {match.score:.4f}")
    print(f"元数据: {match.metadata}")

# 带过滤的查询
results = index.query(
    vector=query_vector,
    top_k=5,
    filter={
        "source": {"$eq": "web"},
        "year": {"$gte": 2023}
    },
    include_metadata=True
)

# 复杂过滤
results = index.query(
    vector=query_vector,
    top_k=5,
    filter={
        "$and": [
            {"source": {"$in": ["web", "book"]}},
            {"year": {"$gte": 2020, "$lte": 2024}},
            {"category": {"$ne": "spam"}}
        ]
    },
    include_metadata=True
)

5. 命名空间 ​

python
# 使用命名空间隔离数据
index.upsert(
    vectors=[
        {"id": "doc1", "values": [...], "metadata": {...}}
    ],
    namespace="production"
)

index.upsert(
    vectors=[
        {"id": "doc1", "values": [...], "metadata": {...}}
    ],
    namespace="staging"
)

# 在指定命名空间查询
results = index.query(
    vector=query_vector,
    top_k=5,
    namespace="production",
    include_metadata=True
)

# 删除命名空间
index.delete(delete_all=True, namespace="staging")

6. 批量查询 ​

python
# 批量查询
query_vectors = [
    np.random.random(768).tolist(),
    np.random.random(768).tolist(),
    np.random.random(768).tolist()
]

results = index.query(
    vector=query_vectors[0],
    top_k=5,
    include_metadata=True
)

# 或使用async进行并发查询
import asyncio
import os
# 异步支持需要额外安装:pip install "pinecone[asyncio]"
from pinecone import Pinecone

pc = Pinecone(api_key=os.environ["PINECONE_API_KEY"])

async def batch_query(vectors, top_k=5):
    """批量并发查询"""
    async_index = pc.IndexAsyncio("documents")

    tasks = [
        async_index.query(vector=v, top_k=top_k)
        for v in vectors
    ]

    results = await asyncio.gather(*tasks)
    await async_index.close()
    return results

与LangChain集成 ​

python
import os
from langchain_pinecone import PineconeVectorStore
from langchain_openai import OpenAIEmbeddings
from pinecone import Pinecone

# 初始化Pinecone客户端(替代旧的 pinecone.init())
pc = Pinecone(api_key=os.environ["PINECONE_API_KEY"])

# 创建向量存储
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

vectorstore = PineconeVectorStore.from_documents(
    documents=docs,
    embedding=embeddings,
    index_name="documents",
    namespace="production"
)

# 或从现有索引加载
vectorstore = PineconeVectorStore.from_existing_index(
    index_name="documents",
    embedding=embeddings,
    namespace="production"
)

# 相似性搜索
results = vectorstore.similarity_search("查询内容", k=3)

# 带过滤的搜索
results = vectorstore.similarity_search(
    "查询内容",
    k=3,
    filter={"source": "web"}
)

# 检索器
retriever = vectorstore.as_retriever(
    search_kwargs={"k": 5, "filter": {"year": {"$gte": 2023}}}
)

产品类型对比 ​

类型价格性能适用场景
Starter免费低学习和原型
Standard按量付费中小规模生产
Enterprise定制高大规模生产
Dedicated定制最高关键业务

最佳实践 ​

1. 命名空间策略 ​

python
# 按环境隔离
namespaces = {
    "dev": "开发环境",
    "staging": "预发布环境",
    "production": "生产环境"
}

# 按数据类型隔离
namespaces = {
    "documents": "文档数据",
    "conversations": "对话数据",
    "user_profiles": "用户数据"
}

2. 元数据设计 ​

python
# 合理设计元数据结构
metadata_schema = {
    "text": str,           # 文本内容
    "source": str,         # 数据来源
    "year": int,          # 年份
    "category": str,       # 类别
    "tags": list,          # 标签
    "importance": float,   # 重要性分数
    "created_at": str      # 创建时间
}

3. 性能优化 ​

python
# 选择合适的Pod类型
pod_types = {
    "s1": {"vcpu": 0.5, "memory": 0.5, "storage": 2},
    "p1": {"vcpu": 1, "memory": 1, "storage": 5},
    "p2": {"vcpu": 2, "memory": 2, "storage": 10}
}

# 根据数据量选择
def choose_pod_type(num_vectors, dimension):
    """根据数据量选择Pod类型"""
    memory_needed = num_vectors * dimension * 4 / 1024 / 1024 / 1024  # GB
    
    if memory_needed < 1:
        return "s1.x1"
    elif memory_needed < 5:
        return "p1.x1"
    else:
        return "p2.x1"

适用场景 ​

场景推荐度说明
快速上线⭐⭐⭐⭐⭐全托管,无需运维
生产环境⭐⭐⭐⭐⭐高可用,自动扩展
团队小⭐⭐⭐⭐⭐无需专业运维
预算充足⭐⭐⭐⭐按量付费
原型开发⭐⭐⭐⭐Starter免费
大规模数据⭐⭐⭐⭐支持十亿级

局限性 ​

  1. 成本较高 - 大规模使用成本不低
  2. 供应商锁定 - 数据迁移到其他平台困难
  3. 功能有限 - 相比开源方案功能较少
  4. 网络依赖 - 需要稳定的网络连接

与其他方案对比 ​

对比维度PineconeMilvusQdrant
部署方式全托管自部署自部署
运维成本零高中
成本按量付费硬件成本硬件成本
灵活性低高高
扩展性自动手动手动

下一步学习 ​