yinglong-behaviour-anomaly
The behaviour model (M3) of YINGLONG, an AI agent wallet that pays only inside spending rules the owner locked. It looks at one payment the agent is about to make, compares it with how this kind of wallet usually behaves, and says whether the payment is unusual enough to ask the owner first.
Important: this model is advisory and can only escalate. In YINGLONG a machine-learning signal can raise a payment to a stricter tier (from "act alone" to "ask the owner"). It never lowers a tier and never refuses by itself; deterministic code and the on-chain contracts decide. Do not use it as the only defence of anything.
How it works
Two scorers per wallet archetype (student, sme): an isolation forest (unsupervised) and a LightGBM classifier
(supervised). Each score becomes a conformal p-value against held-out normal payments of the same archetype (Mondrian
conformal), the two p-values are combined (twice the smaller one), and the payment is escalated when the combined p-value
is at or below alpha = 0.0221, chosen for a target false-escalation rate of 2.0%.
Input: 23 features of the payment and the wallet's recent history (amount and how it compares with the usual, hour,
night, new payee, address age and changes, look-alike address, payments in the last hour and day, x402 micropayments,
amounts just under a threshold, untrusted source). The full list is in m3_calibration.json and results.json.
How to use
# pip install lightgbm scikit-learn skops huggingface_hub numpy
from huggingface_hub import hf_hub_download
import importlib.util, sys
spec = importlib.util.spec_from_file_location("yinglong_m3", hf_hub_download("ABRUBAB/yinglong-behaviour-anomaly", "yinglong_m3.py"))
m3 = importlib.util.module_from_spec(spec); spec.loader.exec_module(m3)
model = m3.BehaviourModel()
print(model.score("student", {"f_log_amount": 9.2, "f_new_payee": 1, "f_night": 1, "f_n_1h": 6, "f_untrusted": 1}))
Files
| File | What it is |
|---|---|
m3_lightgbm.txt |
LightGBM model (plain text) |
m3_isoforest_student.skops, m3_isoforest_sme.skops |
Isolation forests in the safe skops format (no pickle) |
m3_calibration.json |
Feature order, alpha and the conformal calibration scores per archetype |
yinglong_m3.py |
The scoring function, the same as the live service |
results.json |
Full evaluation, including the SHA-256 of the files the live service runs |
conversion_check.json |
Proof that these safe copies score exactly like the live files |
The live service loads the same fitted objects from a hash-pinned pickle (m3_models.pkl, SHA-256
7b8af61b9c7f4412...). We publish no pickle, because loading one can run code. Before upload, the
copies here were checked against it on 4000 feature rows: largest score difference 0.0, calibration
identical.
Results (held-out test split)
177,209 payments from 90 synthetic wallets, 11,043 of them anomalous, in nine attack families. Test split: 41,567 payments.
- AUROC 0.994 combined (isolation forest 0.979, LightGBM 0.994); AUPRC 0.986.
- False escalations on normal payments: 2.1% (2.0% to 2.3%, n = 38,907), against a target of 2.0%.
| Attack family | Test items | Escalated (95% CI) | AUROC |
|---|---|---|---|
| duplicate payment | 60 | 45.0% (33.1% to 57.5%) | 0.761 |
| split payment | 261 | 100.0% (98.6% to 100.0%) | 1.000 |
| lookalike address | 66 | 100.0% (94.5% to 100.0%) | 1.000 |
| velocity burst | 664 | 100.0% (99.4% to 100.0%) | 1.000 |
| inflated invoice | 67 | 98.5% (92.0% to 99.7%) | 0.999 |
| x402 drain | 1358 | 100.0% (99.7% to 100.0%) | 1.000 |
| new payee large | 55 | 100.0% (93.5% to 100.0%) | 1.000 |
| dormant reactivation | 62 | 100.0% (94.2% to 100.0%) | 1.000 |
| address swap (held out of training) | 67 | 86.6% (76.4% to 92.8%) | 0.994 |
Honest limits: duplicate payments are hard for a per-payment model (recall 45.0%); YINGLONG catches those with deterministic checks first. The "address swap" family was left out of training to test an unseen attack.
Training data
Synthetic only: fictional wallets and payments generated by ml/anomaly/world.py, trained and evaluated by
ml/anomaly/train_eval.py in https://github.com/ABRUBAB/YINGLONG. No real person's data. Live system: https://app.yinglong-agent.tech.