Skip to content

Technology stack

Actual dependencies and rationale. This reflects what ships today, not every option considered during design.


Stack by maturity stage

Stage Components Status
1 — Data Foundation PyMuPDF ingest, Qdrant, manifest metadata, vector + payload filters Done (MVP)
2 — Trusted Agent Layer LangGraph, FastAPI, Streamlit, Pydantic tools, sentence-transformers, eval Done
3 — Solver Orchestration Docker, Celery/Redis or k8s Jobs, Solver Agent, result parsers Deferred

Overview (Stage 2 — shipped)

Layer Technology Role
Orchestration LangGraph + langchain-core State graph, routing, tool loops
API FastAPI + uvicorn POST /ask, /ask/stream (SSE), feedback, kb stats
UI Streamlit Chat front-end; HTTP client only (SSE streaming)
Vector store Qdrant Embeddings + metadata payloads
Embeddings sentence-transformers intfloat/multilingual-e5-base
LLM OpenRouter / OpenAI / Anthropic Intent, tool selection, report synthesis
Config pydantic-settings CAEC_* environment variables
Portfolio services ask_service.py, follow_ups.py, suggest_questions.py, rate_limit.py SSE orchestration, follow-ups, starters, rate limit
Deps PDM + mamba pyproject.toml + environment.yml
CI/CD GitLab CI env-dev image, lint, test, k8s deploy
Docs MkDocs Material GitLab Pages

Why LangGraph

Option Verdict
LangGraph Chosen — explicit state, conditional edges, retry loops, debuggable
LangChain agents Too opaque for engineering workflows with validation
CrewAI / AutoGen Anti-goal — extra framework without added control

LangGraph covers intent routing, tool calling, and error retry without a second agent framework.


Why Qdrant

Option Verdict
Qdrant Chosen — Rust performance, payload filters, self-hosted or cloud
Pinecone Managed only; no self-hosted for portfolio demo
Chroma Fine for prototypes; weaker production story
In-memory Implemented as offline fallback when CAEC_QDRANT_URL is empty

Embeddings

  • Model: intfloat/multilingual-e5-base (configurable via CAEC_EMBEDDING_MODEL)
  • Library: sentence-transformers
  • Prefixes: E5 query: / passage: convention in rag/embeddings.py

Supports Russian and English engineering documents without separate indexes.


LLM providers

See also Usage economics on the home page (production pricing and order-of-magnitude cost per request).

Configured via CAEC_LLM_PROVIDER and CAEC_LLM_API_KEY:

Provider Typical use
OpenRouter Local dev default (qwen/qwen3-coder:free)
Anthropic Claude for long-context RAG synthesis
OpenAI GPT-4o class models for tool calling

Without an API key the graph uses keyword intent and regex tool dispatch.

Model-agnostic / on-prem: set CAEC_LLM_BASE_URL to a compatible local endpoint (Qwen-class, YandexGPT-class, LM Studio) — no code changes required.

Key settings

Variable Purpose
CAEC_QDRANT_URL Qdrant endpoint; empty → in-memory retriever
CAEC_REQUIRE_CITATIONS Report must cite sources
CAEC_REFUSE_UNSAFE_CALCULATIONS Guardrail for stress without FoS context
CAEC_DEMO_ENABLED Kill switch — returns 503 on /ask when false
CAEC_RATE_LIMIT_PER_MINUTE POST /ask rate limit (default 30)

Full list: src/cae_copilot/config.py · deployment.


Stage 1 target (not yet in dependencies)

Component Role
Unstructured.io PDF/GOST parsing, table extraction into governed chunks

Stage 3 target (deferred)

Component Role
Docker Isolated solver containers
Celery + Redis or k8s Jobs Async job queue
Result parsers .dat, .rst, solver-specific output

Spec: solver-agent-skill.md.


Not in the MVP stack

These were considered or appear in early notes but are not dependencies:

Item Reason excluded
LlamaIndex Direct qdrant-client + langchain retrievers suffice
CrewAI / AutoGen Anti-goals — see requirements
Poetry PDM is source of truth
GitHub Actions GitLab CI only
Chainlit Replaced by Streamlit for portfolio UI

Local development

mamba activate cae-copilot
pdm install
make dev-stack      # Qdrant + API + Streamlit
make ingest         # load Rocky PDFs via manifest

Docker images install from pre-exported requirements-*.txt (not pdm install in CI). Regenerate after dependency changes:

make requirements