Don't Trust the Score: A Fraud Investigator That Argues Both Sides on TigerGraph A developer built Fraud Investigator, a TigerGraph-backed fraud detection agent that treats bank risk scores as one weak witness rather than a verdict, after profiling five provided files with DuckDB showed all 900 cleared cases scored 0.81 or higher while 31% of confirmed fraud scored under 0.3. The system routes all reads through TigerGraph's MCP tool surface and all state-changing actions through a deterministic policy engine, using three schema-checked LLM calls per case for planning, explanation and SAR writing. Graph features reached an AUC of 0.91 versus 0.62 for the bank score among alerts at or above 0.8, and a score-blind sweep surfaced a hidden fraud ring of 60 transactions across 28 customers that no closed case contained. ๐ŸŽฅ Demo video: Watch the Fraud Investigator in action https://www.youtube.com/watch?v=kXDzmKNrhIE Most fraud-agent demos work the same way: a model produces a risk score, then an LLM writes a convincing story about why the score is right. Before writing any code, We profiled all five provided files with DuckDB. The data showed that approach would fail in both directions : it blocks innocent people and misses real fraud. | What I measured | Result | Design consequence | |---|---|---| | Cleared false-alarm cases | All 900 scored 0.81 or higher | A high score is where innocence lives, so the agent must be able to clear a 0.9 | | Confirmed fraud | Mean score 0.47 , and 31% scored under 0.3 | The agent must be able to convict a 0.05 | | A hidden fraud ring | 60 transactions, 28 customers, every score โ‰ค 0.44 , in no closed case | A score-blind sweep is needed | | Graph features vs bank score, among alerts โ‰ฅ 0.8 | AUC 0.91 vs 0.62 | The graph decides where the score is confused | | "Customers" | 104 of them hold 48% of all transactions | A customer is not a person, so baselines must be per card | Here is the same story as one picture. Fraud appears at every score. Innocence appears in only one zone: bank score bin : 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 confirmed fraud: โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ cleared safe : ยท ยท ยท ยท ยท ยท ยท ยท โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–ฒ the "decoy zone": the score cannot separate them here Chart shows where each outcome appears; it is not a count. The score tells you where to look. The graph tells you what happened. So I built an agent that treats the score as one weak witness, not the judge. Fraud Investigator takes an alert from any of three triggers a bank risk flag, a customer saying "I never made this" , or an analyst asking "look for related activity" and investigates it like a small legal team: Five layers. Everything that reads goes through TigerGraph's MCP tool surface. Everything that can change the world goes through the policy engine. flowchart TB subgraph ENTRY "ENTRY" direction LR E1 "Risk-score alert" E2 "Customer report" E3 "Analyst request" E4 "Analyst console" end subgraph ORCH "ORCHESTRATOR - bounded state machine, typed evidence ledger" direction LR O1 "Intake" -- O2 "Recall" -- O3 "Advocates x3" -- O4 "Judge" -- O5 "Plan" -- O6 "Gate" -- O7 "Act" -- O8 "Learn" end subgraph ENG "DETERMINISTIC ENGINES - no LLM inside" direction LR G1 "Signature library