mirror of
https://github.com/JMP-MS/ASPIC.git
synced 2026-10-27 18:17:09 +00:00
67 lines
3.3 KiB
PHP
67 lines
3.3 KiB
PHP
<?php
|
||
/**
|
||
* ASPIC — journal_ia.php
|
||
*
|
||
* Journalisation du coût réel des appels à l'API Anthropic (11 septembre
|
||
* 2026) — demande explicite de Jean-Marc après avoir constaté plus de 20€
|
||
* de consommation sans pouvoir se l'expliquer : ni collaborateur_dialogue.php
|
||
* ni mission_agent.php ne traçaient jusqu'ici le champ `usage` pourtant
|
||
* renvoyé par l'API à chaque appel. Même préoccupation que celle qui avait
|
||
* mené à `_realisation`/`_avertissement` dans moteur_consignes.php (7
|
||
* septembre 2026) : ne jamais laisser un appel IA sans trace.
|
||
*
|
||
* Tarifs (USD par million de tokens, vérifiés le 8 septembre 2026 — voir
|
||
* Réflexions stratégiques section 18 — susceptibles d'évoluer, à recontrôler
|
||
* si un écart est constaté). Cache : ratios documentés par Anthropic au
|
||
* moment de l'écriture de ce fichier (écriture ×1,25, lecture ×0,1 du tarif
|
||
* d'entrée de base) — comme le reste de ce mécanisme, jamais essayé en
|
||
* conditions réelles avant ce soir (voir en-tête de mission_agent.php pour
|
||
* le même type de réserve). Coût exprimé en dollars US (devise de
|
||
* facturation réelle d'Anthropic), jamais converti en euros ici — une
|
||
* conversion afficherait une fausse précision sans connaître le taux de
|
||
* change réel appliqué par Anthropic au moment du prélèvement.
|
||
*/
|
||
|
||
const TARIFS_IA = [
|
||
'claude-haiku-4-5' => ['entree' => 1.0, 'sortie' => 5.0],
|
||
'claude-sonnet-5' => ['entree' => 2.0, 'sortie' => 10.0],
|
||
'claude-opus-5' => ['entree' => 5.0, 'sortie' => 25.0],
|
||
'claude-fable-5-1' => ['entree' => 10.0, 'sortie' => 50.0],
|
||
];
|
||
|
||
/**
|
||
* Enregistre un appel réel à l'API Anthropic. $usage est le champ "usage"
|
||
* tel que renvoyé par l'API (input_tokens, output_tokens,
|
||
* cache_creation_input_tokens, cache_read_input_tokens — ces deux derniers
|
||
* absents/à 0 si le cache n'a pas été sollicité ce tour-ci). Jamais
|
||
* bloquant : une erreur ici ne doit jamais faire échouer le dialogue
|
||
* lui-même, seulement être signalée dans les journaux serveur.
|
||
*/
|
||
function journaliserAppelIA(PDO $pdo, string $origine, ?int $agentIncr, ?int $missionIncr, string $modele, array $usage): void
|
||
{
|
||
$entreeFrais = (int) ($usage['input_tokens'] ?? 0);
|
||
$entreeCache = (int) ($usage['cache_read_input_tokens'] ?? 0);
|
||
$ecritureCache = (int) ($usage['cache_creation_input_tokens'] ?? 0);
|
||
$sortie = (int) ($usage['output_tokens'] ?? 0);
|
||
|
||
$tarif = TARIFS_IA[$modele] ?? TARIFS_IA['claude-sonnet-5'];
|
||
$cout = (
|
||
$entreeFrais / 1_000_000 * $tarif['entree'] +
|
||
$ecritureCache / 1_000_000 * $tarif['entree'] * 1.25 +
|
||
$entreeCache / 1_000_000 * $tarif['entree'] * 0.1 +
|
||
$sortie / 1_000_000 * $tarif['sortie']
|
||
);
|
||
|
||
try {
|
||
$pdo->prepare(
|
||
'INSERT INTO ASP_AppelsIA
|
||
(AIA_Origine, AIA_AgentIncr, AIA_MissionIncr, AIA_Modele,
|
||
AIA_TokensEntreeFrais, AIA_TokensEntreeCache, AIA_TokensEcritureCache, AIA_TokensSortie,
|
||
AIA_CoutEstimeUsd)
|
||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)'
|
||
)->execute([$origine, $agentIncr, $missionIncr, $modele, $entreeFrais, $entreeCache, $ecritureCache, $sortie, $cout]);
|
||
} catch (PDOException $e) {
|
||
error_log('ASPIC journal_ia : échec de journalisation — ' . $e->getMessage());
|
||
}
|
||
}
|