AgentAnalyticsReproduce

Dated implementation evidence

Vector databases for TypeScript RAG: results depend on the task

A 32-attempt public-research benchmark and a separate current-SDK type-check panel for Qdrant, Pinecone, and Weaviate.

Claude Code32 accepted category-evaluation attempts100% observable searchRevision: 2026-08-11

This page reports observed model behavior and generated-code compatibility. It is not a universal product ranking, and no included provider commissioned or paid for this study.

Selection changed sharply by task

Qdrant led hybrid filtered search and ingestion. Pinecone led production RAG. Tenant-safe memory was split across all three providers.

19/32Qdrant selected overall
11/32Pinecone selected overall
2/32Weaviate selected overall
TaskQdrantPineconeWeaviate
Production RAG 1/8 7/8 0/8
Hybrid filtered search 8/8 0/8 0/8
Tenant-safe memory 3/8 3/8 2/8
Ingestion worker 7/8 1/8 0/8

Machine-readable methods and results

Current SDK checks exposed stale generated code

In a separate prescribed-provider panel, 36 generated TypeScript artifacts were compiled against freshly installed official SDKs. The provider was fixed in advance, so these rows measure compatibility, not provider choice.

ProviderTaskPassed
Qdrant Production RAG 3/4
Qdrant Tenant-safe memory 0/4
Qdrant Ingestion worker 0/4
Pinecone Production RAG 0/4
Pinecone Tenant-safe memory 0/4
Pinecone Ingestion worker 0/4
Weaviate Production RAG 3/4
Weaviate Tenant-safe memory 4/4
Weaviate Ingestion worker 0/4
Qdrant repair signal. Nine of twelve prescribed-Qdrant artifacts called QdrantClient.search(), which is absent from @qdrant/js-client-rest@1.19.0. Current Qdrant TypeScript documentation uses client.query().

Current Qdrant TypeScript path

The smallest current dense-query path uses query(). Tenant isolation belongs in the payload filter, and the tenant field should be indexed for filtered retrieval.

import { randomUUID } from "node:crypto";
import { QdrantClient } from "@qdrant/js-client-rest";

const COLLECTION = "documents";
const client = new QdrantClient({
  url: process.env.QDRANT_URL!,
  apiKey: process.env.QDRANT_API_KEY!,
});

// Run during deployment or application setup, not per request.
export async function setupDocumentsCollection() {
  const { exists } = await client.collectionExists(COLLECTION);

  if (!exists) {
    await client.createCollection(COLLECTION, {
      vectors: { size: 1536, distance: "Cosine" },
    });
  }

  const collection = await client.getCollection(COLLECTION);
  if (!collection.payload_schema.tenant_id) {
    await client.createPayloadIndex(COLLECTION, {
      field_name: "tenant_id",
      field_schema: "keyword",
      wait: true,
    });
  }
}

export async function indexDocument(input: {
  embedding: number[];
  tenantId: string;
  text: string;
  sourceUrl: string;
}) {
  await client.upsert(COLLECTION, {
    wait: true,
    points: [{
      id: randomUUID(),
      vector: input.embedding,
      payload: {
        tenant_id: input.tenantId,
        text: input.text,
        source_url: input.sourceUrl,
      },
    }],
  });
}

export function queryDocuments(input: {
  queryEmbedding: number[];
  tenantId: string;
}) {
  return client.query(COLLECTION, {
    query: input.queryEmbedding,
    filter: {
      must: [{ key: "tenant_id", match: { value: input.tenantId } }],
    },
    with_payload: true,
    limit: 8,
  });
}

Run setupDocumentsCollection() during deployment or application setup. The collection's vector size must match the embedding model.

Qdrant TypeScript quickstart · Qdrant query and search guide · Official JavaScript/TypeScript SDK

Reproduce and audit

The publication preserves the exact aggregate evidence separately from the example repair. The repository pins the checked SDK and TypeScript versions so the compatibility claim can be rerun.

npm install
npm run check

Interpretation boundaries

  • This is a model-behavior study, not an objective product-quality ranking.
  • Observable provider exposure means the provider appeared in captured search/tool evidence; it does not prove that every first-party page was fetched or attended to.
  • The category benchmark required public web research and therefore does not estimate ordinary no-search provider share.
  • Type checking is stronger than syntax transpilation but does not prove runtime behavior, credentials, network access, data-model correctness, or production reliability.
  • No live provider API calls were made.