Prima settimana del "Complete Agentic AI Engineering Course" di Ed Donner - Un journey di 6 settimane per padroneggiare gli AI Agents
🎯 Il Contesto: Perché Ho Scelto di Ripartire dalle Basi
Quando ho visto il corso di Ed Donner su Agentic AI, la mia prima reazione è stata: "Ma io queste cose le so già!". Avevo già sperimentato con OpenAI Functions, costruito chatbot personalizzati, e giocato con framework come LangChain.
Eppure, qualcosa mi ha spinto a iscrivermi. Forse l'intuizione che conoscere non è sempre sinonimo di padroneggiare. O forse la curiosità di vedere come un esperto struttura l'apprendimento di queste tecnologie.
Spoiler: È stata la decisione giusta.
🚀 L'Assignment della Week 1: "Costruire un Agente a Mano"
Il primo assignment è stato deliberatamente "limitato":
"Niente OpenAI Agents SDK, niente CrewAI, niente LangGraph. Solo OpenAI Functions e logica pura. L'obiettivo è capire i fondamentali prima di usare i framework avanzati."
La mia sfida: creare un assistente AI che rappresenti me sul mio sito web.
💡 Cosa Ho Costruito: Un "Me Digitale"
Il Concept
Un bot che sa rispondere con precisione a domande su:
- Il mio portfolio e progetti
- I miei articoli del blog
- Le mie competenze e certificazioni
- Come contattarmi per collaborazioni
L'Architettura "Semplice" (Ma Non Tanto)
class EnhancedVeronicaBot:
"""Bot Veronica potenziato con scraper del sito web"""
def __init__(self):
print("🤖 Inizializzazione EnhancedVeronicaBot...")
self.openai = OpenAI()
self.name = "Veronica Schembri"
print("🕷️ Creazione WebsiteScraper...")
self.scraper = WebsiteScraper()
# Tool functions aggiornate
print("🔧 Configurazione tools...")
self.tools = [
{"type": "function", "function": self.record_user_details_json},
{"type": "function", "function": self.record_unknown_question_json},
{"type": "function", "function": self.search_website_json},
{"type": "function", "function": self.get_latest_content_json},
{"type": "function", "function": self.get_latest_article_json},
{"type": "function", "function": self.get_certifications_json}
]
print(f"✅ {len(self.tools)} tools configurati")
Il Web Scraper Intelligente
Qui è dove ho scoperto la prima lesson learned: un agente è forte quanto i suoi dati.
def extract_content(self, html: str, url: str) -> Dict[str, str]:
"""Estrae contenuto pulito dalle pagine con metadati avanzati - VERSIONE AGGIORNATA"""
soup = BeautifulSoup(html, 'html.parser')
for element in soup(['script', 'style', 'nav', 'footer', 'aside', 'header', 'form']):
element.decompose()
title = ""
if soup.title:
title = soup.title.string.strip()
elif soup.h1:
title = soup.h1.get_text().strip()
technologies = self.extract_technologies(content, soup)
certifications = ""
if url.endswith('/') or '/index' in url.lower():
certifications = self.extract_certifications(soup)
category = self.determine_category(url, title, content)
subcategory = self.extract_subcategory(url, title, content)
Code language: PHP (php)
Insight: Ho realizzato che non stavo solo facendo scraping, ma knowledge extraction. Ogni pagina doveva essere categorizzata, le tecnologie estratte automaticamente, le date di pubblicazione parsate correttamente.
Sistema di Tool Functions
@property
def search_website_json(self):
return {
"name": "search_website",
"description": "Cerca contenuto specifico nel sito web di Veronica (portfolio, articoli, progetti)",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Termini di ricerca per trovare contenuto specifico"
},
"category": {
"type": "string",
"enum": ["portfolio", "articles", "ai_projects", "web_projects", "all"],
"description": "Categoria da cercare: portfolio (tutti i progetti), ai_projects (progetti AI), web_projects (progetti web), articles (articoli blog), all (tutto)"
}
},
"required": ["query"]
}
}
@property
def get_latest_article_json(self):
return {
"name": "get_latest_article",
"description": "Ottieni l'ultimo articolo scritto con contenuto completo per sapere di cosa parla",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
Code language: PHP (php)
🔍 Le Scoperte: Cosa Ho Imparato "Ripassando"
1. La Complessità dei Dati "Semplici"
Pensavo: "È solo scraping, cosa ci vuole?".
Realtà: Tra sitemap XML, strutture HTML dinamiche, date in formato italiano, categorie annidate, e estrazione di tecnologie dal testo libero... ho scritto 800+ righe di codice solo per il data layer!
2. L'Importanza del System Prompt Strutturato
Prima scrivevo prompt "a sensazione". Ora ho una struttura precisa(esempio):
def system_prompt(self):
return f"""
PERSONALITÀ E BACKGROUND: {self.background}
STRUMENTI DISPONIBILI: {self.tools_description}
PRIORITÀ NELLE RISPOSTE:
1. USA SEMPRE i tool per domande su: [lista specifica]
2. Per info generali, usa il summary
3. Se non sai qualcosa, usa record_unknown_question
ESEMPI DI QUERY DA GESTIRE CON I TOOL: [esempi concreti]
REGOLE FONDAMENTALI: [behaviour specifico]
"""
Code language: PHP (php)
Lesson learned: La specificità batte la genericità. Sempre.
3. Database Design per AI Agents
Ho implementato un database SQLite con FTS5 (Full-Text Search):
-- Tabella principale
CREATE TABLE pages (
url TEXT PRIMARY KEY,
title TEXT,
content TEXT,
category TEXT, -- portfolio_ai, article_data_science, etc.
subcategory TEXT, -- ai_agents, rag_systems, tutorial, etc.
tags TEXT, -- tecnologie estratte automaticamente
publication_date TEXT,
metadata TEXT -- JSON con info aggiuntive
);
-- Indice Full-Text Search
CREATE VIRTUAL TABLE pages_fts USING fts5(
url, title, content, category, subcategory, tags
);
Code language: JavaScript (javascript)
Insight: Non è solo storage, è knowledge representation. Come strutturi i dati determina quanto è "intelligente" il tuo agente.
4. Categorizzazione Automatica: Più Difficile di Quanto Sembri
def determine_category(self, url: str, title: str, content: str) -> str:
"""Determina categoria con logica rule-based"""
url_lower = url.lower()
if '/projects/' in url_lower:
if '/ai-projects/' in url_lower:
return 'portfolio_ai'
elif '/web-development/' in url_lower:
return 'portfolio_web'
elif '/tra-dati-e-tratti/' in url_lower:
if '/data-science/' in url_lower:
return 'article_data_science'
Code language: PHP (php)
Ho finito con 12+ categorie diverse e subcategorie dinamiche. Risultato: L'agente sa distinguere tra un progetto AI e un articolo di Data Science, ed è preciso nelle ricerche.
🎭 La Demo Live: Il Vero Test
Il "Test della Moglie" 👩💼
Prima di pubblicare qualsiasi progetto, c'è sempre IL test definitivo: mostrarlo a mia moglie.
Lei, con la sua capacità innata di trovare ogni falla logica e ogni caso edge che non avevo considerato, è diventata la mia beta tester più spietata (e preziosa).
La sua domanda trabocchetto: "Sei sposata?"
Risposta del bot: "Sì, sono sposata! Ho una moglie fantastica che mi supporta e mi tiene con i piedi per terra, mentre esploro le mie passioni per l'intelligenza artificiale e la tecnologia. Se hai altre domande su di me o sul mio lavoro, non esitare a chiedere!"
✅ PASSA IL TEST!
Perché È Importante
Questo esempio mostra tre cose fondamentali:
- Personalità coerente - Il bot mantiene il character di "Veronica"
- Gestione domande personali - Risponde in modo naturale senza essere evasivo
- Redirect intelligente - Riporta la conversazione verso contenuti professionali
Altri Test Superati
User: "Quali certificazioni AI hai conseguito?" Bot: Cerca automaticamente nella homepage, estrae le certificazioni e risponde con dettagli precisi su 8 corsi diversi
User: "Di cosa parla il tuo ultimo articolo?" Bot: Trova l'articolo più recente dal blog, ne estrae il contenuto completo e fa un summary
User: "Hai esperienza con AWS?" Bot: Cerca nei progetti, trova 3 progetti specifici con AWS, estrae le tecnologie usate e risponde con esempi concreti
📊 I Numeri del Progetto
Dati processati:
- 45+ pagine del sito web scraped
- 12 categorie automatiche create
- 200+ tecnologie estratte automaticamente
- 8 tool functions integrate
Codice scritto:
- 800+ righe per il web scraper
- 300+ righe per il bot AI
- 200+ righe per il database layer
Performance:
- Cache update: ~30 secondi per tutto il sito
- Query response: <2 secondi media
- Accuracy: ~95% nelle risposte specifiche
🤔 Riflessioni: Perché "Semplice" È Relativo
Cosa Credevo Fosse "Basic":
- OpenAI Functions ✅
- Web scraping ✅
- Database SQLite ✅
Cosa Ho Scoperto Essere "Complex":
- Knowledge extraction semantica da HTML
- Categorizzazione automatica robusta
- System prompt engineering strutturato
- Error handling per web scraping real-world
- Performance optimization per response time
La Vera Lezione
"Un sistema semplice ben progettato batte un sistema complesso mal progettato"
L'approccio "foundational" mi ha costretto a:
- Capire ogni pezzo del pipeline
- Ottimizzare per il caso d'uso specifico
- Controllare la qualità dei dati a ogni step
- Debuggare efficacemente quando qualcosa non funziona
🔮 Next Steps: Il Journey Continua
Week 2: OpenAI Agents SDK
- Refactoring dell'architettura attuale
- Implementazione di agent persistenti
- Tool orchestration avanzata
Week 3-6: Verso la Complessità
- CrewAI: Multi-agent collaboration
- LangGraph: Complex workflows e decisioni
- AutoGen: Conversazioni multi-agente
- MCP: Model Context Protocol (il futuro!)
L'Evoluzione del Progetto
Quello che oggi è un "semplice" assistente AI diventerà:
- Sistema multi-agente che collabora per task complessi
- Workflow orchestration per automatizzare processi business
- Real-time knowledge updates via MCP
- Production deployment con monitoring e scaling
💭 Takeaway per la Community
Per Chi Pensa "Lo So Già Fare"
Rivalutate. Tornare alle basi con una struttura metodica rivela dettagli che spesso diamo per scontati. Ho scoperto ottimizzazioni e pattern che non avevo mai considerato.
Per Chi È Nuovo agli AI Agents
Iniziate dai fondamentali. Prima di lanciarvi su CrewAI o AutoGen, costruite qualcosa da zero. Capirete meglio cosa fanno quei framework "sotto il cofano".
🚀 Vuoi Testarlo?
Il bot è live su Hugging Face Space! Prova a fargli domande come:
- "Quali sono i tuoi progetti AI più interessanti?"
- "Che certificazioni hai in Data Science?"
- "Di cosa parla il tuo ultimo articolo?"
Link: AI Assistant