Thank you nostr:npub16zsllwrkrwt5emz2805vhjewj6nsjrw0ge0latyrn2jv5gxf5k0q5l92l7 for looking this.

>Is your relay adding content warning tags?

No it didn't. It will make new classification event tagging event id and pubkey of author (kind: 9978) with classification labels (Language, toxicity, etc). Actually, i want to change and migrate that into NIP-32 format instead of custom kind 9978 like now.

I think i really need to draw some flowchart later to explain but did not have time yet. I'm sorry hopefully this can explain a bit 😅

How it works:

1. nostr-filter-relay will run several softwares: atrifat/nostr-monitoring-tool, atrifat/nostr-filter, and hoytech/strfry relay in launch script at startup.

2. nostr-monitoring-tool is classification tool that fetch and subscribe notes (kind: 1) from various relays. It will process every notes (extraction of image url, text preprocessing) it seen and send it into external AI classification tool. Currently it will send processed notes content into NSFW Detector API instance (using atrifat/nsfw-detector-api), LibreTranslate instance, and Hate Speech Detector API instance (using atrifat/hate-speech-detector-api). All three API will give classification results (NSFW class, Language class, Toxic classification) that will be saved as custom kind 9978 in local strfry relay that has already been running. Data format shown in atrifat/nostr-monitoring-tool in github.

Basic Data flow:

source relays (notes) -> nostr-monitoring-tool (connect to external API for classification) -> local strfry

3. Now, using classification data (kind: 9978) saved in local strfry relay, atrifat/nostr-filter will act as proxy relay and intercept any REQ from nostr client and forward them into local strfry relay. Local strfry relay will respond as usual by giving events based on REQ back to nostr-filter. Before sending events back to nostr clients, nostr-filter will check events from strfry whether it has classification data (kind: 9978) or not. For example users set nostr-filter-relay parameters to only gives notes which has "English" language then nostr-filter will only gives those notes using classification data. Any non "English" notes will be skipped.

Basic Data flow:

nostr clients <-> nostr-filter (act like frontend proxy) <-> strfry

4. Nostr client will get filtered events (Real data from strfry are 2000 notes but filtered into 1500 "english" notes) and show that to users.

Reply to this note

Please Login to reply.

Discussion

Very cool! I see the whole picture now. How did you get the content warning showing in Amethyst? Did that note just happen to already have a content warning on it? We are using a more robust ontology for content reports than what is defined in NIP-56. I’d be interested to hear your thoughts on it and whether or not it would be useful to you. https://github.com/rabble/nips/blob/724e05e762a634e501bdcf6cbefaa91f99b1903b/69.md

Here is what we publish when you report someone in Nos:

{

"content": "This content has been reported for Spam using NIP-69 vocabulary https://github.com/nostr-protocol/nips/pull/457",

"id": "03fdb75f9a8c927247cc4fc20abb419bb02932e615f056f67971e6cb8d073e09",

"tags": [

[

"L",

"MOD"

],

[

"l",

"MOD>SP",

"MOD"

],

[

"e",

"79123c0f6e54b330c8e1abba7ef5d6919ae493b072dcac7b603cada5f54bf4d3",

"spam"

]

],

"created_at": 1697565603,

"kind": 1984,

"sig": "5de629322692f102b85a8fc9921ce75b0f78fa3d4ff6f1d5cc69a777a75e6761b3448a689e1799d5d7e1f03aedad709910df03d2800e9801a8c9368841f46858",

"pubkey": "b1e4418e15a3660b5fa29e15e9e543427f2b3969617136be76072c7d674779a2"

}

Thank you. I'm glad that it can be understood. I think i really need to improve documentation in Github to make it easier. 😅

> How did you get the content warning showing in Amethyst? Did that note just happen to already have a content warning on it?

Oh no, i was intentionally made that post marked by using NIP-36 directly on Amethyst. What i have test was how my nostr-filter-relay test relay (wss://nostr-id-test-relay.hf.space) will react if i posted that negative comment. It works correctly by excluding those event. It will be merged soon into main relay (wss://nostr-id-relay.hf.space).

> https://github.com/rabble/nips/blob/724e05e762a634e501bdcf6cbefaa91f99b1903b/69.md

It is nice NIPs proposal to have list of ontology for labelling. I'm confused a bit since this PR seems to be cancelled because NIP-32 has been merged and superseded it, right? Also what is the source or reference to determine those ontology structure (IH, IL, NA, NS, etc.)?

Actually, i have already made considerations to transform current data format (kind: 9978) into NIP-32 format https://github.com/atrifat/nostr-monitoring-tool/issues/1 . Maybe i will do that after finishing other planned features (sentiment analysis and topic classification).

Currently, this is data format used by nostr-filter-relay internally. Data in "content" field (JSON stringified) were used in nostr-filter to determine the filtering. I think i need to format this in more efficient structure into NIP-32 compatible format. 😅

Example of language classification data:

{

"content": "[{\"confidence\":82,\"language\":\"ja\"}]",

"created_at": 1700614355,

"id": "event_id",

"kind": 9978,

"pubkey": "pubkey_of_classifier_bot",

"sig": "signature",

"tags": [

[

"d",

"nostr-language-classification"

],

[

"t",

"nostr-language-classification"

],

[

"e",

"75316bf6db0c75f8e57d2f3a2044d6eadacac92bfda780c62a89d5c47725fbe1"

],

[

"p",

"34a85403b43ff13441c7d79c98ba0f036add04b084b24f91c10d643f6d3f3665"

]

]

}

Example of hate speech (toxic comment) classification data:

{

"content": "{\"identity_attack\":0.6200000047683716,\"insult\":0.4620000123977661,\"obscene\":0.010999999940395355,\"severe_toxicity\":0,\"sexual_explicit\":0.0020000000949949026,\"threat\":0.004999999888241291,\"toxicity\":0.8059999942779541}",

"created_at": 1700000000,

"id": "event_id",

"kind": 9978,

"pubkey": "pubkey_of_classifier_bot",

"sig": "signature",

"tags": [

[

"d",

"nostr-hate-speech-classification"

],

[

"t",

"nostr-hate-speech-classification"

],

[

"e",

"c86cf6f0f7a30adfbd231d0e6d7b48c6d8909dd06bbcde9dd62a05f5ced072b5"

],

[

"p",

"dc369036ad76c7fe51b381ace9569e7add87c03dc74d9ab73b7e3299c18fe1c2"

]

]

}

Example of SFW/NSFW classification data:

{

"id": "event_id",

"created_at": 1696817846,

"kind": 9978,

"pubkey": "pubkey_of_classifier_bot",

"sig": "signature",

"content": "[{\"id\":\"58bd02d8c46eaa6f1598d5eff7cb33c06ff57c4c9ad3dad32ae2b70d3258f661\",\"author\":\"5fd004926969381ac2bb3a32720036d9f9632d29fb22dc1bf5d8fb1c9e265798\",\"is_activitypub_user\":false,\"has_content_warning\":false,\"has_nsfw_hashtag\":false,\"probably_nsfw\":false,\"high_probably_nsfw\":false,\"responsible_nsfw\":true,\"data\":{\"hentai\":0.0000018745902252703672,\"neutral\":0.9998550415039062,\"pornography\":0.0000746770019759424,\"sexy\":0.00006828152254456654,\"predictedLabel\":\"neutral\"},\"url\":\"url\"}]",

"tags": [

[

"d",

"nostr-nsfw-classification"

],

[

"t",

"nostr-nsfw-classification"

],

[

"e",

"58bd02d8c46eaa6f1598d5eff7cb33c06ff57c4c9ad3dad32ae2b70d3258f661"

],

[

"p",

"5fd004926969381ac2bb3a32720036d9f9632d29fb22dc1bf5d8fb1c9e265798"

]

]

}