# @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`).
