본문으로 건너뛰기

재순위화

쿼리와 후보 문서 목록이 있다고 가정합니다. 후보 문서는 벡터 검색의 청크, 키워드 쿼리의 행, FAQ 항목 등이며, 실제로 쿼리에 얼마나 잘 답하는지에 따라 순서를 정해야 합니다. 벡터 유사도만으로도 근접한 결과를 얻을 수 있지만, 전용 재순위화 모델을 사용하면 훨씬 더 정확해집니다. 이 가이드를 끝내면 문서별 관련성 점수와 함께 해당 목록의 순서가 재정렬됩니다.

rerank()는 검색 파이프라인의 정밀화 단계입니다. 먼저 많은 후보를 저렴하게 검색한 다음, 중요한 소수의 후보가 드러나도록 재순위화합니다.

제공자

현재 두 어댑터에서 재순위화를 사용할 수 있습니다.

  • Cohere (@tanstack/ai-cohere) — cohereRerank('rerank-v3.5')를 사용하며 Cohere에 직접 연결합니다.
  • OpenRouter (@tanstack/ai-openrouter) — openRouterRerank('cohere/rerank-v3.5')를 사용하며 기존 OpenRouter 키를 통해 재순위화 요청을 라우팅합니다.

둘 다 동일한 rerank() 활동을 구현하므로 어댑터만 교체하고 호출은 그대로 유지하면 됩니다.

설치

npm install @tanstack/ai-cohere
# or, to rerank through OpenRouter:
npm install @tanstack/ai-openrouter

피어 의존성:

npm install @tanstack/ai

기본 사용법

querydocuments 배열을 전달합니다. 결과의 rerankedDocuments는 관련성이 가장 높은 항목부터 정렬되며, ranking에는 각 항목의 관련성 점수와 원래 인덱스가 포함됩니다.

import { rerank } from '@tanstack/ai'
import { cohereRerank } from '@tanstack/ai-cohere'

const { ranking, rerankedDocuments } = await rerank({
adapter: cohereRerank('rerank-v3.5'),
query: 'talk about rain',
documents: ['sunny day at the beach', 'rainy afternoon in the city'],
topN: 2,
})

console.log(rerankedDocuments[0]) // 'rainy afternoon in the city'
console.log(ranking[0]) // { index: 1, score: 0.98, document: 'rainy afternoon in the city' }

어댑터는 환경에서 COHERE_API_KEY를 읽습니다. 키를 명시적으로 전달하려면 createCohereRerank('rerank-v3.5', 'co-...')를 사용합니다.

대신 OpenRouter를 통해 재순위화하려면 어댑터를 교체합니다. 나머지는 모두 동일하게 유지됩니다.

import { rerank } from '@tanstack/ai'
import { openRouterRerank } from '@tanstack/ai-openrouter'

const { rerankedDocuments } = await rerank({
adapter: openRouterRerank('cohere/rerank-v3.5'),
query: 'talk about rain',
documents: ['sunny day at the beach', 'rainy afternoon in the city'],
topN: 2,
})

console.log(rerankedDocuments[0]) // 'rainy afternoon in the city'

openRouterRerank는 환경에서 OPENROUTER_API_KEY를 읽습니다.

객체 문서 재순위화

문서는 문자열일 필요가 없습니다. JSON으로 직렬화할 수 있는 객체를 전달하면 원래 객체가 완전한 타입 정보와 함께 결과로 반환됩니다. 따라서 재순위화 과정에서 id나 메타데이터를 유지하고 순위가 매겨진 결과에서 다시 읽을 수 있습니다.

import { rerank } from '@tanstack/ai'
import { cohereRerank } from '@tanstack/ai-cohere'

const chunks = [
{ id: 'doc-1', text: 'A heavy gaming desktop with an RTX card.' },
{ id: 'doc-2', text: 'A lightweight ultrabook with all-day battery.' },
]

const { ranking } = await rerank({
adapter: cohereRerank('rerank-v3.5'),
query: 'best laptop for travel',
documents: chunks,
})

// `document` is the original object — `id` is available and type-safe.
console.log(ranking[0]?.document.id) // 'doc-2'

객체 문서는 제공자에게 전송되기 전에 JSON으로 직렬화됩니다. 순위는 인덱스를 기준으로 원래 요소에 다시 매핑됩니다.

옵션

옵션타입설명
adapterRerankAdapter모델로 생성한 재순위화 어댑터입니다(예: cohereRerank('rerank-v3.5')).
querystring문서의 점수를 매길 검색 쿼리입니다. 필수입니다.
documentsArray<string | object>재순위화할 후보 문서입니다. 필수입니다.
topNnumber상위 N개의 결과만 반환합니다.
abortSignalAbortSignal진행 중인 요청을 취소합니다.
modelOptionsprovider options제공자별 옵션입니다(아래 참조).
middlewareArray<GenerationMiddleware>관찰 전용 수명 주기 훅입니다(사용량, 완료, 오류, 중단).

제공자 옵션

Cohere 재순위화는 다음을 허용합니다.

import { rerank } from '@tanstack/ai'
import { cohereRerank } from '@tanstack/ai-cohere'

const { ranking } = await rerank({
adapter: cohereRerank('rerank-v3.5'),
query: 'refund policy',
documents: ['Returns accepted within 30 days.', 'Free shipping over $50.'],
modelOptions: {
// Cap tokens kept per document when chunking long inputs (Cohere default: 4096).
maxTokensPerDoc: 512,
},
})

console.log(ranking)

결과 형태

import type { TokenUsage } from '@tanstack/ai'

interface RerankResult<TDocument = string> {
id: string
model: string
// Scored results, most relevant first.
ranking: Array<{ index: number; score: number; document: TDocument }>
// The documents reordered by relevance (ranking.map(r => r.document)).
rerankedDocuments: Array<TDocument>
// Rerank typically bills in provider "search units"
// (usage.billed = { quantity, unit: 'units' }). Some providers (for example
// OpenRouter) also report totalTokens and cost. Cohere reports only search
// units and leaves token counts at 0.
usage: TokenUsage
}

서버 엔드포인트

재순위화는 서버에서 실행됩니다(API 키가 필요함). API 라우트로 감싼 다음 클라이언트에서 fetch를 통해 호출합니다.

// routes/api/rerank.ts
import { rerank } from '@tanstack/ai'
import { cohereRerank } from '@tanstack/ai-cohere'
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/api/rerank')({
server: {
handlers: {
POST: async ({ request }) => {
const body: unknown = await request.json()
if (
typeof body !== 'object' ||
body === null ||
!('query' in body) ||
typeof body.query !== 'string' ||
!('documents' in body) ||
!Array.isArray(body.documents)
) {
return new Response('Invalid request body', { status: 400 })
}
const { query, documents } = body
const topN = 'topN' in body && typeof body.topN === 'number'
? body.topN
: undefined

const result = await rerank({
adapter: cohereRerank('rerank-v3.5'),
query,
documents,
topN,
})

return Response.json(result)
},
},
},
})
// client.ts — call the endpoint and use the reordered documents
async function rerankDocuments(query: string, documents: Array<string>) {
const res = await fetch('/api/rerank', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, documents, topN: 3 }),
})
const result = await res.json()
return result.rerankedDocuments
}

RAG 파이프라인에서 사용

재순위화는 저렴하고 광범위한 검색 다음의 두 번째 단계에서 특히 유용합니다. 벡터 검색으로 후보를 넉넉히 가져온 다음 재순위화하여 프롬프트에 사용할 가장 관련성 높은 소수만 남깁니다.

import { rerank } from '@tanstack/ai'
import { cohereRerank } from '@tanstack/ai-cohere'
import { vectorSearch } from './my-vector-store'

async function retrieveContext(query: string) {
// 1. Over-fetch candidates cheaply.
const candidates = await vectorSearch(query, { limit: 50 })

// 2. Rerank and keep the most relevant handful for the prompt.
const { rerankedDocuments } = await rerank({
adapter: cohereRerank('rerank-v3.5'),
query,
documents: candidates.map((c) => c.text),
topN: 5,
})

return rerankedDocuments
}

취소

진행 중인 요청을 취소하려면 abortSignal을 전달합니다.

import { rerank } from '@tanstack/ai'
import { cohereRerank } from '@tanstack/ai-cohere'

const controller = new AbortController()
setTimeout(() => controller.abort(), 5000)

const result = await rerank({
adapter: cohereRerank('rerank-v3.5'),
query: 'q',
documents: ['a', 'b'],
abortSignal: controller.signal,
})

console.log(result.rerankedDocuments)

관찰 가능성

사용량, 완료, 오류, 취소를 추적하려면 관찰 전용 미들웨어를 연결합니다. 미디어 활동에서 사용하는 것과 동일한 GenerationMiddleware 계약입니다.

import { rerank } from '@tanstack/ai'
import { cohereRerank } from '@tanstack/ai-cohere'

const result = await rerank({
adapter: cohereRerank('rerank-v3.5'),
query: 'q',
documents: ['a', 'b'],
middleware: [
{
name: 'usage-logger',
onUsage: (_ctx, usage) => {
if (usage.billed) {
console.log(
`search units billed: ${usage.billed.quantity} ${usage.billed.unit}`,
)
}
},
},
],
})

console.log(result.rerankedDocuments)

팁: 재순위화 호출에 대한 OpenTelemetry 스팬을 생성하려면 otelMiddleware()를 전달합니다. OpenTelemetry를 참조하세요.

환경 변수

Cohere 재순위화 어댑터는 다음을 사용합니다.

  • COHERE_API_KEY: Cohere API 키입니다.

오류 처리

import { rerank } from '@tanstack/ai'
import { cohereRerank } from '@tanstack/ai-cohere'

try {
const result = await rerank({
adapter: cohereRerank('rerank-v3.5'),
query: 'q',
documents: ['a', 'b'],
})
console.log(result.rerankedDocuments)
} catch (error) {
if (error instanceof Error) {
console.error('Rerank failed:', error.message)
}
}

documents 배열을 전달하면 요청이 이루어지기 전에 예외가 발생합니다.

실행 가능한 예제

examples/ts-react-rerank는 이 페이지의 모든 기능을 실행하는 작은 TanStack Start 앱입니다. 최신순으로 나열된 고정 지원 문서 모음, 쿼리 입력 상자, 점수와 함께 원래 순서와 재순위화된 순서를 나란히 비교하는 보기를 제공합니다. 제공자 드롭다운을 사용하면 동일한 rerank() 호출에서 Cohere 어댑터와 OpenRouter 어댑터 사이를 전환할 수 있습니다.

cd examples/ts-react-rerank
pnpm install
cp .env.example .env # add COHERE_API_KEY and/or OPENROUTER_API_KEY
pnpm dev

다음 단계