Implements vector search with Pinecone for semantic similarity and RAG applications. Use when building embeddings-based search, recommendation systems, or retrieval-augmented generation.
Enables vector similarity search using Pinecone for RAG and semantic search applications. Use this when you need to store document embeddings and retrieve them by semantic meaning rather than keyword matching.
/plugin marketplace add mgd34msu/goodvibes-plugin/plugin install goodvibes@goodvibes-marketThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Vector database for similarity search. Store embeddings and query by semantic meaning for RAG, recommendations, and search.
npm install @pinecone-database/pinecone
import { Pinecone } from '@pinecone-database/pinecone';
const pinecone = new Pinecone({
apiKey: process.env.PINECONE_API_KEY!,
});
const index = pinecone.index('my-index');
await pinecone.createIndex({
name: 'my-index',
dimension: 1536, // OpenAI embedding dimension
metric: 'cosine', // cosine, euclidean, dotproduct
spec: {
serverless: {
cloud: 'aws',
region: 'us-east-1',
},
},
});
const indexes = await pinecone.listIndexes();
console.log(indexes);
const description = await pinecone.describeIndex('my-index');
console.log(description);
await pinecone.deleteIndex('my-index');
const index = pinecone.index('my-index');
await index.upsert([
{
id: 'doc-1',
values: [0.1, 0.2, 0.3, ...], // 1536 dimensions
metadata: {
title: 'Introduction to AI',
category: 'technology',
url: 'https://example.com/intro-ai',
},
},
{
id: 'doc-2',
values: [0.4, 0.5, 0.6, ...],
metadata: {
title: 'Machine Learning Basics',
category: 'technology',
url: 'https://example.com/ml-basics',
},
},
]);
const namespace = index.namespace('articles');
await namespace.upsert([
{
id: 'article-1',
values: embedding,
metadata: { title: 'Article 1' },
},
]);
const batchSize = 100;
const vectors = [...]; // Large array of vectors
for (let i = 0; i < vectors.length; i += batchSize) {
const batch = vectors.slice(i, i + batchSize);
await index.upsert(batch);
}
const queryEmbedding = [0.1, 0.2, 0.3, ...];
const results = await index.query({
vector: queryEmbedding,
topK: 10,
includeMetadata: true,
includeValues: false,
});
for (const match of results.matches) {
console.log(`ID: ${match.id}, Score: ${match.score}`);
console.log(`Metadata:`, match.metadata);
}
const results = await index.query({
vector: queryEmbedding,
topK: 10,
includeMetadata: true,
filter: {
category: { $eq: 'technology' },
},
});
const results = await index.query({
vector: queryEmbedding,
topK: 10,
includeMetadata: true,
filter: {
$and: [
{ category: { $eq: 'technology' } },
{ year: { $gte: 2020 } },
{ tags: { $in: ['ai', 'ml'] } },
],
},
});
| Operator | Description |
|---|---|
| $eq | Equal to |
| $ne | Not equal to |
| $gt | Greater than |
| $gte | Greater than or equal |
| $lt | Less than |
| $lte | Less than or equal |
| $in | In array |
| $nin | Not in array |
| $exists | Field exists |
| $and | Logical AND |
| $or | Logical OR |
const results = await index.query({
id: 'doc-1',
topK: 10,
includeMetadata: true,
});
const namespace = index.namespace('articles');
const results = await namespace.query({
vector: queryEmbedding,
topK: 5,
includeMetadata: true,
});
const fetchResult = await index.fetch(['doc-1', 'doc-2']);
for (const [id, record] of Object.entries(fetchResult.records)) {
console.log(`ID: ${id}`);
console.log(`Values: ${record.values}`);
console.log(`Metadata: ${record.metadata}`);
}
await index.update({
id: 'doc-1',
metadata: {
title: 'Updated Title',
lastModified: new Date().toISOString(),
},
});
await index.update({
id: 'doc-1',
values: newEmbedding,
metadata: { updated: true },
});
await index.deleteOne('doc-1');
// Or multiple
await index.deleteMany(['doc-1', 'doc-2', 'doc-3']);
await index.deleteMany({
filter: {
category: { $eq: 'deprecated' },
},
});
const namespace = index.namespace('temp');
await namespace.deleteAll();
const stats = await index.describeIndexStats();
console.log('Total vectors:', stats.totalRecordCount);
console.log('Namespaces:', stats.namespaces);
import { Pinecone } from '@pinecone-database/pinecone';
import OpenAI from 'openai';
const pinecone = new Pinecone();
const openai = new OpenAI();
const index = pinecone.index('my-index');
// Create embedding
async function embed(text: string) {
const response = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: text,
});
return response.data[0].embedding;
}
// Upsert document
async function upsertDocument(id: string, text: string, metadata: object) {
const embedding = await embed(text);
await index.upsert([
{
id,
values: embedding,
metadata: { text, ...metadata },
},
]);
}
// Search
async function search(query: string, topK = 5) {
const queryEmbedding = await embed(query);
const results = await index.query({
vector: queryEmbedding,
topK,
includeMetadata: true,
});
return results.matches;
}
import { Pinecone } from '@pinecone-database/pinecone';
import OpenAI from 'openai';
const pinecone = new Pinecone();
const openai = new OpenAI();
const index = pinecone.index('knowledge-base');
async function ragQuery(question: string) {
// 1. Embed the question
const embedding = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: question,
});
// 2. Search for relevant documents
const results = await index.query({
vector: embedding.data[0].embedding,
topK: 5,
includeMetadata: true,
});
// 3. Build context from results
const context = results.matches
.map((match) => match.metadata?.text)
.filter(Boolean)
.join('\n\n');
// 4. Generate answer with context
const completion = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'system',
content: `Answer based on this context:\n\n${context}`,
},
{ role: 'user', content: question },
],
});
return completion.choices[0].message.content;
}
// app/api/search/route.ts
import { Pinecone } from '@pinecone-database/pinecone';
import OpenAI from 'openai';
import { NextRequest, NextResponse } from 'next/server';
const pinecone = new Pinecone();
const openai = new OpenAI();
export async function POST(request: NextRequest) {
const { query } = await request.json();
// Embed query
const embedding = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: query,
});
// Search
const index = pinecone.index('my-index');
const results = await index.query({
vector: embedding.data[0].embedding,
topK: 10,
includeMetadata: true,
});
return NextResponse.json({
results: results.matches.map((match) => ({
id: match.id,
score: match.score,
...match.metadata,
})),
});
}
// app/api/upsert/route.ts
import { Pinecone } from '@pinecone-database/pinecone';
import OpenAI from 'openai';
import { NextRequest, NextResponse } from 'next/server';
const pinecone = new Pinecone();
const openai = new OpenAI();
export async function POST(request: NextRequest) {
const { id, text, metadata } = await request.json();
// Create embedding
const embedding = await openai.embeddings.create({
model: 'text-embedding-3-small',
input: text,
});
// Upsert to Pinecone
const index = pinecone.index('my-index');
await index.upsert([
{
id,
values: embedding.data[0].embedding,
metadata: { text, ...metadata },
},
]);
return NextResponse.json({ success: true, id });
}
import { Pinecone, RecordMetadata } from '@pinecone-database/pinecone';
interface ArticleMetadata extends RecordMetadata {
title: string;
content: string;
category: string;
publishedAt: string;
}
const pinecone = new Pinecone();
const index = pinecone.index<ArticleMetadata>('articles');
// Type-safe metadata
await index.upsert([
{
id: 'article-1',
values: embedding,
metadata: {
title: 'My Article',
content: 'Article content...',
category: 'tech',
publishedAt: new Date().toISOString(),
},
},
]);
// Type-safe query results
const results = await index.query({
vector: queryEmbedding,
topK: 5,
includeMetadata: true,
});
for (const match of results.matches) {
console.log(match.metadata?.title); // TypeScript knows this is string
}
PINECONE_API_KEY=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.