agentskit.js
Recipes

RAG reranking + hybrid search

Wrap your vector retriever with BM25 hybrid scoring and pluggable rerankers (Cohere Rerank, BGE, etc.).

Vector search is fast, but often misses exact-keyword matches and ranks weakly on specifics. Two additions to @agentskit/rag fix both: createHybridRetriever merges BM25 with vector scores, and createRerankedRetriever runs any external reranker over the top-N candidates.

Install

Ships with @agentskit/rag.

Reranked retrieval (Cohere / BGE / BM25)

import { createRerankedRetriever, createRAG } from '@agentskit/rag'
import { fileVectorMemory } from '@agentskit/memory'
import { openaiEmbedder } from '@agentskit/adapters'

const base = createRAG({
  embed: openaiEmbedder({ apiKey: process.env.OPENAI_API_KEY! }),
  store: fileVectorMemory({ path: './kb.vectors.json' }),
  topK: 20,
})

const reranked = createRerankedRetriever(base, {
  candidatePool: 20,
  topK: 5,
  rerank: async ({ query, documents }) => {
    const res = await fetch('https://api.cohere.ai/v1/rerank', {
      method: 'POST',
      headers: { 'authorization': `Bearer ${process.env.COHERE_API_KEY}`, 'content-type': 'application/json' },
      body: JSON.stringify({
        model: 'rerank-english-v3.0',
        query,
        documents: documents.map(d => d.content),
      }),
    })
    const data = await res.json()
    return data.results.map((r: { index: number; relevance_score: number }) => ({
      ...documents[r.index],
      score: r.relevance_score,
    }))
  },
})

const hits = await reranked.retrieve({ query: 'how do refunds work?', messages: [] })

No reranker function? The default is BM25 — good baseline, zero deps.

Hybrid vector + BM25

Great when users mix exact product names or SKUs with fuzzy intent:

import { createHybridRetriever } from '@agentskit/rag'

const hybrid = createHybridRetriever(base, {
  vectorWeight: 0.6,
  bm25Weight: 0.4,
  topK: 5,
})

Scores are normalized to [0, 1] within the candidate set before mixing, so the weights behave as you'd expect.

BM25 standalone

If you need a pure-keyword pass somewhere else in the stack:

import { bm25Score } from '@agentskit/rag'

const ranked = bm25Score('refund policy', documents, { k1: 1.5, b: 0.75 })

See also

✎ Edit this page on GitHub·Found a problem? Open an issue →·How to contribute →

On this page