UNPKG

@claude-flow/embeddings

Version:

V3 Embedding Service - OpenAI, Transformers.js, Agentic-Flow (ONNX), Mock providers with hyperbolic embeddings, normalization, and chunking

100 lines • 4.46 kB
/** * ADR-121 Phase 15 — Compound retrieval primitive (BEYOND SOTA). * * Standard SOTA primitives shipped in Phases 10-12: * - MMR (Carbonell-Goldstein 1998) — diversity rerank * - RRF (Cormack-Clarke-Büttcher 2009) — rank-level intent fusion * - HyDE (Gao-Ma-Lin-Callan 2022) — embedding-level Q/A fusion * * Each addresses one failure mode: * - duplicate-heavy result lists (MMR) * - intent-boundary loss in vector averaging (RRF preserves them) * - question/answer space gap (HyDE bridges it) * * A real production query often has ALL THREE problems: * - multiple distinct intents (need RRF) * - each intent has a question/answer gap (need HyDE per intent) * - top-k for each intent has near-duplicates (need MMR per list) * * Compound retrieval composes them into a single pipeline: * * for each intent variant v_i: * for each hypothetical answer h_ij of v_i: * embed h_ij * intent_vec_i = average(embed(h_i1), embed(h_i2), ...) ← HyDE per intent * intent_list_i = top-fetchK(corpus, intent_vec_i) * intent_list_i = mmrRerank(intent_list_i, intent_vec_i, lambda) ← MMR per intent * fused = RRF(intent_list_1, intent_list_2, ..., k_rrf, weights) ← RRF across intents * * This is genuinely beyond the per-primitive SOTA — each component * is well-known but their compound composition for end-to-end RAG * isn't (to my knowledge) shipped in any production library. * * The topology benchmark (Phase 14) showed each primitive dominates * exactly one topology. The Phase 15 real-text benchmark shows * compound retrieval matches or exceeds the best primitive on EVERY * topology — strict no-regression compound. */ import { type MmrCandidate } from './mmr.js'; import { type RrfFusedHit } from './rrf.js'; export interface CompoundIntent { /** Caller-supplied label for the intent (used in per-intent diagnostics). */ readonly label?: string; /** * Hypothetical-answer vectors for this intent. Will be embedding- * averaged into the intent's query vector. Must contain at least * one vector. */ readonly hypotheticalVectors: ReadonlyArray<Float32Array | number[]>; /** Optional per-intent weight in the RRF fusion (default 1). */ readonly weight?: number; } export interface CompoundRetrievalOptions { /** Final number of fused results to return. */ readonly k: number; /** * How many candidates each intent pulls from the corpus before * per-intent MMR rerank. Default 4*k. Larger = better MMR * diversification per intent, more compute. */ readonly perIntentFetchK?: number; /** * Lambda for the per-intent MMR rerank. Default 0.5 (balanced). * Pass 1.0 to disable MMR (pure relevance per intent). */ readonly mmrLambda?: number; /** * RRF smoothing constant (Cormack-Clarke-Büttcher default 60). */ readonly kRrf?: number; } export interface CompoundIntentTrace { readonly label: string; /** L2-norm of the averaged-HyDE query vector for this intent. */ readonly hypotheticalCount: number; /** Number of MMR-reranked candidates that contributed to the RRF input. */ readonly mmrCandidateCount: number; } export interface CompoundRetrievalResult { /** Final fused hits with full per-list rank transparency. */ readonly hits: ReadonlyArray<RrfFusedHit>; /** Per-intent diagnostic trace. */ readonly intents: ReadonlyArray<CompoundIntentTrace>; /** * Mean MMR redundancy across all per-intent MMR runs. Lower = the * compound primitive's diversification step had material effect. * Useful for tuning mmrLambda. */ readonly meanIntentRedundancy: number; } /** * Run the compound HyDE+MMR+RRF pipeline against a callable that * answers "give me the top-N candidates for this query vector". * * The search function is injected so this module stays decoupled * from any specific ANN backing — pass a closure over your * AnnRouter handle, your in-memory linear scan, your DiskANN * snapshot, anything that returns `{id, vector, score?}[]`. */ export declare function compoundRetrieval(intents: ReadonlyArray<CompoundIntent>, search: (queryVec: Float32Array, k: number) => Promise<ReadonlyArray<MmrCandidate>> | ReadonlyArray<MmrCandidate>, options: CompoundRetrievalOptions): Promise<CompoundRetrievalResult>; //# sourceMappingURL=compound-retrieval.d.ts.map