What We Built
We built an agentic fraud investigation system on TigerGraph for the TigerGraph x Hacker House Goa hackathon. It takes twenty fraud alerts from the IEEE-CIS dataset (590,742 transactions), investigates each one using graph traversals, calibrates its confidence, and - this is the key part - asks for more evidence when one signal is not enough.
For each alert the agent produces three things:
- An internal case record written into the graph
- A suspicious activity report when policy requires one
- A next-best-action with an approval route, recorded before and after any evidence it asks for
The bank's risk score is an input, not an answer: above 0.7 most flagged transactions are legitimate, and some fraud scores near zero. The agent's job is calibration and restraint as much as detection.
Architecture
alert -> LangGraph agent -> TigerGraph MCP -> TigerGraph (GSQL, algorithms, vectors)
| ^
+-> Gemini (temperature 0) |
+-> action registry (permissions) ----+ case writeback
+-> FastAPI (+SSE) -> React analyst UI
The pipeline is a state machine:
TRIGGER -> OPEN_CASE -> GATHER_EVIDENCE -> ASSESS -> [uncertain? REQUEST_EVIDENCE -> RE-ASSESS]* -> DECIDE_NBA -> APPROVAL_GATE -> EXPLAIN -> WRITE_CASE
All graph access goes through the tool layer; the model never sees raw rows - only structured evidence briefs.
How TigerGraph Is Used
TigerGraph is the backbone of this system. Here's how we used every major capability:
Schema Design
We designed a rich graph schema with 12 vertex types and 15+ edge types:
- Core entities: Customer, Card, Transaction, DeviceProfile, EmailDomain, BillingRegion
- Investigation entities (agent-written): Case, Evidence, Action, Pattern, PolicyClause
- Historical: ClosedCase (with embeddings for similarity search)
Key edges like OWNS, MADE, FROM_DEVICE, BILLED_IN model the transaction network, while HAS_EVIDENCE, TOOK, SIMILAR_TO capture the agent's reasoning chain.
GSQL Queries
We wrote 14 GSQL-backed tool functions:
| Tool | Purpose |
|---|---|
card_profile |
Cardholder history: median spend, products, regions, devices |
card_window |
All transactions within +/-72h of the alert |
velocity_stats |
Transaction velocity in configurable time windows |
device_neighbors |
Other customers sharing this device profile |
path_to_known_fraud |
Shortest path (<=4 hops) to a confirmed fraud case |
fraud_ring_detection |
WCC + Louvain on shared device/region subgraph |
similar_cases |
Vector similarity search over closed case embeddings |
policy_lookup |
Vector search over policy clause embeddings |
Graph Algorithms
- Weakly Connected Components and Louvain Community Detection on the shared device / region / email subgraph to find fraud rings
- PageRank for entity centrality - identifying the most connected nodes in suspicious clusters
Vector Search (GraphRAG)
We embedded closed-case narratives and policy clauses using MiniLM (384-d) and stored them as vector attributes on TigerGraph vertices. For each new case, the agent:
- Retrieves similar closed cases by vector similarity
- Finds relevant policy clauses
- Condenses graph facts + similar cases + policy into an evidence brief
- Reasons over that brief with the LLM
MCP Integration
The agent's only interface to the graph is through TigerGraph MCP tools. Every claim in a case file cites a query name and entity IDs - full provenance, no hallucination.
Agentic Behaviour - The Interesting Part
1. Uncertainty is Explicit
The agent doesn't just classify fraud/not-fraud. It maintains a calibrated probability and uses Bayesian updates:
def odds_mult(p, lr):
return sig(logit(p) + math.log(lr))
Thresholds come from the fraud policy:
- >= 0.85: Act (with >=2 independent signals)
- 0.15 - 0.85: Request more evidence
- <= 0.15: Clear
2. Evidence Requests Change Outcomes
When uncertain, the agent requests customer validation, step-up authentication, or analyst review - selecting the channel with the highest expected information gain.
Example from Case HHG-001:
- Initial probability: 0.59 (out-of-region use pattern)
- Action: VERIFY_WITH_CUSTOMER
- Customer denies the transaction
- Final probability: 0.93 -> BLOCK_CARD
3. The Recommendation Changes
nba_before and nba_after are stored with a diff and a reason:
- At 0.45 on one signal ->
VERIFY_WITH_CUSTOMER - After denial ->
BLOCK_CARD,CREATE_CASE, maybeFILE_REPORT
4. Permissions Live in Code
Only auto-routed actions execute. L1 (team lead) and L2 (fraud manager) actions are recorded as pending with the approver role. BLOCK_ALL_CARDS is refused unless policy R10 holds.
5. Memory Through the Graph
Prior case outcomes are retrieved by vector similarity AND shared entities. They're cited in the case file and change recommendations - a cleared travel case makes the agent verify instead of block.
Pattern Discovery
We ran graph algorithms over the full dataset and discovered two undocumented fraud patterns:
DISC-001: Shared-Device Ring - One Samsung SM-G935F behind an anonymous proxy, marked New on 28 different customers' cards within 30 days (60 transactions, $16,556). The graph found it through device-neighbor traversal.
DISC-002: Threshold Structuring - 3-4 online purchases each just under $500 within 45 minutes on rotating device profiles (44 episodes found).
Case HHG-014 hit the shared-device ring with 0.988 probability - the bank's risk score was 0.05. The graph caught what the model missed.
Results
All 20 benchmark cases processed successfully:
| Metric | Value |
|---|---|
| Cases processed | 20/20 |
| Fraud detected | Multiple patterns including card-not-present, out-of-region, account takeover |
| Undocumented patterns found | 2 (DISC-001, DISC-002) |
| SARs generated | Filed when exposure > $1,000 or shared device/customer fraud |
| Avg tool calls per case | ~30 |
| Avg latency | ~5-11 seconds per case |
| Evidence requests | Bayesian updates with simulated customer/auth responses |
Case HHG-014 - The Graph Found What the Model Missed
The bank's risk score was 0.05 (extremely low risk). But TigerGraph revealed:
- The device profile was shared by 28 customers in 30 days
- 100% of uses were marked "New"
- 100% were behind an anonymous proxy
- The device appeared on 3 confirmed fraud cases
- The agent classified it as 0.988 probability fraud - an undocumented coordinated abuse pattern
The Interface
The analyst UI is a React + TypeScript + Framer Motion application with:
- Case queue with priority sorting
- Bento case view: verdict, confidence, evidence list
- Before->After action timeline showing how recommendations changed
- Interactive subgraph visualization (react-force-graph-2d)
- Live investigation streaming via SSE
- Approval workflow for L1/L2 actions
What We Learned
- Deciding between "case only" and "case plus report" is as important as spotting the fraud - the policy engine needs to be as rigorous as the detection engine
- Keeping the model away from raw rows made runs cheaper and outputs easier to audit
- Graph traversals > ML features for discovering coordinated fraud that individual transaction models miss
- TigerGraph's vector search + graph traversals together enable a true GraphRAG pattern - combining structured graph reasoning with semantic similarity
Tech Stack
- Graph Database: TigerGraph (Savanna Cloud)
- LLM: Gemini Flash (temperature 0)
- Backend: Python, FastAPI, SSE
- Frontend: React, TypeScript, Vite, Tailwind, Framer Motion, react-force-graph-2d
- Embeddings: sentence-transformers/all-MiniLM-L6-v2 (384-d)
- Graph Algorithms: WCC, Louvain, PageRank via GSQL
Built at the TigerGraph x Hacker House Goa hackathon. Dataset: IEEE-CIS Fraud Detection (Vesta Corporation).
Top comments (0)