Improve lead tracking and agent advice quality
- Use GACampaignID field + FIND(gad_campaignid) fallback in Leads Lake filter - Add ConvLeadsLakeMes to campaign data for tracking discrepancy comparison - Update ConvLeadsLakeMesFinal daily as snapshot of Airtable lead count - Agent: ignore capping when capping=0 in advice Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e80ed58000
commit
c728cfc149
3
agent.py
3
agent.py
@ -19,6 +19,9 @@ ESTADO DE LA CAMPAÑA:
|
|||||||
- Nunca recomiendes reactivar una campaña si status_google = ENABLED (ya está activa).
|
- Nunca recomiendes reactivar una campaña si status_google = ENABLED (ya está activa).
|
||||||
- Si status_google = PAUSED y la acción es AUMENTAR_PRESUPUESTO, menciona en el consejo que primero hay que reactivarla.
|
- Si status_google = PAUSED y la acción es AUMENTAR_PRESUPUESTO, menciona en el consejo que primero hay que reactivarla.
|
||||||
|
|
||||||
|
CAPPING:
|
||||||
|
- Si capping = 0, significa que no hay límite de leads configurado para este mes. No menciones el capping en el consejo ni en la justificación. Toma la decisión basándote únicamente en rentabilidad y ritmo.
|
||||||
|
|
||||||
REGLAS DE DECISIÓN:
|
REGLAS DE DECISIÓN:
|
||||||
1. urgencia=PAUSAR → accion=PAUSAR siempre. El capping está lleno, seguir gastando destruye margen.
|
1. urgencia=PAUSAR → accion=PAUSAR siempre. El capping está lleno, seguir gastando destruye margen.
|
||||||
2. urgencia=SPRINT → accion=AUMENTAR_PRESUPUESTO con parametro entre 1.3 y 1.5. Quedan pocos días y leads por entregar.
|
2. urgencia=SPRINT → accion=AUMENTAR_PRESUPUESTO con parametro entre 1.3 y 1.5. Quedan pocos días y leads por entregar.
|
||||||
|
|||||||
@ -306,6 +306,7 @@ class AirtableClient:
|
|||||||
"capping_mensual": int(f.get("CapTotalMes") or 0),
|
"capping_mensual": int(f.get("CapTotalMes") or 0),
|
||||||
"cpa_maximo": float(f.get("CPAMax") or 0),
|
"cpa_maximo": float(f.get("CPAMax") or 0),
|
||||||
"margen_objetivo": float(f.get("MargenObjetivo") or 0),
|
"margen_objetivo": float(f.get("MargenObjetivo") or 0),
|
||||||
|
"conv_leads_lake_mes": int(f.get("ConvLeadsLakeMes") or 0),
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -341,7 +342,10 @@ class AirtableClient:
|
|||||||
mes_inicio = f"{now.year}-{now.month:02d}-01"
|
mes_inicio = f"{now.year}-{now.month:02d}-01"
|
||||||
formula = (
|
formula = (
|
||||||
f"AND("
|
f"AND("
|
||||||
f"FIND('gad_campaignid={campaign_id}',{{attr_referer}}),"
|
f"OR("
|
||||||
|
f"{{GACampaignID}}='{campaign_id}',"
|
||||||
|
f"FIND('gad_campaignid={campaign_id}',{{attr_referer}})"
|
||||||
|
f"),"
|
||||||
f"{{attr_utm_medium}}='paid_search',"
|
f"{{attr_utm_medium}}='paid_search',"
|
||||||
f"{{creado}}>='{mes_inicio}'"
|
f"{{creado}}>='{mes_inicio}'"
|
||||||
f")"
|
f")"
|
||||||
@ -354,6 +358,19 @@ class AirtableClient:
|
|||||||
"""Actualiza el campo 'Leads Lake' de un registro GACampaignMes."""
|
"""Actualiza el campo 'Leads Lake' de un registro GACampaignMes."""
|
||||||
self.gacampaignmes.update(gcm_record_id, {"Leads Lake": lead_ids})
|
self.gacampaignmes.update(gcm_record_id, {"Leads Lake": lead_ids})
|
||||||
|
|
||||||
|
def batch_update_gacampaignmes_final_leads(self, gcm_records: list[dict]) -> None:
|
||||||
|
"""
|
||||||
|
Copia ConvLeadsLakeMes → ConvLeadsLakeMesFinal en GACampaignMes.
|
||||||
|
Se llama una vez por ejecución diaria.
|
||||||
|
gcm_records: lista de dicts con 'airtable_id' y 'conv_leads_lake_mes'
|
||||||
|
"""
|
||||||
|
batch = [
|
||||||
|
{"id": r["airtable_id"], "fields": {"ConvLeadsLakeMesFinal": r["conv_leads_lake_mes"]}}
|
||||||
|
for r in gcm_records
|
||||||
|
]
|
||||||
|
for i in range(0, len(batch), 10):
|
||||||
|
self.gacampaignmes.batch_update(batch[i:i+10])
|
||||||
|
|
||||||
def batch_update_gacampaignmes_advice(self, updates: list[tuple[str, str, str]]) -> None:
|
def batch_update_gacampaignmes_advice(self, updates: list[tuple[str, str, str]]) -> None:
|
||||||
"""
|
"""
|
||||||
Actualiza en lote los campos 'Consejo' y 'Criticidad' de GACampaignMes.
|
Actualiza en lote los campos 'Consejo' y 'Criticidad' de GACampaignMes.
|
||||||
|
|||||||
@ -35,8 +35,9 @@ def analyze(campaign_config: dict, leads_entregados: int, ads_metrics: dict) ->
|
|||||||
else:
|
else:
|
||||||
urgencia = "EN_RITMO"
|
urgencia = "EN_RITMO"
|
||||||
|
|
||||||
# Discrepancia entre leads Airtable y conversiones Google
|
# Discrepancia entre leads Airtable (ConvLeadsLakeMes) y conversiones Google
|
||||||
discrepancia = abs(conversiones_google - leads_entregados)
|
conv_leads_lake_mes = campaign_config.get("conv_leads_lake_mes", leads_entregados)
|
||||||
|
discrepancia = abs(conversiones_google - conv_leads_lake_mes)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"curso": campaign_config["curso"],
|
"curso": campaign_config["curso"],
|
||||||
|
|||||||
13
run.py
13
run.py
@ -211,7 +211,7 @@ def run():
|
|||||||
|
|
||||||
if analysis["alerta_tracking"]:
|
if analysis["alerta_tracking"]:
|
||||||
print(f" 🚨 ALERTA TRACKING: {analysis['discrepancia_tracking']} leads de diferencia "
|
print(f" 🚨 ALERTA TRACKING: {analysis['discrepancia_tracking']} leads de diferencia "
|
||||||
f"entre Airtable ({leads}) y Google Ads ({int(analysis['conversiones_google'])})")
|
f"entre Airtable ({campaign['conv_leads_lake_mes']}) y Google Ads ({int(analysis['conversiones_google'])})")
|
||||||
|
|
||||||
print(f" Decisión: {accion_icono} {decision['accion']} "
|
print(f" Decisión: {accion_icono} {decision['accion']} "
|
||||||
f"(confianza: {decision['confianza']*100:.0f}%)")
|
f"(confianza: {decision['confianza']*100:.0f}%)")
|
||||||
@ -251,6 +251,17 @@ def run():
|
|||||||
at.batch_update_gacampaignmes_advice(advice_updates)
|
at.batch_update_gacampaignmes_advice(advice_updates)
|
||||||
print(" ✓ Consejos y criticidad guardados.")
|
print(" ✓ Consejos y criticidad guardados.")
|
||||||
|
|
||||||
|
# Copiar ConvLeadsLakeMes → ConvLeadsLakeMesFinal (snapshot diario)
|
||||||
|
final_leads_data = [
|
||||||
|
{"airtable_id": item["campaign"]["airtable_id"],
|
||||||
|
"conv_leads_lake_mes": item["campaign"]["conv_leads_lake_mes"]}
|
||||||
|
for item in collected
|
||||||
|
]
|
||||||
|
if final_leads_data:
|
||||||
|
print(f"→ Actualizando ConvLeadsLakeMesFinal ({len(final_leads_data)} registros)...")
|
||||||
|
at.batch_update_gacampaignmes_final_leads(final_leads_data)
|
||||||
|
print(" ✓ ConvLeadsLakeMesFinal actualizado.")
|
||||||
|
|
||||||
# Resumen final ordenado por prioridad (ya está ordenado)
|
# Resumen final ordenado por prioridad (ya está ordenado)
|
||||||
print(f"{'='*55}")
|
print(f"{'='*55}")
|
||||||
print("RESUMEN FINAL")
|
print("RESUMEN FINAL")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user