423 lines
9.0 KiB
Markdown
423 lines
9.0 KiB
Markdown
# Vector Stores - Complete Reference
|
|
|
|
In-depth guide to OpenAI's Vector Stores for the Assistants API.
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
Vector Stores provide scalable semantic search infrastructure for the file_search tool:
|
|
- **Capacity**: Up to 10,000 files per assistant
|
|
- **Automatic**: Chunking, embedding, indexing
|
|
- **Search**: Vector + keyword hybrid with reranking
|
|
- **Pricing**: $0.10/GB/day (first 1GB free)
|
|
|
|
---
|
|
|
|
## Creating Vector Stores
|
|
|
|
### Basic Creation
|
|
|
|
```typescript
|
|
const vectorStore = await openai.beta.vectorStores.create({
|
|
name: "Company Knowledge Base",
|
|
});
|
|
```
|
|
|
|
### With Auto-Expiration
|
|
|
|
```typescript
|
|
const vectorStore = await openai.beta.vectorStores.create({
|
|
name: "Temporary KB",
|
|
expires_after: {
|
|
anchor: "last_active_at",
|
|
days: 7,
|
|
},
|
|
});
|
|
```
|
|
|
|
**Anchors**:
|
|
- `last_active_at`: Expires N days after last use (recommended)
|
|
- `created_at`: Expires N days after creation (not yet available)
|
|
|
|
### With Metadata
|
|
|
|
```typescript
|
|
const vectorStore = await openai.beta.vectorStores.create({
|
|
name: "Q4 2025 Documentation",
|
|
metadata: {
|
|
department: "sales",
|
|
quarter: "Q4-2025",
|
|
version: "1.0",
|
|
},
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
## Adding Files
|
|
|
|
### Single File Upload
|
|
|
|
```typescript
|
|
// 1. Upload file to OpenAI
|
|
const file = await openai.files.create({
|
|
file: fs.createReadStream("document.pdf"),
|
|
purpose: "assistants",
|
|
});
|
|
|
|
// 2. Add to vector store
|
|
await openai.beta.vectorStores.files.create(vectorStore.id, {
|
|
file_id: file.id,
|
|
});
|
|
```
|
|
|
|
### Batch Upload (Recommended)
|
|
|
|
```typescript
|
|
// Upload multiple files
|
|
const files = await Promise.all([
|
|
openai.files.create({ file: fs.createReadStream("doc1.pdf"), purpose: "assistants" }),
|
|
openai.files.create({ file: fs.createReadStream("doc2.md"), purpose: "assistants" }),
|
|
openai.files.create({ file: fs.createReadStream("doc3.docx"), purpose: "assistants" }),
|
|
]);
|
|
|
|
// Batch add to vector store
|
|
const batch = await openai.beta.vectorStores.fileBatches.create(vectorStore.id, {
|
|
file_ids: files.map(f => f.id),
|
|
});
|
|
|
|
// Monitor progress
|
|
let batchStatus = batch;
|
|
while (batchStatus.status === 'in_progress') {
|
|
await new Promise(r => setTimeout(r, 1000));
|
|
batchStatus = await openai.beta.vectorStores.fileBatches.retrieve(
|
|
vectorStore.id,
|
|
batch.id
|
|
);
|
|
console.log(`${batchStatus.file_counts.completed}/${batchStatus.file_counts.total}`);
|
|
}
|
|
```
|
|
|
|
**Benefits of Batch Upload**:
|
|
- Faster processing (parallel indexing)
|
|
- Single operation to track
|
|
- Better error handling
|
|
|
|
---
|
|
|
|
## Vector Store States
|
|
|
|
| State | Description |
|
|
|-------|-------------|
|
|
| `in_progress` | Files being indexed |
|
|
| `completed` | All files indexed successfully |
|
|
| `failed` | Indexing failed |
|
|
| `expired` | Auto-expiration triggered |
|
|
|
|
**Important**: Wait for `completed` before using with assistants.
|
|
|
|
---
|
|
|
|
## File Management
|
|
|
|
### List Files in Vector Store
|
|
|
|
```typescript
|
|
const files = await openai.beta.vectorStores.files.list(vectorStore.id, {
|
|
limit: 100,
|
|
});
|
|
|
|
for (const file of files.data) {
|
|
console.log(`${file.id}: ${file.status}`);
|
|
}
|
|
```
|
|
|
|
### Remove File from Vector Store
|
|
|
|
```typescript
|
|
await openai.beta.vectorStores.files.del(vectorStore.id, fileId);
|
|
```
|
|
|
|
**Note**: This removes the file from the vector store but doesn't delete the file from OpenAI's storage.
|
|
|
|
### Check File Status
|
|
|
|
```typescript
|
|
const file = await openai.beta.vectorStores.files.retrieve(vectorStore.id, fileId);
|
|
|
|
console.log(file.status); // "in_progress", "completed", "failed"
|
|
|
|
if (file.status === 'failed') {
|
|
console.error(file.last_error);
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Pricing & Cost Management
|
|
|
|
### Pricing Structure
|
|
|
|
- **Storage**: $0.10 per GB per day
|
|
- **Free tier**: First 1GB
|
|
- **Calculation**: Total vector store size (not original file size)
|
|
|
|
**Example Costs**:
|
|
| Original Files | Vector Store Size | Daily Cost | Monthly Cost |
|
|
|----------------|-------------------|------------|--------------|
|
|
| 500 MB | 0.5 GB | $0.00 | $0.00 (free tier) |
|
|
| 2 GB | 2 GB | $0.10 | $3.00 |
|
|
| 10 GB | 10 GB | $0.90 | $27.00 |
|
|
| 50 GB | 50 GB | $4.90 | $147.00 |
|
|
|
|
### Monitor Usage
|
|
|
|
```typescript
|
|
const store = await openai.beta.vectorStores.retrieve(vectorStoreId);
|
|
|
|
const sizeGB = store.usage_bytes / (1024 * 1024 * 1024);
|
|
const costPerDay = Math.max(0, (sizeGB - 1) * 0.10);
|
|
const costPerMonth = costPerDay * 30;
|
|
|
|
console.log(`Storage: ${sizeGB.toFixed(2)} GB`);
|
|
console.log(`Cost: $${costPerDay.toFixed(4)}/day ($${costPerMonth.toFixed(2)}/month)`);
|
|
```
|
|
|
|
### Cost Optimization
|
|
|
|
**1. Auto-Expiration**:
|
|
```typescript
|
|
expires_after: {
|
|
anchor: "last_active_at",
|
|
days: 30,
|
|
}
|
|
```
|
|
|
|
**2. Regular Cleanup**:
|
|
```typescript
|
|
async function cleanupUnusedVectorStores() {
|
|
const stores = await openai.beta.vectorStores.list({ limit: 100 });
|
|
|
|
for (const store of stores.data) {
|
|
const ageDays = (Date.now() / 1000 - store.created_at) / (60 * 60 * 24);
|
|
|
|
if (ageDays > 90) { // 90 days old
|
|
await openai.beta.vectorStores.del(store.id);
|
|
console.log(`Deleted: ${store.name}`);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**3. Deduplicate Content**:
|
|
- Remove duplicate files before upload
|
|
- Combine similar documents
|
|
- Archive old versions
|
|
|
|
---
|
|
|
|
## Using with Assistants
|
|
|
|
### Attach to Assistant
|
|
|
|
```typescript
|
|
const assistant = await openai.beta.assistants.create({
|
|
name: "Support Bot",
|
|
tools: [{ type: "file_search" }],
|
|
tool_resources: {
|
|
file_search: {
|
|
vector_store_ids: [vectorStore.id],
|
|
},
|
|
},
|
|
model: "gpt-4o",
|
|
});
|
|
```
|
|
|
|
### Multiple Vector Stores
|
|
|
|
```typescript
|
|
// Combine multiple knowledge bases
|
|
tool_resources: {
|
|
file_search: {
|
|
vector_store_ids: [generalKBId, productDocsId, policyDocsId],
|
|
},
|
|
}
|
|
```
|
|
|
|
**Limit**: Maximum of 1 vector store per assistant in current API (subject to change).
|
|
|
|
---
|
|
|
|
## Advanced Operations
|
|
|
|
### Update Metadata
|
|
|
|
```typescript
|
|
const updated = await openai.beta.vectorStores.update(vectorStoreId, {
|
|
name: "Updated Name",
|
|
metadata: {
|
|
version: "2.0",
|
|
last_updated: new Date().toISOString(),
|
|
},
|
|
});
|
|
```
|
|
|
|
### Retrieve Vector Store Details
|
|
|
|
```typescript
|
|
const store = await openai.beta.vectorStores.retrieve(vectorStoreId);
|
|
|
|
console.log({
|
|
id: store.id,
|
|
name: store.name,
|
|
status: store.status,
|
|
usage_bytes: store.usage_bytes,
|
|
file_counts: store.file_counts,
|
|
created_at: new Date(store.created_at * 1000),
|
|
expires_at: store.expires_at ? new Date(store.expires_at * 1000) : null,
|
|
metadata: store.metadata,
|
|
});
|
|
```
|
|
|
|
### List All Vector Stores
|
|
|
|
```typescript
|
|
const stores = await openai.beta.vectorStores.list({
|
|
limit: 20,
|
|
order: "desc",
|
|
});
|
|
|
|
for (const store of stores.data) {
|
|
console.log(`${store.name}: ${store.file_counts.completed} files`);
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Best Practices
|
|
|
|
### 1. Pre-Process Documents
|
|
|
|
- Remove headers/footers
|
|
- Clean formatting
|
|
- Extract text from images (OCR separately)
|
|
- Organize with clear structure
|
|
|
|
### 2. Monitor Indexing
|
|
|
|
```typescript
|
|
async function waitForIndexing(vectorStoreId: string, batchId: string) {
|
|
let batch;
|
|
const startTime = Date.now();
|
|
|
|
do {
|
|
batch = await openai.beta.vectorStores.fileBatches.retrieve(vectorStoreId, batchId);
|
|
|
|
if (batch.status === 'failed') {
|
|
throw new Error('Batch indexing failed');
|
|
}
|
|
|
|
console.log(`Progress: ${batch.file_counts.completed}/${batch.file_counts.total}`);
|
|
|
|
await new Promise(r => setTimeout(r, 2000));
|
|
|
|
// Timeout after 10 minutes
|
|
if (Date.now() - startTime > 600000) {
|
|
throw new Error('Indexing timeout');
|
|
}
|
|
} while (batch.status === 'in_progress');
|
|
|
|
return batch;
|
|
}
|
|
```
|
|
|
|
### 3. Set Reasonable Expiration
|
|
|
|
```typescript
|
|
// For temporary projects
|
|
expires_after: { anchor: "last_active_at", days: 7 }
|
|
|
|
// For active knowledge bases
|
|
expires_after: { anchor: "last_active_at", days: 90 }
|
|
|
|
// For permanent KB (no expiration)
|
|
// Don't set expires_after
|
|
```
|
|
|
|
### 4. Tag with Metadata
|
|
|
|
```typescript
|
|
metadata: {
|
|
project: "project-alpha",
|
|
environment: "production",
|
|
version: "1.0",
|
|
owner: "team@company.com",
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Files Not Indexing
|
|
|
|
**Check file status**:
|
|
```typescript
|
|
const file = await openai.beta.vectorStores.files.retrieve(vectorStoreId, fileId);
|
|
|
|
if (file.status === 'failed') {
|
|
console.error(file.last_error);
|
|
}
|
|
```
|
|
|
|
**Common causes**:
|
|
- Unsupported file format
|
|
- Corrupted file
|
|
- File too large (>512 MB)
|
|
|
|
### Vector Store Shows `failed` Status
|
|
|
|
**Check batch details**:
|
|
```typescript
|
|
const batch = await openai.beta.vectorStores.fileBatches.retrieve(vectorStoreId, batchId);
|
|
console.log(batch.file_counts); // Check failed count
|
|
```
|
|
|
|
**Solutions**:
|
|
- Remove failed files
|
|
- Re-upload with correct format
|
|
- Check error messages
|
|
|
|
### High Storage Costs
|
|
|
|
**Audit vector stores**:
|
|
```typescript
|
|
const stores = await openai.beta.vectorStores.list({ limit: 100 });
|
|
let totalGB = 0;
|
|
|
|
for (const store of stores.data) {
|
|
const sizeGB = store.usage_bytes / (1024 * 1024 * 1024);
|
|
totalGB += sizeGB;
|
|
console.log(`${store.name}: ${sizeGB.toFixed(2)} GB`);
|
|
}
|
|
|
|
console.log(`Total: ${totalGB.toFixed(2)} GB = $${((totalGB - 1) * 0.10).toFixed(2)}/day`);
|
|
```
|
|
|
|
---
|
|
|
|
## Limits
|
|
|
|
| Resource | Limit |
|
|
|----------|-------|
|
|
| Files per vector store | 10,000 |
|
|
| Vector stores per account | Not documented |
|
|
| File size | 512 MB |
|
|
| Storage (billable) | Unlimited (pay per GB) |
|
|
| Indexing time | Varies by size |
|
|
|
|
---
|
|
|
|
**Last Updated**: 2025-10-25
|