diff --git a/MyIA.AI.Notebooks/GenAI/Texte/09d_Production_Caches.ipynb b/MyIA.AI.Notebooks/GenAI/Texte/09d_Production_Caches.ipynb
index 5065f60fca..9f736df202 100644
--- a/MyIA.AI.Notebooks/GenAI/Texte/09d_Production_Caches.ipynb
+++ b/MyIA.AI.Notebooks/GenAI/Texte/09d_Production_Caches.ipynb
@@ -5,10 +5,10 @@
"id": "2af54d71",
"metadata": {
"papermill": {
- "duration": 0.004305,
- "end_time": "2026-09-28T16:33:45.397438+00:00",
+ "duration": 0.005891,
+ "end_time": "2026-10-01T20:41:46.787856+00:00",
"exception": false,
- "start_time": "2026-09-28T16:33:45.393133+00:00",
+ "start_time": "2026-10-01T20:41:46.781965+00:00",
"status": "completed"
},
"tags": []
@@ -27,8 +27,8 @@
" presque identiques dont la réponse est différente, servies depuis le cache comme si de rien\n",
" n'était ;\n",
"2. **Le cache de préfixe fournisseur** — OpenAI facture moins cher les tokens de prompt déjà\n",
- " vus (`cached_tokens` dans la réponse). On mesure ce que ça rend vraiment, et le point\n",
- " d'équilibre du préfixe long.\n",
+ " vus (`cached_tokens` dans la réponse). On mesure ce que ça rend vraiment, et à quelles\n",
+ " conditions l'allonger se justifie.\n",
"\n",
"> **Terrain réel, lecture seule** : embeddings OpenAI (`text-embedding-3-small`, clé dans `.env`,\n",
"> jamais affichée), catalogue de prix du proxy multi-fournisseurs (`/v1/models`), inférence locale\n",
@@ -40,10 +40,10 @@
"id": "3120652c",
"metadata": {
"papermill": {
- "duration": 0.005203,
- "end_time": "2026-09-28T16:33:45.407081+00:00",
+ "duration": 0.005784,
+ "end_time": "2026-10-01T20:41:46.801577+00:00",
"exception": false,
- "start_time": "2026-09-28T16:33:45.401878+00:00",
+ "start_time": "2026-10-01T20:41:46.795793+00:00",
"status": "completed"
},
"tags": []
@@ -58,16 +58,16 @@
"id": "a93fb585",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:33:45.416232Z",
- "iopub.status.busy": "2026-09-28T16:33:45.415821Z",
- "iopub.status.idle": "2026-09-28T16:33:45.440942Z",
- "shell.execute_reply": "2026-09-28T16:33:45.439609Z"
+ "iopub.execute_input": "2026-10-01T20:41:46.814920Z",
+ "iopub.status.busy": "2026-10-01T20:41:46.814240Z",
+ "iopub.status.idle": "2026-10-01T20:41:46.842225Z",
+ "shell.execute_reply": "2026-10-01T20:41:46.840841Z"
},
"papermill": {
- "duration": 0.030602,
- "end_time": "2026-09-28T16:33:45.441950+00:00",
+ "duration": 0.036307,
+ "end_time": "2026-10-01T20:41:46.843486+00:00",
"exception": false,
- "start_time": "2026-09-28T16:33:45.411348+00:00",
+ "start_time": "2026-10-01T20:41:46.807179+00:00",
"status": "completed"
},
"tags": []
@@ -103,16 +103,16 @@
"id": "a5e557f7",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:33:45.452649Z",
- "iopub.status.busy": "2026-09-28T16:33:45.451907Z",
- "iopub.status.idle": "2026-09-28T16:33:48.393897Z",
- "shell.execute_reply": "2026-09-28T16:33:48.392318Z"
+ "iopub.execute_input": "2026-10-01T20:41:46.857088Z",
+ "iopub.status.busy": "2026-10-01T20:41:46.856634Z",
+ "iopub.status.idle": "2026-10-01T20:41:50.133830Z",
+ "shell.execute_reply": "2026-10-01T20:41:50.132390Z"
},
"papermill": {
- "duration": 2.949887,
- "end_time": "2026-09-28T16:33:48.395622+00:00",
+ "duration": 3.285901,
+ "end_time": "2026-10-01T20:41:50.135279+00:00",
"exception": false,
- "start_time": "2026-09-28T16:33:45.445735+00:00",
+ "start_time": "2026-10-01T20:41:46.849378+00:00",
"status": "completed"
},
"tags": []
@@ -123,7 +123,13 @@
"output_type": "stream",
"text": [
"Inference locale (Ollama) HTTP 200 2 modèles\n",
- "Proxy multi-fournisseurs HTTP 200 458 modèles\n",
+ "Proxy multi-fournisseurs HTTP 200 464 modèles\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
"Prix catalogue openai/gpt-5-mini : $0.25/M entrée, $2.00/M sortie\n"
]
}
@@ -169,10 +175,10 @@
"id": "6a187710",
"metadata": {
"papermill": {
- "duration": 0.003864,
- "end_time": "2026-09-28T16:33:48.405078+00:00",
+ "duration": 0.006592,
+ "end_time": "2026-10-01T20:41:50.147867+00:00",
"exception": false,
- "start_time": "2026-09-28T16:33:48.401214+00:00",
+ "start_time": "2026-10-01T20:41:50.141275+00:00",
"status": "completed"
},
"tags": []
@@ -197,16 +203,16 @@
"id": "ce8c7da3",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:33:48.420548Z",
- "iopub.status.busy": "2026-09-28T16:33:48.419805Z",
- "iopub.status.idle": "2026-09-28T16:33:48.433784Z",
- "shell.execute_reply": "2026-09-28T16:33:48.432524Z"
+ "iopub.execute_input": "2026-10-01T20:41:50.162782Z",
+ "iopub.status.busy": "2026-10-01T20:41:50.162072Z",
+ "iopub.status.idle": "2026-10-01T20:41:50.175738Z",
+ "shell.execute_reply": "2026-10-01T20:41:50.174193Z"
},
"papermill": {
- "duration": 0.023731,
- "end_time": "2026-09-28T16:33:48.435175+00:00",
+ "duration": 0.023389,
+ "end_time": "2026-10-01T20:41:50.177179+00:00",
"exception": false,
- "start_time": "2026-09-28T16:33:48.411444+00:00",
+ "start_time": "2026-10-01T20:41:50.153790+00:00",
"status": "completed"
},
"tags": []
@@ -264,10 +270,10 @@
"id": "8c017cd0",
"metadata": {
"papermill": {
- "duration": 0.007141,
- "end_time": "2026-09-28T16:33:48.447939+00:00",
+ "duration": 0.005705,
+ "end_time": "2026-10-01T20:41:50.189109+00:00",
"exception": false,
- "start_time": "2026-09-28T16:33:48.440798+00:00",
+ "start_time": "2026-10-01T20:41:50.183404+00:00",
"status": "completed"
},
"tags": []
@@ -288,16 +294,16 @@
"id": "c78de773",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:33:48.469431Z",
- "iopub.status.busy": "2026-09-28T16:33:48.468872Z",
- "iopub.status.idle": "2026-09-28T16:34:54.212129Z",
- "shell.execute_reply": "2026-09-28T16:34:54.210891Z"
+ "iopub.execute_input": "2026-10-01T20:41:50.204834Z",
+ "iopub.status.busy": "2026-10-01T20:41:50.204448Z",
+ "iopub.status.idle": "2026-10-01T20:43:04.407408Z",
+ "shell.execute_reply": "2026-10-01T20:43:04.405871Z"
},
"papermill": {
- "duration": 65.757496,
- "end_time": "2026-09-28T16:34:54.217651+00:00",
+ "duration": 74.21729,
+ "end_time": "2026-10-01T20:43:04.412582+00:00",
"exception": false,
- "start_time": "2026-09-28T16:33:48.460155+00:00",
+ "start_time": "2026-10-01T20:41:50.195292+00:00",
"status": "completed"
},
"tags": []
@@ -307,9 +313,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "Cache rempli : 90 réponses réelles du modèle local en 66 s\n",
+ "Cache rempli : 90 réponses réelles du modèle local en 74 s\n",
"qualité du fond de cache : 78/90 justes (87 %)\n",
- "latence de référence d'un appel non caché (médiane) : 574 ms\n"
+ "latence de référence d'un appel non caché (médiane) : 806 ms\n"
]
}
],
@@ -355,10 +361,10 @@
"id": "8a394d76",
"metadata": {
"papermill": {
- "duration": 0.004518,
- "end_time": "2026-09-28T16:34:54.228081+00:00",
+ "duration": 0.005866,
+ "end_time": "2026-10-01T20:43:04.424948+00:00",
"exception": false,
- "start_time": "2026-09-28T16:34:54.223563+00:00",
+ "start_time": "2026-10-01T20:43:04.419082+00:00",
"status": "completed"
},
"tags": []
@@ -380,16 +386,16 @@
"id": "ff89eb3a",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:34:54.240043Z",
- "iopub.status.busy": "2026-09-28T16:34:54.239523Z",
- "iopub.status.idle": "2026-09-28T16:35:00.402373Z",
- "shell.execute_reply": "2026-09-28T16:35:00.400941Z"
+ "iopub.execute_input": "2026-10-01T20:43:04.439331Z",
+ "iopub.status.busy": "2026-10-01T20:43:04.438733Z",
+ "iopub.status.idle": "2026-10-01T20:43:12.789200Z",
+ "shell.execute_reply": "2026-10-01T20:43:12.787426Z"
},
"papermill": {
- "duration": 6.169964,
- "end_time": "2026-09-28T16:35:00.403624+00:00",
+ "duration": 8.359348,
+ "end_time": "2026-10-01T20:43:12.790407+00:00",
"exception": false,
- "start_time": "2026-09-28T16:34:54.233660+00:00",
+ "start_time": "2026-10-01T20:43:04.431059+00:00",
"status": "completed"
},
"tags": []
@@ -457,10 +463,10 @@
"id": "db39fe10",
"metadata": {
"papermill": {
- "duration": 0.004558,
- "end_time": "2026-09-28T16:35:00.414091+00:00",
+ "duration": 0.005892,
+ "end_time": "2026-10-01T20:43:12.802582+00:00",
"exception": false,
- "start_time": "2026-09-28T16:35:00.409533+00:00",
+ "start_time": "2026-10-01T20:43:12.796690+00:00",
"status": "completed"
},
"tags": []
@@ -480,16 +486,16 @@
"id": "3dcbad44",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:35:00.427594Z",
- "iopub.status.busy": "2026-09-28T16:35:00.427038Z",
- "iopub.status.idle": "2026-09-28T16:35:00.436608Z",
- "shell.execute_reply": "2026-09-28T16:35:00.435393Z"
+ "iopub.execute_input": "2026-10-01T20:43:12.817514Z",
+ "iopub.status.busy": "2026-10-01T20:43:12.816985Z",
+ "iopub.status.idle": "2026-10-01T20:43:12.828333Z",
+ "shell.execute_reply": "2026-10-01T20:43:12.826733Z"
},
"papermill": {
- "duration": 0.018454,
- "end_time": "2026-09-28T16:35:00.437783+00:00",
+ "duration": 0.020778,
+ "end_time": "2026-10-01T20:43:12.829663+00:00",
"exception": false,
- "start_time": "2026-09-28T16:35:00.419329+00:00",
+ "start_time": "2026-10-01T20:43:12.808885+00:00",
"status": "completed"
},
"tags": []
@@ -499,7 +505,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "rejeu de la banque par cache exact : 90/90 hits, 0.1 ms au total\n",
+ "rejeu de la banque par cache exact : 90/90 hits, 0.2 ms au total\n",
"reformulations (n=20) : 0 hit(s) — le cache exact est aveugle à la formulation\n"
]
}
@@ -529,10 +535,10 @@
"id": "64d7a5ac",
"metadata": {
"papermill": {
- "duration": 0.005373,
- "end_time": "2026-09-28T16:35:00.449293+00:00",
+ "duration": 0.006899,
+ "end_time": "2026-10-01T20:43:12.843194+00:00",
"exception": false,
- "start_time": "2026-09-28T16:35:00.443920+00:00",
+ "start_time": "2026-10-01T20:43:12.836295+00:00",
"status": "completed"
},
"tags": []
@@ -557,16 +563,16 @@
"id": "70adea70",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:35:00.462228Z",
- "iopub.status.busy": "2026-09-28T16:35:00.461706Z",
- "iopub.status.idle": "2026-09-28T16:36:00.624765Z",
- "shell.execute_reply": "2026-09-28T16:36:00.623515Z"
+ "iopub.execute_input": "2026-10-01T20:43:12.859954Z",
+ "iopub.status.busy": "2026-10-01T20:43:12.859426Z",
+ "iopub.status.idle": "2026-10-01T20:44:19.389976Z",
+ "shell.execute_reply": "2026-10-01T20:44:19.388685Z"
},
"papermill": {
- "duration": 60.17635,
- "end_time": "2026-09-28T16:36:00.631288+00:00",
+ "duration": 66.544916,
+ "end_time": "2026-10-01T20:44:19.394353+00:00",
"exception": false,
- "start_time": "2026-09-28T16:35:00.454938+00:00",
+ "start_time": "2026-10-01T20:43:12.849437+00:00",
"status": "completed"
},
"tags": []
@@ -605,7 +611,7 @@
"
faux succès (pièges) | \n",
" faux succès % | \n",
" exactitude % | \n",
- " latence évitée (s, à 574 ms/appel) | \n",
+ " latence évitée (s, à 806 ms/appel) | \n",
" \n",
" \n",
" | seuil γ | \n",
@@ -625,7 +631,7 @@
" 30 | \n",
" 100.0 | \n",
" 63.6 | \n",
- " 63.1 | \n",
+ " 88.7 | \n",
"
\n",
" \n",
" | 0.950 | \n",
@@ -634,7 +640,7 @@
" 30 | \n",
" 100.0 | \n",
" 63.6 | \n",
- " 63.1 | \n",
+ " 88.7 | \n",
"
\n",
" \n",
" | 0.980 | \n",
@@ -643,7 +649,7 @@
" 21 | \n",
" 70.0 | \n",
" 71.8 | \n",
- " 56.2 | \n",
+ " 79.0 | \n",
"
\n",
" \n",
" | 0.990 | \n",
@@ -652,7 +658,7 @@
" 12 | \n",
" 40.0 | \n",
" 75.5 | \n",
- " 41.3 | \n",
+ " 58.0 | \n",
"
\n",
" \n",
" | 0.995 | \n",
@@ -661,7 +667,7 @@
" 1 | \n",
" 3.3 | \n",
" 81.8 | \n",
- " 35.0 | \n",
+ " 49.2 | \n",
"
\n",
" \n",
" | 0.999 | \n",
@@ -670,7 +676,7 @@
" 0 | \n",
" 0.0 | \n",
" 82.7 | \n",
- " 34.4 | \n",
+ " 48.4 | \n",
"
\n",
" \n",
"\n",
@@ -686,14 +692,14 @@
"0.995 61 55.5 1 3.3 \n",
"0.999 60 54.5 0 0.0 \n",
"\n",
- " exactitude % latence évitée (s, à 574 ms/appel) \n",
+ " exactitude % latence évitée (s, à 806 ms/appel) \n",
"seuil γ \n",
- "0.900 63.6 63.1 \n",
- "0.950 63.6 63.1 \n",
- "0.980 71.8 56.2 \n",
- "0.990 75.5 41.3 \n",
- "0.995 81.8 35.0 \n",
- "0.999 82.7 34.4 "
+ "0.900 63.6 88.7 \n",
+ "0.950 63.6 88.7 \n",
+ "0.980 71.8 79.0 \n",
+ "0.990 75.5 58.0 \n",
+ "0.995 81.8 49.2 \n",
+ "0.999 82.7 48.4 "
]
},
"execution_count": 7,
@@ -757,10 +763,10 @@
"id": "64cdd0f0",
"metadata": {
"papermill": {
- "duration": 0.005524,
- "end_time": "2026-09-28T16:36:00.643566+00:00",
+ "duration": 0.006057,
+ "end_time": "2026-10-01T20:44:19.406303+00:00",
"exception": false,
- "start_time": "2026-09-28T16:36:00.638042+00:00",
+ "start_time": "2026-10-01T20:44:19.400246+00:00",
"status": "completed"
},
"tags": []
@@ -788,10 +794,10 @@
"id": "3fd446a6",
"metadata": {
"papermill": {
- "duration": 0.005022,
- "end_time": "2026-09-28T16:36:00.654810+00:00",
+ "duration": 0.006248,
+ "end_time": "2026-10-01T20:44:19.418897+00:00",
"exception": false,
- "start_time": "2026-09-28T16:36:00.649788+00:00",
+ "start_time": "2026-10-01T20:44:19.412649+00:00",
"status": "completed"
},
"tags": []
@@ -813,16 +819,16 @@
"id": "1aa99002",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:36:00.672259Z",
- "iopub.status.busy": "2026-09-28T16:36:00.671696Z",
- "iopub.status.idle": "2026-09-28T16:36:43.095699Z",
- "shell.execute_reply": "2026-09-28T16:36:43.094275Z"
+ "iopub.execute_input": "2026-10-01T20:44:19.432838Z",
+ "iopub.status.busy": "2026-10-01T20:44:19.432383Z",
+ "iopub.status.idle": "2026-10-01T20:44:54.368141Z",
+ "shell.execute_reply": "2026-10-01T20:44:54.366810Z"
},
"papermill": {
- "duration": 42.438583,
- "end_time": "2026-09-28T16:36:43.101971+00:00",
+ "duration": 34.949764,
+ "end_time": "2026-10-01T20:44:54.374596+00:00",
"exception": false,
- "start_time": "2026-09-28T16:36:00.663388+00:00",
+ "start_time": "2026-10-01T20:44:19.424832+00:00",
"status": "completed"
},
"tags": []
@@ -864,8 +870,8 @@
" \n",
" | 1 | \n",
" 1304 | \n",
- " 1152 | \n",
- " 88.3 | \n",
+ " 0 | \n",
+ " 0.0 | \n",
"
\n",
" \n",
" | 2 | \n",
@@ -928,7 +934,7 @@
"text/plain": [
" tokens prompt dont cachés part cachée %\n",
"appel \n",
- "1 1304 1152 88.3\n",
+ "1 1304 0 0.0\n",
"2 1305 1152 88.3\n",
"3 1304 1152 88.3\n",
"4 1304 1152 88.3\n",
@@ -1045,10 +1051,10 @@
"id": "9305d528",
"metadata": {
"papermill": {
- "duration": 0.010125,
- "end_time": "2026-09-28T16:36:43.118967+00:00",
+ "duration": 0.007398,
+ "end_time": "2026-10-01T20:44:54.388498+00:00",
"exception": false,
- "start_time": "2026-09-28T16:36:43.108842+00:00",
+ "start_time": "2026-10-01T20:44:54.381100+00:00",
"status": "completed"
},
"tags": []
@@ -1056,14 +1062,19 @@
"source": [
"### Lecture du cache de préfixe\n",
"\n",
- "Sur cette exécution, le 1ᵉʳ appel affiche déjà 88 % de tokens cachés : ce préfixe avait\n",
- "déjà été envoyé quelques minutes plus tôt (runs de préparation) — le cache du fournisseur\n",
- "survit d'une exécution à l'autre, c'est précisément son intérêt en production. Sur un\n",
- "préfixe réellement froid, le 1ᵉʳ appel paie le plein tarif. L'économie réelle se calcule avec les **prix du catalogue** lus en section 0 : le\n",
- "token caché est facturé à fraction du prix d'entrée (politique fournisseur, `R_CACHED`\n",
- "ci-dessous) — on mesure la part servie, le reste est arithmétique. Le **point d'équilibre**\n",
- "répond à la question qui précède tout investissement dans un préfixe long : combien d'appels\n",
- "partageant ce préfixe faut-il pour que le préfixe se rentabilise ?\n"
+ "Cette exécution est partie d'un cache **froid** : le 1ᵉʳ appel affiche 0 token caché — il paie\n",
+ "le préfixe au plein tarif — et dès le 2ᵉ appel, 88 % des tokens du prompt sont servis depuis\n",
+ "le cache. Ce contraste entre la première ligne du tableau et les suivantes EST la mécanique du\n",
+ "cache fournisseur : un premier paiement plein tarif, puis la même part servie au tarif réduit à\n",
+ "chaque appel suivant (le cache survit d'une exécution à l'autre ; une série démarrée quelques\n",
+ "minutes après une autre peut afficher son 1ᵉʳ appel déjà chaud — c'est précisément son intérêt\n",
+ "en production). L'économie réelle se calcule avec les **prix du catalogue** lus en section 0 : le token\n",
+ "caché est facturé à une fraction du prix d'entrée — 0,1× sur la route mesurée ici, un ratio\n",
+ "qui dépend du fournisseur et du modèle (`R_CACHED` ci-dessous), à vérifier avant d'estimer\n",
+ "une facture. Et la bonne question n'est pas un « point d'équilibre » universel : si le\n",
+ "préfixe est **commun** aux appels — un contexte qu'on enverrait de toute façon —, chaque hit\n",
+ "est une économie immédiate, il n'y a rien à amortir ; si on **ajoute** un préfixe long pour\n",
+ "atteindre le cache, il faut le comparer à la requête courte qu'on vient d'allonger.\n"
]
},
{
@@ -1072,16 +1083,16 @@
"id": "f3e21358",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:36:43.138004Z",
- "iopub.status.busy": "2026-09-28T16:36:43.137338Z",
- "iopub.status.idle": "2026-09-28T16:36:43.146848Z",
- "shell.execute_reply": "2026-09-28T16:36:43.145342Z"
+ "iopub.execute_input": "2026-10-01T20:44:54.403298Z",
+ "iopub.status.busy": "2026-10-01T20:44:54.402934Z",
+ "iopub.status.idle": "2026-10-01T20:44:54.413533Z",
+ "shell.execute_reply": "2026-10-01T20:44:54.412142Z"
},
"papermill": {
- "duration": 0.021729,
- "end_time": "2026-09-28T16:36:43.148049+00:00",
+ "duration": 0.019386,
+ "end_time": "2026-10-01T20:44:54.414823+00:00",
"exception": false,
- "start_time": "2026-09-28T16:36:43.126320+00:00",
+ "start_time": "2026-10-01T20:44:54.395437+00:00",
"status": "completed"
},
"tags": []
@@ -1091,31 +1102,44 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "préfixe : ~1304 tokens, part cachée mesurée sur le dernier appel : 88 %\n",
- "coût plein du préfixe par appel : $0.000326\n",
- "économie par appel une fois chaud : $0.000144 (tarif caché = 50% du plein)\n",
- "point d'équilibre : ~2 appels par préfixe pour rentrer dans les frais (au-delà, tout est gain)\n"
+ "route : openai/gpt-5-mini via proxy, catalogue mesuré $0.25/M entrée, $2.00/M sortie, entrée cachée $0.025/M (10% de l'entrée)\n",
+ "préfixe : ~1304 tokens dont 88 % cachés ; scénario préfixe commun : chaque hit économise $0.0002592 -- gain dès le premier hit, sans seuil\n",
+ "scénario préfixe ajouté : requête courte = $0.0000250, prompt long déjà chaud = $0.0000668\n",
+ "le hit fonctionne (entrée servie au tarif réduit) mais la stratégie reste $0.0000418 plus chère : un préfixe ajouté ne se justifie que s'il remplace du travail, jamais pour le cache seul\n"
]
}
],
"source": [
- "# Point d'équilibre : le préfixe coûte PRIX_IN plein tarif tant qu'il n'est pas caché ;\n",
- "# une fois chaud, une part f de ses tokens est facturée au tarif réduit R_CACHED (0,5 = politique\n",
- "# fournisseur standard : le token caché vaut la moitié du prix d'entrée).\n",
- "R_CACHED = 0.5\n",
+ "# Tarif cache de la route mesurée : gpt-5-mini facture l'entrée CACHÉE à 0,1 fois le prix\n",
+ "# d'entrée (politique publiée par le fournisseur, relevée le 2026-10-01). Ce ratio n'est pas\n",
+ "# universel : il dépend de la route et du modèle -- nommer les deux avant d'estimer une facture.\n",
+ "R_CACHED = 0.1\n",
+ "prix_cache = R_CACHED * PRIX_IN\n",
"tokens_prompt = mesures_pref[-1][\"prompt\"]\n",
- "part_cachee = mesures_pref[-1][\"cached\"] / tokens_prompt if tokens_prompt else 0.0\n",
- "cout_prefixe_usd = tokens_prompt * PRIX_IN / 1e6\n",
- "economie_par_appel = tokens_prompt * (1 - R_CACHED) * part_cachee * PRIX_IN / 1e6\n",
- "\n",
- "print(f\"préfixe : ~{tokens_prompt} tokens, part cachée mesurée sur le dernier appel : {100 * part_cachee:.0f} %\")\n",
- "print(f\"coût plein du préfixe par appel : ${cout_prefixe_usd:.6f}\")\n",
- "print(f\"économie par appel une fois chaud : ${economie_par_appel:.6f} (tarif caché = {R_CACHED:.0%} du plein)\")\n",
- "if economie_par_appel > 0:\n",
- " n_equilibre = cout_prefixe_usd / economie_par_appel\n",
- " print(f\"point d'équilibre : ~{n_equilibre:.0f} appels par préfixe pour rentrer dans les frais (au-delà, tout est gain)\")\n",
- "else:\n",
- " print(\"aucune économie mesurée sur ce terrain : le point d'équilibre n'existe pas\")\n"
+ "tokens_cache = mesures_pref[-1][\"cached\"]\n",
+ "part_cachee = tokens_cache / tokens_prompt if tokens_prompt else 0.0\n",
+ "\n",
+ "def cout_appel(entree_non_cachee, entree_cachee, sortie):\n",
+ " \"\"\"Coût exact d'un appel, poste par poste : entrée non cachée, entrée cachée, sortie.\"\"\"\n",
+ " return (entree_non_cachee * PRIX_IN + entree_cachee * prix_cache + sortie * PRIX_OUT) / 1e6\n",
+ "\n",
+ "print(f\"route : {MODELE_CHAT} via proxy, catalogue mesuré ${PRIX_IN:.2f}/M entrée, \"\n",
+ " f\"${PRIX_OUT:.2f}/M sortie, entrée cachée ${prix_cache:.3f}/M ({R_CACHED:.0%} de l'entrée)\")\n",
+ "\n",
+ "# Scénario 1 -- préfixe COMMUN : les appels paieraient ce contexte au plein tarif même sans\n",
+ "# cache ; chaque hit économise la différence plein/réduit sur la part servie. Rien à amortir.\n",
+ "economie_par_hit = tokens_cache * (PRIX_IN - prix_cache) / 1e6\n",
+ "print(f\"préfixe : ~{tokens_prompt} tokens dont {100 * part_cachee:.0f} % cachés ; scénario préfixe \"\n",
+ " f\"commun : chaque hit économise ${economie_par_hit:.7f} -- gain dès le premier hit, sans seuil\")\n",
+ "\n",
+ "# Scénario 2 -- préfixe AJOUTÉ : on allonge la requête pour atteindre le cache. Témoin,\n",
+ "# entrée seule : requête courte de 100 tokens contre le même prompt long déjà chaud.\n",
+ "court = cout_appel(100, 0, 0)\n",
+ "long_chaud = cout_appel(tokens_prompt - tokens_cache, tokens_cache, 0)\n",
+ "print(f\"scénario préfixe ajouté : requête courte = ${court:.7f}, prompt long déjà chaud = ${long_chaud:.7f}\")\n",
+ "print(f\"le hit fonctionne (entrée servie au tarif réduit) mais la stratégie reste \"\n",
+ " f\"${long_chaud - court:.7f} plus chère : un préfixe ajouté ne se justifie que s'il \"\n",
+ " \"remplace du travail, jamais pour le cache seul\")\n"
]
},
{
@@ -1123,10 +1147,10 @@
"id": "e4c5921c",
"metadata": {
"papermill": {
- "duration": 0.007938,
- "end_time": "2026-09-28T16:36:43.162494+00:00",
+ "duration": 0.006644,
+ "end_time": "2026-10-01T20:44:54.428882+00:00",
"exception": false,
- "start_time": "2026-09-28T16:36:43.154556+00:00",
+ "start_time": "2026-10-01T20:44:54.422238+00:00",
"status": "completed"
},
"tags": []
@@ -1138,7 +1162,7 @@
"|---|---|---|---|\n",
"| exact | 100 % des répétitions à l'identique | aucun | plancher gratuit, toujours actif |\n",
"| sémantique | les reformulations (hit mesuré au seuil γ) | **faux succès** : pièges jumeaux servis | selon la distribution mesurée en section 3 |\n",
- "| préfixe | la part `cached_tokens` du prompt | préfixe payé plein tarif à froid | équilibre mesuré en section 6 |\n",
+ "| préfixe | la part `cached_tokens` du prompt | préfixe payé plein tarif à froid | économie par hit mesurée en section 6 |\n",
"\n",
"La leçon transversale : **un cache est un pari sur la distribution des questions**. Le cache\n",
"exact parie qu'elles se répètent à l'identique ; le sémantique qu'elles se répètent *en\n",
@@ -1157,10 +1181,10 @@
"id": "3db41b3e",
"metadata": {
"papermill": {
- "duration": 0.010578,
- "end_time": "2026-09-28T16:36:43.180225+00:00",
+ "duration": 0.00632,
+ "end_time": "2026-10-01T20:44:54.442055+00:00",
"exception": false,
- "start_time": "2026-09-28T16:36:43.169647+00:00",
+ "start_time": "2026-10-01T20:44:54.435735+00:00",
"status": "completed"
},
"tags": []
@@ -1193,16 +1217,16 @@
"id": "838780a1",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:36:43.208372Z",
- "iopub.status.busy": "2026-09-28T16:36:43.207753Z",
- "iopub.status.idle": "2026-09-28T16:36:43.218213Z",
- "shell.execute_reply": "2026-09-28T16:36:43.216239Z"
+ "iopub.execute_input": "2026-10-01T20:44:54.457610Z",
+ "iopub.status.busy": "2026-10-01T20:44:54.457063Z",
+ "iopub.status.idle": "2026-10-01T20:44:54.463614Z",
+ "shell.execute_reply": "2026-10-01T20:44:54.462317Z"
},
"papermill": {
- "duration": 0.031134,
- "end_time": "2026-09-28T16:36:43.219563+00:00",
+ "duration": 0.016542,
+ "end_time": "2026-10-01T20:44:54.464787+00:00",
"exception": false,
- "start_time": "2026-09-28T16:36:43.188429+00:00",
+ "start_time": "2026-10-01T20:44:54.448245+00:00",
"status": "completed"
},
"tags": []
@@ -1233,16 +1257,16 @@
"id": "894db209",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:36:43.234877Z",
- "iopub.status.busy": "2026-09-28T16:36:43.234295Z",
- "iopub.status.idle": "2026-09-28T16:36:43.241179Z",
- "shell.execute_reply": "2026-09-28T16:36:43.239892Z"
+ "iopub.execute_input": "2026-10-01T20:44:54.480352Z",
+ "iopub.status.busy": "2026-10-01T20:44:54.479779Z",
+ "iopub.status.idle": "2026-10-01T20:44:54.486324Z",
+ "shell.execute_reply": "2026-10-01T20:44:54.484869Z"
},
"papermill": {
- "duration": 0.016488,
- "end_time": "2026-09-28T16:36:43.242453+00:00",
+ "duration": 0.01598,
+ "end_time": "2026-10-01T20:44:54.487547+00:00",
"exception": false,
- "start_time": "2026-09-28T16:36:43.225965+00:00",
+ "start_time": "2026-10-01T20:44:54.471567+00:00",
"status": "completed"
},
"tags": []
@@ -1273,16 +1297,16 @@
"id": "29ff3335",
"metadata": {
"execution": {
- "iopub.execute_input": "2026-09-28T16:36:43.259478Z",
- "iopub.status.busy": "2026-09-28T16:36:43.258894Z",
- "iopub.status.idle": "2026-09-28T16:36:43.265668Z",
- "shell.execute_reply": "2026-09-28T16:36:43.264238Z"
+ "iopub.execute_input": "2026-10-01T20:44:54.503183Z",
+ "iopub.status.busy": "2026-10-01T20:44:54.502625Z",
+ "iopub.status.idle": "2026-10-01T20:44:54.509197Z",
+ "shell.execute_reply": "2026-10-01T20:44:54.507756Z"
},
"papermill": {
- "duration": 0.017244,
- "end_time": "2026-09-28T16:36:43.267062+00:00",
+ "duration": 0.01639,
+ "end_time": "2026-10-01T20:44:54.510335+00:00",
"exception": false,
- "start_time": "2026-09-28T16:36:43.249818+00:00",
+ "start_time": "2026-10-01T20:44:54.493945+00:00",
"status": "completed"
},
"tags": []
@@ -1312,10 +1336,10 @@
"id": "2641d0c2",
"metadata": {
"papermill": {
- "duration": 0.007192,
- "end_time": "2026-09-28T16:36:43.281704+00:00",
+ "duration": 0.007176,
+ "end_time": "2026-10-01T20:44:54.524404+00:00",
"exception": false,
- "start_time": "2026-09-28T16:36:43.274512+00:00",
+ "start_time": "2026-10-01T20:44:54.517228+00:00",
"status": "completed"
},
"tags": []
@@ -1371,14 +1395,14 @@
},
"papermill": {
"default_parameters": {},
- "duration": 182.013867,
- "end_time": "2026-09-28T16:36:44.713024+00:00",
+ "duration": 191.282333,
+ "end_time": "2026-10-01T20:44:55.315265+00:00",
"environment_variables": {},
"exception": null,
- "input_path": "09d_Production_Caches.ipynb",
- "output_path": "09d_exec.ipynb",
+ "input_path": "MyIA.AI.Notebooks/GenAI/Texte/09d_Production_Caches.ipynb",
+ "output_path": "MyIA.AI.Notebooks/GenAI/Texte/09d_Production_Caches.ipynb",
"parameters": {},
- "start_time": "2026-09-28T16:33:42.699157+00:00",
+ "start_time": "2026-10-01T20:41:44.032932+00:00",
"version": "2.7.0"
}
},