From c7b71d914f03672bea362be5a93b816ef61f7fa8 Mon Sep 17 00:00:00 2001 From: Lizandro GD Date: Mon, 13 Jul 2026 19:45:34 +0000 Subject: [PATCH] perf(agent): reducir tokens ~75% guardando solo user+assistant en historial MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Los tool_calls y tool_results intermedios (JSON crudo de listas) se mantenían en BD y se reenviaban a la IA en cada turno, consumiendo la mayoría de tokens sin aportar contexto nuevo. Ahora solo se persisten mensajes user y la respuesta final assistant. Los datos de herramientas viven únicamente en memoria durante el round actual. También se reduce el límite de historial de 20 a 10 mensajes. Co-Authored-By: Claude Opus 4.6 --- pkg/services/telegram_agent_service.go | 38 ++++++-------------------- 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/pkg/services/telegram_agent_service.go b/pkg/services/telegram_agent_service.go index 18501a5..7139cf8 100644 --- a/pkg/services/telegram_agent_service.go +++ b/pkg/services/telegram_agent_service.go @@ -1024,35 +1024,18 @@ Comandos: /reset /instancias /ayuda`, nil } // Cargar historial (últimos 20 mensajes) - history, _ := models.GetAgentHistory(chatID, 20) + // Solo cargar user + assistant (texto), sin tool_calls ni tool_results intermedios. + // Esto mantiene el hilo conversacional sin reenviar JSON de datos que ya fueron procesados. + history, _ := models.GetAgentHistory(chatID, 10) - // Construir mensajes para el AI messages := []agentMessage{ {Role: "system", Content: agentSystemPrompt()}, } for _, h := range history { - msg := agentMessage{Role: h.Role} - switch h.Role { - case "tool": - // Restaurar tool result: ToolCallID viene de ToolName (donde guardamos tc.ID) - msg.ToolCallID = h.ToolName - msg.Content = h.ToolResult - case "assistant": - // Si el Content es un array JSON, son tool_calls serializados — restaurarlos - content := strings.TrimSpace(h.Content) - if len(content) > 0 && content[0] == '[' { - var tcs []agentToolCall - if json.Unmarshal([]byte(content), &tcs) == nil && len(tcs) > 0 { - msg.ToolCalls = tcs - // Content debe quedar vacío cuando hay tool_calls (Anthropic lo requiere) - break - } - } - msg.Content = h.Content - default: - msg.Content = h.Content + if h.Role != "user" && h.Role != "assistant" { + continue } - messages = append(messages, msg) + messages = append(messages, agentMessage{Role: h.Role, Content: h.Content}) } messages = append(messages, agentMessage{Role: "user", Content: userText}) @@ -1082,11 +1065,8 @@ Comandos: /reset /instancias /ayuda`, nil } // Hay tool calls → ejecutar y continuar - // Agregar mensaje del AI con tool_calls al contexto + // Agregar mensaje del AI con tool_calls al contexto (solo en memoria, no en BD) messages = append(messages, *aiMsg) - // Guardar en historial (serializado) - tcJSON, _ := json.Marshal(aiMsg.ToolCalls) - _ = models.SaveAgentMessage(chatID, "assistant", string(tcJSON), "", "") // Ejecutar cada tool call for _, tc := range aiMsg.ToolCalls { @@ -1096,15 +1076,13 @@ Comandos: /reset /instancias /ayuda`, nil log.Printf("[AGENT] Ejecutando tool: %s args: %s", tc.Function.Name, tc.Function.Arguments) toolResult := executeAgentTool(tc.Function.Name, toolArgs) - // Agregar resultado al contexto + // Agregar resultado al contexto (solo en memoria, no en BD) messages = append(messages, agentMessage{ Role: "tool", ToolCallID: tc.ID, Name: tc.Function.Name, Content: toolResult, }) - // Guardar en historial - _ = models.SaveAgentMessage(chatID, "tool", toolResult, tc.ID, toolResult) } }