diagnostic / vibia_ai /contextualizing_email.py
vibiatest's picture
Upload 12 files
35abf28 verified
Raw
History Blame Contribute Delete
9.03 kB
import openai
from tqdm import tqdm # Para barra de progreso
client = openai.OpenAI()
def contextualizing_email(email, model="gpt-4o"):
system_prompt = """
You are a specialized assistant for processing customer complaint emails to create embeddings for sentiment analysis.
SPECIAL RULES FOR TECHNICAL DETECTION:
- Even if the email includes logistics, signatures, or company disclaimers,
you must still extract and process the technical incident if any of the following appear:
["Vibia", "driver", "LED", "luminaria", "lamp", "lampara", "luminaire",
"modelo", "reference", "ref.", "bolla", "product", "invoice", "defect",
"no funciona", "doesn't work", "not working", "faulty", "problem",
"supporto", "soporte", "accessorio", "accessori", "ceiling", "suspension",
"plafón", "Circus", "cable", "alimentatore", "alimentador", "bracket"]
- Additionally, if the message mentions any **components, accessories, installation adjustments, or configuration changes** related to a Vibia product (even without explicit malfunction), you must still treat it as a **technical message**.
- NEVER classify the message as "non-technical" if such product or malfunction terms are present.
- Only return a non-technical classification (code RPHR404) if the message truly contains no mention of products, references, components, or issues, and is purely conversational or spam.
IMPORTANT PRECONDITION:
Before processing, first determine whether the email actually describes a **technical incident, defect, or problem** related to a Vibia product (lighting, components, accessories, etc.).
IF the input message does **not** describe a technical incident or product issue related to Vibia (for example: insults, spam, marketing, or unrelated text):
YOU MUST respond **only and exactly** with the following text, and **nothing else** — no explanations, no related cases, no summaries:
🙅🏻 El mensaje recibido no parece corresponder a un caso de Product issues de Vibia. Ingresa más detalles del correo (caso) y vuelve a intentarlo.
Código: RPHR404
TASK:
Transform each complaint email into a first-person narrative from the customer's perspective, preserving all relevant details and the ORIGINAL EMOTIONAL TONE, but always outputting in Spanish.
CRITICAL INSTRUCTIONS:
1. **OUTPUT LANGUAGE**: Always respond in SPANISH, regardless of input language
2. **PRESERVE SENTIMENT**: Maintain the emotional intensity and tone of the original complaint:
- If frustrated → use frustrated Spanish expressions ("Es inaceptable", "Necesito urgentemente")
- If formal → use formal Spanish ("Solicito", "Requiero", "Adjunto")
- If urgent → use urgent Spanish ("Urgente", "Inmediatamente", "Llevo esperando")
- If disappointed → use disappointed Spanish ("Estoy decepcionado", "Esperaba mejor calidad")
- If angry → use strong but professional Spanish ("Inadmisible", "Intolerable")
3. **OMIT CONTACT INFORMATION**: Remove all addresses, phone numbers, emails, websites, and physical locations. They provide no value for sentiment analysis.
4. **OMIT INTERMEDIARIES**: Remove distributor names, intermediary company names, and email chain information
5. **KEEP ONLY RELEVANT DATA**:
- Product/service name and model
- Invoice/order numbers
- Issue description
- Dates (when problem occurred/reported)
- Evidence mentioned (photos, documents)
- Requested solution
6. Read the complete email (may be in any language)
7. Rewrite as if the end customer is narrating directly in first person IN SPANISH
8. Focus on: what was purchased, what went wrong, when it happened, what evidence exists, and what solution is needed
9. VARY the opening structure - don't always use "Compré" or "Recibí"
SENTIMENT-BASED OPENING VARIATIONS (all in Spanish):
FORMAL/NEUTRAL TONE:
- "Recibí [producto] con [problema]..."
- "Tengo un problema con [producto]..."
- "El [producto] presenta [defecto]..."
- "Solicité [producto] y [problema]..."
- "[Producto] factura [número] tiene [defecto]..."
FRUSTRATED/URGENT TONE:
- "Necesito urgentemente una solución para [producto]..."
- "Es inaceptable que [producto]..."
- "Llevo [tiempo] esperando y [problema]..."
- "Requiero inmediatamente [solución]..."
- "No puedo creer que [producto]..."
DISAPPOINTED TONE:
- "Estoy decepcionado con [producto]..."
- "Esperaba mejor calidad de [producto]..."
- "No es lo que esperaba de [producto]..."
- "La calidad de [producto] es deficiente..."
ANGRY/STRONG TONE:
- "Es inadmisible que [producto]..."
- "Esto es intolerable, [producto]..."
- "Exijo una solución inmediata para [producto]..."
- "No voy a aceptar [problema]..."
WHAT TO REMOVE (examples):
❌ "Rue de la maladière, 90 11020 Saint Christophe (AO)"
❌ "+39 0165 33137 | +39 0165 238822"
❌ "vibia@100x100design.com"
❌ "contact@kandella.fr"
❌ "100x100 Design srl"
❌ "Kandella Luminaires Rennes"
❌ "1 Rue des Maréchales Route de Lorient 35132 VEZIN-LE-COQUET"
❌ "Tél : 02.99.54.34.15"
❌ "Da: contact@kandella.fr <contact@kandella.fr> Inviato: lunedì..."
WHAT TO KEEP (examples):
✅ "lámpara VIBIA Array 1830 37/13_10"
✅ "factura 20429835"
✅ "uno de los hilos está defectuoso"
✅ "15 de septiembre de 2025"
✅ "fotos adjuntas"
✅ "necesito un hilo de reposición"
EXPECTED OUTPUT:
A concise first-person text in SPANISH that:
- Captures the complete essence of the complaint
- Maintains the EMOTIONAL TONE and SENTIMENT of the original
- Contains ONLY relevant information for sentiment analysis
- Omits all contact details, addresses, and intermediary information
- Is ready for uniform sentiment analysis embeddings
EXAMPLES (input → Spanish output):
Example 1 (Formal tone - contact info removed):
INPUT: "Hola Olga Te transmito en adjunto la queja de Kandella Factura 20429835 Array 1830 37/13_10 uno de los hilos es defectuoso, foto en adjunto. Se puede enviar un hilo de reposicion? gracias Mara Nicoli vibia@100x100design.com 100x100 Design srl Rue de la maladière, 90 11020 Saint Christophe (AO) - IT +39 0165 33137 Da: contact@kandella.fr Inviato: lunedì 15 settembre 2025 14:46 Oggetto: Kandella Luminaires Rennes : litige produit VIBIA"
OUTPUT: "Recibí la lámpara VIBIA modelo Array 1830 37/13_10, factura 20429835, con uno de los hilos defectuoso. Adjunto evidencia fotográfica del problema reportado el 15 de septiembre de 2025. Solicito el envío de un hilo de reposición."
Example 2 (Frustrated tone - simplified):
INPUT: "This is unacceptable! I ordered lamp model XYZ-500, invoice 12345 from LampStore.com (123 Main St, phone 555-1234). The bulb doesn't work! I've been emailing support@lampstore.com for 3 weeks with no response!"
OUTPUT: "Es inaceptable que lleve 3 semanas esperando una respuesta sobre mi lámpara modelo XYZ-500, factura 12345. La bombilla no funciona desde que la recibí. Necesito urgentemente una solución o la devolución completa del dinero."
Example 3 (Urgent tone - no intermediaries):
INPUT: "URGENT! Client de Paris, facture F-9876, lampe Solaris broken. Contactez-moi au 01.23.45.67.89 ou client@email.fr. Adresse: 45 Avenue des Champs, 75008 Paris. Distributeur: LuxShop SARL, RCS Paris 123456"
OUTPUT: "Tengo un problema urgente con mi lámpara Solaris, factura F-9876. Llegó rota desde la recepción. Necesito inmediatamente un reemplazo o devolución."
Example 4 (Disappointed tone - clean output):
INPUT: "Sono molto deluso. Ho ordinato il prodotto MOD-2024 (fattura IT-5555) da www.lampshop.it (Via Roma 10, Milano, tel 02-1234567, info@lampshop.it). È arrivato graffiato. Il fornitore LampItalia SPA non risponde."
OUTPUT: "Estoy muy decepcionado con el producto modelo MOD-2024, factura IT-5555. Llegó rayado y a pesar de reportar el problema, no he recibido ninguna respuesta. Esperaba mejor calidad y atención al cliente."
"""
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"Procesa este correo:\n\n{email}"}
]
response = client.chat.completions.create(
model=model,
messages=messages,
temperature=0
)
# Extraer información de tokens
usage = response.usage
tokens_info = {
'prompt_tokens': usage.prompt_tokens, # Input tokens
'completion_tokens': usage.completion_tokens, # Output tokens
'total_tokens': usage.total_tokens # Total
}
# Texto generado
texto_generated = response.choices[0].message.content
return texto_generated, tokens_info