Information overload
Information overload is in de moderne tijd een serieus probleem geworden. Een van de domeinen waar information overload duidelijk aanwezig is, is nieuws. Aan de ene kant wil ik graag up-to-date blijven over wat er in de wereld gebeurt, vooral als het mij raakt. Aan de andere kant merk ik vaak dat ik me afvraag of bepaalde artikelen wel relevant zijn voor mij, of dat ik eigenlijk mijn tijd verspil aan eindeloze ruis.
Het filteren van die ruis is relatief eenvoudig met tools zoals Large Language Models. In plaats van elke ochtend handmatig door talloze bronnen te scannen, kun je LLM’s inzetten om nieuwsartikelen te filteren op basis van expliciet beschreven interesses en professionele behoeften.
In dit blog laat ik een oplossing zien die ruis filtert uit een IT-gerelateerde RSS nieuwsfeed, waarbij ik de LLM in feite decision making laat doen: is een artikel het lezen waard of niet? Let op: mijn evaluatie gaat niet zozeer over de specifieke toepassing (ruis filteren uit een IT-newsfeed), maar vooral over het concept: het inzetten van een LLM voor een niet-kritische beslissing. Dat concept is goed te vertalen naar veel andere domeinen, en ik hoop dat dit je inspireert om het toe te passen op je persoonlijke of zakelijke behoeften.
Het script
Laten we beginnen met het interessante deel: het programma zelf. Ik heb het script in Python geschreven en het ziet er zo uit:
#!/usr/bin/env python3
from datetime import datetime, timedelta
from email.utils import parsedate_to_datetime
from openai import OpenAI
from os import getenv
import json
import requests
import subprocess
import xml.etree.ElementTree as ET
FEED_URL = "https://www.security.nl/rss/headlines.xml"
MODEL = "Claude-Haiku-3.5"
with open("system_prompt.txt", "r") as f:
SYSTEM_PROMPT = f.read()
def get_feed():
"""Get RSS feed"""
response = requests.get(FEED_URL)
response.raise_for_status()
return response.content
def parse(feed_content: bytes):
"""Parse RRS feed"""
root = ET.fromstring(feed_content)
channel = root.find("channel")
title = channel.findtext("title", default="(untitled)")
link = channel.findtext("link", default="")
description = channel.findtext("description", default="")
pub_date = channel.findtext("pubDate")
last_build = channel.findtext("lastBuildDate")
return {
"channel": {
"title": title,
"link": link,
"description": description,
"pubDate": pub_date,
"lastBuildDate": last_build,
},
"items": [
{
"title": item.findtext("title", default="(no title)").strip(),
"link": item.findtext("link", default="").strip(),
"description": item.findtext("description", default="").strip(),
"pubDate": item.findtext("pubDate", default="").strip(),
}
for item in channel.findall("item")
],
}
def extract_recent_items(feed, days_back: int = 0):
"""Check if the publication date is within the specified number of days back from today."""
recent_items = []
for item in feed["items"]:
dt = parsedate_to_datetime(item["pubDate"])
now = datetime.now()
today = now.date()
cutoff_date = today - timedelta(days=days_back)
item_date = dt.date()
if item_date >= cutoff_date:
recent_items.append(item)
return recent_items
def evaluate(items, filter=True):
"""Evaluate all items"""
api_key = getenv("POE_API_KEY")
client = OpenAI(api_key=api_key, base_url=getenv("POE_BASEURL"))
evaluations = []
for i, it in enumerate(items):
title = it["title"]
completion = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": title},
],
)
out = completion.choices[0].message.content
data = json.loads(out)
data["title"] = title
data["link"] = it["link"]
evaluations.append(data)
return evaluations
return evaluations
def notify(results):
"""Notify about all results that are noteworthy"""
for r in results:
if r["decision"] == "yes":
command = [
"/usr/local/bin/telegram.py",
f"=== {r['title']} ===\n\n{r['reasoning']}\n\n{r['link']}==========="
"".strip(),
]
subprocess.run(command, check=True, text=True, capture_output=True)
def main():
feed_content = get_feed()
items = parse(feed_content)
recent_items = extract_recent_items(items)
results = evaluate(recent_items)
notify(results)
if __name__ == "__main__":
main()
Copy code
De workflow van het script is als volgt:
- Haal een voorbeeld RSS newsfeed op; ik gebruik www.security.nl, een Nederlandse site die IT-gerelateerd nieuws publiceert
- Parse de feed om alle nieuwsitems eruit te halen.
- Filter alleen de items van vandaag.
- Evalueer de items met een LLM om te bepalen of ze belangrijk zijn.
- Stuur een notificatie over het nieuwsartikel als de LLM bepaalt dat het interessant is.
Elke stap heeft een eigen functie, en het is de main() functie die al deze functies aanroept.
Runtime!
Nieuwsitems ophalen
Het script start met het ophalen van de RSS feed via de functie get_feed(). Die stuurt een HTTP request naar het RSS endpoint van de site die ik gebruik en geeft de response content terug.
Daarna parse() de feed content en worden alle feed-items eruit gehaald. Een enkel nieuwsitem (een item in de items[“items”] lijst) ziet er bijvoorbeeld zo uit:
{
"title": "Ziekenhuis ontslaat medewerkers wegens ongeoorloofd inzien patiëntendossiers",
"link": "https://www.security.nl/posting/908552/Ziekenhuis+ontslaat+medewerkers+wegens+ongeoorloofd+inzien+pati%C3%ABntendossiers?channel=rss",
"description": "Het Albert Schweitzer Ziekenhuis heeft twee medewerkers ontslagen die elfhonderd patiëntendossiers ongeoorloofd inzagen. Het ...",
"pubDate": "Thu, 09 Oct 2025 17:10:37 +0200"
}
Copy code
Om alleen de items van vandaag te filteren, gaat de feed door extract_recent_items(), die standaard alleen items van de laatste dag teruggeeft. Dit doe ik zodat ik het script dagelijks kan schedulen zonder artikelen dubbel te zien. Als je dit verder wilt uitbreiden, kun je state bijhouden (bijvoorbeeld in een database) om te registreren welke items al zijn afgehandeld. Daarmee kun je het script vaker dan één keer per dag draaien.
Modelkeuze, system prompt en het versturen van het bericht
Met de items van vandaag gefilterd, kan een LLM evalueren of het artikel de moeite waard is om te lezen, op basis van een system prompt (die ik hieronder laat zien). Het filteren gebeurt in de functie evaluate(). Ik gebruik www.poe.com voor interactie met LLM’s. Poe is een bedrijf van Quora dat recent een OpenAI-compatibele API heeft geïntroduceerd. Daardoor kan ik de OpenAI Python SDK gebruiken om via Poe met LLM’s te praten.
Zoals je aan het begin van de code ziet, gebruik ik Claude Haiku 3.5. Deze keuze is gebaseerd op kosten en energie-efficiëntie. Claude Haiku is een kleiner model met minder parameters. Het was dus goedkoper om te trainen, en inference is ook goedkoper, in termen van energie én geld. De trade-off is capability, maar omdat we hier geen enorme complexiteit nodig hebben, is dit ruim voldoende.
De system prompt die gebruikt wordt voor filtering door de LLM wordt uit een lokaal bestand gelezen (system_prompt.txt). Hieronder staat een Engelse vertaling van de prompt (ik heb hem zelf in het Nederlands geïmplementeerd omdat ik een Nederlandse nieuwsbron gebruik en mijn resultaten ook in het Nederlands wilde):
You are an IT news filter for a Linux consultant. Assess news headlines for relevance to Cloud consultancy work.
CONSULTANT PROFILE:
- Cloud consultant
- Works with: Ansible, Terraform, HashiCorp Vault, Python, AI/LLMs, Linux distributions, Kubernetes
- Has limited time - only let critical items through
FILTER CRITERIA:
YES (let through):
- Security issues in the above technologies or Linux
- Breaking changes/major releases of the above tools
- Major cloud/infrastructure outages
- Enterprise Linux regulations/compliance
- Zero-days, CVEs, critical patches
NO (filter out):
- Consumer tech, gaming, mobile apps
- Marketing announcements, tutorials, opinions
- Minor updates, conferences, startup news
- Regional news that doesn't have major impact on the IT industry
- Non-Dutch national news that doesn't have major impact on the IT industry
WHEN IN DOUBT: Filter out (be conservative)
OUTPUT:
Always return JSON with this structure:
{
"decision": "yes" | "no",
"reasoning": "brief explanation why relevant/not relevant for Linux consultant",
"other": "optional additional context if relevant"
}
No additional text is possible outside this structure. Do not provide explanations outside the JSON.
Focus on: Would this directly impact the consultant's work or clients?
Copy code
Deze prompt is bovendien grotendeels AI-generated. Het enige dat ik heb gedaan is wat specifieke technologieën toegevoegd waar ik vaak mee werk, en de regel toegevoegd dat het model nooit uitleg buiten de JSON mag geve, dat begon het te doen tijdens het testen van de prompt. De raw output van de LLM voor één nieuwsitem ziet er bijvoorbeeld zo uit:
{
"decision": "no",
"reasoning": "Geen directe technische of IT infrastructuur relevantie voor Linux consultancy werk",
"other": "Privacy incident, meer geschikt voor HR of compliance afdelingen"
}
Copy code
In dit format kan downstream code eenvoudig handelen op basis van de beslissingen van de LLM.
Notificaties
Tot slot: om daadwerkelijk notificaties te krijgen over interessante artikelen, gaan de gefilterde items door de functie notify(). Deze gebruikt een lokale tool die ik zelf heb geschreven om notificaties via Telegram te sturen. Deze tool behandel ik hier niet, maar ik laat hem wel zien om het script compleet te maken. Je kunt dit uiteraard vervangen door elke andere notificatiemethode.
Dit concept vertalen naar andere toepassingen
Het is niet moeilijk te zien hoe deze technieken zich vertalen naar business-applicaties. Retailers gebruiken LLM’s (en andere vormen van Natural Language Processing) bijvoorbeeld voor inventory management decisions, analyse van customer reviews en meer. In de juridische sector worden LLM’s gebruikt voor contractanalyse en legal research. Trading en hedge funds gebruiken LLMs zelfs om trading strategies en risk assessments te ondersteunen.
Conclusie
Bovenstaande is een manier om LLM’s in te zetten voor een niet-kritische beslissing. Door een LLM beslissingen te laten nemen op basis van user input (de system prompt), bespaar je veel tijd en moeite en filter je ruis uit een nieuwsfeed. Het is een praktisch voorbeeld, maar de onderliggende ideeën zijn goed toepasbaar in veel andere domeinen.
Ben je benieuwd hoe LLM’s, of AI in het algemeen, kunnen helpen bij jouw persoonlijke of zakelijke behoeften? Of heeft dit je geïnspireerd om LLM’s te implementeren voor een persoonlijke of professionele use case? Neem dan vooral contact met ons op, we horen graag van je.