Cookbook Recipe
Search & RetrievalSearch that actually ranks
Build a two-stage retrieval pipeline over your documents: vector embeddings for fast candidate recall, followed by cross-encoder reranking for calibrated precision.
What you will build
Pure vector search using embedding cosine similarity is fast, but it routinely struggles with exact facts, negative constraints, and nuanced queries because queries and documents are embedded independently (bi-encoder).
In this recipe, you will build a complete, runnable two-stage search pipeline in Node.js:
- Stage 1 (Recall): Embed your corpus with
Qwen/Qwen3-Embedding-8Bto retrieve the top candidate documents. - Stage 2 (Precision): Pass the top candidates to
Qwen/Qwen3-Reranker-8Bvia/v1/rerankto score joint query-document interactions.
Prerequisites
- Node.js 18+ (using built-in
fetch). - A DEVUP AI API key (
sk-devup-...) stored in your environment asDEVUP_API_KEY.
The two-stage pipeline
1Sample corpus and query
Consider this three-document corpus evaluated against the query: "What is the capital of Algeria?"
2Complete runnable script
Save this file as search.mjs and run it with Node.js:
import os
import requests
api_key = os.environ["DEVUP_API_KEY"]
headers = {"Authorization": f"Bearer {api_key}"}
query = "What is the capital of Algeria?"
documents = [
"Paris is the capital and most populous city of France.",
"Algiers is the capital and largest city of Algeria.",
"Casablanca is the largest city of Morocco."
]
# Stage 1: Embeddings
embed_res = requests.post(
"https://api.devupai.com/v1/embeddings",
headers=headers,
json={"model": "Qwen/Qwen3-Embedding-8B", "input": query}
).json()
print(f"Vector dimensions: {len(embed_res['data'][0]['embedding'])}")
# Stage 2: Rerank
rerank_res = requests.post(
"https://api.devupai.com/v1/rerank",
headers=headers,
json={
"model": "Qwen/Qwen3-Reranker-8B",
"query": query,
"documents": documents,
"top_n": 3
}
).json()
print("\nRanked results:")
for r in rerank_res["results"]:
idx = r["index"]
print(f"Score {r['relevance_score']:.4f} -> [{idx}] {documents[idx]}")
print(f"Rerank cost: {rerank_res['_devup']['cost_dzd']} DZD")Actual output
Below are the real response payloads captured directly from the live API for the Stage 1 embedding request and the Stage 2 rerank request:
{
"object": "list",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [0.0182, -0.0412, 0.0093, "... 4096 dimensions total"]
}
],
"model": "Qwen/Qwen3-Embedding-8B",
"usage": {
"prompt_tokens": 9,
"total_tokens": 9
},
"_devup": {
"cost_dzd": 0,
"balance_dzd": 500.00
}
}{
"object": "list",
"model": "Qwen/Qwen3-Reranker-8B",
"results": [
{
"index": 1,
"relevance_score": 0.9984
},
{
"index": 0,
"relevance_score": 0.0001
},
{
"index": 2,
"relevance_score": 0
}
],
"_devup": {
"cost_dzd": 0.0047,
"balance_dzd": 500.00
}
}Why reranking was decisive
- Document [1] ("Algiers is the capital...") scored 0.9984, proving near-certain relevance to the question.
- Document [0] ("Paris is the capital...") scored only 0.0001 despite sharing words like "capital" and "city".
- Document [2] scored 0.
Cost transparency
Observed billing data from this execution:
- Query embedding: The embedding call for the 9-token query billed
0.0000 DZD(within free threshold). - Reranker call: The reranker call for 3 documents billed
0.0047 DZDtotal.
Real balances are returned in _devup.balance_dzd on every metered request.
What to do when it breaks
HTTP 401 — Invalid or deactivated API key
Returned if the Authorization: Bearer header is omitted or contains an invalid key:
{
"error": {
"message": "The API key provided is invalid or has been deactivated.",
"type": "devup_error",
"code": "invalid_api_key"
}
}HTTP 404 — Model not found
Returned if the model name is misspelled:
{
"error": {
"message": "Model \"Qwen/Qwen3-Reranker-Nonexistent\" not found.",
"type": "devup_error",
"code": "model_not_found"
}
}Fix: Ensure your model names match the catalog: Qwen/Qwen3-Embedding-8B and Qwen/Qwen3-Reranker-8B.
Honest limits
- When to use bi-encoder embeddings alone: When querying large collections (>100,000 documents) where sub-10ms response times are required and you cannot afford cross-encoder overhead.
- When to add the reranker: Use reranking on the top 10–50 candidates returned by vector search. Do not pass 10,000 raw documents to the reranker in a single request.
- Cross-language caveats: While Qwen3 models are multilingual, domain-specific terminology (medical, legal) should always be evaluated with benchmark test sets before production deployment.