Files
ASPIC/journal_ia.php

67 lines
3.3 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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());
}
}