| name | pinecone |
| description | Set up Pinecone as the vector DB in a RAG pipeline — index config, batch upsert, semantic query, metadata filters. Use when the user is adding Pinecone or debugging vector search. |
| when_to_use | When the user mentions Pinecone, vector search, or needs a vector DB for RAG. |
| allowed-tools | Bash Read Write Edit |
Pinecone
Managed vector database. Used as the vector store in a RAG pipeline — see the rag skill for the full pipeline pattern.
Install
pnpm add @pinecone-database/pinecone
Env
PINECONE_API_KEY=
PINECONE_INDEX_NAME=chatbot-knowledge
Client
import { Pinecone } from "@pinecone-database/pinecone";
const pinecone = new Pinecone({ apiKey: process.env.PINECONE_API_KEY! });
const index = pinecone.index(process.env.PINECONE_INDEX_NAME ?? "chatbot-knowledge");
Batch upsert
const BATCH_SIZE = 100;
export async function upsertVectors(vectors: VectorRecord[], namespace: string) {
const ns = index.namespace(namespace);
for (let i = 0; i < vectors.length; i += BATCH_SIZE) {
await ns.upsert(vectors.slice(i, i + BATCH_SIZE));
}
}
Query
export async function queryVectors(
embedding: number[],
topK: number,
filter?: MetadataFilter,
) {
const result = await index.namespace("default").query({
vector: embedding,
topK,
includeMetadata: true,
filter,
});
return result.matches;
}
Metadata filter pattern
Store token arrays on each vector for flexible keyword matching:
metadata: {
tokens: ["com", "tam", "com tam"],
district_tokens: ["quan 1", "quan binh thanh"],
}
const filter = { tokens: { $in: tokenize(userQuery) } };
If no tokens match, return {} to fall through to pure semantic search (no filter applied).
Supported operators: $in, $eq, $and, $or.
Increase topK when filters are active — filtering reduces recall before ranking.
e.g. RAG_TOP_K=5 unfiltered, RAG_TOP_K_FILTERED=10-30 filtered.
References