Sådan oprettes en nyhedsopsummeringspipeline med GPT
At kalde client.responses.create én gang er ligetil. Håndtering af 1,000 artikler om dagen betyder også at styre omkostninger, faktatjekke og undgå opsummeringer baseret kun på en overskrift. Denne guide forklarer, hvilken arbejdsgang der skal bruges, hvordan man estimerer omkostninger, hvordan man tjekker opsummeringer mod artiklerne, hvornår man skal cache prompts, og hvornår API's eksisterende opsummering gør GPT unødvendig.
Et GPT nyhedsoversættelses-pipeline er et produktionssystem, der optager nyhedsartikler (rå eller via API), dirigerer hver artikel gennem en af fire LangChain oversættelses-strategier (stuff, map_reduce, refine eller en brugerdefineret LCEL-kæde) baseret på token-antal, efterbehandler outputtet gennem en faktualitets-grundings-kontrol og gemmer resultatet med metadata til downstream-brug såsom sammendrag, advarsler eller lydbriefer. I modsætning til generiske tutorials til sammenfatning af store dokumenter, der leverer én kæde og går videre, skal nyhedsoversætning håndtere korte artikler i bulk plus lejlighedsvise lange features, skal beskytte mod hallucination på enhedsniveau, fordi forkerte fakta i nyheder er omdømmeincidenter, og skal konkurrere på omkostninger mod en baseline, der er gratis — den ekstraktive oversætning, som dit nyhedsmedie API allerede returnerer.
Hvad du vil bygge
En seks-delt produktionspipeline:
- Et basis GPT-kald, der opsummerer én artikel fra APITube
- En kædetype-router, der vælger
stuff/map_reduce/refine/ brugerdefineret LCEL baseret på artikellængde - En månedlig omkostningsberegner, der sammenligner tre OpenAI model-niveauer ved nyhedsvolumen
- En enheds-jordingskontrol, der markerer hallucinerende fakta før udgivelse
- Prompt-caching, der reducerer inputomkostninger ~70% på et statisk systemprompt
- En komplet pipeline: APITube → dedupe → chain → ground → store
Oplysning
Vi er APITube. Vores /v1/news/everything endepunkt leverer allerede en ekstraktiv summary (nøglesætninger med sentiment pr. sætning) pr. artikel – for mange anvendelsestilfælde er det det rigtige svar, og du springer GPT helt over. Vi skrev stadig denne guide, fordi abstraktiv GPT-summarisering retfærdiggør sin pris for digests, lyd-briefings og syntese af flere artikler. Vi vil vise linjen mellem at bygge og købe.
Forudsætninger
- Python 3.10+
openai>=1.40,langchain>=0.3,tiktoken,requests- En OpenAI API-nøgle med aktiveret fakturering
- En APITube-nøgle (gratis niveau: 30 anmodninger/30 min — nok til prototyping)
- Kendskab til chat-kompletteringer og grundlæggende LangChain-primitiver
Installer:
pip install openai langchain langchain-openai tiktoken requests
export OPENAI_API_KEY=sk-...
export APITUBE_KEY=...
Trin 1 — Baseline: opsummer én artikel fra APITube
Hent en artikel, opsummer, tæl tokens. Dette er det opkald, alle andre sektioner optimerer omkring.
import os, requests
from openai import OpenAI
import tiktoken
openai_client = OpenAI()
enc = tiktoken.encoding_for_model("gpt-4o-mini")
def get_article(query):
res = requests.get(
"https://api.apitube.io/v1/news/everything",
params={"title": query, "language.code": "en", "per_page": 1},
headers={"X-API-Key": os.environ["APITUBE_KEY"]},
)
res.raise_for_status()
return res.json()["results"][0]
SYSTEM = (
"You are a news summarizer. Produce a 3-sentence summary that includes only "
"facts present in the article. Do not infer beyond the text."
)
def summarize(article, model="gpt-4o-mini"):
body = article.get("body") or article["description"]
res = openai_client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": SYSTEM},
{"role": "user", "content": body},
],
max_tokens=200,
)
return res.choices[0].message.content, len(enc.encode(body))
article = get_article("election")
summary, in_tokens = summarize(article)
print(in_tokens, "input tokens —", summary)
APITube's responsstruktur er { status, results[], has_next_pages, page, request_id }. Hvert resultat har body (fuld tekst), description (kort uddrag), summary (ekstraktiv — vi vender tilbage til dette), keywords, is_duplicate og words_count. Cache body, hvis du vil gen-opsummere.
Hvordan opsummerer du nyhedsartikler med GPT?
For at opsummere nyhedsartikler med GPT, send artikelteksten til et chat-completions-endepunkt med en snævert defineret systemprompt, der begrænser modellen til fakta i kilden ("brug kun fakta, der findes i artiklen; inferer ikke"), sæt en lav max_tokens for at begrænse output, og efterbehandl for entitetsgrundlag for at fange hallucineret navne, tal eller datoer. For mere end ca. 12K tokens input, skift fra et enkelt kald (stuff kæde) til map_reduce eller en brugerdefineret LCEL kæde.
Trin 2 — Vælg en kædetype efter token-antal
LangChain leverer fire kædestrategier, og de fleste tutorials bruger som standard én. Det rigtige valg afhænger af inputlængde, latenstidbudget og om du ønsker inkrementel output.
| Kæde | Maksimal input (tokens) | Kald pr. artikel | Brug når |
|---|---|---|---|
stuff | ≤12,000 (passer til moderne kontekst) | 1 | Én artikel ad gangen, eller en lille pakke. Simpelt, billigt, laveste latenstid. |
map_reduce | 12,000 – ~300,000 | 1 pr. chunk + 1 reducer | Multi-artikel batch, lange funktioner, paralleliserbar, intet krav om streaming. |
refine | streaming/inkrementel | 1 pr. chunk, sekventiel | Kontinuerlig indtagelse af relaterede artikler (e.g., en udviklende historie), ønsker progressivt bedre opsummering. |
Brugerdefineret LCEL (prompt | model | parser) | enhver | Du har brug for kontrol over tokenisering, genforsøg, struktureret output eller logning pr. trin. |
De fleste nyhedspipelines bør som standard bruge stuff. Moderne chatmodeller accepterer hundredtusindvis af input-tokens, og en enkelt nyhedsartikel overstiger sjældent 4,000 tokens. map_reduce er kun kompleksiteten værd, når du opsummerer et multi-artikel-digest i ét kald.
from langchain_openai import ChatOpenAI
from langchain.chains.summarize import load_summarize_chain
from langchain.docstore.document import Document
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
def pick_chain(token_count, llm):
if token_count <= 12_000:
prompt = ChatPromptTemplate.from_messages([("system", SYSTEM), ("user", "{text}")])
return prompt | llm | StrOutputParser()
return load_summarize_chain(llm, chain_type="map_reduce")
llm = ChatOpenAI(model="gpt-4o-mini", max_tokens=200)
chain = pick_chain(in_tokens, llm)
result = chain.invoke({"text": article["body"]})
Hvad er den bedste LangChain kædetype til summarisering?
Den bedste LangChain kædetype til opsummering afhænger af inputlængden: brug stuff til input op til ~12,000 tokens (en artikel eller en lille pakke), map_reduce til 12K–500K tokens (multi-artikel digests), refine til inkrementel/streaming-indtagelse af en udviklende historie, og en brugerdefineret LCEL kæde (prompt | model | parser), når du har brug for fin kontrol over genforsøg, struktureret output eller observerbarhed pr. trin.
Trin 3 — Omkostningsberegning ved nyhedsvolumen
Priser som af 2026 — verificer på openai.com før forpligtelse, da OpenAI ofte opdaterer prislisten. Tallene nedenfor er vejledende størrelsesordener.
Antag en gennemsnitlig artikel er 800 input tokens og resuméet er 150 output tokens. For 1,000 artikler pr. dag på tværs af tre modelniveauer:
| Niveau | Modelklasse | Ca. input $/1M | Ca. output $/1M | Daglig inputomkostning | Daglig outputomkostning | Månedlig regning (1K/dag) | Månedlig regning (10K/dag) |
|---|---|---|---|---|---|---|---|
| Billig | GPT-4o-mini klasse | $0.15 | $0.60 | $0.12 | $0.09 | ~$6 | ~$60 |
| Mellem | GPT-4o klasse | $2.50 | $10.00 | $2.00 | $1.50 | ~$105 | ~$1,050 |
| Premium | GPT-4.1 / o-klasse | $5–15 | $15–60 | $4.00–12.00 | $2.25–9.00 | ~$190–630 | ~$1,900–6,300 |
Formel:
monthly_cost = articles_per_day × 30 × (
avg_input_tokens / 1_000_000 × input_price +
avg_output_tokens / 1_000_000 × output_price
)
Tre takeaways. Først er det billige niveau næsten gratis ved 1,000 artikler/dag — start der og eskaler kun, når kvaliteten kræver det. For det andet dominerer output-tokens omkostningerne på premium-niveauer; stram max_tokens til 150–200 for overskriftslignende opsummeringer. For det tredje skalerer omkostningerne lineært med artikelvolumen, men multiplikativt med modelniveau — en 17× omkostningsstigning fra billig til mellem er sjældent værd kvalitetsforbedringen for korte nyhedsopsummeringer; reserver premium til syntese af flere artikler.
Hvad koster det at opsummere nyheder med GPT?
Opsummering af nyheder med GPT koster ca. $6/måned ved 1,000 artikler/dag på en billig-model (GPT-4o-mini klasse), $105/måned på en mellem-model (GPT-4o klasse) og $190–630/måned på en premium-model — ved gennemsnitlige input på 800 tokens og output på 150 tokens pr. artikel. Verificér den aktuelle pris på openai.com, da OpenAI opdaterer satserne regelmæssigt.
Trin 4 — Hallucinations-grundlag for nyheder
Nyhedssummering fejler anderledes end generel dokumentsummering: et forkert firmanavn, et fejlagtigt tilskrevet citat eller et opdigtet dollarbeløb bliver en offentlig fejl i det øjeblik, din opsummering sendes. Det billige forsvar er entitets-grounding — ekstraher entiteter (PERSON, ORG, MONEY, DATE, GPE) fra input og fra output, og flag enhver output-entitet, der ikke findes i input.
import spacy
nlp = spacy.load("en_core_web_sm")
GROUND_LABELS = {"PERSON", "ORG", "MONEY", "DATE", "GPE", "PERCENT"}
def entities(text):
return {(e.text, e.label_) for e in nlp(text).ents if e.label_ in GROUND_LABELS}
def grounding_check(input_text, summary_text):
in_ents = entities(input_text)
out_ents = entities(summary_text)
in_strings = {e[0].lower() for e in in_ents}
hallucinated = [e for e in out_ents if e[0].lower() not in in_strings]
return hallucinated
bad = grounding_check(article["body"], result)
if bad:
print("Hallucination flag:", bad)
# retry with stricter prompt or escalate to human review
Dette fanger de åbenlyse fejl — opdigtede personer, opdigtede dollarbeløb — men ikke de stille (omformulerede tal, ombyttede pronominer). Til pipelines med højere indsats skal du tilføje en NLI-model (facebook/bart-large-mnli-stil), der scorer hver opsummeringssætning mod input som entaillment / modsigelse / neutral. En flagrate over ~5% på dit eget korpus er et signal til at skifte modeller eller stramme prompten; under 1% kan udgives med en stikprøvebaseret menneskelig gennemgang.
Hvordan forhindrer du hallucinationer i nyhedsopsummeringer?
Forhindr hallucinationer i nyhedsopsummeringer med tre lag: en begrænset systemprompt, der forbyder inferens ud over kilden, en enheds-grounding-kontrol, der markerer enhver PERSON/ORG/MONEY/DATE i outputtet, som ikke findes i inputtet, og en NLI-baseret faktatjek-klassifikator, der scorer hver opsummeringssætning mod artiklen som enten medfører eller modsigelse. Afvis eller gennemgå manuelt enhver opsummering med en modsigelsesflag.
Trin 5 — Prompt-caching til produktionsomkostningsreduktion
Statiske systemprompter, der gentages på tværs af tusindvis af opsummeringskald, kvalificerer sig til prompt-caching på moderne OpenAI-implementeringer. Mekanismen: når de samme prefix-tokens rammer API gentagne gange, faktureres cachede tokens til en brøkdel af den normale input-rate. Den strukturelle regel er enkel — placer alt statisk (systemprompt, format-eksempler, output-skema) i starten af forespørgslen, placer den dynamiske artikel sidst.
For en typisk nyhedssummerizer, hvor systemprompten er ~500 tokens og artikelbrødteksten er ~800 tokens, er prompten ~38% statisk. Skub den statiske del højere med eksempler, og du kan ramme 70–80% statisk. Med en 90% cache-hitrate på den statiske præfiks falder de samlede inputomkostninger med ca.:
savings = static_fraction × hit_rate × cache_discount
= 0.80 × 0.90 × 0.50
= 36% on total input cost
Kombineret med den billige model er dette forskellen mellem $6/måned og $4/måned ved 1,000 artikler/dag — lille isoleret, men materiel ved 100K artikler/dag, hvor samme forhold betyder $400/måned versus $250/måned. Verificer cache-rabat og berettigelse i den aktuelle OpenAI-dokumentation.
Trin 6 — End-to-end pipeline
Bind det sammen. Hent fra APITube, fjern dubletter via is_duplicate, rute efter token-antal, grund, gem.
from sqlite3 import connect
db = connect("summaries.db")
db.execute("CREATE TABLE IF NOT EXISTS summaries (article_id TEXT PRIMARY KEY, summary TEXT, flagged INT)")
def fetch_articles(query, limit=20):
res = requests.get(
"https://api.apitube.io/v1/news/everything",
params={"title": query, "language.code": "en", "per_page": limit},
headers={"X-API-Key": os.environ["APITUBE_KEY"]},
)
res.raise_for_status()
return res.json()["results"]
def run(query):
for a in fetch_articles(query):
if a.get("is_duplicate"):
continue
body = a.get("body") or a["description"]
in_tokens = len(enc.encode(body))
chain = pick_chain(in_tokens, llm)
summary = chain.invoke({"text": body})
flagged = bool(grounding_check(body, summary))
db.execute(
"INSERT OR REPLACE INTO summaries VALUES (?, ?, ?)",
(a["id"], summary, int(flagged)),
)
db.commit()
run("election")
Ved 1,000 artikler/dag kører dette komfortabelt på en enkelt worker. Ved 10K/dag, paralleliser med asyncio.gather og batch OpenAI kaldene; ved 100K/dag, skift til OpenAI Batch API for 50% rabatten på ikke-tidsfølsomme resuméer.
Kan ChatGPT opsummere flere nyhedsartikler ad gangen?
ChatGPT kan opsummere flere nyhedsartikler i ét enkelt kald ved at sammenkæde dem til én input med klare skilletegn og bruge en map_reduce-kæde, der opsummerer hver artikel i map-trinnet og syntetiserer et samlet overblik i reduce-trinnet. Moderne kontekstvinduer accepterer snesevis af artikler pr. kald, men omkostningerne skalerer med det samlede antal input-tokens — for rutinemæssig batch-opsummering er det normalt billigere og lettere at debugge at loope enkelte artikels stuff-kald.
Byg vs. køb: GPT-pipeline vs. forudbygget ekstraktiv opsummering
APITube's /v1/news/everything-endepunkt returnerer allerede en ekstraktiv summary pr. artikel — nøglesætninger trukket direkte fra teksten, med per-sætnings-sentiment. Du betaler for det én gang via API-kaldet. Ærlig sammenligning:
| Tilgang | Omkostning pr. artikel | Outputstil | Hallucinationsrisiko | Bedst til |
|---|---|---|---|---|
Ekstraktiv (APITube summary) | inkluderet med artikelhentning | Ordrette kildesætninger | Ingen (ekstraktiv kan ikke opfinde fakta) | Søgesnit, mobilfeeds, push-notifikationer om alarmer, RSS-stil digests |
Hybrid (APITube summary + GPT polering) | ~$0.0001/artikel (billig-tier polish) | Glat, stadig jordet | Lav (begræns GPT til kun at omformulere) | E-mail-digester, ledelsesbriefinger hvor læseflow er vigtigt |
Fuld abstraktiv (GPT fra body) | ~$0.0002–0.02/artikel | Ægte syntese, ræsonnement med flere sætninger | Mellem-høj (kræver 4 jordforbindelse) | Lydbriefinger, resuméer af flere artikler, syntese på tværs af kilder |
Vælg ekstraktiv til ethvert volumen, hvor læseflowkvalitet ikke er differentiatoren. Skift til hybrid, når du har brug for en ensartet stemme på tværs af tusindvis af artikler. Reserver fuld abstraktiv til brugsscenarier, hvor modellen virkelig syntetiserer — multi-artikel-digester, lydbriefinger, "forklar mig, hvad der skete i dag"-grænseflader — fordi det er det eneste sted, hvor GPT tjener sin pris over API's forudbyggede opsummering.
Prøv det gratis
Valider hele pipelinen på APITube's gratis niveau — 30 anmodninger pr. 30 minutter er nok til at opsummere et par hundrede artikler ende-til-ende og beslutte, om du overhovedet har brug for GPT. Hvert resultat inkluderer allerede den ekstraktive summary, så du kan sammenligne den side om side med dit GPT-output. Prøv APITube gratis på apitube.io.
Ressourcer
- APITube — apitube.io — prøv det gratis, sentiment og entiteter inkluderet på hver artikel
- Dokumentation — docs.apitube.io — endpoints, parametre, svarsstruktur, integrationer
- Prissætning — apitube.io/pricing — alle niveauer
- APITube blog — apitube.io/blog — flere guides og sammenligninger

