mirror of
https://github.com/siop-spelev/siop2.git
synced 2026-08-08 12:41:54 +00:00
Recette (mode extractif, aucune clé) — elle a invalidé le modèle R5.1 : - MiniLM-384 classait la page-réponse DERRIÈRE des passages sans rapport (0,24 vs 0,41 sur la question type du plan) → bascule mesurée vers paraphrase-multilingual-mpnet-base-v2 (768 d, local/CPU), ADR-004 amendé avec le banc comparatif (e5-large écarté : 2,2 Go, scores compressés). - Migration r5_embeddings_mpnet : pgvector 384 → 768, index vidé (re-dérivable par « Réindexer tout »). - Découpage affiné (~350 caractères) : la phrase-réponse ne se noie plus, l'extrait cité est lisible ; seuils par défaut recalés 0,45/0,40/0,55. - Rejouée après bascule : réponse sourcée p. 2 en tête, refus honnête chiffré, suggestions étagées — 16/16 Playwright, 78 API, 23 pytest. - Revue pixel publiée (6 écrans réels vs maquettes, 3 arbitrages). Durcissement : - apps/ai/Dockerfile : uv, modèle ONNX téléchargé AU BUILD (ADR-004 §1), non-root, healthcheck ; répétition locale conteneurisée validée (healthz, reindex via MinIO/pgvector, 401 sans jeton, refus de boot api-sans-clé, réponse sourcée depuis le conteneur). - Compose Dokploy : siop2-ai interne (jamais sur dokploy-network, AI_SERVICE_TOKEN requis, génération opt-in, seuils par env) ; siop2-api branché (AI_SERVICE_URL). - Runbook §5-6 : service IA en production, calibrage des seuils sur le corpus client, réindexation post-déploiement. Le tag release/r5 attend la validation de la revue pixel par le référent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
39 lines
1.8 KiB
Docker
39 lines
1.8 KiB
Docker
# SIOP V2 — image du service IA (siop2-ai, ADR-004).
|
|
# Contexte de build : apps/ai (le service est autonome, pas de dépendance au
|
|
# monorepo). Étage 1 : uv sync + téléchargement du modèle ONNX AU BUILD
|
|
# (ADR-004 §1 — jamais au démarrage) ; étage 2 : runtime minimal non-root.
|
|
# Ce service n'est JAMAIS exposé publiquement : seul siop2-api le contacte,
|
|
# porteur du secret AI_SERVICE_TOKEN (ADR-004 §4).
|
|
|
|
FROM ghcr.io/astral-sh/uv:python3.11-bookworm-slim AS builder
|
|
WORKDIR /app
|
|
ENV UV_LINK_MODE=copy \
|
|
FASTEMBED_CACHE_PATH=/opt/fastembed
|
|
|
|
# Manifestes d'abord (cache de couche), puis le code. L'installation du projet
|
|
# reste éditable (.pth → /app/src) : src est donc copié dans l'image finale.
|
|
COPY pyproject.toml uv.lock ./
|
|
RUN uv sync --frozen --no-install-project --no-dev \
|
|
--extra embeddings --extra generation
|
|
COPY src src
|
|
RUN uv sync --frozen --no-dev \
|
|
--extra embeddings --extra generation
|
|
|
|
# Le modèle d'embeddings est EMBARQUÉ dans l'image : pas de téléchargement au
|
|
# boot (démarrage prévisible, marche sans accès à Hugging Face en production).
|
|
RUN uv run python -c "from siop_ai.embeddings import EmbeddeurLocal; EmbeddeurLocal()"
|
|
|
|
FROM python:3.11-slim-bookworm
|
|
WORKDIR /app
|
|
ENV PATH=/app/.venv/bin:$PATH \
|
|
FASTEMBED_CACHE_PATH=/opt/fastembed
|
|
RUN useradd --system --create-home siop
|
|
COPY --from=builder --chown=siop:siop /app/.venv /app/.venv
|
|
COPY --from=builder --chown=siop:siop /app/src /app/src
|
|
COPY --from=builder --chown=siop:siop /opt/fastembed /opt/fastembed
|
|
USER siop
|
|
EXPOSE 8000
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=40s --retries=3 \
|
|
CMD python -c "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://localhost:8000/healthz', timeout=4).status==200 else 1)"
|
|
CMD ["uvicorn", "siop_ai.app:app", "--host", "0.0.0.0", "--port", "8000"]
|