Architecture
Aktilot ships as a Docker Compose stack: a React frontend, a FastAPI backend, a Temporal cluster for durable workflow execution, Postgres for metadata, and ChromaDB for vectors — plus a full OpenTelemetry observability stack.

Workflows on a Temporal cluster
All three workflows run on a Temporal cluster for durable, individually-retryable execution:
DocumentWorkflow
Chunks, embeds, and indexes uploaded files into ChromaDB. Metadata is stored in Postgres.
Activities observed in a real trace: update_file_status → read_and_split_file → clear_existing_vectors → embed_and_index_chunks → update_file_status
ChatWorkflow
Hybrid BM25 + vector retrieval, LLM answer generation, and conversation persistence. Each step is checkpointed; a failed OpenAI call retries alone without re-running earlier steps.
Activities observed in a real trace: get_agent_config → extract_keywords → embed_query → search_vectors → hybrid_rank → generate_answer → persist_messages
BenchmarkWorkflow (coming soon)
Evaluates retrieval quality with Recall@K, MRR, and latency metrics, storing results in an evaluation DB.
Retrieval pipeline
Ingestion parses PDF (pypdf/pdfplumber), DOCX (python-docx), or plain text, cleans it, splits it into overlapping chunks (~1000 characters with ~200 character overlap), embeds each chunk with text-embedding-3-small (1536 dimensions), and writes it into ChromaDB.
At query time, Aktilot extracts keywords, runs dense vector search and sparse BM25 search in parallel, blends and reranks the results, assembles context from the top-ranked chunks, and generates an answer:
final_score = (0.5 × vector_similarity) + (0.5 × keyword_match_ratio)
This is the simplest hybrid variant — a production system tuned further would use learned weights or Reciprocal Rank Fusion. Combining keyword overlap with semantic similarity consistently outperforms pure vector search on precise factual questions like dates, names, and figures.
Where Aktilot sits on the RAG maturity model
Aktilot is architected to evolve toward agentic RAG without a rewrite — the service layer, tool-step recording, and response schema are already agent-compatible.
Embed a question, do a single vector search, stuff the top chunks into a prompt. Most tutorials stop here.
Keywords → search → rank → context → answer, with hybrid scoring and full tool-step visibility. This is where Aktilot is today.
The agent decides steps dynamically — it can loop, verify its own answer, or decompose a question into sub-queries, and it has memory across turns.
Specialised agents coordinated by an orchestrator — production RAG at scale.