Einen Morning-Briefing-Agenten mit der News Search API bauen

Gründer, PM und Analystinnen wollen morgens um acht dasselbe: einen sauberen Digest dessen, was über Nacht passiert ist. Mit einer News-Search-API, einem LLM und einem Cronjob baust du das an einem Nachmittag.
Auf einen Blick
- •Architektur: cron → News Search → URL Extract der Top-Storys → LLM-Zusammenfassung → Slack-Post.
- •Frische über <code>start_date</code> = heute − 1, Region über <code>country_code</code>.
- •Briefings parallel pro Thema; das LLM mergt und entdupliziert.
- •Gesamtkosten ≈ 15 Credits/Thema/Tag plus LLM-Tokens. Ein 5-Themen-Briefing ist < $0.10/Tag zum Listenpreis.
Wie ein nützliches Briefing aussieht
Ein Morning-Briefing-Agent muss eine Frage beantworten: 'Was hat sich über Nacht geändert, das ich wissen muss?' Eine Schlagzeilenliste reicht nicht — das ist RSS und wird in einer Woche stummgeschaltet. Was übrig bleibt, ist ein 5-Punkt-Digest mit Links, nach Thema gegliedert, in der Stimme des Lesers.
Das zerlegt sich in eine kleine Pipeline:
- Holen — aktuelle Nachrichten zu N Themen via News Search API.
- Extrahieren — Bodies der Storys, die das LLM zitieren möchte, via URL Extract API.
- Zusammenfassen + Clustern — LLM deiner Wahl.
- Posten — Slack / E-Mail / Notion.
- Planen — Cron mit Vercel Cron, GitHub Actions, n8n, AWS EventBridge.
Schritt 1: Themen wählen
3–6 Themen reichen. Ein 12-Themen-Briefing wird weggescrollt. Beispiele:
- B2B-SaaS-Gründer: 'AI-Funding-Runden', 'OpenAI/Anthropic-News', 'Wettbewerberbewegungen'.
- Finanzanalyst: 'FOMC und Treasury', 'Halbleiter-Lieferkette', 'spezifische Tickers'.
- Healthcare-PM: 'FDA-Zulassungen', 'klinische Studien-Readouts', 'Erstattungsänderungen'.
Schritt 2: Rohsignal holen
Pro Thema einmal News Search parallel aufrufen. Frische via start_date:
from datetime import date, timedelta
import asyncio, aiohttp
KEY = "pk_yourkey"
TOPICS = [
"AI agent infrastructure funding",
"OpenAI Anthropic Google new releases",
"RAG and LLM tool calling research",
]
async def fetch_topic(session, q):
yesterday = (date.today() - timedelta(days=1)).isoformat()
async with session.post(
"https://www.apipick.com/api/search/news",
headers={"x-api-key": KEY},
json={"query": q, "start_date": yesterday},
) as r:
return q, await r.json()
async def fetch_all():
async with aiohttp.ClientSession() as s:
return await asyncio.gather(*[fetch_topic(s, q) for q in TOPICS])Jeder Aufruf liefert bis zu 5 ranked Schlagzeilen (max 10 mit num_results). Ein 3-Themen-Briefing kostet 3 × 15 = 45 Credits/Tag, $0.045/Tag bei $5/5.000-Listenpreis. Die News-API ist nicht der Kostentreiber, das ist das LLM.
Schritt 3: Selektiv Bodies extrahieren
Du brauchst nicht jeden Volltext — nur die, die das Modell ausführlich zitieren will. Heuristik: Top 2 pro Thema. Mit API Pick ist das ein einzelner Batch:
import requests
urls = [r["url"] for topic, payload in results for r in payload["results"][:2]]
extracted = requests.post(
"https://www.apipick.com/api/extract",
headers={"x-api-key": KEY},
json={"urls": urls, "extract_effort": "auto"},
).json()Bei 2 Credits pro URL fügt der Extract-Schritt für ein 3-Themen-Briefing ~ 12 Credits/Tag hinzu.
Schritt 4: Der Zusammenfassungs-Prompt
Der Prompt definiert die Stimme des Briefings. Ein Startpunkt:
You are an assistant that writes a morning briefing in <Sarah's> voice:
direct, no fluff, no marketing language.
Input: a JSON list of {topic, headlines, extracted_bodies}.
Output rules:
- 1 short paragraph per topic, max 60 words.
- Each paragraph ends with up to 3 inline source links.
- If a topic has fewer than 2 substantive stories overnight, omit it.
- If the entire briefing has fewer than 2 substantive topics, output the
literal token SKIP and nothing else.
- Never editorialise. Quote facts and figures verbatim from the sources.
Output format: Slack-flavoured markdown.Die Regel 'SKIP bei zu wenig Signal' hat den höchsten ROI — und ist der Grund, warum dein Briefing nicht stummgeschaltet wird.
Schritt 5: Posten und Planen
Das gesamte Python-Skript bleibt unter 80 Zeilen. Slack-Post:
if briefing.strip() == "SKIP":
return
requests.post(
SLACK_WEBHOOK_URL,
json={"text": briefing, "username": "Morning Briefing", "icon_emoji": ":sunrise:"},
)Planen mit Vercel Cron (in vercel.json), GitHub Actions, AWS EventBridge oder n8n. 7:45 deiner Zeitzone laufen lassen — Ziel: das Briefing wartet, wenn du um 8 am Schreibtisch sitzt.
Wer lieber n8n nutzt
- Schedule trigger — täglich, 7:45 User-TZ.
- HTTP-Request-Nodes (eines pro Thema), POST
/api/search/newsmitstart_date= gestern. - Merge kombiniert die Themenresultate.
- HTTP-Request ruft
/api/extractmit den Top-URLs. - OpenAI/Anthropic-Node führt den Zusammenfassungs-Prompt aus.
- If-Node prüft, dass das Output kein SKIP ist.
- Slack-Node postet das Briefing.
Worauf in Produktion zu achten ist
- Themen-Drift. 'AI agents' wird nach 6 Monaten zu breit — Index wächst, dein Briefing soll spezifisch bleiben. Queries quartalsweise nachschärfen.
- Tagesübergreifende Wiederholung. Modell die URLs des Vortages mit 'do not re-cover stories from this list' mitgeben.
- Stille Wochenenden. SKIP-Regel kümmert sich darum; den Tagesrhythmus nicht ans Briefing koppeln.
Iterieren, nicht abschließen
Lies das Briefing eine Woche lang jeden Morgen. Notier, wo das Modell halluzinierte, falsch kategorisierte oder etwas verpasste. Prompt anpassen. Nach einer Woche wird das Briefing zur Gewohnheit — und du hast einen funktionierenden Agenten in ~80 Zeilen Code und drei API-Calls gebaut.
Häufig gestellte Fragen
Warum nicht einfach Google News oder einen RSS-Aggregator?
Beides funktioniert — und überlässt dir den langweiligen Teil: Clustering, Dedupe, Zusammenfassung, das eigentliche Briefing schreiben. Ein Agent erledigt das per LLM. RSS gibt dir Schlagzeilen; ein Agent gibt dir einen Absatz, der sagt, was wichtig ist, mit Quellenlinks.
Wie aktuell ist die News Search API?
Indexiert große Outlets nahezu in Echtzeit. Für ein Briefing um 8 Uhr morgens, das die letzten 24 Stunden abdeckt, start_date auf gestern setzen. Stündliche Bots auf heute setzen und gegen den letzten Lauf entduplizieren.
Was, wenn das Briefing wenig zu sagen hat?
In den Prompt schreiben: 'If fewer than 3 substantive stories changed overnight, return SKIP.' Der Cronjob respektiert SKIP und postet kein schwaches Briefing. Briefing-Müdigkeit ist der schnellste Weg zum stummgeschalteten Slack-Channel.
Geht das auch ohne n8n?
Ja. Derselbe Flow läuft als 30-Zeilen-Python-Skript per Cron. n8n erleichtert visuelles Debugging und Slack-Integration, ist aber nicht nötig.
Wie verhindere ich, dass dieselbe Story themenübergreifend doppelt zusammengefasst wird?
Modell die URLs früherer Queries im selben Lauf mit der Anweisung 'do not re-mention any URL already covered' übergeben — oder eine multi-thematische Suche und Modell partitioniert. Beides funktioniert; zweiteres ist günstiger.
APIs in diesem Artikel
Sarah Choy ist CEO von API Pick. Sie schreibt über produktionsreife APIs für KI-Agenten und LLM-Workflows.