46 lines
1.2 KiB
Go
46 lines
1.2 KiB
Go
package tokens
|
|
|
|
import "sync"
|
|
|
|
// Calibrator passt die Schätzung anhand echter usage-Werte aus der API-
|
|
// Antwort an (E-09). Ein laufender Korrekturfaktor pro Prozess; Persistenz
|
|
// über Sessions hinweg ist für v1 nicht vorgesehen — jeder Lauf kalibriert
|
|
// neu, was bei einem einzelnen Modell pro Session ausreicht.
|
|
type Calibrator struct {
|
|
mu sync.Mutex
|
|
factor float64
|
|
n int
|
|
}
|
|
|
|
func NewCalibrator() *Calibrator {
|
|
return &Calibrator{factor: 1.0}
|
|
}
|
|
|
|
// Observe nimmt einen (geschätzt, tatsächlich)-Datenpunkt auf und aktualisiert
|
|
// den Korrekturfaktor per exponentiell gleitendem Mittel.
|
|
func (c *Calibrator) Observe(estimated, actual int) {
|
|
if estimated <= 0 || actual <= 0 {
|
|
return
|
|
}
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
|
|
ratio := float64(actual) / float64(estimated)
|
|
const alpha = 0.2
|
|
if c.n == 0 {
|
|
c.factor = ratio
|
|
} else {
|
|
c.factor = c.factor*(1-alpha) + ratio*alpha
|
|
}
|
|
c.n++
|
|
}
|
|
|
|
// Adjust wendet den aktuellen Korrekturfaktor plus einen 15%-Sicherheits-
|
|
// abstand auf eine rohe Schätzung an (E-09: konservativ schätzen ist
|
|
// billiger als ein echter Tokenizer).
|
|
func (c *Calibrator) Adjust(estimate int) int {
|
|
c.mu.Lock()
|
|
factor := c.factor
|
|
c.mu.Unlock()
|
|
return int(float64(estimate) * factor * 1.15)
|
|
}
|