Metadati specializzati: ACF fields per context specifico
Processing ottimizzato: Estrazione automatica del contenuto rilevante
🛠️ Backend: Sistema AI con Tool-based Retrieval
Architettura del Sistema Tool-based
Il mio sistema implementa un tool-based retrieval completo:
@tool
def search_all_content(query: str, limit_per_type: int = 3) -> str:
"""
Ricerca generale nei contenuti di Veronica (articoli, progetti, certificazioni, etc.).
"""try:
config = Configuration()
wp_client = OptimizedWordPressClient(config.wordpress_base_url)
results = {"search_query": query, "results": {}}
# 🔍 RETRIEVAL: Multi-source search
posts = wp_client.get_posts({"search": query, "per_page": limit_per_type})
projects = wp_client.get_projects({"search": query, "per_page": limit_per_type})
certifications = wp_client.get_certifications({"search": query, "per_page": limit_per_type})
# 📝 PROCESSING: Content extraction and cleaningif posts:
results["results"]["articles"] = [
ContentProcessor.process_post(p) for p in posts]
if projects:
results["results"]["projects"] = [
ContentProcessor.process_project(p) for p in projects]
# 🤖 PROCESSING: Structured data for LLM contextreturn json.dumps(results)Code language:PHP(php)
9 Tools Specializzati per Content Retrieval
Invece di un tool generico, ho creato tools specializzati per ogni tipo di contenuto:
TOOLS = [
search_blog_posts, # 📝 Articoli del blog
get_latest_blog_post, # 🆕 Ultimo articolo pubblicato
get_portfolio_projects, # 💼 Progetti del portfolio
get_certifications, # 🎓 Certificazioni e formazione
get_work_experience, # 👔 Esperienze lavorative
get_books_and_reading, # 📚 Libri letti e recensiti
get_tools_and_stack, # 🔧 Stack tecnologico
search_all_content, # 🔍 Ricerca globale
get_contact_info # 📞 Informazioni contatto
]Code language:PHP(php)
Ogni tool:
È ottimizzato per il suo content type specifico
Processa i dati in modo context-aware
Restituisce JSON strutturato per l'LLM
Content Processing Intelligente
class ContentProcessor:
@staticmethod
def process_project(project: Dict) -> Dict:
"""Processa un progetto del portfolio"""
title = project.get("title", {}).get("rendered", "")
content = project.get("content", {}).get("rendered", "")
# Estrai campi ACF specifici per progetti
acf = project.get("acf", {})
return {
"title": title,
"description": ContentProcessor.clean_html(content)[:400] + "...",
"repository": acf.get("project_repository", ""),
"external_url": acf.get("project_external_url", ""),
"frontend_url": acf.get("project_frontend", ""),
"preview_text": acf.get("project_preview_text", ""),
"type": "project"
}
Features del processing:
🧹 HTML cleaning: Rimozione tag e entità HTML
✂️ Content truncation: Limite lunghezza per token efficiency
🏷️ Metadata extraction: ACF fields strutturati
🎯 Type classification: Ogni content ha il suo tipo
🧠 System Prompt Engineering: L'Arte dell'Identità AI
La Sfida dell'Impersonificazione Professionale
Una delle parti più complesse è stata creare un system prompt che faccia sentire l'AI come "Veronica digitale". Il prompt finale è lungo 200+ righe e rappresenta il vero "cervello" del sistema:
def create_system_prompt() -> str:
"""Crea il system prompt professionale"""
personal_summary = load_personal_summary()
return f"""Tu sei Veronica Schembri, AI Engineer e Data Scientist.
PERSONALITÀ E BACKGROUND:
Rappresenti Veronica sul suo sito web per potenziali clienti e datori di lavoro.
Il tuo background include:
- Percorso dall'illustrazione → programmazione → AI
- Specializzazione in Data Science, LLM e agenti AI
- Esperienza in web development e design visivo
- Metodo di lavoro strutturato (sistemi organizzativi, Building a Second Brain)
- Passioni: serie TV, fumetti, Magic: The Gathering, Lego
INFORMAZIONI DI CONTATTO:
📧 Email principale: veronicaschembri@gmail.com
🌐 Sito web: https://www.veronicaschembri.com
💼 LinkedIn: https://www.linkedin.com/in/veronicaschembri/
🐙 GitHub: https://github.com/Pandagan-85/
"""Code language:PHP(php)
Tool Orchestration via Prompt
Il prompt mappa esplicitamente ogni tipo di query ai tools appropriati:
STRUMENTI DISPONIBILI:
1. search_blog_posts(query, limit): cerca negli articoli del blog per argomenti specifici
2. get_latest_blog_post(): ottieni l'ultimo articolo pubblicato con contenuto completo
3. get_portfolio_projects(category, limit): ottieni progetti del portfolio
4. get_certifications(limit): ottieni tutte le certificazioni e formazione
PRIORITÀ NELLE RISPOSTE:
1. USA SEMPRE i tool per domande su:
✅ "Quali certificazioni hai?" → get_certifications()
✅ "Di cosa parla l'ultimo articolo?" → get_latest_blog_post()
✅ "Progetti con tecnologia X" → get_portfolio_projects()
✅ "Articoli su argomento Y" → search_blog_posts("Y")
ESEMPI DI QUERY DA GESTIRE CON I TOOL:
- "Quali certificazioni hai conseguito?" → get_certifications()
- "Hai formazione su AI?" → get_certifications()
- "Di cosa parla il tuo ultimo articolo?" → get_latest_blog_post()
- "Progetti di machine learning?" → search_all_content("machine learning")
- "Come posso contattarti?" → get_contact_info()Code language:PHP(php)
Boundary Setting Professionale
Parte critica: definire cosa l'AI può e non può fare per mantenere il focus professionale:
REGOLE FONDAMENTALI:
🚫 RISPONDI SOLO SU ARGOMENTI RIGUARDANTI VERONICA SCHEMBRI:
- Il suo background professionale e percorso
- I suoi progetti, articoli e competenze
- Le sue esperienze e tecnologie utilizzate
🚫 NON RISPONDERE A DOMANDE GENERICHE come:
- "Come creare un sito WordPress?"
- "Tutorial su tecnologie generiche"
- "Spiegazioni teoriche non legate alla tua esperienza"
✅ INVECE, PER DOMANDE GENERICHE, REINDIRIZZA COSÌ:
"Interessante! Nel mio blog e nei miei progetti affronto spesso argomenti tecnici come questo.
Ti suggerisco di esplorare i miei contenuti per vedere la mia prospettiva specifica,
oppure contattami se vuoi discutere di una collaborazione su progetti simili!"
COMPORTAMENTO:
- Sii professionale ma coinvolgente
- Rimani sempre focalizzata su Veronica e il suo lavoro
- Integra i risultati dei tool in modo naturale nella conversazione
- Mostra curiosità per le esigenze del visitatore in relazione al lavoro di Veronica
- Incoraggia collaborazioni e contatti professionali
- NON INVENTARE MAI informazioni - se non sai, usa i tool appropriatiCode language:PHP(php)
Integrazione con il Summary Personale
Il prompt carica dinamicamente il mio profilo personale dal file me/summary.txt:
def load_personal_summary() -> str:
"""Carica il summary personale dalla cartella me/"""try:
summary_path = "me/summary.txt"if os.path.exists(summary_path):
with open(summary_path, "r", encoding="utf-8") as f:
return f.read()Code language:JavaScript(javascript)
Questo permette di aggiornare la personalità dell'AI semplicemente modificando un file di testo, senza toccare il codice.
Risultato: Conversazioni Autentiche
Il prompt engineerging ha prodotto conversazioni che sembrano davvero parlare con me:
✅ Prima persona: "Ho lavorato su...", "Nel mio progetto..."
✅ Dettagli specifici: Cita progetti, tecnologie, esperienze reali
✅ Boundaries professionali: Non diventa un ChatGPT generico
✅ Call-to-action naturali: Incoraggia contatti per collaborazioni
✅ Coerenza: Ogni risposta è allineata con il mio brand professionale
🚀 Deploy e Observability
Railway Deploy
Per il deploy ho scelto Railway per la sua semplicità.
Environment variables:
OPENAI_API_KEY=sk-...
WORDPRESS_URL=https://www.veronicaschembri.com
LANGSMITH_API_KEY=lsv2_... # Per monitoring
LANGSMITH_PROJECT=veronica-wordpress-chatbotCode language:PHP(php)
LangSmith Monitoring
Integrazione completa con LangSmith per osservabilità:
@traceable(name="wordpress_chatbot_request")
def process_chat_with_tracing(message: str, thread_id: str) -> tuple[str, Optional[str]]:
"""Processa la chat con tracing LangSmith"""if chatbot is None:
raise Exception("Chatbot non inizializzato")
# LangSmith traccia automaticamente:# - Ogni tool call# - Token usage# - Latency# - Error rate
response = chatbot.chat(message, thread_id)
return response, trace_urlCode language:PHP(php)
🎨 Frontend: React Widget con Sicurezza
React Component Architecture
Il frontend è un React component completamente autocontenuto:
⚙️ Configurazione API: URL backend, theme, posizione 📊 Statistiche usage: Conversazioni, messaggi, sessioni attive 🧪 Test connessione: Verifica API endpoint in tempo reale 🔧 Debug mode: Console debugging per sviluppo 💾 Gestione persistenza: Controlli durata sessione e timeout
Cross-Page Persistence
La conversazione rimane aperta mentre l'utente naviga tra pagine del sito, creando un'esperienza seamless.
💭 Riflessioni Finali
Questo progetto rappresenta il mio primo vero sistema full-stack, dove ho dovuto integrare tecnologie diverse e competenze multiple:
🚀 DevOps: Railway deployment, CI/CD, production management
Il salto qualitativo rispetto agli esperimenti del corso è evidente: da prototype educativo a sistema in produzione utilizzato quotidianamente da visitatori reali.
Nextcloud self-hosted è la mia soluzione per sostituire Google Calendar, Contacts e Drive con un'alternativa open-source che controllo completamente. Deploy su Oracle Cloud Infrastructure usando il free tier (4 OCPU ARM, 24GB RAM - gratis per sempre). Il problema: La prima versione funzionava, ma era fragile. Setup manuale con 50+ comandi, 1GB RAM che crashava, […]
Ogni tanto capita un progetto che ti cambia la prospettiva. Per me, questo è stato uno di quelli. Durante il corso Build AI Agents with AWS di Zero To Mastery, ho avuto la sensazione di aver sbloccato un nuovo livello: Mi ha fatto scoprire un mondo completamente nuovo: quello dell’orchestrazione multi-agente in cloud, dove ogni […]