UNPKG

@claude-flow/embeddings

Version:

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

143 lines • 6.39 kB
/** * ADR-121 Phase 16 — Adaptive primitive selection (BEYOND SOTA). * * Phase 14's topology benchmark proved each RAG primitive dominates * exactly one corpus shape: * * easy → plain wins (no fusion needed) * duplicate-heavy → MMR wins on subtopic-coverage * multi-intent → RRF wins on intent-boundary preservation * q-a-gap → HyDE wins on centroid-finding * * Production RAG systems don't route between primitives automatically * — they pick one pipeline at design time or run all-of-them and * vote/reduce. Both choices leave performance on the table. * * This module ships **adaptive primitive selection**: extract three * cheap signals from the candidate set + query variants + hypothetical * answers, then pick the right primitive (or the compound) based on * which signals fire. Cost: one extra small-fan cosine pass over the * candidate set and the variant/hypothetical embeddings. * * Signals: * * 1. duplicateDensity — mean pairwise cosine among the top-N * candidates from a plain search. High = corpus has near-dup * structure → MMR signal. * * 2. queryIntentCohesion — mean pairwise cosine among the query * reformulation vectors. Low = reformulations cover distinct * intents → RRF signal. * * 3. qaSpaceGap — 1 - cosine(question_vector, mean(hypothetical_vectors)). * High = the question and the hypothetical answers live in * different vector regions → HyDE signal. * * The router applies a small set of thresholds (defaults from the * Phase 14 topology data) and returns a structured decision the * caller can act on or override. */ export interface RetrievalFeatures { /** Mean pairwise cosine among top-N candidates from a plain search. Range [-1, 1]. Higher = more duplicate-like. */ readonly duplicateDensity: number; /** Mean pairwise cosine among query reformulation vectors. Range [-1, 1]. Higher = more cohesive (single intent). */ readonly queryIntentCohesion: number; /** 1 - cosine(question_vec, mean(hypothetical_vecs)). Range [0, 2]. Higher = larger Q/A space gap. */ readonly qaSpaceGap: number; /** * Phase 17 — Mean IDF of unique query tokens (relative to a BM25 * index over the corpus). Higher = query has rare/technical * tokens that dense embeddings tend to underweight → hybrid * sparse+dense retrieval wins. 0 when no BM25 index was provided. */ readonly rareTokenDensity: number; /** How many top candidates were used to compute duplicateDensity. */ readonly candidateCountUsed: number; /** How many variants were used to compute intent cohesion. */ readonly variantCount: number; /** How many hypotheticals were used to compute Q/A gap. */ readonly hypotheticalCount: number; /** True if the caller provided a BM25 index for rareTokenDensity. */ readonly bm25IndexProvided: boolean; } export interface AdaptiveRouterOptions { /** * Threshold above which duplicateDensity triggers the MMR signal. * Default 0.85 — duplicates are very close to each other in * cosine space. */ readonly duplicateThreshold?: number; /** * Threshold below which queryIntentCohesion triggers the RRF * signal. Default 0.55 — orthogonal-ish reformulations. */ readonly intentCohesionThreshold?: number; /** * Threshold above which qaSpaceGap triggers the HyDE signal. * Default 0.35 — meaningful question/answer space drift. */ readonly qaGapThreshold?: number; /** * Phase 17 — Threshold above which rareTokenDensity (mean query IDF) * triggers the HYBRID signal. Default 2.0 — IDF ≥ 2.0 means the * query's tokens appear in <~13% of the corpus, where BM25's * sparse lexical signal materially helps dense retrieval. */ readonly rareTokenThreshold?: number; /** * If 2+ signals fire, return `compound` instead of one of the * individual primitives. Default true. */ readonly preferCompoundWhenMultipleSignals?: boolean; } export type AdaptivePrimitive = 'plain' | 'mmr' | 'rrf' | 'hyde' | 'hybrid' | 'compound'; export interface AdaptiveDecision { /** The recommended primitive. */ readonly primitive: AdaptivePrimitive; /** Human-readable explanation citing which signals fired. */ readonly reason: string; /** Which signals were above their respective thresholds. */ readonly signals: Readonly<{ mmr: boolean; rrf: boolean; hyde: boolean; hybrid: boolean; }>; /** Echo of the input features for traceability. */ readonly features: RetrievalFeatures; } /** * Extract the routing signals from the available inputs. * * @param topCandidates — top-N hits from a cheap plain search, * with vectors. Used for duplicateDensity. * Pass `null` to disable that signal. * @param queryVector — the user-question vector. Required for * qaSpaceGap. * @param variantVectors — N query reformulation vectors. Used for * queryIntentCohesion. At least 2 required * to compute the signal. * @param hypotheticalVectors — N hypothetical-answer vectors. Used * for qaSpaceGap. At least 1 required. * @param bm25Input — optional {queryText, bm25Index} pair for the * Phase 17 hybrid signal. Pass `null` to * disable. * * Cost: O(N²·dim) for the pairwise cosines + O(|q|) for the BM25 * mean-IDF lookup. */ export declare function extractRetrievalFeatures(topCandidates: ReadonlyArray<{ vector: Float32Array | number[]; }> | null, queryVector: Float32Array | number[], variantVectors: ReadonlyArray<Float32Array | number[]>, hypotheticalVectors: ReadonlyArray<Float32Array | number[]>, bm25Input?: { queryText: string; index: { df: ReadonlyMap<string, number>; N: number; }; } | null): RetrievalFeatures; /** * Apply the routing heuristic to a set of features. Returns the * recommended primitive plus the reasoning trace. */ export declare function adaptiveRoute(features: RetrievalFeatures, options?: AdaptiveRouterOptions): AdaptiveDecision; //# sourceMappingURL=adaptive-router.d.ts.map