AI Hírek Automata Küldése (AI agenttel)
Íme a javasolt architektúra az MVP (Minimum Viable Product) verzióhoz:
1. A rendszer felépítése
Futatókörnyezet: Google Apps Script (GAS).
Miért: Szervermentes, ingyenes, közvetlen hozzáférése van a Gmailhez, Drive-hoz, és van beépített időzítője (Trigger).
Intelligencia: Gemini API (Google AI Studio).
Miért: A Flash modellek (pl. 1.5 Flash, vagy az érkező 2.0) olcsók/ingyenesek a free tier-ben, és nagy a kontextus ablakuk.
Keresés: Google Custom Search JSON API vagy RSS Aggregátor.
Kritika: A Search API ingyenes kvótája napi 100 kérés. Ez elég, de szűkös. Alternatíva: TechCrunch, The Verge, Wired RSS feedjeinek begyűjtése és feldolgozása a Geminivel (ez stabilabb).
Memória & Tanulás: Google Sheets vagy Google Drive JSON file.
Megoldás: A script nem a kódot írja át, hanem egy JSON fájlt frissít a Drive-on (pl.
memory.json). Ebben tárolja: utolsó témák hash-ét (duplikáció szűrés), felhasználói preferencia súlyozást (hossz, stílus).
2. A megvalósítás lépései
1. Lépés: API Kulcsok beszerzése
Gemini API: Lépj be a
-ba, kérj egy API kulcsot.Google AI Studio Google Search (Opcionális): Ha ragaszkodsz a valós kereséshez, aktiváld a Custom Search API-t a Google Cloud Console-ban.
2. Lépés: A „Szerver” létrehozása (Apps Script)
Nyiss egy új projektet a
script.google.comoldalon.Ez lesz a
main.gs, ami a logikát futtatja.
3. Lépés: A Logika megírása (Vázlat)
4. Lépés: A visszacsatolás (Learning Loop) – A kritikus pont Az e-mail elolvasását technikailag nehéz mérni („pixel tracking” megbízhatatlan). Helyette interakciót kell kérni.
Megoldás: Az e-mail aljára generálj két linket (Apps Script Web App URL paraméterekkel):
[Túl hosszú volt]-> Kattintás -> Script csökkenti alength_preferenceértéket a JSON-ban.[Releváns volt]-> Kattintás -> Script megerősíti a témaköröket.
5. Lépés: Automatizálás
Az Apps Script felületén kattints a Triggers (Óra ikon) menüre.
Adj hozzá új triggert:
mainAgentJobfuttatása ->Time-driven->Day timer->8am to 9am.
Kritika és Kockázatok
Search vs. Context Window: A Google Search API találatai csak címek és snippetek. A teljes cikkek tartalmának elemzéséhez a találatokra rá kellene kattintani (crawling), amit a GAS
UrlFetchAppkorlátozottan tud (időtúllépés, JavaScriptes oldalak).Javaslat: Kezdd RSS feedekkel. Azok tartalmazzák a lead-et vagy a teljes szöveget, amit a Gemini sokkal jobban tud feldolgozni hiba nélkül.
Öntanulás korlátai: A rendszer nem fogja "érteni", hogy elolvastad-e, hacsak nem kattintasz. A passzív tanulás e-mailben nem működik megbízhatóan.
Token költség: Ha túl sok hírt küldesz be a Gemininek minden reggel, gyorsan elérheted a Rate Limit-et (RPM - Request Per Minute). Kezeld a hibákat (try-catch block).
Hogyan kezdj neki?
Ne a teljes autonóm rendszert építsd meg egyszerre.
Írd meg a scriptet, ami csak egy statikus szöveget (pl. "Hello World") elküld emailben, amikor lefuttatod.
Kösd be a Gemini API-t, hogy a statikus szöveg helyett egy viccet generáljon.
Cseréld le a viccet RSS feed tartalomra.
Implementáld a memória JSON-t Drive-on.
Módosítsuk a kódot úgy, hogy soha ne küldjön kétszer ugyanarról a hírről?
(Ez teszi majd emberivé, mert úgy tűnik, mintha követné az eseményeket).
// --- KONFIGURÁCIÓ ---
// A kulcsot a Project Settings -> Script Properties menüben tárold 'GEMINI_API_KEY' néven!
const MODEL_NAME = 'gemini-1.5-flash';
const MEMORY_FILE_ID = 'IDE_ÍRD_A_DRIVE_FILE_ID-T'; // A te JSON fájl ID-d
const MAX_MEMORY_ITEMS = 50; // Ennyi régi cikkre emlékezzen vissza
// --- FŐ PROGRAM ---
function mainAgentJob() {
try {
// 1. Memória betöltése
var memory = loadMemory();
Logger.log("Memória betöltve. Eddig ismert cikkek száma: " + memory.history.length);
// 2. Hírek lekérése és PARSOLÁSA
var allNews = fetchAndParseRSS();
Logger.log("Összes hír a feedben: " + allNews.length);
// 3. Szűrés: Csak azokat tartsuk meg, amik nincsenek a memóriában
var newArticles = allNews.filter(function(article) {
return memory.history.indexOf(article.link) === -1;
});
Logger.log("Ebből ténylegesen új hír: " + newArticles.length);
// HA NINCS ÚJ HÍR, LEÁLLUNK
if (newArticles.length === 0) {
Logger.log("Nincs új tartalom mára. Pihenés.");
return;
}
// 4. Gondolkodás (Gemini hívás) - Csak az újakat küldjük!
// JSON stringgé alakítjuk az új cikkeket, hogy a Gemini könnyen értse
var promptData = newArticles.map(function(a) {
return "- Cím: " + a.title + "\n Leírás: " + a.description;
}).join("\n\n");
var prompt = `
Te egy AI hírügynök vagy. Ma ${newArticles.length} új cikket találtam, amiről még nem beszéltünk.
Feladat: Válaszd ki a legfontosabbakat, és készíts belőlük egy összefoglalót.
Ne csak fordíts, hanem elemezz: miért fontos ez?
Formátum: HTML (használj <h2>, <ul>, <li>, <b>).
Stílus: Tömör, lényegretörő.
Hírek:
${promptData}
`;
var analysis = callGemini(prompt);
Logger.log("Gemini elemzés kész.");
// 5. E-mail küldése
var emailAddress = Session.getActiveUser().getEmail();
GmailApp.sendEmail(emailAddress, "🤖 Napi AI Frissítés (" + newArticles.length + " új)", "", {
htmlBody: analysis + generateFeedbackLinks()
});
Logger.log("E-mail elküldve.");
// 6. Memória frissítése (Hozzáadjuk az újakat)
newArticles.forEach(function(a) {
memory.history.push(a.link);
});
// Karbantartás: Ne hízzon a végtelenségig a fájl, tartsuk meg csak az utolsó 50-et
if (memory.history.length > MAX_MEMORY_ITEMS) {
memory.history = memory.history.slice(memory.history.length - MAX_MEMORY_ITEMS);
}
updateMemory(memory);
} catch (e) {
Logger.log("KRITIKUS HIBA: " + e.toString());
}
}
// --- ÚJ HÍRLEKÉRŐ (XML PARSER) ---
function fetchAndParseRSS() {
var url = 'https://techcrunch.com/category/artificial-intelligence/feed/';
var xml = UrlFetchApp.fetch(url).getContentText();
var document = XmlService.parse(xml);
var root = document.getRootElement();
// RSS struktúra bejárása: channel -> item
var channel = root.getChild('channel');
var items = channel.getChildren('item');
var newsList = [];
// Csak az első 10-et nézzük meg, felesleges 50-et feldolgozni
for (var i = 0; i < Math.min(items.length, 10); i++) {
var item = items[i];
var title = item.getChildText('title');
var link = item.getChildText('link');
var description = item.getChildText('description');
// HTML tagek eltávolítása a leírásból (clean up)
if (description) {
description = description.replace(/<[^>]*>/g, '').substring(0, 300) + "...";
}
newsList.push({
title: title,
link: link,
description: description
});
}
return newsList;
}
// --- EGYÉB SEGÉDFÜGGVÉNYEK ---
function callGemini(prompt) {
var key = PropertiesService.getScriptProperties().getProperty('GEMINI_API_KEY');
if (!key) throw new Error("Nincs beállítva a GEMINI_API_KEY a Script Properties-ben!");
var url = `https://generativelanguage.googleapis.com/v1beta/models/${MODEL_NAME}:generateContent?key=${key}`;
var payload = { contents: [{ parts: [{ text: prompt }] }] };
var options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
var response = UrlFetchApp.fetch(url, options);
var json = JSON.parse(response.getContentText());
if (json.error) throw new Error(json.error.message);
return json.candidates[0].content.parts[0].text;
}
function generateFeedbackLinks() {
return `<br><hr><small>🤖 AI Memory System v2.0 | Auto-learning enabled</small>`;
}
// --- MEMÓRIA ---
function loadMemory() {
try {
var file = DriveApp.getFileById(MEMORY_FILE_ID);
var content = file.getBlob().getDataAsString();
if (!content || content.trim() === "") return initializeMemory();
var mem = JSON.parse(content);
// Biztosítjuk, hogy a history tömb létezzen (régi json esetén)
if (!mem.history) mem.history = [];
return mem;
} catch (e) {
return initializeMemory();
}
}
function initializeMemory() {
return { lastRun: null, history: [] };
}
function updateMemory(memory) {
try {
memory.lastRun = new Date().toString();
DriveApp.getFileById(MEMORY_FILE_ID).setContent(JSON.stringify(memory, null, 2));
} catch (e) {
Logger.log("Mentési hiba: " + e.toString());
}
}
Mit csinál ez a kód másképp?
Szűrés: Az XML Parse segítségével kinyeri a linkeket. Ha a link már benne van a memory.json-ban, akkor azt a cikket nem küldi el a Gemininek.
Költséghatékonyság: Mivel a Gemini csak az új cikkeket kapja meg, sokkal kevesebb tokent használsz, és a válasz is relevánsabb lesz.
Memória tisztítás: A MAX_MEMORY_ITEMS = 50 sor biztosítja, hogy a JSON fájl ne nőjön túl nagyra (a legrégebbi híreket elfelejti).
Tipp az első futtatáshoz:
Amikor először futtatod ezt az új kódot, minden hír újnak fog számítani, ezért kapsz majd egy e-mailt. Ha rögtön utána futtatod újra, a Logban azt kell látnod: "Nincs új tartalom mára. Pihenés.", és nem kapsz e-mailt. Ez jelzi, hogy az ügynököd "emlékszik".
Megjegyzések
Megjegyzés küldése