RAG¶
Retriever¶
RAGRetriever ¶
Bases: BaseModel
RAG Retriever combining embedding and vector store.
Provides a unified interface for: - Adding documents (with automatic embedding) - Retrieving relevant context for queries - Chunking large documents
Example
from locus.rag import RAGRetriever, OCIEmbeddings, OracleVectorStore
retriever = RAGRetriever( ... embedder=OCIEmbeddings(model_id="cohere.embed-english-v3.0"), ... store=OracleVectorStore(dsn="..."), ... )
Add documents¶
await retriever.add_documents( ... [ ... "Python is a programming language.", ... "Oracle Database supports vectors.", ... ] ... )
Retrieve relevant context¶
results = await retriever.retrieve("What is Python?", limit=3) for r in results.documents: ... print(f"{r.score:.2f}: {r.document.content[:50]}...")
Example with chunking
retriever = RAGRetriever( ... embedder=embedder, ... store=store, ... chunk_size=500, ... chunk_overlap=50, ... ) await retriever.add_document(long_document, metadata={"source": "manual"})
add_document
async
¶
add_document(content: str, doc_id: str | None = None, metadata: dict[str, Any] | None = None, chunk: bool = True) -> list[str]
Add a document, optionally chunking it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
str
|
Document text |
required |
doc_id
|
str | None
|
Optional document ID (auto-generated if not provided) |
None
|
metadata
|
dict[str, Any] | None
|
Optional metadata |
None
|
chunk
|
bool
|
Whether to chunk large documents |
True
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of document IDs (multiple if chunked) |
Source code in src/locus/rag/retriever.py
add_documents
async
¶
add_documents(contents: list[str], metadata: dict[str, Any] | None = None, chunk: bool = True) -> list[str]
Add multiple documents.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contents
|
list[str]
|
List of document texts |
required |
metadata
|
dict[str, Any] | None
|
Optional metadata (applied to all) |
None
|
chunk
|
bool
|
Whether to chunk large documents |
True
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of all document IDs |
Source code in src/locus/rag/retriever.py
add_file
async
¶
add_file(file_path: str | Path, doc_id: str | None = None, metadata: dict[str, Any] | None = None, chunk: bool = True) -> list[str]
Add a file (text, PDF, image, or audio).
Automatically detects content type and processes accordingly: - PDFs: Extracts text (with OCR fallback for scanned docs) - Images: OCR text extraction + optional description - Audio: Speech-to-text transcription - Text: Direct processing
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str | Path
|
Path to the file |
required |
doc_id
|
str | None
|
Optional document ID |
None
|
metadata
|
dict[str, Any] | None
|
Optional metadata |
None
|
chunk
|
bool
|
Whether to chunk large documents |
True
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of document IDs |
Example
await retriever.add_file("manual.pdf") await retriever.add_file("diagram.png") await retriever.add_file("meeting.mp3")
Source code in src/locus/rag/retriever.py
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | |
add_image
async
¶
add_image(image: bytes | str | Path, doc_id: str | None = None, metadata: dict[str, Any] | None = None, use_ocr: bool = True) -> str
Add an image document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
bytes | str | Path
|
Image bytes, base64 string, or file path |
required |
doc_id
|
str | None
|
Optional document ID |
None
|
metadata
|
dict[str, Any] | None
|
Optional metadata |
None
|
use_ocr
|
bool
|
Whether to use OCR for text extraction |
True
|
Returns:
| Type | Description |
|---|---|
str
|
Document ID |
Source code in src/locus/rag/retriever.py
add_pdf
async
¶
add_pdf(pdf: bytes | str | Path, doc_id: str | None = None, metadata: dict[str, Any] | None = None, chunk: bool = True) -> list[str]
Add a PDF document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pdf
|
bytes | str | Path
|
PDF bytes, base64 string, or file path |
required |
doc_id
|
str | None
|
Optional document ID |
None
|
metadata
|
dict[str, Any] | None
|
Optional metadata |
None
|
chunk
|
bool
|
Whether to chunk the document |
True
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of document IDs (multiple if chunked) |
Source code in src/locus/rag/retriever.py
add_audio
async
¶
add_audio(audio: bytes | str | Path, doc_id: str | None = None, metadata: dict[str, Any] | None = None) -> str
Add an audio/voice document.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
audio
|
bytes | str | Path
|
Audio bytes, base64 string, or file path |
required |
doc_id
|
str | None
|
Optional document ID |
None
|
metadata
|
dict[str, Any] | None
|
Optional metadata |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Document ID |
Source code in src/locus/rag/retriever.py
retrieve
async
¶
retrieve(query: str, limit: int = 5, threshold: float | None = None, metadata_filter: dict[str, Any] | None = None) -> RetrievalResult
Retrieve relevant documents for a query.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
Query text |
required |
limit
|
int
|
Maximum documents to return |
5
|
threshold
|
float | None
|
Minimum similarity score (0.0-1.0) |
None
|
metadata_filter
|
dict[str, Any] | None
|
Filter by metadata fields |
None
|
Returns:
| Type | Description |
|---|---|
RetrievalResult
|
RetrievalResult with ranked documents |
Source code in src/locus/rag/retriever.py
retrieve_text
async
¶
retrieve_text(query: str, limit: int = 5, threshold: float | None = None, separator: str = '\n\n---\n\n', spotlight: bool = True) -> str
Retrieve and concatenate relevant documents as text.
Convenience method for injecting context into prompts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
Query text |
required |
limit
|
int
|
Maximum documents to return |
5
|
threshold
|
float | None
|
Minimum similarity score |
None
|
separator
|
str
|
Text to join documents |
'\n\n---\n\n'
|
spotlight
|
bool
|
When True (default), wrap each document in
|
True
|
Returns:
| Type | Description |
|---|---|
str
|
Concatenated document contents. |
Security note
Retrieved content is untrusted data — a poisoned document can attempt an indirect prompt-injection. The spotlight wrappers let you instruct the model (in the system prompt) to treat anything inside those tags as data only, never as instructions, and to refuse to perform tool calls whose arguments are quoted verbatim from retrieved content.
Source code in src/locus/rag/retriever.py
delete_document
async
¶
clear
async
¶
count
async
¶
close
async
¶
as_tool ¶
Create a tool function for agent use.
Returns a tool that can be registered with an agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Tool name |
'search_knowledge'
|
description
|
str | None
|
Tool description |
None
|
Returns:
| Type | Description |
|---|---|
Any
|
Tool function decorated with @tool |
Source code in src/locus/rag/retriever.py
Embeddings¶
OCIEmbeddings ¶
OCIEmbeddings(model_id: str = OCIEmbeddingModel.COHERE_EMBED_ENGLISH_V3.value, compartment_id: str = '', profile_name: str = 'DEFAULT', auth_type: str = 'api_key', service_endpoint: str | None = None, **kwargs: Any)
Bases: BaseModel, BaseEmbedding
OCI GenAI Embeddings using Cohere models.
Uses Oracle Cloud Infrastructure GenAI service which hosts Cohere embedding models with enterprise-grade reliability.
Example
embedder = OCIEmbeddings( ... model_id="cohere.embed-english-v3.0", ... profile_name="DEFAULT", ... auth_type="security_token", ... ) result = await embedder.embed("Hello world") print(len(result.embedding)) # 1024
Example with compartment
embedder = OCIEmbeddings( ... model_id="cohere.embed-multilingual-v3.0", ... compartment_id="ocid1.compartment.oc1..xxx", ... )
Source code in src/locus/rag/embeddings/oci.py
capabilities
property
¶
OCI Cohere embeddings: native batching (96), separate
SEARCH_QUERY vs SEARCH_DOCUMENT input types, image-capable
variants for cohere.embed-*-image-v3.0.
embed
async
¶
embed_batch
async
¶
Embed multiple texts.
Source code in src/locus/rag/embeddings/oci.py
embed_query
async
¶
Embed a query for retrieval.
Uses SEARCH_QUERY input type for Cohere models.
Source code in src/locus/rag/embeddings/oci.py
embed_documents
async
¶
Embed documents for storage.
Uses SEARCH_DOCUMENT input type for Cohere models.
Source code in src/locus/rag/embeddings/oci.py
OpenAIEmbeddings ¶
OpenAIEmbeddings(model: str = 'text-embedding-3-small', api_key: str | None = None, dimensions: int | None = None, base_url: str | None = None, **kwargs: Any)
Bases: BaseEmbedding
OpenAI Embeddings provider.
Uses OpenAI's text-embedding models for generating embeddings.
Example
embedder = OpenAIEmbeddings( ... model="text-embedding-3-small", ... api_key="sk-...", ... ) result = await embedder.embed("Hello world") print(len(result.embedding)) # 1536
Initialize OpenAI embeddings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str
|
OpenAI embedding model ID |
'text-embedding-3-small'
|
api_key
|
str | None
|
API key (defaults to OPENAI_API_KEY env var) |
None
|
dimensions
|
int | None
|
Output dimensions (for supported models) |
None
|
base_url
|
str | None
|
Custom base URL |
None
|
**kwargs
|
Any
|
Additional configuration |
{}
|
Source code in src/locus/rag/embeddings/openai.py
capabilities
property
¶
OpenAI embeddings: text-only, native batching, no separate query/doc spaces (text-embedding-3-* use the same space).
embed
async
¶
Embed a single text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to embed |
required |
Returns:
| Type | Description |
|---|---|
EmbeddingResult
|
EmbeddingResult with vector and metadata |
Source code in src/locus/rag/embeddings/openai.py
embed_batch
async
¶
Embed multiple texts in a single request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
texts
|
list[str]
|
List of texts to embed |
required |
Returns:
| Type | Description |
|---|---|
list[EmbeddingResult]
|
List of EmbeddingResult, one per input text |
Source code in src/locus/rag/embeddings/openai.py
close
async
¶
embed_query
async
¶
embed_documents
async
¶
Embed documents. Override if model has document-specific embeddings.
Vector stores¶
OracleVectorStore ¶
OracleVectorStore(dsn: str | None = None, user: str = 'admin', password: str | SecretStr = '', host: str | None = None, port: int = 1521, service_name: str | None = None, dimension: int = 1024, distance_metric: str = 'COSINE', **kwargs: Any)
Bases: BaseModel, BaseVectorStore
Oracle 26ai Vector Store with native VECTOR support.
Uses Oracle Database 23ai/26ai's native VECTOR data type for efficient similarity search. Supports cosine, dot product, and Euclidean distance metrics.
Example with DSN
store = OracleVectorStore( ... dsn="mydb_high", ... user="admin", ... password="secret", ... dimension=1024, ... ) await store.add(document) results = await store.search(query_embedding, limit=5)
Example with connection string
store = OracleVectorStore( ... host="adb.us-ashburn-1.oraclecloud.com", ... port=1522, ... service_name="xxx_high.adb.oraclecloud.com", ... )
Source code in src/locus/rag/stores/oracle.py
add
async
¶
Add a document with embedding.
Source code in src/locus/rag/stores/oracle.py
add_batch
async
¶
Add multiple documents.
Source code in src/locus/rag/stores/oracle.py
get
async
¶
Get a document by ID.
Source code in src/locus/rag/stores/oracle.py
delete
async
¶
Delete a document.
Source code in src/locus/rag/stores/oracle.py
search
async
¶
search(query_embedding: list[float], limit: int = 10, threshold: float | None = None, metadata_filter: dict[str, Any] | None = None) -> list[SearchResult]
Search for similar documents using vector similarity.
Uses Oracle's VECTOR_DISTANCE function for efficient similarity search.
Source code in src/locus/rag/stores/oracle.py
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 | |
count
async
¶
Count documents in store.
Source code in src/locus/rag/stores/oracle.py
clear
async
¶
Delete all documents.
Source code in src/locus/rag/stores/oracle.py
InMemoryVectorStore ¶
Bases: BaseVectorStore
In-memory vector store for testing and development.
Fast but not persistent - data is lost when process exits.
Example
store = InMemoryVectorStore(dimension=1024) await store.add(document) results = await store.search(query_embedding, limit=5)
Source code in src/locus/rag/stores/memory.py
add
async
¶
add_batch
async
¶
get
async
¶
delete
async
¶
search
async
¶
search(query_embedding: list[float], limit: int = 10, threshold: float | None = None, metadata_filter: dict[str, Any] | None = None) -> list[SearchResult]
Search for similar documents.