# @siop/ai — service IA (R5) FastAPI + uv (ADR-001), **jamais exposé** : seule l'API NestJS le contacte avec `X-Service-Token` (ADR-004 §4). Maquettes et décisions D1-D5 validées le 17/07/2026. ## Lancer (dev) ```bash cd apps/ai uv sync --extra embeddings # le vrai modèle ONNX (CPU, ~120 Mo au premier run) uv run uvicorn siop_ai.app:app --port 8000 # CI / tests : uv sync && uv run pytest (embeddeur déterministe, aucun téléchargement) ``` Variables (défauts dev dans `config.py`, gabarit dans `.env.example`) : `DATABASE_URL`, `MINIO_*`, `AI_SERVICE_TOKEN`, `AI_EMBEDDINGS=locale|deterministe`, et la génération opt-in (ADR-004 §3) : `AI_GENERATION=off|api`, **`AI_API_KEY`** (exigée en mode api — le boot refuse sinon, jamais loguée ni exposée), `AI_MODEL` (défaut `claude-opus-4-8`). Mode api : `uv sync --extra generation` (SDK officiel `anthropic`) ; tout échec du LLM retombe sur le mode extractif. ## Ce que porte R5.1 (socle) - **Ingestion anonymisée (D4)** : PDF de la bibliothèque (MinIO) page par page + bilans codés clôturés → anonymisation (e-mails, téléphones, noms connus de la base) → découpage → embeddings locaux → `RagChunk` (pgvector, schéma Prisma). - **Recherche sémantique** `/internal/search` : extraits sourcés (document + page ou bilan daté) avec score — la brique de « sourcé ou silencieux » (D2). - `/internal/reindex` idempotent ; l'exclusion de corpus (`Document.inCorpus`, D3) s'applique à l'ingestion ET à la lecture. La suite : R5.2 assistant (mode extractif puis génération opt-in) + suggestion de bilan ; R5.3 écrans ; durcissement : Dockerfile + compose Dokploy (`siop2-ai`).