- L’idea
- I suggerimenti (complicati) di ChatGpt
- Allora provo NotebookLM
- Dicono che Claude sia meglio [spoiler: sì e no]
- Prova subito il chatbot creato con Claude
- Prova subito il chatbot creato con NotebookLM
L’intelligenza artificiale sta cambiando anche il modo con il quale ci relazioniamo con i contenuti editoriali. Attraverso i sistemi di ricerca IA cambia il modo col quale li troviamo e come ci vengono restituiti. Ma cambia anche il modo col quale vengono creati.
Sempre più spesso, da giornalista, mi capita di pensare che le formula che abbiamo adottato fino a oggi per fare informazione devono essere affiancate da altre, al passo coi tempi. Ripeto: affiancate, non sostituite.
Per questo ti racconto come ho deciso di creare come esperimento un chatbot che rispondesse a ciò che ho raccontato per più di un’ora in una conferenza.
Ma andiamo con ordine.
Quando, agli inizi di dicembre, sono stato chiamato a tenere una conferenza sul tema Come l’intelligenza artificiale sta cambiando le nostre vite, avevo pensato di filmarla. Non avevo ancora le idee chiare su come avrei utilizzato il video, ma volevo riprenderla anche per studiare meglio i miei eventuali errori.
Purtroppo, per una serie di ragioni anche banali, quella sera non ho potuto filmarla ma solo registrarne l’audio.
Mi sembrava poca cosa mandare un file MP3, tutto sommato anche noioso, visto che dura un’ora, a chi, nei giorni successivi mi chiedeva se esisteva la registrazione di quella serata. Così, per qualche giorno, l’ho lasciato fermo, finché non mi è venuta l’idea di trasformarlo in un testo. Ho pensato, magari potrei farne un piccolo libro in PDF da regalare ai miei amici a Natale.
Così ho chiesto all’intelligenza artificiale di trasformare in testo quel lungo file audio. Nonostante il lavoro eccellente fatto da Gemini, restavano ovviamente quelle frasi non chiuse e non perfette, tipiche di quando si parla in una conferenza rispetto a quando si scrive. Così ho passato il risultato su un’altra, e questa volta su cloud, e gli ho chiesto di metterle a posto utilizzando il mio stile. Per poterlo fare, tempo addietro, avevo insegnato a Claude come scrivo quando tratto temi tecnologici.
Una volta creato il testo, tutto sommato di qualità più che decente, non mi restava che trasformarlo in un piccolo libro PDF.
Eppure non ero soddisfatto. Qualcosa mi diceva di aspettare. Finché mi è venuta un’idea: perché non mettere tutto quel materiale in una sorta di chatbot che potesse essere interrogato dalle persone, così da non dover obbligare amici e colleghi a dovere leggere il libretto dall’inizio alla fine, imbattendosi magari in aree e temi che già conoscevano o non gli interessavano?
A questo punto ho aperto ChatGPT e ho chiesto dei consigli su come fare tecnicamente. Ne è venuta fuori una conversazione piuttosto difficile da comprendere per uno come me, che ha solo delle conoscenze di base di informatica e di linguaggi, e che, se vuoi, puoi trovare qui.
Allora provo NotebookLM
Vista la difficoltà, almeno per me, di fare un sistema simile con ChatGPT ho provato con NotebookLM. Personalmente trovo il sistema di Google davvero utile per chi fa il giornalista. Permette di creare notebook che contengono una o più fonti legate a uno o più argomenti, con la possibilità di fare riassunti, ottenere podcast, infografiche, slide e, ovviamente, poter interrogare tutto il materiale attraverso delle domande.
Così ne ho realizzato uno a partire da due PDF: uno con il testo della mia conferenza, uno con le slide che ho usato (così da rendere più chiaro al sistema la scansione dei temi trattati). Dopo averlo testato, ero davvero soddisfatto e anche la grafica, pur nella sua semplicità, non mi sembrava male. Ti metto un frame qui sotto.

Testandolo mi sono accorto che il sistema, da solo, aveva fatto delle sostituzioni gravi. Per esempio, aveva cancellato dalla conferenza Papa Leone XIV. Questo perché l’intelligenza artificiale di Google continua ancora oggi a considerare il Papa regnante, Papa Francesco, e a non vedere l’elezione di Leone XIV.
A questo punto ho caricato un secondo PDF come fonte con tutte le slide che avevo preparato per la conferenza, alcune delle quali erano in maniera specifica incentrate su Papa Leone. Soltanto a questo punto il sistema ha cominciato a dare le risposte giuste sul nuovo Papa.

Dicono che Claude sia meglio. Davvero?
Non sono io a dirlo, ma persone molto più esperte di me: Claude, per quanto riguarda la capacità di creare codici e programmare, al momento è superiore ad altre intelligenze artificiali.
Così ho provato a realizzare il mio sistema usando questa intelligenza artificiale.
Non essendo questo un blog di informatici, non ti metto tutto il ragionamento che mi ha fatto anche Claude. Mi limiterò a raccontarti che, inizialmente, mi ha proposto anche lei una soluzione tecnicamente non facile.
Poi, stimolata da me, è invitata a realizzare qualcosa che potesse essere utilizzata anche da una persona con scarse conoscenze informatiche. È passata a soluzioni più semplici.
Quando dico semplici, però, non voglio dire alla portata di tutti, perché ha realizzato file che andavano caricati via FTP in una certa area del mio sito e poi altri, ai quali dovevano essere fatte delle correzioni nei codici HTML.Insomma, niente di incredibile, ma neanche di così facile per chi non ha alcuna conoscenza di queste cose. Ci ho messo un po’ a farlo funzionare correttamente, ma devo dire che tutte le soluzioni che mi ha dato Claude hanno migliorato sensibilmente il progetto.
L’idea finale è fatta così. Ho creato una versione che funziona 100% offline, completamente client-side, senza bisogno di API esterne.
Andava tutto bene, tranne una cosa. Dopo la prima risposta, il sistema mi dava una sezione rilevante dove cercava, all’interno di tutto il documento, testi che potessero in qualche modo avvicinarsi alla domanda che avevo fatto, in percentuali variabili che andavano dal 10% al 55%. Il risultato era un elenco piuttosto confusionario.Così gli ho chiesto di togliere questa sezione e di mettere al suo posto una serie successiva di domande che potessero aiutare chi interroga il sistema ad approfondire il tema.
Sembrava tutto perfetto. Ma più interrogavo il nuovo chatbot creato con Claude, più trovavo delle imprecisioni. Per cui tornavo a interrogare il sistema che l’avevo creato e gli chiedevo di fare delle correzioni. Il problema della IA è che, se non stai attento a tutto, il suo aiuto non è completo. Mi spiego. Quando facevo domande sulla Chiesa e l’intelligenza artificiale, confondeva il magistero di Papa Francesco con quello di Papa Leone XIV. Quando glielo ho fatto notare con una serie di esempi pratici, ha suddiviso meglio la sezione così da ridurre la possibilità di errore.
Peccato che le altre 22 sezioni, con le quali era stata suddivisa la mia conferenza, non avessero lo stesso trattamento e quindi erano imprecise.
Ho quindi dovuto chiedere espressamente al sistema di fare un’analisi globale di tutto il contenuto e una suddivisione più rigorosa.

Pensavo di avere risolto tutto, ma non avevo fatto i conti con gli errori che mi ero portato dall’inizio. Quindi, anche in questo chatbot, Papa Leone XIV non esisteva più. Ho così ripassato tutto il testo della conferenza e l’ho corretto. Poi ho chiesto al sistema di fare la stessa cosa nel suo database, sperando correggesse l’errore.
Al primo tentativo ha commesso un altro errore: ha sostituito Papa Leone XIV tutte le volte che incontrava le parole Papa Francesco. Ho quindi dovuto rispiegargli che a guidare la Chiesa prima c’era papa Francesco e ora Leone XIV, che entrambi hanno fatto dichiarazioni sull’intelligenza artificiale e che queste dovevano essere attribuite in maniera corretta ai due papi.
Sembrava avesse capito tutto; invece, ha attribuito il documento vaticano sull’intelligenza artificiale del gennaio 2025 a Papa Leone XIV, quando invece c’era ancora Papa Francesco.

Claude mi aveva risposto di aver risolto tutto. Invece, quando mi ha restituito questa domanda correlata Cosa significa che l’IA lavora per probabilità?, quando l’ho cliccata mi ha dato una risposta su papa Leone XIV.
Quando gliel’ho fatto notare, mi ha risposto: Hai fatto benissimo a chiedere! Ho trovato un GROSSO problema: le keywords compound come “papa leone xiv”, “essere umani”, “bene comune” NON matchano correttamente!
Quindi ha promesso di correggere tutto e di rivedere anche l’algoritmo. Te la faccio breve: c’è voluta mezz’ora di lavoro per trovare il problema e correggere l’algoritmo.
Ed ecco il chatbot di Claude sulla mia conferenza
Sistema RAG per esplorare i contenuti della conferenza di Gigio Rancilio con domande in linguaggio naturale
Sotto il chatbot creato con NotebookLM
Assistente Virtuale della Conferenza
Vuoi approfondire un punto specifico delle slide o del mio intervento? Chiedilo direttamente alla mia base documentale tramite NotebookLM.
- Risposte basate esclusivamente sui miei PDF
- Citazioni dirette alle pagine e alle slide
- Generazione di riassunti personalizzati

Le mie considerazioni finali
Dopo avere testato due chatbot per qualche ora, posso dire che quello creato con Notebook LM, pur essendo molto più lento, dà risposte più concrete, più complete e coerenti, pescando anche da parti diverse della conferenza.
Quello creato con Claude, che ha una grafica sicuramente più accattivante e il bonus di fornire dopo ogni risposta, ulteriori domande correlate per approfondire il tema, è molto veloce ma un po’ meno preciso.
| Caratteristica | Chatbot con Claude | NotebookLM |
|---|---|---|
| Focus Principale | Creatività e ragionamento logico | Analisi e grounding sui documenti |
| Domande Correlate | Grafica più bella | Suggerimenti contestuali alle fonti |
| Interfaccia | Moderna e rifinita | Grafica spartana |
| Approfondimento | Risposte bilanciate | Risposte più esaurienti |
| Velocità | Molto veloce ed efficiente | Sistema più lento |
A questo punto ti chiedo la gentilezza di provarli anche tu e di indicarmi gli eventuali errori e le inesattezze che contengono.
Per chi fosse interessato metto qui sotto la prima conversazione con ChatGPT per creare il chatbot sulla conferenza
La conversazione con ChatGPT per creare il chatbot sulla conferenza
Qui sotto una roadmap concreta per farlo bene, cioè “risponde solo dal libro” + citazioni + controlli.
1) Prepara il testo del libro (digitale)
- Se è PDF: estrai il testo in modo pulito (attenzione a intestazioni/piedipagina, note, rientri).
- Se è EPUB: di solito è più semplice ottenere testo “pulito”.
- Mantieni (o ricostruisci) struttura: capitoli, sezioni, numeri pagina (o “posizioni”) → servono per le citazioni.
Output ideale: una cartella con file tipo:
capitolo-01.md,capitolo-02.md… (oppure JSON con campichapter,text,page_start,page_end).
2) Crea l’indice di ricerca (il cuore del sistema)
- Spezza in chunk (es. 300–800 parole, con 10–20% di sovrapposizione).
- Salva metadati per ogni chunk:
capitolo,paragrafo,pagina/posizione, eventualmente un ID univoco. - Indicizza in un sistema di retrieval:
- minimo: solo vector search (embeddings)
- meglio: ibrido (semantico + keyword) per prendere anche nomi propri, date, termini tecnici.
3) Costruisci il chatbot “chiuso” sul libro (RAG con guardrail)
Flusso:
- domanda utente
- recupero dei chunk migliori (es. top 5–10)
- risposta solo usando quei chunk
Guardrail che fanno la differenza:
- Citazioni obbligatorie: ogni risposta deve riportare “Capitolo X, p. Y” (o sezione/posizione).
- Soglia di confidenza: se i chunk recuperati non sono abbastanza pertinenti → risposta standard:
“Nel libro non trovo informazioni sufficienti per rispondere con certezza.” - Regola anti-estratti lunghi (importante se lo condividi): limita la verbatim quote a poche righe e preferisci parafrasi + citazioni.
4) Decidi come lo condividi (scelta pratica)
Tre opzioni tipiche:
A) Sito web pubblico
- Frontend (una pagina chat) + backend (API).
- Autenticazione opzionale (token/utente) se vuoi controllare accessi.
- Rate limit per evitare abuso/costi.
B) Chatbot “chiuso” con accesso a invito
- Login, whitelist email, o link con token.
- Ideale se vuoi testarlo con lettori selezionati.
C) Widget embed
- Un widget da incorporare nel tuo sito (stessa logica, UI integrata).
5) Protezioni “da autore” (anti-copia / anti-leak)
Se lo condividi, pensa a questi punti:
- Non far scaricare i chunk sorgente.
- Limite di output (es. max 800–1200 caratteri) e limite di citazioni testuali.
- Blocca richieste tipo: “incollami tutto il capitolo 3” → rispondere con riassunto + rimando.
- Log e monitoraggio: domande frequenti, tentativi di estrazione massiva.
6) Test e qualità
- Prepara 50 domande (semplici, difficili, trabocchetto) e verifica:
- citazioni corrette
- “non lo so” quando serve
- coerenza terminologica (nomi, date, concetti ricorrenti)
Se vuoi una “ricetta” super concreta (stack tipico)
- Ingest & indice: LlamaIndex o LangChain
- Vector DB: Qdrant / pgvector / Pinecone (scegli in base a dove hosti)
- Backend: FastAPI / Node
- Frontend: Next.js (o anche una pagina HTML semplice)
- Regole: citazioni obbligatorie + soglia + blocco estratti lunghi
Se mi dici in che formato digitale è il libro (PDF o EPUB) e quante pagine circa, ti propongo un setup preciso (anche “tutto su un VPS” o “serverless”), con parametri consigliati: chunk size, top-k, soglia, formato delle citazioni e limiti anti-estrazione.
Spiegami come fare, passo dopo passo, come se lo spiegassi a tua zia di 60 anni
Ragionato per 40s
Certo. Ti spiego un modo semplice e “da zia” per creare un chatbot che risponde solo usando il tuo libro e poi metterlo online.
L’idea è questa: il chatbot non “sa” davvero il libro a memoria. Quando gli fai una domanda, prima cerca nel libro i pezzi giusti e poi risponde usando solo quelli (con citazioni). Questa tecnica si chiama RAG, ma tu puoi pensarla come: “prima cerco nel libro, poi parlo”. OpenAI Platform+1
Strada più facile (consigliata): usare “File search” + una mini web-app
Questa strada ti evita di costruire da zero un motore di ricerca: lo fai con l’API e un sito molto semplice. “File search” supporta proprio l’idea di caricare file in un “contenitore” (vector store) e farli cercare al modello con ricerca semantica + keyword. OpenAI Platform+1
Passo 1 — Metti in ordine il file del libro
- Assicurati di avere un PDF (o altro formato supportato) pulito:
- testo selezionabile (non “immagini di testo”)
- niente doppie versioni, niente password
- Se il PDF è impaginato male (colonne, note strane), può comunque funzionare, ma a volte conviene partire da EPUB o testo se lo hai.
Passo 2 — Crea “la casa” del chatbot
- Ti serve un account sulla piattaforma API che userai (es. OpenAI API).
- Crea una API key (una “chiave” segreta).
- Tieni la chiave solo nel server, mai dentro una pagina web pubblica.
Passo 3 — Carica il libro nel “magazzino di ricerca”
- Crei un vector store (immagina uno scaffale dove il sistema mette il libro a pezzetti indicizzati).
- Carichi il PDF dentro quello scaffale.
- Da quel momento, il chatbot può “cercare nel tuo libro” prima di rispondere. OpenAI Platform+1
(Nota: esistono anche limiti dimensionali/di token per i file, quindi se il libro è enorme o hai tanti file, va gestito con attenzione.) OpenAI Platform
Passo 4 — Imposta le regole: “rispondi solo dal libro”
Questa è la parte più importante per evitare invenzioni.
Nel messaggio di sistema (le istruzioni fisse del bot) metti regole tipo:
- “Usa esclusivamente le informazioni trovate nei file.”
- “Se nel libro non c’è, rispondi: ‘Non è nel libro’.”
- “Metti sempre le citazioni (capitolo/pagina o riferimento).”
- “Non copiare lunghi pezzi del testo: fai riassunti brevi.”
Passo 5 — Crea una pagina web “chat” (la vetrina)
Qui ci sono 2 pezzetti:
A) Backend (server): una piccola API che:
- riceve la domanda dell’utente
- chiama il modello con lo strumento file search
- restituisce risposta + citazioni
B) Frontend (sito): una pagina con:
- una casella dove scrivi
- un bottone “Invia”
- area dove leggi la risposta e le citazioni
(Per pubblicarlo, puoi usare servizi tipo Vercel/Render/Fly/Cloudflare, ma la scelta dipende da cosa sai già usare.)
Passo 6 — Metti “cinture di sicurezza” perché sarà pubblico
Se lo condividi, ti conviene aggiungere:
- limite di domande (rate limit) per evitare abuso e costi a sorpresa
- moderazione base (blocca spam/insulti)
- limite lunghezza risposta
- blocco richieste tipo: “incollami tutto il capitolo 3” → rispondi con riassunto + invito a consultare il libro
Passo 7 — Prova con domande “cattive”
Prima di pubblicare, fai un test tipo:
- 20 domande facilissime (deve andare liscio)
- 20 domande trabocchetto su cose non presenti (deve dire “non è nel libro”)
- 10 domande ambigue (deve chiedere chiarimenti o rispondere con prudenza)
Strada “più controllabile” (se vuoi più libertà): LlamaIndex/LangChain + un tuo database vettoriale
Se vuoi avere più controllo (chunking, metadati, capitoli/pagine perfette, ecc.), usi strumenti tipo LlamaIndex/LangChain per:
- caricare documenti
- spezzarli in chunk
- aggiungere metadati
- creare embeddings
- salvare tutto in un vector DB tipo Qdrant developers.llamaindex.ai+2Documentazione LangChain+2
È più lavoro, ma permette “fine tuning” del comportamento del retriever.
Se vuoi, ti do una checklist precisa “da seguire e spuntare”
Per farla davvero su misura, dimmi solo:
- Il tuo libro è PDF o EPUB?
- Quante pagine circa?
- Vuoi che sia pubblico per tutti o con accesso (password/link)?
E ti scrivo i passaggi esatti con: struttura cartelle, regole del prompt, formato delle citazioni e impostazioni consigliate (top-k/soglia/limiti) senza farti impazzire.
1 pdf 2 40 3 con password
Ragionato per 2m 8s
Ok: PDF (40 pagine) + accesso con password + chatbot che risponde solo usando il tuo libro. Ti descrivo la strada più semplice, “da zia”, usando:
- un sito Next.js (la pagina chat)
- una password (Basic Auth: ti chiede user+password prima di entrare)
- File Search + Vector Store (OpenAI indicizza il PDF e lo fa “cercare” al bot) OpenAI Platform+2OpenAI Platform+2
Cosa ti serve (ingredienti)
- Il tuo file:
mio-libro.pdf - Un computer con Terminale (o Prompt)
- Account su:
- OpenAI Platform (per la chiave API)
- Vercel (per pubblicare il sito)
Regola d’oro: la API key non va mai messa nel browser. Deve stare “dietro”, nel server. OpenAI Help Center+1
Passo 1 — Crea il sito “con password” (pronto in 2 minuti)
Useremo un modello già pronto di Vercel che mette la password davanti a tutto il sito. Vercel
- Apri il Terminale e incolla (così com’è):
pnpm create next-app --example https://github.com/vercel/examples/tree/main/edge-middleware/basic-auth-password basic-auth-password
cd basic-auth-password
pnpm dev
- Vai nel browser su
http://localhost:3000 - Ti chiede user+password (per ora sono quelle di demo nel template). Vercel
Se non hai
pnpm, installalo con:
npm i -g pnpm
Passo 2 — Metti la tua password
Nel progetto, crea un file chiamato .env.local (nella cartella del progetto) e mettici:
BASIC_AUTH_USER=tuoUser
BASIC_AUTH_PASSWORD=unaPasswordLungaERobusta
Il template usa l’Edge Middleware per proteggere le pagine con Basic Auth. Vercel+1
Passo 3 — Carica il PDF in un “contenitore” di ricerca (Vector Store)
Qui crei lo “scaffale” dove il PDF viene spezzato e indicizzato automaticamente. Poi il bot ci cerca dentro. OpenAI Platform+2OpenAI Cookbook+2
3A) Prepara la chiave OpenAI
- Prendi la tua OPENAI_API_KEY
- Aggiungila a
.env.local:
OPENAI_API_KEY=la_tua_chiave_openai
3B) Crea vector store + carica PDF (script “una volta sola”)
- Metti
mio-libro.pdfdentro la cartella del progetto. - Crea un file
upload_book.pycon questo contenuto:
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
# 1) crea il "magazzino"
vs = client.vector_stores.create(name="Mio libro (chatbot)")
print("VECTOR_STORE_ID =", vs.id)
# 2) carica il PDF come file
f = client.files.create(
file=open("mio-libro.pdf", "rb"),
purpose="assistants"
)
# 3) collega il file al vector store
client.vector_stores.files.create(
vector_store_id=vs.id,
file_id=f.id
)
print("OK: PDF caricato e indicizzato (potrebbe volerci un po' di tempo).")
- Esegui:
pip install openai
python upload_book.py
- Copia il valore stampato
VECTOR_STORE_ID = ...e mettilo in.env.local:
VECTOR_STORE_ID=vs_xxxxxx
(Questo flusso di upload è esattamente quello usato negli esempi ufficiali.) OpenAI Cookbook+1
Passo 4 — Crea l’API del chatbot (il “cervello” dietro)
Il punto chiave: la tua pagina web chiama il tuo server, e il server chiama OpenAI con file_search puntato al tuo vector store. OpenAI Help Center+2OpenAI Platform+2
- Nel progetto, crea questo file:
pages/api/chat.js(se usi Pages Router)
Dentro incolla (versione semplice):
import OpenAI from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
export default async function handler(req, res) {
if (req.method !== "POST") return res.status(405).json({ error: "Use POST" });
const { question } = req.body || {};
if (!question) return res.status(400).json({ error: "Missing question" });
const systemRules = `
Rispondi ESCLUSIVAMENTE usando il contenuto del libro caricato.
Se nel libro non trovi la risposta, dì: "Non è presente nel libro."
Non inventare.
Alla fine, aggiungi una sezione "Fonti" con i riferimenti ai passaggi trovati.
`;
const response = await openai.responses.create({
model: "gpt-4.1",
input: [
{ role: "system", content: systemRules },
{ role: "user", content: question },
],
tools: [{
type: "file_search",
vector_store_ids: [process.env.VECTOR_STORE_ID],
max_num_results: 5,
}],
include: ["file_search_call.results"],
});
// risposta testuale “pronta”
const answer = response.output_text || "";
res.status(200).json({ answer });
}
Queste opzioni (file_search, vector_store_ids, max_num_results, include) sono documentate nella guida ufficiale di File Search. OpenAI Platform+1
Passo 5 — Crea la pagina chat (la “faccia”)
- Apri
pages/index.js(o la pagina principale del template) - Metti un form semplice che manda la domanda a
/api/chate stampaanswer.
Se vuoi, posso darti un file index.js già pronto “copia-incolla” (molto corto).
Passo 6 — Pubblica su internet (con password)
- Carica il progetto su GitHub (anche privato va bene)
- Su Vercel: “New Project” → collega il repo → Deploy
- Su Vercel → Settings → Environment Variables: inserisci
OPENAI_API_KEYVECTOR_STORE_IDBASIC_AUTH_USERBASIC_AUTH_PASSWORD
E ridistribuisci.
Due accorgimenti importanti (per farlo davvero “solo dal libro”)
- Mantieni la regola: se non trova nel libro, deve dire “non è presente” (niente supposizioni).
- Metti un limite: se qualcuno chiede “incollami l’intero capitolo”, rispondi con riassunto e basta (utile anche per evitare estrazioni massicce).
Se mi dici solo che sistema stai usando (Windows/Mac), ti adatto i comandi (Terminale/Prompt) e ti passo anche la pagina chat completa già pronta da incollare.
windows
Ragionato per 3m 45s
Perfetto. Ti spiego come farlo su Windows, passo-passo, in modo “da zia”: copi/incolli comandi, crei 3–4 file, e poi lo pubblichi con password.
L’idea tecnica è: il bot prima cerca nel PDF (con File Search su un vector store) e poi risponde solo usando quello. OpenAI Platform
0) Prima di iniziare (cose da installare su Windows)
- Node.js LTS (serve per far girare il sito)
- Git (serve per pubblicare su Vercel tramite GitHub)
- Visual Studio Code (consigliato, per modificare i file)
Se non sai dove prenderli: cerca su Google “Node.js LTS download”, “Git for Windows”, “VS Code”.
1) Crea il progetto (con la password già pronta)
Apri PowerShell (Start → cerca “PowerShell”) e incolla:
npm install -g pnpm
pnpm create next-app --example https://github.com/vercel/examples/tree/main/edge-middleware/basic-auth-password libro-chatbot
cd libro-chatbot
pnpm dev
Poi apri il browser su http://localhost:3000 → vedrai che chiede user/password. Questo template è fatto apposta per proteggere con password usando Middleware. Vercel+1
2) Metti la tua password (davvero tua)
Nel progetto, crea un file chiamato .env.local (nella cartella libro-chatbot) con questo contenuto:
BASIC_AUTH_USER=Gigio
BASIC_AUTH_PASSWORD=UnaPasswordLunga123!
Ora crea (o sostituisci) il file middleware.ts nella cartella principale del progetto (stesso livello di package.json) con questo codice:
import { NextResponse } from "next/server";
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};
export function middleware(req: Request) {
const user = process.env.BASIC_AUTH_USER ?? "";
const pass = process.env.BASIC_AUTH_PASSWORD ?? "";
const auth = req.headers.get("authorization");
const valid =
auth &&
auth.startsWith("Basic ") &&
(() => {
const b64 = auth.slice("Basic ".length);
const [u, p] = Buffer.from(b64, "base64").toString().split(":");
return u === user && p === pass;
})();
if (valid) return NextResponse.next();
return new Response("Auth required", {
status: 401,
headers: { "WWW-Authenticate": 'Basic realm="Protected"' },
});
}
Questa è la “porta con la chiave” davanti a tutto il sito. Middleware in Next.js/Vercel funziona proprio così. Vercel+1
Riavvia il server (nel terminale: CTRL+C, poi):
pnpm dev
3) Metti il PDF nel progetto
Copia il tuo libro (40 pagine) dentro la cartella libro-chatbot e chiamalo libro.pdf.
4) Crea il “magazzino” dove il bot cercherà nel PDF (Vector Store)
4A) Metti la chiave OpenAI
Nel file .env.local aggiungi anche:
OPENAI_API_KEY=la_tua_chiave_openai
4B) Installa la libreria OpenAI
In PowerShell (dentro libro-chatbot):
pnpm add openai
4C) Crea lo script che carica il PDF
Crea la cartella scripts e dentro un file upload.mjs:
scripts/upload.mjs
import fs from "node:fs";
import OpenAI from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
async function sleep(ms) {
return new Promise((r) => setTimeout(r, ms));
}
async function main() {
// 1) crea un vector store (lo “scaffale”)
const vectorStore = await openai.vectorStores.create({ name: "Libro PDF" });
// 2) carica il file su Files API
const file = await openai.files.create({
file: fs.createReadStream("libro.pdf"),
purpose: "assistants",
});
// 3) aggancia il file al vector store
await openai.vectorStores.files.create(vectorStore.id, { file_id: file.id });
// 4) aspetta finché l’indicizzazione è pronta (status = completed)
while (true) {
const list = await openai.vectorStores.files.list({
vector_store_id: vectorStore.id,
});
const status = list.data?.[0]?.status;
console.log("Stato indicizzazione:", status);
if (status === "completed") break;
if (status === "failed") throw new Error("Indicizzazione fallita");
await sleep(1500);
}
console.log("\n✅ Fatto!");
console.log("VECTOR_STORE_ID =", vectorStore.id);
}
main().catch((e) => {
console.error(e);
process.exit(1);
});
E avvialo:
node scripts/upload.mjs
Quando finisce, copia il VECTOR_STORE_ID = vs_... e incollalo in .env.local:
VECTOR_STORE_ID=vs_qualcosa
Questi passaggi (upload file → attach al vector store → status “completed”) sono esattamente quelli descritti nella guida ufficiale di File Search. OpenAI Platform+2OpenAI Platform+2
5) Crea l’API “/api/chat” (il cervello del chatbot)
Qui facciamo una rotta che:
- riceve una domanda
- usa
file_searchsul tuoVECTOR_STORE_ID - risponde solo usando il libro (e se non c’è, dice “non è nel libro”) OpenAI Platform
Se nel tuo progetto c’è la cartella app
Crea: app/api/chat/route.js
import OpenAI from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
export async function POST(req) {
const { question } = await req.json();
const system = `
Rispondi ESCLUSIVAMENTE usando il contenuto del file fornito tramite file_search (il libro).
Se nel libro non trovi la risposta, scrivi: "Non è presente nel libro."
Non inventare. Risposta breve e chiara.
`.trim();
const response = await openai.responses.create({
model: "gpt-4.1",
input: [
{ role: "system", content: system },
{ role: "user", content: question },
],
tools: [
{
type: "file_search",
vector_store_ids: [process.env.VECTOR_STORE_ID],
max_num_results: 5,
},
],
});
return Response.json({ answer: response.output_text });
}
Se nel tuo progetto c’è la cartella pages
Crea: pages/api/chat.js
import OpenAI from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
export default async function handler(req, res) {
if (req.method !== "POST") return res.status(405).end();
const { question } = req.body || {};
const system = `
Rispondi ESCLUSIVAMENTE usando il contenuto del file fornito tramite file_search (il libro).
Se nel libro non trovi la risposta, scrivi: "Non è presente nel libro."
Non inventare. Risposta breve e chiara.
`.trim();
const response = await openai.responses.create({
model: "gpt-4.1",
input: [
{ role: "system", content: system },
{ role: "user", content: question },
],
tools: [
{
type: "file_search",
vector_store_ids: [process.env.VECTOR_STORE_ID],
max_num_results: 5,
},
],
});
res.status(200).json({ answer: response.output_text });
}
Il modo in cui si usa file_search, vector_store_ids, max_num_results e la Responses API è documentato ufficialmente. OpenAI Platform+1
6) Crea la pagina “chat” (la faccia del bot)
Dimmi solo se nel tuo progetto c’è app/page.* oppure pages/index.* e ti incollo la pagina completa giusta (è un file corto, con una casella di testo + bottone + risposta).
7) Mettilo online con password (Vercel)
Metodo semplice:
- Carica il progetto su GitHub (repo privato o pubblico)
- Su Vercel: “New Project” → importi il repo → Deploy
- In Vercel → Settings → Environment Variables aggiungi:
OPENAI_API_KEYVECTOR_STORE_IDBASIC_AUTH_USERBASIC_AUTH_PASSWORD
Così, appena qualcuno apre il sito, vede subito la richiesta password (grazie al middleware).
