惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
小众软件
小众软件
博客园_首页
博客园 - 聂微东
V
V2EX
WordPress大学
WordPress大学
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 司徒正美
博客园 - 三生石上(FineUI控件)
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
SegmentFault 最新的问题
J
Java Code Geeks
Last Week in AI
Last Week in AI
The Cloudflare Blog
月光博客
月光博客
雷峰网
雷峰网
宝玉的分享
宝玉的分享
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hugging Face - Blog
Hugging Face - Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
有赞技术团队
有赞技术团队
人人都是产品经理
人人都是产品经理
博客园 - Franky
腾讯CDC
Jina AI
Jina AI
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
阮一峰的网络日志
阮一峰的网络日志
量子位
爱范儿
爱范儿
美团技术团队
T
Tailwind CSS Blog
博客园 - 【当耐特】
D
Docker
IT之家
IT之家
V
Visual Studio Blog
P
Proofpoint News Feed
L
LangChain Blog
Engineering at Meta
Engineering at Meta
C
Check Point Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
云风的 BLOG
云风的 BLOG
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
Recorded Future
Recorded Future

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Preventing GPT hallucination in automated content pipelines: how I structure Make.com flows with data injection
Kevin Seeberger · 2026-05-26 · via DEV Community

I run a Make.com pipeline that produces daily sports betting articles. Odds API in, API-Football in, aggregation in the middle, GPT-4o for the writing, Google Docs out. Looks great on the diagram. Worked beautifully in testing.

Then it shipped. And within a week we had articles confidently telling readers that a Spanish second-division side was "the reigning Champions League winners," that a 38-year-old striker had "just signed his first professional contract," and — my personal favourite — that a match scheduled for Saturday would "kick off this past Tuesday."

Every fact technically plausible. Every fact completely wrong.

This post is what I changed to stop that happening. Not a clever prompt trick. Not a model swap. A structural change in how the data flows into the LLM call.

The cause is almost never "the model"

The instinct when GPT invents facts is to blame the model. Bigger model, better prompt, lower temperature. Most of the time that's wrong. In a pipeline, hallucination is almost always caused by the prompt asking GPT to know things it has no way to know.

My original system prompt looked something like this:

You are a sports betting journalist. Write a 600-word match preview for the upcoming match. Cover team form, head-to-head history, key players, and betting angles. Be authoritative and confident.

Then the user prompt contained the two team names and the match date.

Read that carefully. I told GPT to write authoritatively about team form, h2h history, and key players — without giving it any of those things. So it did exactly what an LLM does when asked a confident question with no data: it generated something that sounds like sports journalism, drawn from training data that's months or years stale, hallucinating the gaps.

The fix isn't "tell GPT not to hallucinate." That instruction does almost nothing. The fix is to make hallucination structurally impossible by giving GPT every fact it needs and forbidding it from going beyond those facts.

This is what people mean when they say "data injection." It's not jargon — it's a constraint pattern.

What changed in the flow

Here's the before and after at the module level.

Before:

Odds API → API-Football → Aggregator → GPT-4o → Google Docs

The Aggregator module passed a clean object to GPT. The prompt asked GPT to write a preview. Everything between "here are two team names" and "600 words of confident content" was a black box that GPT filled with plausible-sounding nonsense.

After:

Odds API → API-Football → Aggregator → Data Validator →
  Structured Fact Block Builder → GPT-4o (constrained) →
  Output Validator → Google Docs (or Error Queue)

Three extra modules. None of them are AI. All of them exist to make sure GPT only ever sees verified facts and is structurally prevented from inventing more.

Let's go through them.

1. The Data Validator: catch missing data before it becomes a hallucination

Hallucinations are often born in null fields. If the API returns no head-to-head data for two teams that haven't played in five years, and the Aggregator forwards h2h: null to GPT, the prompt will still ask GPT to "cover head-to-head history." Guess what GPT does with that.

The Data Validator is a Make.com router that checks every field the article will reference. If any required field is missing, the flow branches: either skip the article entirely, fetch a fallback, or proceed but mark that field as "data unavailable" — which the prompt later treats as a hard constraint.

Example: I require the last 5 matches for each team. If the API returns fewer than 5 for either side, the flow doesn't fail — it sets a form_data_complete: false flag, and the prompt builder downstream handles it differently.

In code-equivalent terms (your Make.com setup will use a Router + filters, but the logic is this):

const required = {
  home_team_name: data.home_team?.name,
  away_team_name: data.away_team?.name,
  match_date_iso: data.fixture?.date,
  kickoff_time_local: data.fixture?.kickoff_local,
  venue: data.fixture?.venue?.name,
  home_last_5: data.home_team?.last_5_results,
  away_last_5: data.away_team?.last_5_results,
  odds_home: data.odds?.home,
  odds_draw: data.odds?.draw,
  odds_away: data.odds?.away,
};

const missing = Object.entries(required)
  .filter(([_, v]) => v === null || v === undefined || v === '')
  .map(([k]) => k);

if (missing.length > 0) {
  // Route to error queue, don't generate
  return { action: 'skip', reason: `missing: ${missing.join(', ')}` };
}

This single step killed more hallucinations than any prompt change ever did. Most of the bad articles in the early days came from articles GPT shouldn't have been asked to write at all because the underlying data was incomplete.

2. The Structured Fact Block: give GPT a context window full of truth

This is the core of the data injection pattern. Instead of asking GPT to write about teams using its training data, the prompt builder constructs a deterministic, structured fact block from the validated API data — and the system prompt is rewritten to say only use the facts in the block below.

Here's what gets injected:

=== MATCH FACTS (USE ONLY THESE) ===

FIXTURE
- Home team: AFC Bournemouth
- Away team: Villarreal CF
- Competition: Friendly (pre-season)
- Date: Saturday, 9 August 2025
- Kickoff: 15:00 local time
- Venue: Vitality Stadium, Bournemouth

HOME TEAM RECENT FORM (last 5, most recent first)
1. W 2-1 vs Brentford (29 July)
2. D 1-1 vs Bristol City (24 July)
3. L 0-2 vs Real Sociedad (20 July)
4. W 3-0 vs Yeovil Town (15 July)
5. W 1-0 vs Hashtag United (10 July)

AWAY TEAM RECENT FORM (last 5, most recent first)
1. L 0-1 vs Aston Villa (2 August)
2. W 2-0 vs Levante (28 July)
3. D 1-1 vs Real Betis (24 July)
4. W 4-1 vs Cádiz B (20 July)
5. W 2-1 vs Mirandés (16 July)

HEAD-TO-HEAD (last 5 meetings)
- No previous competitive meetings
- 2 previous friendlies: 1 win each, both 1-0

CURRENT ODDS (decimal)
- Home win: 2.10
- Draw: 3.40
- Away win: 3.20

KEY PLAYERS (from current squad data)
- Home: Solanke, Semenyo, Tavernier (top scorers this pre-season)
- Away: Pino, Moreno, Baena (confirmed in pre-season starting XI)

=== END OF FACTS ===

Notice what's not in the block: nothing speculative, nothing about "form trends," nothing about player narratives. Just data points the API confirmed.

The Make.com module that builds this is just a text aggregator with template variables — no AI involved. It's deterministic and auditable. If the article says "Solanke scored twice last weekend," I can trace exactly which API field that came from. If it doesn't trace, it's a hallucination.

3. The constrained system prompt: explicit guardrails

The system prompt that consumes the fact block is the second half of the data injection pattern. It's not "be a great sports writer." It's a contract.

You are a sports betting content writer. You are writing a 600-word
match preview using ONLY the facts provided in the MATCH FACTS block.

HARD CONSTRAINTS:
1. Every factual claim you make MUST be directly supported by the
   MATCH FACTS block. Do not introduce facts, statistics, transfers,
   injuries, manager quotes, historical context, or player biographies
   that are not in the block.
2. If a topic would normally require information not in the block
   (e.g. detailed h2h history, specific injury news, manager tactics),
   either omit it or explicitly write "no recent data available."
3. Do not invent player names. Only reference players named in
   KEY PLAYERS.
4. Do not invent dates or times. Use only the date/time in FIXTURE.
5. Do not state outcomes as certain. Use language like "favoured,"
   "value bet," "the odds suggest" — never "will win" or "guaranteed."
6. If the facts contradict your training data (e.g. a player you
   remember as injured is listed as a key player), trust the facts.
   The block reflects the current state.

STRUCTURE:
- Lead paragraph: fixture, venue, kickoff
- Form section: recent results for both sides (use the data, don't
  characterise it beyond what 5 results can support)
- Betting angle: discuss the odds rationally
- Closing: brief value-bet suggestion based on odds + form

TONE: neutral, German sports-journalism register. No hype.

Two things matter here. First, constraint #6 — "trust the facts over your training data." This is the line that prevents the model from "correcting" current data with outdated training memories. Without it I'd see GPT helpfully writing about a player who'd retired six months ago because training data said they were a star.

Second, constraint #2 — explicit permission to write "no recent data available." Without that, GPT will fill silence with invention. With it, GPT will happily skip a topic and the article reads as appropriately measured rather than confidently wrong.

Temperature stays low (0.3-0.4). Not zero — you still want readable prose — but low enough that the model isn't reaching for creative completions.

4. The Output Validator: catch what slipped through

No matter how tight the prompt, occasional hallucinations slip past. The Output Validator is a final Make.com step that runs the generated article through a set of regex and lookup checks against the fact block.

The checks I run:

  • Date check: regex out any date in the article, cross-reference against match_date_iso. If a date in the article doesn't match, route to manual review.
  • Player name check: extract proper nouns that look like player names, cross-reference against the KEY PLAYERS list and the squad data from the API. Unknown names = flag.
  • Score check: any "X-Y" pattern in the article gets checked against the last_5_results data for both teams. If it's neither a real recent result nor framed as a prediction, flag.
  • Forbidden phrases: a small blocklist of certainty language ("will definitely win," "guaranteed," "lock of the week"). Pure hygiene for compliance reasons in betting content, but it doubles as a hallucination tripwire because confidently-wrong articles tend to use confidently-certain language.

Articles that fail any check route to a "Needs Review" Google Doc folder. Articles that pass go straight to publish queue.

Roughly 5-8% of articles trip a flag in any given week. Maybe a third of those are actual hallucinations, the rest are false positives from the regex (a player whose name overlaps with a common word, etc.). I'd rather review false positives than ship false facts.

What I learned from this

Three things, in priority order.

One: hallucination is a data problem, not a model problem. Every hour I'd spent on prompt engineering before this change had near-zero impact. The hour I spent building the Data Validator and the Fact Block had a 10x impact. If your pipeline produces confidently wrong output, look at what you're not giving the model before you look at the model itself.

Two: deterministic modules around the LLM are non-negotiable. Make.com (or n8n, or whatever you're using) is great at exactly this — building the boring, predictable, auditable scaffolding around the unpredictable LLM call. If your flow is "API → GPT → Output," you have no scaffolding. The LLM is doing work it shouldn't be doing.

Three: explicit permission to fail gracefully beats implicit pressure to perform. Telling the model "write a great preview" creates pressure to invent when data is thin. Telling it "if data is missing, write that data is missing" releases that pressure. Counterintuitively, the article quality went up after I gave the model permission to say "no recent data available" — because the alternative was always invention, and invention always read worse than honest gaps.

If you're building content pipelines and hitting hallucination problems, start with the Data Validator. It's the cheapest change with the biggest impact, and it surfaces a lot of upstream data issues you didn't know you had.

I'll write up the n8n version of this same pattern in a follow-up — same logic, different scaffolding.