question-explorer-api / services /vectorSearch.js
Eric Gardner
Initial deployment
cdc50ff
/**
* Compute cosine similarity between two vectors
* Assumes vectors are already normalized
*/
export function cosineSimilarity( a, b ) {
let dot = 0;
for ( let i = 0; i < a.length; i++ ) {
dot += a[ i ] * b[ i ];
}
return dot;
}
/**
* Search chunks by embedding similarity
*/
export function search( queryEmbedding, chunks, topK = 3, threshold = 0.4 ) {
const scored = chunks.map( ( chunk ) => ( {
...chunk,
score: cosineSimilarity( queryEmbedding, chunk.embedding )
} ) );
scored.sort( ( a, b ) => b.score - a.score );
const results = scored.slice( 0, topK ).map( ( r ) => ( {
chunkId: r.id,
text: r.text,
score: r.score,
confidence: scoreToConfidence( r.score ),
sectionId: r.sectionId,
sectionTitle: r.sectionTitle,
selector: r.selector,
paragraphIndex: r.paragraphIndex
} ) );
const belowThreshold = results.length === 0 || results[ 0 ].score < threshold;
return { results, belowThreshold };
}
function scoreToConfidence( score ) {
if ( score >= 0.6 ) {
return 'high';
}
if ( score >= 0.45 ) {
return 'medium';
}
return 'low';
}