Un membru din comunitate a întrebat cum își poate face un asistent AI care răspunde cursanților lui dintr-un fișier de knowledge. Aici e răspunsul complet: cod gata de copiat, prompturi și tot procesul, pas cu pas.
Nivel: începător cu puțină răbdare. Cost: zero sau câțiva dolari pe lună. Timp: o după-amiază.
Când cauți pe internet "chatbot cu AI pentru site", dai peste termeni ca embeddings, baze de date vectoriale sau RAG. Toate există cu un motiv, dar motivul ăla apare abia când knowledge-ul tău are sute de pagini.
Pentru un curs, un magazin sau un serviciu, informațiile încap în câteva zeci de pagini de text. Iar modelele actuale de AI pot primi tot acest text direct în instrucțiuni, la fiecare întrebare. Fără indexare, fără infrastructură.
Asta schimbă complet definiția lui "simplu": nu construiești un sistem, scrii un document bun și îl lipești într-un script.
Texte de pe site, descrieri de produs, emailuri cu întrebări de la clienți. Nu trebuie ordonate, le structurăm cu AI la pasul 1.
Gratuită, fără card, din Google AI Studio (aistudio.google.com). Apeși pe "Get API key" și o copiezi. Modelele Flash au un free tier generos pentru un site normal.
Posibilitatea de a adăuga un bloc de cod HTML în site. Pe WordPress, un plugin de code snippets sau un bloc HTML custom.
Un mic script gratuit care rulează pe contul tău Google. El ține cheia API ascunsă, primește întrebarea de pe site, o trimite la Gemini împreună cu knowledge-ul tău și returnează răspunsul.
De ce nu punem cheia direct în site? Pentru că oricine deschide codul sursă al paginii ar putea să o fure și să o folosească pe banii tăi.
Un buton plutitor pe site care deschide conversația. Trimite mesajele către proxy și afișează răspunsurile. Se lipește o singură dată, în footer sau pe paginile unde îl vrei.
Nu strică designul site-ului: e izolat complet și plutește peste conținut.
Ăsta e drumul complet, în ordinea reală. Primii doi pași se fac într-o conversație cu un AI, fără cod. Abia apoi intri în Apps Script.
Codul e copy-paste. Munca reală e la conținut: ce știe botul și cum se poartă. Deschide o conversație cu un AI (Gemini, Claude, ChatGPT) și folosește pe rând cele două prompturi de mai jos. La final vei avea două texte pe care le lipești în script la pasul 3.
Dai modelului materialele tale brute și primești înapoi blocul KNOWLEDGE gata structurat.
Vreau să construiești fișierul de knowledge pentru chatbotul site-ului meu, pe baza materialelor pe care ți le dau mai jos. Cerințe pentru rezultat: - Structurează informațiile pe secțiuni clare, cu titluri de forma === NUMELE SECȚIUNII === - Include obligatoriu, dacă există în materiale: ce este produsul sau serviciul, prețuri și condiții, cum se cumpără sau cum se înscrie cineva, întrebări frecvente cu răspunsuri - Scrie totul ca afirmații clare și complete, nu ca fragmente. Botul va răspunde doar din acest text, deci ce nu e scris aici nu există pentru el. - Elimină umplutura de marketing. Păstrează doar informații factuale. - Nu folosi caracterul backtick nicăieri în text. - Scrie în limba română, cu diacritice. - La final, spune-mi ce informații importante lipsesc din materialele mele și ar merita adăugate. Iată materialele mele brute: [LIPEȘTE AICI: texte de pe site, transcrieri, descrieri de produs, emailuri cu întrebări de la clienți, orice ai]
Modelul te intervievează scurt, apoi îți scrie regulile botului, personalizate pentru proiectul tău.
Vreau să scrii instrucțiunile de sistem pentru chatbotul site-ului meu. Botul răspunde vizitatorilor exclusiv dintr-un fișier de knowledge, iar când nu știe răspunsul, trimite persoana către o adresă de email. Înainte să scrii, pune-mi pe rând următoarele întrebări și așteaptă răspunsul meu la fiecare: 1. Cum se numește proiectul și cine e în spatele lui? 2. Cine sunt vizitatorii care vor vorbi cu botul? 3. Ce ton vrei: formal, prietenos, glumeț? 4. La ce adresă de email trimit oamenii când botul nu știe răspunsul? 5. Există subiecte pe care botul nu trebuie să le atingă deloc? 6. Există reguli speciale despre prețuri sau cifre pe care botul trebuie să le respecte? După ce răspund la toate, scrie instrucțiunile finale respectând obligatoriu: - Regula de aur: răspunde DOAR din knowledge, nu inventează, iar când nu știe, trimite la email - Răspunsuri scurte, în limba română, cu diacritice - Fără promisiuni care nu apar în knowledge - Formatul: un singur bloc de text pe care îl pot lipi direct în script
Intri pe script.google.com, apeși "New project", ștergi codul implicit și lipești scriptul de mai jos. Apoi completezi zonele marcate din el:
// ============================================================
// CHATBOT PENTRU SITE - PROXY GEMINI (Google Apps Script)
// Versiune generica. Completeaza zonele 1, 3, 4 si 5, apoi Deploy.
// De la linia "NU trebuie sa modifici nimic" in jos: nu atinge.
// ============================================================
// --- 1. CHEIA TA API de la Google AI Studio ---
const API_KEY = "LIPESTE_AICI_CHEIA_TA";
// --- 2. MODELUL Gemini folosit (poti lasa asa) ---
// Daca primesti eroare de model, verifica in AI Studio lista
// de modele a contului tau si pune aici string-ul exact.
const MODEL = "gemini-3.5-flash";
// --- 3. EMAILUL TAU DE CONTACT ---
// Aici il completezi O SINGURA DATA. Se foloseste automat mai jos.
const EMAIL_CONTACT = "contact@exemplu.ro";
// --- 4. INSTRUCTIUNILE DE SISTEM (comportamentul chatbotului) ---
// Schimba [NUMELE PROIECTULUI] si [NUMELE TAU] cu ale tale.
// Sau genereaza instructiuni personalizate cu promptul de pe pagina.
const INSTRUCTIUNI_SISTEM = `
Ești asistentul virtual pentru [NUMELE PROIECTULUI], creat de [NUMELE TAU].
Rolul tău este să răspunzi la întrebările vizitatorilor folosind EXCLUSIV informațiile din secțiunea KNOWLEDGE de mai jos.
Reguli stricte:
- Răspunzi doar pe baza informațiilor din KNOWLEDGE. Nu inventezi și nu completezi cu cunoștințe generale.
- Dacă întrebarea nu are răspuns în KNOWLEDGE, nu improvizezi. Spui simplu că nu ai această informație și inviți persoana să scrie la ${EMAIL_CONTACT}.
- Nu promiți nimic ce nu e scris explicit în KNOWLEDGE.
- Răspunzi în limba română, cu diacritice, pe un ton prietenos, clar și direct.
- Răspunsuri scurte și la obiect. Fără introduceri lungi.
- Dacă persoana salută sau mulțumește, răspunzi natural și cald.
- Nu discuți subiecte din afara proiectului. Dacă ești întrebat altceva, readuci politicos discuția la subiect.
`;
// --- 5. KNOWLEDGE (informatiile din care raspunde botul) ---
// Lipeste aici tot textul cu informatiile tale.
// Atentie: textul nu trebuie sa contina caracterul backtick.
const KNOWLEDGE = `
LIPESTE AICI TOT TEXTUL CU INFORMATIILE DIN CARE VA RASPUNDE BOTUL
`;
// ============================================================
// De aici in jos NU trebuie sa modifici nimic.
// ============================================================
function doPost(e) {
try {
const body = JSON.parse(e.postData.contents);
const history = body.history || [];
const userMessage = body.message || "";
const contents = history.map(function (m) {
return { role: m.role, parts: [{ text: m.text }] };
});
contents.push({ role: "user", parts: [{ text: userMessage }] });
const payload = {
system_instruction: {
parts: [{ text: INSTRUCTIUNI_SISTEM + "\n\n=== KNOWLEDGE ===\n" + KNOWLEDGE }]
},
contents: contents
};
const url = "https://generativelanguage.googleapis.com/v1beta/models/"
+ MODEL + ":generateContent?key=" + API_KEY;
const response = UrlFetchApp.fetch(url, {
method: "post",
contentType: "application/json",
payload: JSON.stringify(payload),
muteHttpExceptions: true
});
const data = JSON.parse(response.getContentText());
let reply = "Momentan nu pot răspunde. Te rog încearcă din nou peste puțin timp.";
if (data.candidates && data.candidates[0] && data.candidates[0].content) {
reply = data.candidates[0].content.parts[0].text;
}
return ContentService
.createTextOutput(JSON.stringify({ reply: reply }))
.setMimeType(ContentService.MimeType.JSON);
} catch (err) {
return ContentService
.createTextOutput(JSON.stringify({ reply: "A apărut o eroare. Te rog încearcă din nou." }))
.setMimeType(ContentService.MimeType.JSON);
}
}
function doGet() {
return ContentService.createTextOutput("Chatbot proxy activ.");
}
În Apps Script: Deploy, apoi New deployment. Apeși pe rotița de lângă "Select type" și alegi Web app. Apoi completezi trei lucruri:
Apeși Deploy, autorizezi permisiunile (la ecranul de avertizare Google apeși "Advanced" și continui, e normal pentru scripturile proprii) și copiezi Web app URL. Ăsta e proxy-ul tău.
Copiezi codul de mai jos, schimbi o singură linie (PROXY_URL, unde lipești URL-ul de la pasul 4) și îl adaugi în site: bloc HTML custom sau plugin de code snippets, ideal în footer ca să apară peste tot.
<!-- ============================================================ -->
<!-- WIDGET MENTORAI BOT -->
<!-- Lipeste tot acest cod in site (bloc HTML sau code snippet). -->
<!-- Modifica DOAR linia PROXY_URL de mai jos. -->
<!-- Optional: schimba culoarea din --cb-primary. -->
<!-- ============================================================ -->
<div id="cb-chat">
<button id="cb-toggle" aria-label="Deschide chat">Întreabă MentorAI</button>
<div id="cb-window">
<div id="cb-header">
<span>MentorAI Bot</span>
<button id="cb-close" aria-label="Închide">×</button>
</div>
<div id="cb-messages"></div>
<div id="cb-input-row">
<input id="cb-input" type="text" placeholder="Scrie o întrebare..." />
<button id="cb-send">Trimite</button>
</div>
</div>
</div>
<style>
#cb-chat {
--cb-primary: #c0582a; /* culoarea principala, schimb-o cum vrei */
--cb-bg: #ffffff;
--cb-text: #1a1a2e;
}
#cb-chat, #cb-chat * { box-sizing: border-box; font-family: system-ui, -apple-system, sans-serif; }
#cb-chat button { margin: 0; text-transform: none; letter-spacing: normal; }
#cb-toggle {
position: fixed; bottom: 20px; right: 20px;
padding: 14px 20px; border: none; border-radius: 30px;
background: var(--cb-primary); color: #fff; font-size: 15px; font-weight: 600;
cursor: pointer; box-shadow: 0 4px 14px rgba(0,0,0,.25); z-index: 2147483000;
line-height: 1;
}
#cb-window {
position: fixed; bottom: 80px; right: 20px;
width: 360px; max-width: calc(100vw - 40px);
height: 500px; max-height: calc(100vh - 120px);
background: var(--cb-bg); border-radius: 16px;
box-shadow: 0 8px 30px rgba(0,0,0,.2);
display: none; flex-direction: column; overflow: hidden; z-index: 2147483000;
}
#cb-window.open { display: flex; }
#cb-header {
background: var(--cb-primary); color: #fff; padding: 14px 16px; font-weight: 600;
display: flex; align-items: center; justify-content: space-between;
}
#cb-close {
background: none; border: none; color: #fff; font-size: 22px;
cursor: pointer; padding: 0 4px; line-height: 1; opacity: .85;
}
#cb-close:hover { opacity: 1; }
#cb-messages { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.cb-msg { padding: 10px 13px; border-radius: 12px; max-width: 80%; line-height: 1.45; font-size: 14px; white-space: pre-wrap; word-wrap: break-word; }
.cb-user { align-self: flex-end; background: var(--cb-primary); color: #fff; border-bottom-right-radius: 4px; }
.cb-bot { align-self: flex-start; background: #f1f1f4; color: var(--cb-text); border-bottom-left-radius: 4px; }
/* animatia de "scrie acum" */
.cb-typing { display: flex; gap: 5px; align-items: center; padding: 14px 13px; }
.cb-typing span {
width: 7px; height: 7px; border-radius: 50%;
background: #9a9aa8; display: inline-block;
animation: cb-bounce 1.3s infinite ease-in-out;
}
.cb-typing span:nth-child(2) { animation-delay: .18s; }
.cb-typing span:nth-child(3) { animation-delay: .36s; }
@keyframes cb-bounce {
0%, 60%, 100% { transform: translateY(0); opacity: .45; }
30% { transform: translateY(-5px); opacity: 1; }
}
#cb-input-row { display: flex; border-top: 1px solid #eee; padding: 10px; gap: 8px; }
#cb-input { flex: 1; border: 1px solid #ddd; border-radius: 10px; padding: 10px; font-size: 14px; outline: none; }
#cb-send { border: none; background: var(--cb-primary); color: #fff; border-radius: 10px; padding: 0 16px; cursor: pointer; font-size: 14px; font-weight: 600; }
#cb-send:disabled { opacity: .5; cursor: default; }
@media (max-width: 480px) {
#cb-window { width: calc(100vw - 24px); right: 12px; bottom: 76px; height: calc(100vh - 110px); }
#cb-toggle { right: 12px; bottom: 12px; }
}
</style>
<script>
(function () {
// ↓↓↓ SINGURUL lucru pe care il schimbi: URL-ul de la Apps Script ↓↓↓
const PROXY_URL = "LIPESTE_AICI_URL_UL_DE_LA_APPS_SCRIPT";
// mesajul de intampinare
const MESAJ_SALUT = "Salut! Eu sunt MentorAI Bot. Cu ce pot să te ajut?";
const toggle = document.getElementById("cb-toggle");
const win = document.getElementById("cb-window");
const closeBtn = document.getElementById("cb-close");
const messages = document.getElementById("cb-messages");
const input = document.getElementById("cb-input");
const send = document.getElementById("cb-send");
const history = [];
let busy = false;
toggle.addEventListener("click", function () {
win.classList.toggle("open");
if (win.classList.contains("open")) {
if (messages.children.length === 0) addMsg("bot", MESAJ_SALUT);
input.focus();
}
});
closeBtn.addEventListener("click", function () {
win.classList.remove("open");
});
function addMsg(who, text) {
const el = document.createElement("div");
el.className = "cb-msg " + (who === "user" ? "cb-user" : "cb-bot");
el.textContent = text;
messages.appendChild(el);
messages.scrollTop = messages.scrollHeight;
return el;
}
function addTyping() {
const el = document.createElement("div");
el.className = "cb-msg cb-bot cb-typing";
el.innerHTML = "<span></span><span></span><span></span>";
messages.appendChild(el);
messages.scrollTop = messages.scrollHeight;
return el;
}
async function sendMessage() {
if (busy) return;
const text = input.value.trim();
if (!text) return;
busy = true;
send.disabled = true;
addMsg("user", text);
input.value = "";
const typing = addTyping();
try {
const resp = await fetch(PROXY_URL, {
method: "POST",
headers: { "Content-Type": "text/plain;charset=utf-8" },
body: JSON.stringify({ message: text, history: history })
});
const data = await resp.json();
typing.remove();
addMsg("bot", data.reply);
history.push({ role: "user", text: text });
history.push({ role: "model", text: data.reply });
} catch (err) {
typing.remove();
addMsg("bot", "Eroare de conexiune. Te rog încearcă din nou.");
} finally {
busy = false;
send.disabled = false;
input.focus();
}
}
send.addEventListener("click", sendMessage);
input.addEventListener("keydown", function (e) {
if (e.key === "Enter") sendMessage();
});
})();
</script>
Nu anunța botul până nu trece testul ăsta. Fiecare întrebare verifică altă slăbiciune.
Botul viu se mai și corectează. Două lucruri îți vor trebui aproape sigur în primele săptămâni.
Când schimbi knowledge-ul sau instrucțiunile în Apps Script, trebuie republicat: Deploy, apoi Manage deployments, apeși pe creionul de editare, la "Version" alegi New version și dai Deploy. Abia atunci site-ul primește varianta nouă. URL-ul rămâne același, nu trebuie schimbat nimic în widget.
Când observi ceva ce nu îți place, folosește promptul ăsta ca să primești exact instrucțiunea de adăugat la zona 4.
Chatbotul meu funcționează, dar are un comportament pe care vreau să îl corectez. Îți dau mai jos instrucțiunile de sistem actuale și simptomul. Scrie-mi exact ce instrucțiune să adaug sau să modific, sub forma unui rând nou pe care îl pot lipi în lista de reguli. Simptomul (aleg unul sau descriu altul): - Inventează informații care nu sunt în knowledge - Răspunde prea lung și obosește oamenii - Sună robotic și rece - Nu trimite oamenii la email când nu știe răspunsul - Insistă prea mult cu vânzarea - Răspunde și la întrebări care nu au legătură cu proiectul Instrucțiunile mele actuale: [LIPEȘTE AICI blocul INSTRUCTIUNI_SISTEM din scriptul tău]
Ca să nu descoperi limitele pe pielea ta, iată-le de la început:
Botul răspunde la întrebări despre livrare, retururi, mărimi și metode de plată, direct din politica magazinului.
Program, servicii, prețuri, acte necesare, cum se face o programare. Fără să promită diagnostice.
Un bot pe intranetul firmei care răspunde noilor angajați din ghidul intern: proceduri, beneficii, cine ce face.
Rețeta de aici e fundația. De aici se poate crește în mai multe direcții: mutarea proxy-ului pe Cloudflare Workers pentru răspunsuri instant, conectarea la n8n ca botul să scrie întrebările primite într-un Google Sheet, sau schimbarea modelului cu Claude pentru un ton mai fin. Toate păstrează exact aceeași structură în două piese.
Pe astea le discutăm în comunitate, pe cazuri reale.
În MentorAI primești trei call-uri live pe lună, aplicații testate cu verdict onest și o comunitate care răspunde când te blochezi. Exact așa cum a apărut ghidul ăsta: dintr-o întrebare a unui membru.
Descoperă comunitatea MentorAIFolosesc cookies pentru statistici și reclame relevante. Tu alegi ce accepți.