import { VectorAIClient, reciprocalRankFusion } from '@actian/vectorai-client';
const COLLECTION = "documents";
const DIMENSION = 384;
function hybridRagRetrieval(client, userQuestion, topK = 5) {
/**
* Perform hybrid retrieval for RAG application
*
* Combines:
* 1. Semantic search on question
* 2. Semantic search on reformulated question
* 3. Returns top-k most relevant documents
*/
// In production, use actual embedding model
// const questionEmbedding = embedModel.encode(userQuestion);
const questionEmbedding = Array.from({ length: DIMENSION }, () => Math.random() * 2 - 1);
// Reformulate question (in production, use LLM)
// const reformulated = llm.reformulate(userQuestion);
// const reformulatedEmbedding = embedModel.encode(reformulated);
const reformulatedEmbedding = Array.from({ length: DIMENSION }, () => (Math.random() * 2 - 1) * 0.95 + 0.1);
// Search with both queries
return Promise.all([
client.points.search(COLLECTION, questionEmbedding, {
limit: 15,
withPayload: true
}),
client.points.search(COLLECTION, reformulatedEmbedding, {
limit: 15,
withPayload: true
})
]).then(([originalResults, reformulatedResults]) => {
// Fuse results
const fused = reciprocalRankFusion(
[originalResults, reformulatedResults],
{ k: 60, limit: 15 }
);
// Return top-k for context
return fused.slice(0, topK);
});
}
async function main() {
const client = new VectorAIClient('localhost:6574');
const userQuestion = "How do I reset my password?";
// Retrieve relevant context
const contextDocs = await hybridRagRetrieval(client, userQuestion, 3);
// Build context for LLM
const context = contextDocs
.map(doc => doc.payload?.text || '')
.join('\n\n');
console.log(`Retrieved ${contextDocs.length} context documents for RAG`);
console.log(`\nContext for LLM (${context.length} chars):`);
console.log(context.slice(0, 500) + "...");
// In production: Pass context + question to LLM
// const response = llm.generate({ question: userQuestion, context });
}
main().catch(console.error);