windlass.rag¶
rag
¶
Retrieval-augmented generation.
Start with :func:windlass.Windlass.rag, which returns a
:class:~windlass.rag.builder.RAGBuilder::
from windlass import Windlass
rag = Windlass.rag().chunker("semantic").retriever("hybrid")
rag.ingest("./docs")
print(rag.ask("How does authentication work?"))
The pieces:
- :class:
~windlass.rag.builder.RAGBuilder— the fluent API, and the place where cross-component wiring is resolved. - :class:
~windlass.rag.pipeline.RAGPipeline— the assembled pipeline that does the work. - :func:
~windlass.rag.loading.loader_for— format auto-detection.
RAGBuilder
¶
Fluent builder for a :class:~windlass.rag.pipeline.RAGPipeline.
Every configuration method returns self, and the pipeline methods
(:meth:ingest, :meth:ask, :meth:search, ...) are forwarded, so a
builder is a usable pipeline — no explicit .build() required.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
container
|
Container | None
|
Dependency container. Defaults to a child of the process root, so application-wide bindings are inherited. |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
container |
The container backing this builder. |
Example
Level 1 — defaults all the way down, no dependencies, no API keys::
rag = Windlass.rag()
rag.ingest_text("Windlass unifies the AI ecosystem.")
print(rag.ask("What does Windlass do?"))
Level 2 — configured::
rag = (Windlass.rag()
.llm("openai", model="gpt-4o-mini", temperature=0)
.embedding("huggingface", model="BAAI/bge-small-en-v1.5")
.chunker("recursive", chunk_size=800, overlap=120)
.vectordb("faiss", persist_path="./index")
.retriever("hybrid", weights=[0.6, 0.4])
.top_k(8))
Level 3 — reach past the abstraction::
index = rag.native_store() # the raw faiss.Index
client = rag.native_llm() # the raw openai.AsyncOpenAI
Source code in src\windlass\rag\builder.py
llm
¶
Choose the generation model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Provider options — |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Example
from windlass import Windlass _ = Windlass.rag().llm("fake", responses=["hi"])
Source code in src\windlass\rag\builder.py
embedding
¶
Choose the embedding model.
The same model must embed your corpus and your queries — Windlass uses this one for both, which is why swapping it means re-ingesting.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Provider options — |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Source code in src\windlass\rag\builder.py
vectordb
¶
Choose the vector store.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Store options — |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Source code in src\windlass\rag\builder.py
chunker
¶
Choose the chunking strategy.
The highest-leverage knob in a RAG system: it decides what the retriever can find and what the model gets to read.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Strategy options — |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Example
from windlass import Windlass _ = Windlass.rag().chunker("recursive", chunk_size=1000, overlap=200)
Source code in src\windlass\rag\builder.py
retriever
¶
Choose the retrieval strategy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Strategy options — |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Note
"hybrid" builds a dense leg plus a BM25 leg over the same corpus
automatically. Pass retrievers=[...] to fuse your own set.
Source code in src\windlass\rag\builder.py
loader
¶
Pin a document loader.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Loader options. |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Note
Optional. With no loader configured, Windlass picks one per file from the extension, which is what you want for a mixed corpus.
Source code in src\windlass\rag\builder.py
preprocessor
¶
Add a preprocessing stage.
Called repeatedly, stages compose into a chain in call order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Preprocessor options. |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Example
from windlass import Windlass _ = (Windlass.rag() ... .preprocessor("clean", min_length=50) ... .preprocessor("dedup", threshold=0.95) ... .preprocessor("pii", action="redact"))
Source code in src\windlass\rag\builder.py
memory
¶
Attach conversation memory, making ask multi-turn aware.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Memory options. |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Source code in src\windlass\rag\builder.py
guardrails
¶
Enable input and output guardrails.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Policy options — |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Example
from windlass import Windlass _ = Windlass.rag().guardrails(pii=True, on_violation="redact")
Source code in src\windlass\rag\builder.py
observe
¶
Enable tracing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spec
|
Any
|
Registry name ( |
None
|
**config
|
Any
|
Tracer options — |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Source code in src\windlass\rag\builder.py
prompt
¶
Override the answer prompt template.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
template
|
str
|
A format string containing |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
When a placeholder is missing. |
Source code in src\windlass\rag\builder.py
top_k
¶
Set how many chunks to retrieve per question.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
k
|
int
|
Number of chunks. Must be positive. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src\windlass\rag\builder.py
max_context_tokens
¶
Cap how much retrieved context reaches the prompt.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tokens
|
int
|
Token ceiling. Lower-ranked chunks are dropped first. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
Source code in src\windlass\rag\builder.py
strict
¶
Refuse to answer when retrieval finds nothing.
Removes the model's opportunity to fill an empty context with plausible invention, which is more effective than asking it not to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
enabled
|
bool
|
True to refuse, False to answer from parametric knowledge. |
True
|
Returns:
| Type | Description |
|---|---|
Self
|
|
Note
Dense retrieval returns the nearest vectors, however far away they
are — so it is almost never empty, and strict mode alone will rarely
fire. Pair it with :meth:min_score to make "found nothing relevant"
mean what you expect:
Source code in src\windlass\rag\builder.py
min_score
¶
Discard retrieval hits scoring below threshold.
This is what turns strict mode into a real relevance gate. Without it,
dense retrieval hands back its k nearest neighbours no matter how
unrelated they are, and the model is asked to answer from noise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
threshold
|
float | None
|
Minimum score to keep, or |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
Example
from windlass import Windlass rag = Windlass.rag().retriever("vector").strict().min_score(0.3) rag.ingest_text("Paris is the capital of France.") 1 rag.ask("Explain quantum chromodynamics.").metadata["no_context"] True
Source code in src\windlass\rag\builder.py
batch_size
¶
Set the ingestion batch size.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
size
|
int
|
Chunks embedded and indexed per batch. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
bind
¶
Bind an arbitrary dependency into this builder's container.
The escape hatch for wiring something Windlass has no named slot for.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
Binding key. |
required |
factory
|
Any
|
A factory callable, or a ready-made instance. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
|
Source code in src\windlass\rag\builder.py
build
¶
Resolve every component and construct the pipeline.
Called automatically on first use. Call it explicitly when you want construction errors (a missing API key, an uninstalled extra) to surface at startup rather than on the first request.
Returns:
| Type | Description |
|---|---|
RAGPipeline
|
The assembled :class: |
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
When a component cannot be constructed. |
MissingDependencyError
|
When a chosen provider's extra is not installed. |
Example
from windlass import Windlass pipeline = Windlass.rag().build() pipeline.top_k 5
Source code in src\windlass\rag\builder.py
ingest
¶
aingest
async
¶
ingest_text
¶
Ingest a raw string. See :meth:~windlass.rag.pipeline.RAGPipeline.ingest_text.
aingest_text
async
¶
ingest_documents
¶
ask
¶
Answer a question. See :meth:~windlass.rag.pipeline.RAGPipeline.ask.
aask
async
¶
stream_ask
¶
Stream an answer. See :meth:~windlass.rag.pipeline.RAGPipeline.stream_ask.
astream_ask
¶
search
¶
search(
query: str, k: int | None = None, *, filters: MetadataFilter | None = None
) -> SearchResult
Retrieve without generating. See :meth:~windlass.rag.pipeline.RAGPipeline.search.
Source code in src\windlass\rag\builder.py
asearch
async
¶
evaluate
¶
Evaluate the pipeline. See :meth:~windlass.rag.pipeline.RAGPipeline.evaluate.
aevaluate
async
¶
count
¶
save
¶
load
¶
close
¶
native_llm
¶
native_store
¶
native_retriever
¶
AutoLoader
¶
AutoLoader(
*,
metadata: dict[str, Any] | None = None,
recursive: bool = True,
on_error: str = "skip",
loader_config: dict[str, dict[str, Any]] | None = None,
**config: Any
)
Bases: Loader
Dispatches each source to the loader that claims it.
This is what makes ingest('./docs') handle a folder of mixed formats.
Files with no matching loader are skipped with a warning rather than
aborting the run, so one unreadable file cannot lose a large ingestion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metadata
|
dict[str, Any] | None
|
Metadata attached to every produced document. |
None
|
recursive
|
bool
|
Walk directories recursively. |
True
|
on_error
|
str
|
|
'skip'
|
loader_config
|
dict[str, dict[str, Any]] | None
|
Per-loader keyword arguments, keyed by loader name, e.g.
|
None
|
**config
|
Any
|
Forwarded to :class: |
{}
|
Example
import tempfile, pathlib folder = pathlib.Path(tempfile.mkdtemp()) _ = (folder / "a.txt").write_text("plain") _ = (folder / "b.md").write_text("# heading") sorted(d.metadata["extension"] for d in AutoLoader().load(folder)) ['.md', '.txt']
Source code in src\windlass\rag\loading.py
can_handle
classmethod
¶
aload_source
async
¶
Route one source to its loader and read it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
SourceLike
|
A single path, URL or byte payload. |
required |
Returns:
| Type | Description |
|---|---|
list[Document]
|
The extracted documents, or |
list[Document]
|
and |
Raises:
| Type | Description |
|---|---|
IngestionError
|
When no loader claims the source and
|
Source code in src\windlass\rag\loading.py
RAGPipeline
¶
RAGPipeline(
*,
llm: LLM,
embedder: Embedder,
vectorstore: VectorStore,
retriever: Retriever | None = None,
chunker: Chunker | None = None,
loader: Loader | None = None,
preprocessor: Preprocessor | None = None,
guardrail: Guardrail | None = None,
memory: Memory | None = None,
tracer: Tracer | None = None,
prompt: str = DEFAULT_PROMPT,
top_k: int = 5,
max_context_tokens: int = 6000,
include_sources: bool = True,
answer_without_context: bool = False,
batch_size: int = 64
)
A fully wired retrieval-augmented generation pipeline.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
llm
|
LLM
|
Model used to generate answers. |
required |
embedder
|
Embedder
|
Model used to embed chunks and queries. |
required |
vectorstore
|
VectorStore
|
Where chunk vectors are stored. |
required |
retriever
|
Retriever | None
|
Retrieval strategy. Defaults to dense search over
|
None
|
chunker
|
Chunker | None
|
Chunking strategy. Defaults to recursive. |
None
|
loader
|
Loader | None
|
Loader used by :meth: |
None
|
preprocessor
|
Preprocessor | None
|
Optional cleaning/enrichment stage. |
None
|
guardrail
|
Guardrail | None
|
Optional input/output policy. |
None
|
memory
|
Memory | None
|
Optional conversation memory, making |
None
|
tracer
|
Tracer | None
|
Observability backend. |
None
|
prompt
|
str
|
Prompt template. Must contain |
DEFAULT_PROMPT
|
top_k
|
int
|
How many chunks to retrieve per question. |
5
|
max_context_tokens
|
int
|
Ceiling on context placed in the prompt. Chunks are dropped from the tail until it fits, so the highest-ranked context always survives. |
6000
|
include_sources
|
bool
|
Number each context block and ask the model to cite them. |
True
|
answer_without_context
|
bool
|
When False, retrieval finding nothing returns
:data: |
False
|
batch_size
|
int
|
Chunks embedded and indexed per batch during ingestion. |
64
|
Attributes:
| Name | Type | Description |
|---|---|---|
llm |
The generation model. |
|
retriever |
The retrieval strategy. |
|
vectorstore |
The vector store. |
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
When a required component is missing or the prompt template lacks its placeholders. |
Source code in src\windlass\rag\pipeline.py
aingest
async
¶
aingest(
source: Any, *, metadata: dict[str, Any] | None = None, show_progress: bool = False
) -> int
Load, preprocess, chunk, embed and index a source.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Any
|
A path, directory, URL, glob, byte payload, or a sequence of any of those. Directories are walked and each file routed to the right loader by extension. |
required |
metadata
|
dict[str, Any] | None
|
Extra metadata attached to every resulting chunk — a tenant id, a corpus name, an ingestion date. |
None
|
show_progress
|
bool
|
Log a line per stage. Useful on long runs. |
False
|
Returns:
| Type | Description |
|---|---|
int
|
How many chunks were indexed. |
Raises:
| Type | Description |
|---|---|
IngestionError
|
When nothing could be loaded, or a stage fails. |
Performance
Loading, embedding and indexing are all batched and concurrent. Re-ingesting unchanged content is cheap: chunk ids are content hashes, so the store upserts rather than duplicating, and a configured embedding cache skips the model entirely.
Example
import asyncio, tempfile, pathlib from windlass import Windlass folder = pathlib.Path(tempfile.mkdtemp()) _ = (folder / "a.txt").write_text("Retrieval augmented generation.") asyncio.run(Windlass.rag().aingest(folder)) >= 1 True
Source code in src\windlass\rag\pipeline.py
ingest
¶
ingest(
source: Any, *, metadata: dict[str, Any] | None = None, show_progress: bool = False
) -> int
Blocking :meth:aingest.
aingest_documents
async
¶
Ingest already-loaded documents, skipping the loader.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
documents
|
Sequence[Document]
|
Documents to preprocess, chunk, embed and index. |
required |
Returns:
| Type | Description |
|---|---|
int
|
How many chunks were indexed. |
Source code in src\windlass\rag\pipeline.py
ingest_documents
¶
aingest_text
async
¶
aingest_text(
text: str, *, source: str | None = None, metadata: dict[str, Any] | None = None
) -> int
Ingest a raw string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The text to index. |
required |
source
|
str | None
|
Label recorded as the document's source, used for citation. |
None
|
metadata
|
dict[str, Any] | None
|
Extra metadata. |
None
|
Returns:
| Type | Description |
|---|---|
int
|
How many chunks were indexed. |
Example
import asyncio from windlass import Windlass asyncio.run(Windlass.rag().aingest_text("Some knowledge.")) >= 1 True
Source code in src\windlass\rag\pipeline.py
ingest_text
¶
ingest_text(
text: str, *, source: str | None = None, metadata: dict[str, Any] | None = None
) -> int
Blocking :meth:aingest_text.
asearch
async
¶
asearch(
query: str, k: int | None = None, *, filters: MetadataFilter | None = None
) -> SearchResult
Retrieve without generating an answer.
Useful for building a search UI, for debugging why an answer was wrong, and for evaluating retrieval quality independently of generation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
The search query. |
required |
k
|
int | None
|
Override for :attr: |
None
|
filters
|
MetadataFilter | None
|
Metadata constraints. |
None
|
Returns:
| Type | Description |
|---|---|
SearchResult
|
The ranked results. |
Source code in src\windlass\rag\pipeline.py
search
¶
aask
async
¶
aask(
question: str,
*,
k: int | None = None,
filters: MetadataFilter | None = None,
thread_id: str = "default",
**llm_kwargs: Any
) -> RAGAnswer
Answer a question from the indexed corpus.
The full path: input guardrail, retrieval, context assembly, generation, output guardrail, memory update.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
question
|
str
|
The user's question. |
required |
k
|
int | None
|
Override for :attr: |
None
|
filters
|
MetadataFilter | None
|
Metadata constraints on retrieval. |
None
|
thread_id
|
str
|
Conversation thread, when memory is configured. |
'default'
|
**llm_kwargs
|
Any
|
Per-call model overrides ( |
{}
|
Returns:
| Type | Description |
|---|---|
RAGAnswer
|
The answer, the contexts it was based on, token usage and latency. |
Raises:
| Type | Description |
|---|---|
GuardrailViolation
|
When a guardrail blocks the question or answer. |
PipelineError
|
When generation fails. |
Performance
One retrieval (embedding + store query) plus one model call. Context
is truncated to :attr:max_context_tokens from the tail, so a large
top_k never blows the context window.
Example
import asyncio from windlass import Windlass rag = Windlass.rag() _ = rag.ingest_text("The Eiffel Tower is in Paris.") asyncio.run(rag.aask("Where is the Eiffel Tower?")).question 'Where is the Eiffel Tower?'
Source code in src\windlass\rag\pipeline.py
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | |
ask
¶
ask(
question: str,
*,
k: int | None = None,
filters: MetadataFilter | None = None,
thread_id: str = "default",
**llm_kwargs: Any
) -> RAGAnswer
Blocking :meth:aask.
Source code in src\windlass\rag\pipeline.py
astream_ask
async
¶
astream_ask(
question: str,
*,
k: int | None = None,
filters: MetadataFilter | None = None,
thread_id: str = "default",
**llm_kwargs: Any
) -> AsyncIterator[str]
Stream an answer token by token.
Retrieval completes first (it must — the context shapes the prompt), then
generation streams. Guardrails run on the assembled answer after the
stream finishes, so a blocking output policy cannot un-send text that has
already reached the user; use redact semantics or non-streaming
generation when output blocking must be authoritative.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
question
|
str
|
The user's question. |
required |
k
|
int | None
|
Override for :attr: |
None
|
filters
|
MetadataFilter | None
|
Metadata constraints. |
None
|
thread_id
|
str
|
Conversation thread. |
'default'
|
**llm_kwargs
|
Any
|
Per-call model overrides. |
{}
|
Yields:
| Type | Description |
|---|---|
AsyncIterator[str]
|
Text fragments as the model produces them. |
Source code in src\windlass\rag\pipeline.py
stream_ask
¶
Blocking :meth:astream_ask.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
question
|
str
|
The user's question. |
required |
**kwargs
|
Any
|
Forwarded to :meth: |
{}
|
Yields:
| Type | Description |
|---|---|
str
|
Text fragments. |
Source code in src\windlass\rag\pipeline.py
aevaluate
async
¶
aevaluate(
questions: Sequence[str] | Sequence[dict[str, Any]],
*,
evaluator: Any = None,
metrics: Sequence[str] | None = None
) -> Any
Answer a question set and score the results.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
questions
|
Sequence[str] | Sequence[dict[str, Any]]
|
Question strings, or dicts with |
required |
evaluator
|
Any
|
An :class: |
None
|
metrics
|
Sequence[str] | None
|
Metric names, passed to the default evaluator. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
An |
Any
|
class: |
Example
import asyncio from windlass import Windlass rag = Windlass.rag() _ = rag.ingest_text("Paris is the capital of France.") report = asyncio.run(rag.aevaluate( ... [{"question": "Capital of France?", "reference": "Paris"}], ... metrics=["answer_relevancy_lexical"], ... )) report.samples 1
Source code in src\windlass\rag\pipeline.py
evaluate
¶
evaluate(
questions: Sequence[str] | Sequence[dict[str, Any]],
*,
evaluator: Any = None,
metrics: Sequence[str] | None = None
) -> Any
Blocking :meth:aevaluate.
Source code in src\windlass\rag\pipeline.py
native_llm
¶
native_store
¶
native_retriever
¶
describe
¶
Return a JSON-safe description of every wired component.
Useful for logging what a deployment is actually running, and for diffing two environments that behave differently.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
A dict keyed by component role. |
Source code in src\windlass\rag\pipeline.py
acount
async
¶
Return how many chunks are indexed.
Reads the vector store, falling back to the retriever's own index for purely lexical pipelines where no vectors are stored.
Source code in src\windlass\rag\pipeline.py
count
¶
aclose
async
¶
Release every component's resources.
Source code in src\windlass\rag\pipeline.py
close
¶
save
¶
Persist the index to disk, when the store supports it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory
|
str | Path
|
Where to write. Created if absent. |
required |
Returns:
| Type | Description |
|---|---|
Path
|
The directory written to. |
Raises:
| Type | Description |
|---|---|
PipelineError
|
When the configured store cannot persist. |
Example
import tempfile from windlass import Windlass rag = Windlass.rag() _ = rag.ingest_text("something worth keeping") rag.save(tempfile.mkdtemp()).is_dir() True
Source code in src\windlass\rag\pipeline.py
load
¶
Restore an index previously written by :meth:save.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory
|
str | Path
|
Directory containing the saved index. |
required |
Returns:
| Type | Description |
|---|---|
RAGPipeline
|
|
Raises:
| Type | Description |
|---|---|
PipelineError
|
When the configured store cannot load. |
Source code in src\windlass\rag\pipeline.py
loader_for
¶
loader_for(
source: SourceLike | Sequence[SourceLike],
*,
metadata: dict[str, Any] | None = None,
**config: Any
) -> Loader
Return a loader able to read source.
A heterogeneous sequence (or a directory containing several formats) yields
an :class:AutoLoader, which dispatches per file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
SourceLike | Sequence[SourceLike]
|
A path, URL, directory, byte payload, or sequence of them. |
required |
metadata
|
dict[str, Any] | None
|
Metadata attached to every produced document. |
None
|
**config
|
Any
|
Forwarded to the chosen loader's constructor. |
{}
|
Returns:
| Type | Description |
|---|---|
Loader
|
A ready-to-use loader. |
Raises:
| Type | Description |
|---|---|
IngestionError
|
When nothing can read the source. |
Example
loader_for("report.pdf").provider_name 'pdf' loader_for(b"raw bytes").provider_name 'text'