FAQ

Does this library call an LLM anywhere? No. Verified by inspecting every import and method in the package — there is no LLM SDK import, no HTTP client, no network call of any kind. The library only assembles context; you bring your own LLM call.

Does it support async? No. There is no async def anywhere in the source. All retrieval, filtering, ranking, and composition is synchronous.

Is it thread-safe? Not generally. See the "Thread Safety" section on each class's API page. The cache (ContextCache), conversation history (ConversationHistory), and adaptive learning system (AdaptiveLearningSystem) are all mutated without locks, so a single ContextEngine instance shared across threads can race. Stateless components like RuleBasedQueryAnalyzer and CompositeRanker (aside from mutating the ScoredChunk objects passed in) are safe to call concurrently.

Does it support a real vector database out of the box (Pinecone, Chroma, FAISS, etc.)? Yes, natively — pass a zerda.vector_database.VectorDatabaseBase instance (ChromaVectorDatabase, FAISSVectorDatabase, or PineconeVectorDatabase) as the vector_db parameter on VectorRetriever/ContextEngine.index()/ContextEngine.index_documents(). context calls the backend's own .add()/.search() methods directly — no adapter needed — and resolves metadata filters to whichever kwarg name each backend expects (filters for Chroma, filter_dict for Pinecone, doc_id_filter for FAISS). See api/retriever. For anything not built on zerda.vector_database (a raw LangChain VectorStore, or another framework's store entirely), use the older vector_store_adapter parameter instead — it just needs a similarity_search_with_score(query, k, filter) method, matching the LangChain VectorStore interface.

How do I go from raw text to an indexed ContextEngine without hand-building chunk objects? Use ContextEngine.index_documents(texts, chunker, vector_db=...) — it chunks your raw text with any zerda.chunks chunker (SemanticChunker, StructureAwareChunker, AdaptiveChunker, ArabicTextChunker, …) and indexes the resulting DocumentChunks into vector_db in one call. See the quickstart and the native integration recipe.

Is the budget in characters or tokens? Characters, by default (char_counter). You can switch to tokens by passing a length_counter built with make_token_counter(your_tokenizer) to ContextEngine.

Why is my context coming back empty even though I indexed chunks? Common causes, in likely order of frequency:

  1. You called engine.index(chunks=[]) (or with a falsy list) — index() returns immediately without building anything.
  2. Your chunks don't have a .text (or .page_content) attribute — ScoredChunk.text silently returns "" rather than raising.
  3. FilterConfig.min_chunk_length/max_chunk_length excluded everything.
  4. GuardConfig.check_empty failed because composition genuinely produced nothing — check result.guard_warnings.

Why doesn't changing config.composer.template after creating my engine do anything? SmartContextComposer resolves and caches the template object at construction time (self._tmpl). Mutating the config afterward doesn't re-trigger that resolution. Construct a new ContextEngine (or SmartContextComposer) instead.

Does Arabic-language support require any extra setup? No — it's built into query_analyzer.py and the composer's "arabic" template (which is also the default template, so out of the box, English-only users will see Arabic UI strings like 📚 المعلومات المسترجعة: unless they explicitly set config.composer.template = "english" or "minimal").

Can I use this with documents that aren't pre-chunked? No — chunking is entirely out of scope for this library. It assumes you've already split documents into retrievable units before calling index().

Is there a REST API, CLI, or web server included? No. This is a plain importable Python library with no entry points, no CLI commands, and no HTTP server defined anywhere in the source.

What happens to composite_score if I provide my own retriever class that's not HybridRetriever? ContextEngine.run() only requires self._retriever.retrieve(query, top_k, filters) to return List[ScoredChunk] — it does not require HybridRetriever specifically. As long as your object's retrieve() method returns properly constructed ScoredChunks, the rest of the pipeline (filter → rank → compose → guard) works unchanged, since CompositeRanker recomputes composite_score from scratch anyway.

Is there a confirmed PyPI package name? Not determinable from the provided source — no packaging metadata exists in the analyzed files. See Installation.

If your question isn't answered here, the most reliable path is reading the relevant class's page under API Reference — every behavior documented there was verified directly against the source.

Related pages