A real-time customer data pipeline transformation with "system 1" decision intelligence powered by Jev.
Labels each high-stakes event before it reaches your warehouse or marketing/analytics/product tools by classifying:
- Who is behind it? Human · AI agent · crawler · other automation
- Is it an abuse? A confidence score from 0 to 1
Data teams who need signup, login, checkout, and install events labeled before they reach analytics or the warehouse. Known bots can be caught by simple rules, but this layer classifies the rest so you can drop abuse, keep real-user AI agents, and tag the rest for review. Read comparison with deterministic rules for more details.
- Spot fake signups and fraud before they land in your tools
- Keep AI-agent checkouts that act for a real customer
- Clean bots out of DAU, funnels, and A/B tests
- See AI and search crawler traffic as its own kind
- Tag first, drop later - measure before you enforce
| Field | Values | Meaning |
|---|---|---|
context.isBot |
true / false |
false only when kind is human |
context.bot.category |
human, ai_agent, ai_crawler, search_crawler, seo_tool, scraper, other_automation |
What produced the event |
context.bot.badIntent |
0 to 1 | Probability the event is abuse |
context.bot.kindConfidence |
0 to 1 | How sure Jev is about the category |
context.bot.actsForUser |
true / false |
A real person is behind it |
context.bot.detectedBy |
"jev" |
Which layer tagged it |
- Fork this repo (this is an MIT license project, no restrictions)
- Don't have your customer data pipeline set up? Set it up quickly with RudderStack free account. Use webhook source and any database destination for quick testing.
- Get the Jev api key from Typesafe AI console and update
TYPESAFE_API_KEYvalue in the transformation code - Either create a JavaScript transformation manually and paste the transformation code OR set the repo secrets needed for the GitHub Action included in this repo for automated deployment
- Import
transformations/code/testevents.jsonand run the cases (same panel as the screenshot above). - In the transformation code, keep
MODE = "shadow"until you trust the verdicts, then switch to"enforce".
| # | Scenario | Expected |
|---|---|---|
| 1 | Bot farm signup in a real browser | human, badIntent >= 0.8 (dropped in enforce mode) |
| 2 | AI agent checkout for a logged-in customer | ai_agent, actsForUser: true, low badIntent |
| 3 | Android emulator install fraud | other_automation, badIntent >= 0.8 |
| 4 | Real person signing up | human, low badIntent |
Warning
Jev is probabilistic, so badIntent and kindConfidence vary slightly between runs. Judge a test by the expected column, not exact decimals.
- Edit
EVALUATE_EVENTSto control which events are evaluated (and your cost). - Tune
BAD_INTENT_THRESHOLDusing real traffic in shadow mode. - Add your own user-agent rules at the top of
transformEvent, e.g. the bot filter template.
Rules ask "known bot?". Generally based on user-agent string.
That misses bot farms in real browsers, and blocks AI agents buying for real customers.
When agents have become the primary user, it is not a good idea to treat all bots the same.
With Jev, we are able to identify what kind of bot is it and whether it has a bad intent or not.
Jev is TypeSafe AI's System One model. You send it context and fixed questions; it returns typed answers with probabilities (a choice from your list, or 0 to 1), not free text. This transformation asks what produced the event and how likely it is abuse. See the Jev introduction.
RudderStack collects customer events data from all your apps, then sends them to your warehouse and tools.
- Source code: rudder-server
- Docs: rudderstack.com/docs.
A transformation is JavaScript or Python that runs on each event in the pipeline before destinations receive it. This repo is one of them (jev-bot-layer.js): it calls Jev, writes the verdict onto the event, and in enforce mode can drop high badIntent events. More in the transformations docs.
Use Bot Management for known bots, and set it to Forward events with a flag so those events still reach this layer. Jev only runs on events that still need a decision.
MIT