Розробка RAG з векторною базою даних Pinecone

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1566 послуг
Розробка RAG з векторною базою даних Pinecone
Середній
від 1 тижня до 3 місяців
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1285
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1197
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    902
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1119
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    853

Розробка RAG з векторною базою даних Pinecone

Pinecone — керована векторна база даних з REST/gRPC API, автоматичним масштабуванням та підтримкою гібридного пошуку (sparse + dense). Не вимагає управління інфраструктурою, легко масштабується від прототипу до мільйонів векторів. Pinecone Serverless (з 2024 року) дозволяє працювати без попереднього резервування ресурсів — платите лише за фактичні операції.

Ініціалізація та створення індексу

from pinecone import Pinecone, ServerlessSpec
from openai import OpenAI

pc = Pinecone(api_key="...")

# Створення serverless індексу
pc.create_index(
    name="corporate-knowledge-base",
    dimension=3072,        # text-embedding-3-large
    metric="cosine",
    spec=ServerlessSpec(
        cloud="aws",
        region="us-east-1"
    )
)

index = pc.Index("corporate-knowledge-base")

Індексація документів з метаданими

from langchain_openai import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
import hashlib

embeddings_model = OpenAIEmbeddings(model="text-embedding-3-large")

def index_documents(documents: list, batch_size: int = 100):
    splitter = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=64)
    chunks = splitter.split_documents(documents)

    # Батчева індексація
    for i in range(0, len(chunks), batch_size):
        batch = chunks[i:i + batch_size]

        texts = [c.page_content for c in batch]
        vectors = embeddings_model.embed_documents(texts)

        # Формуємо записи для Pinecone
        records = []
        for chunk, vector in zip(batch, vectors):
            doc_id = hashlib.md5(chunk.page_content.encode()).hexdigest()
            records.append({
                "id": doc_id,
                "values": vector,
                "metadata": {
                    "text": chunk.page_content,
                    "source": chunk.metadata.get("source", ""),
                    "page": chunk.metadata.get("page", 0),
                    "doc_type": chunk.metadata.get("doc_type", "general"),
                    "date": chunk.metadata.get("date", ""),
                }
            })

        index.upsert(vectors=records)
        print(f"Indexed batch {i//batch_size + 1}: {len(records)} chunks")

Запит з фільтрацією за метаданими

def rag_query(
    query: str,
    doc_type_filter: str = None,
    top_k: int = 5
) -> dict:

    # Embedding запиту
    query_vector = embeddings_model.embed_query(query)

    # Формуємо фільтр
    filter_dict = {}
    if doc_type_filter:
        filter_dict["doc_type"] = {"$eq": doc_type_filter}

    # Пошук
    results = index.query(
        vector=query_vector,
        top_k=top_k,
        include_metadata=True,
        filter=filter_dict if filter_dict else None
    )

    # Формуємо контекст
    context_chunks = []
    for match in results["matches"]:
        context_chunks.append({
            "text": match["metadata"]["text"],
            "source": match["metadata"]["source"],
            "score": match["score"]
        })

    return context_chunks

Гібридний пошук у Pinecone

Pinecone підтримує гібридний пошук (dense + sparse) через вбудований BM25:

from pinecone_text.sparse import BM25Encoder

# Навчання BM25 на корпусі документів
bm25 = BM25Encoder()
bm25.fit(all_texts)

def hybrid_query(query: str, alpha: float = 0.5, top_k: int = 5) -> list:
    """
    alpha=1.0: лише dense
    alpha=0.0: лише sparse (BM25)
    alpha=0.5: рівна вага обом
    """
    # Dense вектор
    dense_vector = embeddings_model.embed_query(query)

    # Sparse вектор (BM25)
    sparse_vector = bm25.encode_queries(query)

    results = index.query(
        vector=dense_vector,
        sparse_vector=sparse_vector,
        top_k=top_k,
        include_metadata=True,
        alpha=alpha,
    )
    return results["matches"]

Практичний кейс: корпоративна база знань ритейлера

Масштаб: 45 000 SKU з описами, 3200 сторінок регламентів, 800 FAQ-записів. Разом ~180 000 векторів.

Конфігурація: Pinecone Serverless (aws/us-east-1), dimension=1536 (text-embedding-3-small для економії), metric=cosine.

Паттерн використання: 15 000 запитів/день, пікова навантаженість 200 RPS у години розпродаж.

Результати:

  • Latency P95 для retrieval: 180мс
  • Latency P95 для повної RAG відповіді: 2.1с (включаючи GPT-4o-mini)
  • Вартість Pinecone: ~$80/місяць (Serverless)
  • Context recall (знайшли потрібний документ): 0.87
  • Answer accuracy (LLM-judge): 0.83

Оптимізації:

  • Namespace separation: товари/регламенти/FAQ у окремих namespace — дозволяє фільтрувати без overhead
  • Metadata-only queries: для ряду запитів достатньо фільтра за метаданими без векторного пошуку
  • Cache популярних запитів: Redis кеш для топ-500 частих запитань (~30% hit rate)

Строки

  • Налаштування Pinecone + ingestion pipeline: 3–5 днів
  • RAG-пайплайн з оцінкою якості: 1–2 тижні
  • Оптимізація та production: 1–2 тижні
  • Всього: 2–5 тижнів