Skip to main content

Agent Contract

ML SERVICE ENGINEERING CONTRACT

Questo documento contiene regole obbligatorie per qualsiasi agente AI che sviluppi o modifichi questo repository.

Le parole MUST, MUST NOT, SHOULD e MAY hanno significato prescrittivo.

1. Obiettivo

Il repository deve produrre un servizio ML:

versionabile
riproducibile
containerizzato
osservabile
testabile
rilasciabile in COLLAUDO e PROD
rollback-safe

Stack operativo atteso:

GitLab Self-Managed
GitLab CI/CD
GitLab Container Registry
Docker / Docker Compose
VM Linux con GPU NVIDIA quando richiesta
FastAPI
model artifact versionato esternamente

Non introdurre Kubernetes, Triton, orchestratori, message broker o altra infrastruttura non già richiesta esplicitamente.


2. Prima di modificare il repository

L'agente MUST prima ispezionare:

README
pyproject.toml / requirements
Dockerfile
compose
.gitlab-ci.yml
src/
tests/
config esistente

L'agente MUST preservare le convenzioni già presenti quando compatibili con questo documento.

L'agente MUST NOT inventare:

IP
hostname
registry
VM
credential
path remoto
secret
porta esterna
infrastruttura

Se un valore infrastrutturale non è noto deve essere parametrizzato.


3. Separazione delle responsabilità

Il codice MUST separare chiaramente:

API
configuration
preprocessing
inference runtime
postprocessing
monitoring/logging

Struttura target:

src/
├── api/
├── core/
├── inference/
│   ├── engine.py
│   ├── preprocessing.py
│   └── postprocessing.py
└── main.py

Business logic e inference MUST NOT essere implementate direttamente negli endpoint FastAPI.


4. Modello

I model weights MUST NOT essere aggiunti al repository Git salvo esplicita richiesta.

Il comportamento di default è:

registry
   ↓
exact model version
   ↓
verified local artifact
   ↓
read-only mount
   ↓
inference service

MUST essere configurabili almeno:

MODEL_NAME
MODEL_VERSION
MODEL_PATH
MODEL_SHA256
MODEL_FORMAT
MODEL_PRECISION

MUST NOT essere utilizzati:

latest
main
current
best.pt

come identificatori di release.

Una versione immutabile MUST essere selezionata esplicitamente.


5. Recupero del modello

Il download del modello SHOULD avvenire nella fase di deployment, prima dell'avvio del container.

Il modello SHOULD essere memorizzato in cache sulla VM:

/models/<model-name>/<model-version>/

Il checksum MUST essere verificato.

Il container MUST ricevere il modello tramite mount read-only.

Se il download avviene durante startup:

cached artifact + valid hash

MAY essere utilizzato quando il registry non è disponibile.

Un artifact con hash non valido MUST NOT essere caricato.


6. Model manifest

Ogni modello MUST avere un manifest contenente almeno:

name:
version:
format:
precision:
sha256:

input:
output:

preprocessing_version:
postprocessing_version:

training:
  git_commit:
  dataset_version:

metrics:

runtime:

Una modifica incompatibile di input, output, preprocessing o postprocessing MUST essere trattata come breaking change del model contract.


7. Runtime

Default preferito per modelli compatibili:

ONNX Runtime

PyTorch MAY essere utilizzato quando necessario.

Su GPU NVIDIA SHOULD essere valutato FP16.

INT8 MUST NOT essere introdotto senza:

calibration dataset
quality comparison
performance benchmark
documented result

TensorRT MUST NOT essere introdotto esclusivamente perché teoricamente più veloce.

Deve esistere un benchmark sul target hardware che ne giustifichi la complessità.


8. Ottimizzazione

Ogni trasformazione:

PyTorch → ONNX
FP32 → FP16
FP16 → INT8
ONNX → TensorRT

MUST avere un equivalence/regression test.

L'agente MUST confrontare il modello ottimizzato con il baseline usando metriche coerenti con il task.

Esempi:

classification → accuracy/F1/logit delta
detection → mAP/recall/boxes
segmentation → IoU/Dice
regression → MAE/RMSE

Una riduzione significativa della qualità MUST NOT essere accettata silenziosamente.


9. GPU

Se GPU_REQUIRED=true:

CUDA/provider disponibile
GPU visibile
modello caricato sulla GPU

sono condizioni di readiness.

Il servizio MUST NOT effettuare fallback silenzioso su CPU.

Un eventuale fallback deve essere esplicitamente configurato e loggato.


10. Startup

La sequenza MUST essere:

load configuration
       ↓
validate model artifact
       ↓
initialize runtime
       ↓
load model
       ↓
warmup
       ↓
READY

L'applicazione MUST NOT segnalarsi ready prima del completamento.


11. Health endpoints

FastAPI MUST esporre:

GET /health/live
GET /health/ready
GET /info
GET /metrics

/health/live MUST verificare solamente la vitalità del processo.

/health/ready MUST verificare almeno:

model loaded
model hash valid
runtime initialized
required GPU available
warmup completed

Liveness MUST NOT eseguire inferenze costose.


12. Info endpoint

GET /info MUST permettere di identificare la release.

Output minimo:

{
  "app_version": "",
  "git_sha": "",
  "model_name": "",
  "model_version": "",
  "model_format": "",
  "precision": "",
  "runtime": ""
}

Secret e token MUST NOT comparire.


13. Logging

Logging MUST essere strutturato.

Preferire JSON su stdout/stderr.

Ogni request SHOULD avere un request_id.

Per inference SHOULD essere disponibili:

service
request_id
git_sha
model_name
model_version
preprocess_ms
inference_ms
postprocess_ms
total_ms
status
error_type

L'agente MUST NOT:

loggare secret
loggare token
loggare immagini complete per default
loggare grandi payload binari

Eccezioni MUST essere esplicitamente configurate.


14. Metrics

Il servizio MUST esporre metriche per:

HTTP requests
HTTP errors
HTTP latency
inference count
inference errors
preprocessing duration
inference duration
postprocessing duration
model loaded state

Quando appropriato SHOULD aggiungere:

FPS
queue depth
dropped frames
batch size
confidence distribution
detections
input quality

MUST NOT usare valori ad alta cardinalità come request_id nelle label delle metriche.

GPU/VRAM/temperature SHOULD essere raccolte a livello VM tramite tooling NVIDIA/monitoring dedicato.


15. Error handling

Errori MUST essere classificabili.

Distinguere almeno:

invalid input
preprocessing error
model/runtime error
GPU error
postprocessing error
dependency error
internal error

Le eccezioni MUST essere loggate con stack trace lato server.

La risposta API MUST NOT esporre stack trace o informazioni sensibili.


16. Docker

Il Dockerfile MUST produrre una image adatta esclusivamente all'esecuzione richiesta.

Dipendenze di training MUST NOT essere incluse nell'image inference se inutili.

Il container SHOULD:

eseguire come non-root
avere filesystem minimale
ricevere config da environment
ricevere model artifact read-only
scrivere log su stdout/stderr

MUST NOT contenere credential permanenti.


17. Docker Compose

I Compose destinati a server MUST utilizzare:

image:

e MUST NOT utilizzare:

build:

La build avviene in CI.

La configurazione del Compose MUST essere parametrizzata per ambiente.

La GPU MUST essere dichiarata esplicitamente quando richiesta.

Deve esistere un healthcheck coerente con il servizio.


18. Image versioning

Ogni image MUST essere identificabile tramite commit SHA e/o release version.

PROD SHOULD utilizzare l'image digest immutabile.

MUST NOT essere usato latest come riferimento di deployment.

La stessa image costruita dalla CI MUST passare:

COLLAUDO → PROD

MUST NOT essere ricostruita tra i due ambienti.


19. GitLab CI/CD

La pipeline MUST contenere logicamente:

quality
tests
model-validation
build
publish
collaudo
production

Prima della build devono essere eseguiti almeno:

lint
unit tests
model contract tests
representative inference test

Quando il modello viene esportato o ottimizzato:

equivalence test
performance benchmark

MUST essere eseguiti.

La Docker image MUST essere pubblicata sul GitLab Container Registry.


20. Deployment

Il deployment standard è:

CI build
   ↓
immutable image
   ↓
manual deploy COLLAUDO
   ↓
smoke/integration tests
   ↓
manual approval
   ↓
deploy PROD

Il deploy MUST utilizzare versioni esplicite di image e model.

Il deploy PROD MUST NOT recuperare automaticamente "l'ultimo modello disponibile".


21. Collaudo

Prima della produzione MUST essere verificati:

/health/live
/health/ready
/info
/metrics
GPU
model version
sample inference
logs
latency
VRAM
API contract

Un fallimento MUST impedire la promozione automatica.


22. Release manifest

La pipeline MUST produrre un manifest simile a:

service:
release:
git_sha:

image:
  digest:

model:
  name:
  version:
  sha256:
  format:
  precision:

runtime:

Questo manifest è la fonte di verità della release.


23. Rollback

Ogni modifica al deployment MUST preservare la possibilità di tornare a:

previous IMAGE_DIGEST
previous MODEL_VERSION

Rollback MUST NOT richiedere:

git checkout
rebuild
retraining
re-export

24. Test obbligatori

Quando l'agente modifica preprocessing, runtime, modello o postprocessing MUST aggiungere o aggiornare test.

Il test set minimo deve coprire:

valid input
invalid input
model load
sample inference
expected output schema
health readiness
runtime failure

Le modifiche agli endpoint MUST mantenere o aggiornare esplicitamente l'API contract.


25. Performance

L'agente MUST evitare affermazioni come:

"FP16 è più veloce"
"TensorRT migliora le performance"
"INT8 è migliore"

senza benchmark.

Per modifiche prestazionali riportare almeno:

hardware
model version
precision
input shape
latency
throughput
VRAM
quality metric

26. Sicurezza degli artifact

Artifact provenienti da fonti non trusted MUST NOT essere caricati.

Hash e provenienza MUST essere verificabili.

Formati che consentono deserializzazione Python arbitraria devono essere considerati trusted-code artifacts.


27. Definition of Done dell'agente

Prima di considerare concluso un task che modifica un servizio ML, l'agente MUST verificare:

tests pass
container builds
model contract respected
health endpoints valid
structured logging present
metrics present
configuration externalized
no secrets committed
no mutable release tags
README updated if behavior changed
CI updated when required
rollback preserved

Se non è possibile verificare un requisito, l'agente MUST dichiararlo esplicitamente nel risultato finale invece di assumerlo soddisfatto.


28. Principio finale

Non ottimizzare esclusivamente per fare funzionare il codice in locale.

Ogni modifica deve preservare:

Developability+Reproducibility+Deployability+Observability+Rollbackability\boxed{ Developability + Reproducibility + Deployability + Observability + Rollbackability }

Un modello che produce una buona inference ma non può essere versionato, monitorato, diagnosticato o ripristinato non è production-ready.