Agent Data Guard - Data Trust Score & Decoy Detector
Pricing
Pay per event
Agent Data Guard - Data Trust Score & Decoy Detector
Insurance for your AI agent's inputs. Scores any Apify dataset 0-100 using transparent statistics - fill-rate, Shannon entropy, Benford's law, duplicate and decoy detection - then returns a verdict and per-signal flags. Catch blocked, empty, or manipulated scraper output before your agent trusts it.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Creator Fusion
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
4 hours ago
Last modified
Categories
Share
Agent Data Guard
Before your AI agent acts on a scraped dataset, ask: is this data real?
Agent Data Guard takes an Apify datasetId, runs a battery of generalizable
statistical integrity checks over the rows, and returns a single authenticity
score (0-100), a verdict, and a list of signal flags. It is built for
agents: one call in, one machine-readable summary row out, plus per-field detail.
Scrapers fail silently all the time - a blocked IP returns a 200 with a decoy
body, a source serves a truncated mirror, a template emits the same canned row
thousands of times. The run status says SUCCEEDED and the item count looks
fine. This actor is the check that catches that before your agent trusts it.
What it checks (textbook statistics only)
| # | Signal | What it catches |
|---|---|---|
| 1 | Field fill-rate + null clustering | Missing values, and nulls concentrated in a contiguous block (truncated / decoy tail) |
| 2 | Value distribution + Shannon entropy | Near-zero-entropy fields = constant / canned data |
| 3 | Benford first-digit test | Numeric fields (with real spread) whose leading-digit distribution is unnatural (chi-square vs Benford, p<0.01) |
| 4 | Duplicate detection | Exact-row duplicates + near-duplicates via k-shingling / Jaccard on text |
| 5 | Low-cardinality / constant fields | Columns that never vary |
| 6 | Boilerplate / decoy detection | A single string repeated across >=90% of rows |
| 7 | Row-count sanity | Empty datasets / zero-row decoys |
Scoring (transparent, no black box)
Start at 100 and subtract additive penalties:
| Signal | Max penalty |
|---|---|
| Field fill-rate | (1 - avgFillRate) * 25 |
| Low-entropy fields | fracLowEntropy * 20 |
| Exact duplicates | exactDupeRate * 20 |
| Null clustering | fracClusteredFields * 15 |
| Constant fields | fracConstantFields * 15 |
| Boilerplate fields | fracBoilerplateFields * 15 |
| Near duplicates | nearDupeRate * 10 |
| Benford failures | fracFailingBenford * 10 |
authenticityScore = clamp(100 - totalPenalty, 0, 100). Signals deliberately
overlap (a constant field is penalized as both low-entropy and constant) because
each is a distinct, independently reported red flag.
Verdict: >=70 -> likely-authentic, 40-69 -> degraded,
<40 (or 0 rows) -> probable-decoy-or-empty.
Input
{"datasetId": "aBcDeFgHiJkLmNoPq","fields": ["name", "price", "url"],"sampleLimit": 1000}
datasetId(required) - the dataset to inspect. Read with your own token.fields(optional) - subset of fields to check; omit to check all.sampleLimit(optional, default1000) - max rows to load.
Output
One summary row followed by one detail row per field.
{"rowType": "summary","authenticityScore": 30,"verdict": "probable-decoy-or-empty","signalFlags": [{ "signal": "constant-field", "severity": "high", "detail": "5 field(s) hold a single constant value." },{ "signal": "exact-duplicates", "severity": "high", "detail": "99.5% of rows are exact duplicates." }],"rowsAnalyzed": 400,"fieldsAnalyzed": 5,"avgFillRate": 0.925,"exactDuplicateRate": 0.995,"nearDuplicateRate": 1.0}
Per-field rows carry fillRate, cardinality, entropyBits, normEntropy,
constant, boilerplate, nullClustered, benfordChiSq, benfordFail,
topValueShare, and emptyCount.
Calling it
MCP (Apify actor tool)
Call the actor apricot_blackberry/agent-data-guard with
{ "datasetId": "<id>" }, then read the default dataset's /items. The summary
row is the one with rowType: "summary".
curl
curl -X POST "https://api.apify.com/v2/acts/apricot_blackberry~agent-data-guard/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"datasetId":"aBcDeFgHiJkLmNoPq","sampleLimit":1000}'
JavaScript (apify-client)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('apricot_blackberry/agent-data-guard').call({ datasetId: 'aBcDeFgHiJkLmNoPq' });const { items } = await client.dataset(run.defaultDatasetId).listItems();const summary = items.find((r) => r.rowType === 'summary');if (summary.authenticityScore < 40) throw new Error(`Untrustworthy data: ${summary.verdict}`);
Python (apify-client)
from apify_client import ApifyClientclient = ApifyClient(token=os.environ["APIFY_TOKEN"])run = client.actor("apricot_blackberry/agent-data-guard").call(run_input={"datasetId": "aBcDeFgHiJkLmNoPq"})items = client.dataset(run["defaultDatasetId"]).list_items().itemssummary = next(r for r in items if r["rowType"] == "summary")if summary["authenticityScore"] < 40:raise RuntimeError(f'Untrustworthy data: {summary["verdict"]}')
Pricing
Pay-per-event: a small actor-start fee plus one report charge per run.
No proxy needed - the actor only reads the Apify API.
Notes / limits
- Near-duplicate detection compares the first 300 sampled rows pairwise (O(n^2)); larger samples still get exact-dupe, entropy, and Benford over the full sample.
- Benford is only applied to numeric fields spanning at least one order of magnitude with >=30 positive values - it is skipped (not failed) otherwise.
- Statistical signals are heuristics: a low score means "inspect before trusting", not a proof of forgery.