feat: cache token stat.

This commit is contained in:
2026-05-02 10:13:33 +08:00
parent 6ef84b7488
commit f81ee19bed
4 changed files with 91 additions and 33 deletions
+30 -8
View File
@@ -245,6 +245,8 @@ type aiAnalysisResult struct {
Content string
InputTokens int
OutputTokens int
CacheHitTokens int
CacheMissTokens int
InputSizeBytes int
OutputSizeBytes int
}
@@ -289,10 +291,16 @@ func callAIForAnalysis(prompt string) (*aiAnalysisResult, error) {
}
content := resp.Choices[0].Message.Content
cacheHitTokens := 0
if resp.Usage.PromptTokensDetails != nil {
cacheHitTokens = resp.Usage.PromptTokensDetails.CachedTokens
}
return &aiAnalysisResult{
Content: content,
InputTokens: resp.Usage.PromptTokens,
OutputTokens: resp.Usage.CompletionTokens,
CacheHitTokens: cacheHitTokens,
CacheMissTokens: resp.Usage.PromptTokens - cacheHitTokens,
InputSizeBytes: len(prompt),
OutputSizeBytes: len(content),
}, nil
@@ -397,17 +405,29 @@ func (tc *TrainingController) AnalyzeByAI(c *gin.Context) {
var costJSON string
var totalCost float64
if err := config.DB.First(&pricing).Error; err == nil {
inputCost := float64(analysisResult.InputTokens) * pricing.InputPricePerMillion / 1_000_000
cacheMissPrice := pricing.CacheMissPricePerMillion
if cacheMissPrice == 0 {
cacheMissPrice = pricing.InputPricePerMillion
}
cacheHitPrice := pricing.CacheHitPricePerMillion
if cacheHitPrice == 0 {
cacheHitPrice = pricing.InputPricePerMillion
}
cacheHitCost := float64(analysisResult.CacheHitTokens) * cacheHitPrice / 1_000_000
cacheMissCost := float64(analysisResult.CacheMissTokens) * cacheMissPrice / 1_000_000
outputCost := float64(analysisResult.OutputTokens) * pricing.OutputPricePerMillion / 1_000_000
totalCost = inputCost + outputCost
totalCost = cacheHitCost + cacheMissCost + outputCost
costInfo := map[string]interface{}{
"pricingName": pricing.Name,
"provider": pricing.Provider,
"inputPricePerMillion": pricing.InputPricePerMillion,
"outputPricePerMillion": pricing.OutputPricePerMillion,
"inputCost": inputCost,
"outputCost": outputCost,
"pricingName": pricing.Name,
"provider": pricing.Provider,
"inputPricePerMillion": pricing.InputPricePerMillion,
"cacheHitPricePerMillion": cacheHitPrice,
"cacheMissPricePerMillion": cacheMissPrice,
"outputPricePerMillion": pricing.OutputPricePerMillion,
"cacheHitCost": cacheHitCost,
"cacheMissCost": cacheMissCost,
"outputCost": outputCost,
}
if b, err := json.Marshal(costInfo); err == nil {
costJSON = string(b)
@@ -423,6 +443,8 @@ func (tc *TrainingController) AnalyzeByAI(c *gin.Context) {
TotalCost: totalCost,
InputTokens: analysisResult.InputTokens,
OutputTokens: analysisResult.OutputTokens,
CacheHitTokens: analysisResult.CacheHitTokens,
CacheMissTokens: analysisResult.CacheMissTokens,
InputSizeBytes: analysisResult.InputSizeBytes,
OutputSizeBytes: analysisResult.OutputSizeBytes,
DurationMs: durationMs,