Build a retrieval-augmented generation pipeline using OpenDunes embeddings and a reranking model to ground answers in your documents.
Retrieval-augmented generation (RAG) improves answer accuracy by fetching the most relevant documents from your own data before sending them to the language model. OpenDunes supports this natively with the embeddings endpoint and an optional rerank step — all billed in DA.
Query
→ Embed query (POST /v1/embeddings)
→ Vector search (your vector DB)
→ Rerank top-k results (POST /v1/rerank) ← optional but improves precision
→ Stuff into context (POST /v1/chat/completions)
→ AnswerBefore querying, embed your document chunks and store the vectors in a vector database (pgvector, Qdrant, Pinecone, etc.):
import os
from openai import OpenAI
client = OpenAI(
base_url="https://opendunes.com/v1",
api_key=os.environ["OPENDUNES_API_KEY"],
)
def embed(texts: list[str]) -> list[list[float]]:
resp = client.embeddings.create(
model="openai/text-embedding-3-large",
input=texts,
)
return [e.embedding for e in resp.data]
def index_documents(chunks: list[str], vector_db) -> None:
vectors = embed(chunks)
for chunk, vector in zip(chunks, vectors):
vector_db.upsert(vector=vector, metadata={"text": chunk})At query time, embed the user's question, retrieve the top-k candidates, rerank them, then pass the best results to the language model:
def answer_question(question: str, vector_db) -> str:
# 1. Embed the question
q_vector = embed([question])[0]
# 2. Retrieve top 20 candidates from vector DB
candidates = vector_db.search(q_vector, top_k=20)
texts = [c["text"] for c in candidates]
# 3. Rerank to the top 5 most relevant
rerank_resp = client.post("/v1/rerank", json={
"model": "cohere/rerank-4-pro",
"query": question,
"documents": texts,
"top_n": 5,
}).json()
top_docs = [texts[r["index"]] for r in rerank_resp["results"]]
# 4. Build context and call the language model
context = "\n\n---\n\n".join(top_docs)
messages = [
{"role": "system", "content": f"Answer the question using only the context below.\n\nContext:\n{context}"},
{"role": "user", "content": question},
]
resp = client.chat.completions.create(
model="anthropic/claude-sonnet-5",
messages=messages,
max_tokens=512,
)
return resp.choices[0].message.content or ""The quality of a RAG pipeline depends heavily on how you split documents:
Embedding 1 million tokens costs a small fraction of the cost of generating those tokens. The model catalog shows per-million-token DA rates for each embedding and rerank model — filter with ?modality=embedding or ?modality=rerank. A typical RAG query (embed 1 query + rerank 20 candidates + one chat completion) costs well under 1 DA end-to-end.
OpenDunes runs inside Algeria's data residency boundary. Documents you index via the embeddings API are processed and stored within the platform's infrastructure. This supports compliance with Algeria's Law 18-07 for applications that handle Algerian personal data.