mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-21 22:18:13 +02:00
Compteur de vitesse par bulle, et budget souple d'appels d'outils
Deux défauts révélés par un tour d'agent d'une heure (~50 appels d'outils) sur un modèle très quantifié. 1. La vitesse affichée sous les réponses tombait de 17 tok/s à 0,9 au fil du tour, ce qui donnait à croire que le moteur s'effondrait. Il n'en était rien : un tour d'agent ouvre une bulle NEUVE après chaque appel d'outil (le flux repasse contentEl à null), mais les compteurs n'étaient jamais remis à zéro. Chaque bulle affichait donc le CUMUL de tout le tour divisé par le temps écoulé depuis le tout premier token — exécution des outils, pages web et prefill compris. La vitesse convergeait mécaniquement vers « tokens générés ÷ durée totale du tour ». Les compteurs sont maintenant remis à zéro à la CRÉATION de la bulle, ce qui couvre tout chemin qui en ouvre une neuve, aujourd'hui comme demain. Rejoué sur un tour synthétique où le moteur décode à 20 tok/s constants entre deux outils de deux minutes : 20,5 / 0,6 / 0,5 tok/s avant, 20,5 sur les trois bulles après. La durée « travail », elle, reste bien celle du tour entier — c'est sa définition. 2. Rien n'exerçait de pression sur un tour qui tourne en rond. Le plafond d'itérations avait été retiré en v0.6.3 (il coupait des recherches légitimes) et la déduplication d'appels ne rattrape pas ce cas : sa clé est « nom + arguments bruts », or relire le même fichier par tranches (`sed -n '1,80p'` puis `sed -n '80,160p'`) produit des clés différentes. D'où un budget SOUPLE : au-delà de 24 appels d'outils sur un tour, on rappelle au modèle combien il en a déjà faits et on lui demande de conclure. Le rappel revient à chaque palier en durcissant le ton, et ne coupe jamais le tour. Il est ajouté EN FIN d'historique, ce qui laisse intact le préfixe déjà en cache côté llama-server, et n'est pas persisté. `AGENT_BUDGET` dans config.env règle le palier, `off` le désactive. Élargir plutôt la clé de déduplication à la CIBLE de l'appel a été écarté : deux tranches d'un même fichier renvoient un contenu différent, les confondre casserait toute lecture paginée légitime. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J5UndZ9DedRXPuAoRXbmDb
This commit is contained in:
6 files changed
+243
-12
No files matched your search
@@ -599,11 +599,20 @@ func runChat(ctx context.Context, messages []Message, temperature float64, caps
|
||||
// (ni réponse, ni tool_call). On relance alors UNE fois le tour avec un nudge
|
||||
// explicite au lieu d'afficher « pas de réponse ».
|
||||
nudged := false
|
||||
// Pas de plafond d'itérations ni d'anti-boucle : ils coupaient des tours
|
||||
// parfaitement légitimes (une recherche enchaîne facilement des dizaines
|
||||
// d'appels, parfois identiques). Le seul frein est le bouton stop, qui annule
|
||||
// le contexte — c'est un choix assumé.
|
||||
// Budget SOUPLE d'appels d'outils (llm_budget.go). Toujours pas de plafond
|
||||
// d'itérations : couper un tour cassait des recherches légitimes. Mais au-delà
|
||||
// d'un palier on RAPPELLE au modèle combien d'appels il a déjà faits et on lui
|
||||
// demande de conclure — de la pression, pas une barrière. Sans ça, un modèle
|
||||
// qui tourne en rond n'avait rien en face de lui sauf le bouton stop.
|
||||
toolRuns, budgetNudges, budget := 0, 0, agentBudget()
|
||||
for iter := 0; ; iter++ {
|
||||
// Rappel injecté EN FIN d'historique : le préfixe déjà en cache côté
|
||||
// llama-server reste valide, seul le nouveau message est à traiter.
|
||||
if msg := budgetNudge(toolRuns, budget, budgetNudges); msg != "" {
|
||||
budgetNudges++
|
||||
logBudget(toolRuns, budget, budgetNudges)
|
||||
messages = append(messages, Message{Role: "user", Content: msg})
|
||||
}
|
||||
payload := map[string]any{
|
||||
"model": "loki",
|
||||
"messages": messages,
|
||||
@@ -946,6 +955,7 @@ func runChat(ctx context.Context, messages []Message, temperature float64, caps
|
||||
if ctx.Err() != nil {
|
||||
return extra, nil
|
||||
}
|
||||
toolRuns++ // alimente le budget souple (voir budgetNudge)
|
||||
var args map[string]any
|
||||
_ = json.Unmarshal([]byte(tc.Function.Arguments), &args)
|
||||
// Derive the human label (command / skill name) up front so we can
|
||||
|
||||
Reference in new issue
Block a user