Architecture principles¶
Deliberate design choices behind CAE Copilot. Each principle has direct consequences on how the system is built and operated.
1. State-only communication¶
Statement: All graph nodes read and write a shared CAEState. Nodes never
call each other directly.
Why: In CAE workflows, wrong answers have real cost. A single state object makes every step inspectable — you can replay what the router saw before the report node ran.
Where: src/cae_copilot/state.py, every file in nodes/.
2. Citations required¶
Statement: RAG-derived answers must reference source chunks. Free-floating
claims are rejected when CAEC_REQUIRE_CITATIONS=true.
Why: Engineering knowledge must be auditable. A copilot that invents a safety factor is worse than no copilot.
Where: nodes/rag.py, nodes/report.py, eval faithfulness checks.
3. Pure tools, not LLM math¶
Statement: Engineering calculations are deterministic Python functions with Pydantic-validated inputs. The LLM decides what should be computed; deterministic tools perform the calculation. The LLM does not perform arithmetic.
Why: Tools are the high-trust surface. Unit tests on estimate_particle_count
are stronger evidence than prompt engineering alone.
Where: src/cae_copilot/tools/, tools/registry.py. Full routing rules:
Data-First.
4. Data-First split (RAG vs Tools)¶
Statement: Narrative requirements go to RAG with citations. Tabular numeric facts and catalog lookups should go to structured Tools or APIs (Stage 1 target). Derived results go to deterministic calculation tools.
Why: RAG hallucinates on engineering tables. Separating data types before the agent answers is the core defense against wrong numbers in reports.
Where: data-first.md — target vs implemented routing.
Today the graph routes by intent (knowledge → RAG, calculation → tools);
structured material lookup is planned, not shipped.
5. Graceful degradation¶
Statement: The graph runs without an LLM API key and without Qdrant.
Why: CI, local dev, and portfolio reviewers should not need secrets or GPU. Keyword intent, in-memory RAG, and regex tool dispatch provide a baseline path.
Where: nodes/intent.py, rag/retriever.py (in-memory fallback),
nodes/tools.py (regex dispatch).
6. UI / API separation¶
Statement: Streamlit talks to FastAPI over HTTP only. The UI must not import the graph, retriever, or tools.
Why: Mirrors production layout (separate deployables, independent scaling) and matches the SoccerPredictAI pattern.
Where: ui/api_client.py, docker/Dockerfile.streamlit (slim deps).
7. Vector search + metadata filters¶
Statement: RAG uses vector search plus Qdrant payload filters (doc_type,
manifest metadata) and parent-context expansion for child chunks. BM25 + vector
fusion is planned but not implemented.
Why: Pure semantic search misses domain constraints. A question about Fluent coupling should not return unrelated module sections.
Where: rag/chunking.py (parent/child), rag/retriever.py (Qdrant payload
filters + parent_text expansion).
8. Model-agnostic LLM layer¶
Statement: The LLM provider is configured via CAEC_LLM_PROVIDER,
CAEC_LLM_MODEL, and CAEC_LLM_BASE_URL — not hardcoded to one vendor.
Why: Enterprise deployments need on-prem or regional models (Qwen-class, YandexGPT-class) to avoid vendor lock-in and control data residency. Commodity AI means the orchestration layer is the product, not the model brand.
Where: src/cae_copilot/llm.py, config.py.
9. Execution isolation for external tools (planned)¶
Statement: Long-running external engineering tools (including solver backends) run in isolated containers, not in the LangGraph process.
Why: A tool crash must not take down the API. Docker provides reproducible execution environments.
Status: Stage 3 — deferred. See roadmap, solver-agent-skill.md.
10. Async for long-running jobs (planned)¶
Statement: Long-running external tool jobs use a fire-and-forget pattern with polling or webhooks. LangGraph does not block for minutes or hours.
Why: FEA runs are asynchronous by nature. The agent acknowledges the job, returns a task ID, and delivers results when complete.
Status: Stage 3 — deferred. See roadmap, solver-agent-skill.md.
Related pages¶
- Data-First — RAG vs Tools routing
- Requirements — scope and anti-goals
- Data flow — RAG sequence (implemented)
- Runtime view — tool-calling loop (implemented)
- Stack — technology choices