Claude
Skills
Sign in
Back

vectorize

Included with Lifetime
$97 forever

Vector database for embeddings and semantic search at the edge. Load when building RAG pipelines, implementing semantic search, storing embeddings from Workers AI, finding similar documents, building recommendation systems, or querying vectors by similarity.

AI Agents

What this skill does


# Cloudflare Vectorize

Store and query high-dimensional vector embeddings at the edge for RAG (Retrieval Augmented Generation), semantic search, and similarity matching.

## FIRST: Create Index

```bash
# Create with preset (auto-configures dimensions and metric)
wrangler vectorize create my-index --preset @cf/baai/bge-base-en-v1.5

# Or create with explicit dimensions
wrangler vectorize create my-index --dimensions 768 --metric cosine

# List indexes
wrangler vectorize list
```

Add to `wrangler.jsonc`:

```jsonc
{
  "vectorize": [
    { "binding": "SEARCH_INDEX", "index_name": "my-index" }
  ]
}
```

## When to Use

| Use Case | Description |
|----------|-------------|
| RAG Pipelines | Store document embeddings for context retrieval with LLMs |
| Semantic Search | Find similar content by meaning, not keywords |
| Recommendation Systems | Match users/items based on embedding similarity |
| Duplicate Detection | Find near-duplicate content using vector distance |
| Content Classification | Group similar items by vector clustering |

## Quick Reference

| Operation | API |
|-----------|-----|
| Insert vectors | `await env.INDEX.insert([{ id, values, metadata }])` |
| Query similar vectors | `await env.INDEX.query(vector, { topK: 5 })` |
| Upsert (insert or update) | `await env.INDEX.upsert([{ id, values, metadata }])` |
| Delete by IDs | `await env.INDEX.deleteByIds(["id1", "id2"])` |
| Get by IDs | `await env.INDEX.getByIds(["id1", "id2"])` |

## Basic RAG Example

```typescript
interface Env {
  SEARCH_INDEX: Vectorize;
  AI: Ai;
}

export default {
  async fetch(req: Request, env: Env): Promise<Response> {
    const url = new URL(req.url);

    // Index documents with embeddings
    if (url.pathname === "/index" && req.method === "POST") {
      const { text, id } = await req.json<{ text: string; id: string }>();
      
      // Generate embedding using Workers AI
      const { data } = await env.AI.run("@cf/baai/bge-base-en-v1.5", {
        text: [text],
      });
      
      const embedding = data[0];
      
      // Insert into Vectorize
      await env.SEARCH_INDEX.insert([{
        id,
        values: embedding,
        metadata: { text }
      }]);
      
      return Response.json({ success: true, id });
    }

    // Search similar documents
    if (url.pathname === "/search" && req.method === "POST") {
      const { query } = await req.json<{ query: string }>();
      
      // Generate query embedding
      const { data } = await env.AI.run("@cf/baai/bge-base-en-v1.5", {
        text: [query],
      });
      
      const queryEmbedding = data[0];
      
      // Find similar vectors
      const results = await env.SEARCH_INDEX.query(queryEmbedding, {
        topK: 5,
        returnMetadata: true
      });
      
      return Response.json({
        matches: results.matches.map(match => ({
          id: match.id,
          score: match.score,
          text: match.metadata?.text
        }))
      });
    }

    return new Response("Not found", { status: 404 });
  }
};
```

## Configuration

### wrangler.jsonc

```jsonc
{
  "name": "vectorize-demo",
  "main": "src/index.ts",
  "compatibility_date": "2026-01-01",
  "compatibility_flags": ["nodejs_compat"],
  
  // AI binding for generating embeddings
  "ai": { "binding": "AI" },
  
  // Vectorize binding
  "vectorize": [
    {
      "binding": "SEARCH_INDEX",
      "index_name": "my-index"
    }
  ]
}
```

### Type Definitions

```typescript
interface Env {
  SEARCH_INDEX: Vectorize;
  AI: Ai;
}

// Vector insert/upsert format
interface VectorRecord {
  id: string;
  values: number[];
  metadata?: Record<string, any>;
}

// Query result format
interface VectorQueryResult {
  matches: Array<{
    id: string;
    score: number;
    values?: number[];
    metadata?: Record<string, any>;
  }>;
  count: number;
}
```

## Index Creation

### Using Presets

Presets automatically configure dimensions and distance metrics to match Workers AI embedding models:

```bash
# BGE Base English (768 dimensions, cosine)
wrangler vectorize create docs-index --preset @cf/baai/bge-base-en-v1.5

# BGE Large English (1024 dimensions, cosine)
wrangler vectorize create docs-index --preset @cf/baai/bge-large-en-v1.5

# BGE Small English (384 dimensions, cosine)
wrangler vectorize create docs-index --preset @cf/baai/bge-small-en-v1.5
```

### Manual Configuration

For custom embeddings or external models:

```bash
# Create with specific dimensions and metric
wrangler vectorize create custom-index \
  --dimensions 1536 \
  --metric cosine

# Available metrics: cosine, euclidean, dot-product
```

**Distance Metrics:**

| Metric | Use Case | Range |
|--------|----------|-------|
| `cosine` | Most common for text embeddings | -1 to 1 (1 = identical) |
| `euclidean` | Absolute distance in space | 0 to ∞ (0 = identical) |
| `dot-product` | When embeddings are normalized | -∞ to ∞ (higher = more similar) |

## Insert and Query Operations

### Insert Vectors

```typescript
// Insert single vector
await env.SEARCH_INDEX.insert([{
  id: "doc-1",
  values: [0.1, 0.2, 0.3, ...], // Must match index dimensions
  metadata: {
    title: "Getting Started",
    category: "docs",
    created: new Date().toISOString()
  }
}]);

// Batch insert (more efficient)
const vectors = documents.map(doc => ({
  id: doc.id,
  values: doc.embedding,
  metadata: { title: doc.title, url: doc.url }
}));

await env.SEARCH_INDEX.insert(vectors);
```

### Upsert Vectors

Use `upsert` to insert new vectors or update existing ones:

```typescript
await env.SEARCH_INDEX.upsert([{
  id: "doc-1",
  values: updatedEmbedding,
  metadata: { title: "Updated Title" }
}]);
```

### Query for Similar Vectors

```typescript
// Basic query
const results = await env.SEARCH_INDEX.query(queryEmbedding, {
  topK: 10,
  returnMetadata: true,
  returnValues: false // Set true to get vector values back
});

// Process results
for (const match of results.matches) {
  console.log(`ID: ${match.id}`);
  console.log(`Score: ${match.score}`);
  console.log(`Metadata:`, match.metadata);
}

// Filter by metadata (optional)
const filtered = await env.SEARCH_INDEX.query(queryEmbedding, {
  topK: 10,
  returnMetadata: true,
  filter: { category: "docs" } // Namespace filtering
});
```

### Delete Vectors

```typescript
// Delete by IDs
await env.SEARCH_INDEX.deleteByIds(["doc-1", "doc-2"]);

// Delete all with specific namespace (if using namespace metadata)
const allDocs = await env.SEARCH_INDEX.query(zeroVector, { topK: 10000 });
const idsToDelete = allDocs.matches
  .filter(m => m.metadata?.namespace === "old")
  .map(m => m.id);
await env.SEARCH_INDEX.deleteByIds(idsToDelete);
```

### Retrieve by IDs

```typescript
// Get specific vectors
const vectors = await env.SEARCH_INDEX.getByIds(["doc-1", "doc-2"]);

for (const vector of vectors) {
  console.log(vector.id, vector.metadata);
}
```

## Integration with Workers AI

### Complete RAG Pipeline

```typescript
interface Env {
  SEARCH_INDEX: Vectorize;
  AI: Ai;
}

const EMBEDDING_MODEL = "@cf/baai/bge-base-en-v1.5";
const CHAT_MODEL = "@cf/meta/llama-3.1-8b-instruct";

export default {
  async fetch(req: Request, env: Env): Promise<Response> {
    const { question } = await req.json<{ question: string }>();

    // 1. Generate embedding for user question
    const { data: embeddings } = await env.AI.run(EMBEDDING_MODEL, {
      text: [question],
    });
    
    const queryEmbedding = embeddings[0];

    // 2. Search for relevant context
    const results = await env.SEARCH_INDEX.query(queryEmbedding, {
      topK: 3,
      returnMetadata: true
    });

    // 3. Build context from results
    const context = results.matches
      .map(match => match.metadata?.text)
      .join("\n\n");

    // 4. Generate answer with RAG
    const response = await env.AI.run(CHAT_MODEL, {
      messages: [
        {
          role: "system",
          content: `Answer the question using only the following context:\n\n${context}`
        },
Files: 5
Size: 68.1 KB
Complexity: 47/100
Category: AI Agents

Related in AI Agents