Technical breakdown

How Netpost works

Netpost turns roughly 75 live industry items into five publishable LinkedIn posts in a single request. This page documents the scoring maths, the linter rules and the similarity thresholds that decide what actually reaches you.

Trend scoring

Every ingested item is scored with the same formula: keyword relevance × source weight + freshness bonus. Keyword relevance sums the weights of the scoring terms found in the item's title and summary. The freshness bonus rewards recency on a linear ramp — max(0, 24 − min(age_hours, 24)) / 12 — worth up to 2.0 for something published in the last few minutes and nothing at all after 24 hours.

Keyword weights

Trend scoring keywords and weights
KeywordWeight
fintech2.5
automation2.3
banking2.0
investment2.0
underwriting1.8
diligence1.8
deal1.8
workflow1.8
ai1.7
compliance1.7
payments1.6
agent1.5
fraud1.4
data1.2

Deduplication

Titles are lowercased and stripped of punctuation, then hashed to a SHA-1 fingerprint. Matching fingerprints collapse to a single item, which is what keeps a story syndicated across five outlets from occupying five slots in the brief.

The anti-slop linter

Each generated post starts at 100 and loses points for every flag raised. The score and the flags are shown on the card, so the judgement is visible rather than hidden behind a silent filter.

Linter rules and what each one catches
FlagWhat it catches
Weak hookOpens with "I", "In my experience" or "As a" — the openers that signal a post nobody will stop scrolling for.
Vague claims"Amazing", "incredible", "game-changing" and similar adjectives that assert impact without evidence.
Generic filler"A lot of", "everyone knows" and other phrases that take up space without adding information.
Missing credibilityNo metric and no named authority. A post should cite a number or a source like the SEC, McKinsey or Bloomberg.
Poor readabilityFewer than three paragraphs, or any single paragraph over 65 words. LinkedIn is read on phones.
Hashtag spamMore than five hashtags.
Filler CTA"Feel free to", "hope this helps" and other soft closers that ask for nothing.
Corporate conclusion"In conclusion", "to summarize" — essay scaffolding that does not belong in a feed.
Too many tagsMore than two tagging hints.

Similarity checking

Every draft is compared against the style corpus and previously generated posts using a weighted blend: 35% token overlap (Jaccard), 40% shingle overlap on 3-grams, and 25% cosine similarity. The blended score maps to three states.

Why repeat clicks do not repeat themselves

Freshness is enforced rather than hoped for. Each batch carries a UUID nonce, a fresh angle target drawn from eight banking-specific framings, and a list of recently generated hooks the model is instructed to avoid. Trend IDs used in recent batches are rotated out when enough alternatives exist, and duplicate content within a single batch is rejected outright.

Architecture

The Next.js frontend on Vercel calls a FastAPI backend on Render, which fans out to the trend sources with asyncio.gather, generates through the OpenAI chat completions API with structured JSON output, and persists trend events, batches, posts and feedback to Supabase over its REST API. If AI or database configuration is missing, the backend fails loudly with a real error rather than serving placeholder content.

Source is on GitHub. Back to the generator.