Skip to content

Instantly share code, notes, and snippets.

@yamarten
Last active October 19, 2024 03:29
Show Gist options
  • Save yamarten/5962d3945b487caf011249eae4e3a78a to your computer and use it in GitHub Desktop.
Save yamarten/5962d3945b487caf011249eae4e3a78a to your computer and use it in GitHub Desktop.
atprotoなんでも相談室

atprotoなんでも相談室

モデレーションはどこが行う?

こんにちは。質問です。
atprotoで今後、Bluesky Socialを中心に連合が広がっていく場合、アカウントや投稿に関するモデレーションがどの部分で行われるか知りたいです。
今の構成だと、PDSとAppView側にあるのかなと思いますが、Blueskyでは現状、AppViewで行っているのかな、という気もしています(雰囲気的に挙動でそのように感じているだけで、実際は分かっていません)
モデレーション部分は強い権限取り締まるため、全体、あるいは一部の意思決定を行う部分であり、仮にBlueskyの現状運営の方針と合わない、となった場合、PDSを別にするだけで良いのか、AppView部分から全く別のネットワークを立ち上げ、そこに参加すべきか、とどの部分まで見て判断すべきか知っておきたいです。

回答: 2024/02/10

モデレーション処理を行うのはPDSとappviewですが、判断は主にmoderation service(mod service)と呼ばれる別のサーバで一括で行います。そのため、公式のモデレーションから離れるにはPDS・appviewに加え、mod serviceも立ち上げる必要があります。以下詳細。

mod serviceは簡単に言うと、PDSやappviewからモデレーションを委託されたサーバです。PDSやappviewはユーザからの報告(report)をmod serviceに転送し、またmod serviceからのモデレーション指示を受け付けて処理します。公式のmod serviceはOzoneと呼ばれる実装が使われています[1]

PDSとappviewの話に戻ると、両方変えるべきと思いますが、目的が少し異なります。

PDSを変えるのは、自分のアカウントやコンテンツが(新しいappview環境で)公式モデレーションの影響を受けないためです。なお、現実装では接続可能なappviewはPDSによって固定されていますが、将来的にはクライアントから指定可能になることが期待されます。

一方、appviewを変えるのは、他人のアカウントやコンテンツを公式モデレーションの影響を受けずに見るためです。逆に言えば、全てを新規に立ち上げたところで、公式appviewを使っているユーザからはそのアカウントは公式モデレーションを通った状態で見ることになるわけですが……。

本題から逸れますが、appviewを新規に立ち上げた場合、「全く別のネットワーク」とは言うものの、モデレーションを除けば公式とほぼ同じものを見ることができると思います。公式relayはfull-network relayを目指している節があるため、relayはおそらく共通化できます。また、relayまで新規で作るとしても、公式PDSからデータを汲み取ることは難しくないでしょう[2]

余談:モデレーション詳細

mod serviceが扱うモデレーションには大きくlabelとtakedownの2種類があります。labelはユーザにも見えるので分かると思いますが、「スパム」「性的コンテンツ」みたいなやつをアカウントや投稿に付けるやつですね。appviewでアカウント情報やフィードの生成時に付与し、クライアントが表示制御の材料として利用します。takedownは馴染みが無いと思いますが、BANと呼ばれているのはこれにあたります。

takedownは特定のアカウント・record(≒投稿)・blob(≒画像)を無かったことにするもので、PDSとappviewそれぞれで行います。削除する訳ではなく、対象のデータを外に出さないようにするだけなので、解除も可能です[3]。最近アカウントがBANされると話題になっていますが、それらのアカウントのプロフィールページをbsky.appで見てみると「Account has been taken down」と表示されると思いますが、これがアカウント単位のtakedownです。

ちなみに、mod serviceはfeed generatorのようにユーザが作成できる機能が開発中です。ただし、これは公式のモデレーションを無視できるという訳ではなく、追加のラベル付与に使われる程度とみるべきでしょう。

通知されない引用投稿は可能?

始めまして。Blueskyには引用の機能があり、引用すると引用されたユーザーに通知が行きます。
この通知を、引用する側で「通知を届けない」ように選択する仕様やAPIは存在するのでしょうか?

回答: 2024/02/17

結論から言うと、今のBluesky Socialではできません。公式にlexicon更新を訴えかけるか、そういう機能を自作して普及を図りましょう。ただし、実現しても抜け穴は残ります。

まず、bsky lexiconには通知対象を操作するようなAPIはありません。現状で引用が通知される以上、公式サービス(Bluesky Social)利用者には必ず通知が届きます。

一方、何を通知すべきかは仕様で強制されてもいません[4]。例えば、post recordに通知禁止フラグを追加するクライアントを作り、サーバーなりクライアントなりでフィルタリングすることはできるでしょう。

ただし、開発が必要なのは当然として、引用される側がそのシステムを使ってくれないと意味がありません。仮に公式に「通知されない引用」が実装されたとしても、見る側のサーバー(appview)orクライアントがその機能に対応していなければ、ただの引用として通知されうることに注意してください。

もう少し現実的で即効性の解決を目指すなら、引用を諦めて投稿のURLだけ書くくらいが落とし所かもしれません

余談:atprotoの制御主体

atprotoではコンテンツの扱いを決めるのは(発信側ではなく)見る側です。

これは、全てのコンテンツが(現状)公開データであることを考えればある意味当然のことではありますが、構成上の特性でもあります。atprotoで発信側ができるのは基本的には静的データの投稿のみで、動的な処理はほぼ見る側(が使うappview)で行われています。

例えばブロックは発信側で見る相手をフィルタリングできているように見えますが、あれは閲覧側でフィルタリングする機能です。仮にブロック非対応appviewが存在する場合、それを使う閲覧者はブロックの影響を受けません。

通知に関しても、閲覧側のappviewが生成するものなので、発信者には制御権が無い、という点には注意する必要があります。

通知のフィルタリングはどこで行う?

Lexiconには、通知一覧を取得するapp.bsky.notification.listNotificationsと、未読通知の数を取得するapp.bsky.notification.getUnreadCountが存在しています。どちらもAppViewが公開しているAPIだと思うのですが、こうなると、「不必要な通知を非表示にする」などの「通知内容のフィルタリング」は、クライアントアプリ(非公式クライアントなど)ではなくAppViewでおこなうしかないのではないか、と気づきました。

クライアントアプリは、その気になればlistNotificationsのレスポンスから表示するべき通知内容を取捨選択できるでしょう。しかしそうすると、AppViewから取得した「未読通知の数」とのズレが発生してしまうと思われます。

そこで質問なのですが、ブロックやミュートなどで非表示にしているユーザから送られてきた通知のフィルタリングは、現状はAppViewが行っているのでしょうか?
また今後、「フォローしていないユーザからの「いいね」やリプライや引用の通知を非表示にしたい」などの追加のフィルタリングを導入したい場合も、クライアントアプリだけでなくAppViewの更新も必要になるのでしょうか?

回答: 2024/02/27

ブロックやミュートによる通知フィルタリングはappviewで行います。ただし、公式クライアントは追加でフィルタリングを行っているため、appviewでなければいけないわけでもありません。

質問にあるブロックやミュートはbsky appviewのlistNotifications API内でフィルタリングされていますし、他にもthreadgate(リプライ制限)違反のフィルタリングもappview内です。

一方で、公式クライアントには上記以外にも通知のフィルタリング処理が入っており、具体的にはlabel設定スレッドミュートが該当します。このように前例があるため、クライアント側でフィルタリングすること自体は問題無いと思われます。もちろんフィルタリング有無がクライアント依存になる点には注意してください。

なお、getUnreadCountはappview側のフィルタリング処理すら入っていませんが、そもそも公式クライアントでは使っていないようです。上記フィルタリング処理を行いながら自前で数え上げています。

PDSが止まるとクローリングが止まる?

こんにちは。
PDS がしばらく止まっていると BGS はその PDS をクローリング対象から外しているような気がするのですが、そうなのでしょうか。

回答: 2024/06/10

relay(BGS)には明るくないため推測を含みますが、おそらく公式実装はそうです。

relayはPDSが更新されると(正確にはPDSからRequestCrawlが呼ばれると)subscribeReposでPDSのfirehoseを読み始め、一定期間更新が無いと接続を切るようです。閾値はどうやら1分の模様。

余談ですが、この件について調べていて、今まで少しrelayの挙動を勘違いしていたことに気付きました。繋ぎ直す毎にgetRepoを呼んでるんじゃないかと思ってましたが、普段は全然使わず、firehose頼みみたいです。

API仕様変更の追従

回答: 2024/07/08

こんにちは。
ATProtocol は頻繁に規格が変わっているようですが(例えば com.atproto.server.describeServer で返すべき json など)、これらを逐一追うにはどこを監視していればよいのでしょうか。

端的に答えると、 以下のリポジトリをウォッチするのが最も期待に近いと思います。

atprotoサービスの仕様を考えた時、スキーマと挙動、基盤とサービスの2軸4分類になると思います。

挙動の方はatprotoならatproto.com(atproto-website)、Bluesky Socialならdocs.bsky.app(bsky-docs)を見ればいいわけですが、スキーマはlexiconファイルがマスターです。
将来的にはlexiconファイルを取得する仕組みが定義されると思いますが、現状ではatprotoリポジトリのlexiconファイルを見ることになるでしょう。
とはいえこのリポジトリはlexicon目的でウォッチするにはノイズが多く、あまりオススメしません。

atproto-openapi-typesは公式lexiconを監視し、OpenAPI形式に変換する有志リポジトリで、lexicon更新を見るには適しています。bsky API等も含まれるのでまだ余分が多いかもしれませんが。

ところで、lexiconはその更新ルールにより、古い実装もスキーマ上は合法です。例えばdescribeServerのレスポンスには後からcontactphoneVerificationRequiredといったフィールドが追加されましたが、これらはオプションであり、レスポンスに含まないことが許されます。逆に古いフィールドが残っていたり、独自フィールドを追加しても構いません。
当然古い実装のままでは既存機能も期待通りに動かなくなる場合もありますが、この辺りは他ソフト(例えばappview)の実装依存になります。
「(規格上)返すべき」ではなく特定のソフトが実際に返す/期待するレスポンスの変化を追いたいなら、API叩くなり実装を追うなりする方が望ましいでしょう。

もう少し広い視点で動向を追うには、公式からの開発者向けアナウンスも役に立つかもしれません。

relayによるモデレーション

回答: 2024/10/19

bsky.networkのモデレーションとその影響についての質問です。公式ドキュメントすら碌に読み込んでないので、色々滅茶苦茶だったら申し訳ないです。
https://bsky.app/profile/bnewbold.net/post/3kmbmlejze22d
https://bsky.app/profile/bnewbold.net/post/3kuvp763xqz2q
これらの投稿からRelayでもモデレーションがあること、Relay上でのtakedownはその下流にもtakedownとして伝わること、bsky.networkはアカウントをtakedownすることがあるものと認識しました。
さらにbsky.networkはfull-network relayで、atproto上の全データを吸い上げるという理解なんですが、
だとするとBlueskyが許可しないコンテンツを扱う独自サービスをatproto上に構築しても、結局bsky.networkに吸われてRelay上でtakedown、実質的にBluesky Social上でもtakedownされることになるんでしょうか?
さらにbsky.networkが公共インフラ的に利用される場合、atproto上の多数のサービスからも締め出されそうですが、そうはならない仕組みになっているんでしょうか?

はい。なので他のrelayの登場を祈りましょう。

順を追って回答すると、relayにアカウント単位のtakedownを行う能力があることは仰る通りです。更新頻度が高すぎるアカウントをスパムとして弾く、明らかに違法なコンテンツを発見した際に弾く、といった使い方が想定されているのかと思います。

直接的にはBlueskyのインフラを一切使わないアカウントであっても、bsky.networkが全てのPDSを対象にしている以上、このtakedownは発生します。ただし、現実的には、今の公式relay実装にPDSを発見する能力は無いため、PDSから依頼(com.atproto.sync.requestCrawl)をかけなければ対象にはならなそうです。

さて、このtakedownの効力ですが、下流、つまり当該relayのsubscribeReposを使っているサーバに反映されます[5]。具体的には、api.bsky.app appviewや多くのfeed generatorが該当します。Ozoneによるtakedownとは異なり、PDSまで遡って影響が及ぶことはありません。
新しく作ったappviewがbsky.networkを使っているなら当然同様にtakedownされますし、いずれにしてもapi.bsky.appではtakedownされる、というわけです[6]。まあ、そのアカウントがbsky lexiconを使っていなければ、だからどうという話でもないですが。

relayのモデレーションから逃れるには、他のrelayを使う(またはrelayを使わない)代替appviewが必要になるわけですが、現状そのようなものはありません。将来的には複数のfull-network relayが運用されることを願っているようですが、現時点では夢物語に感じます。
とはいえ、full-network relayのコストは$150/月程度という実験結果[7]があります。ちゃんとatprotoが普及すれば、非現実的というほどではないでしょう。個人的には、独自機能の実現なり公式モデレーションへの反抗なりで新しいbsky appviewが生まれて、そこがrelayの運用も始める、というのが比較的あり得る線じゃないかと思っています。


1. 前身はredskyと呼ばれるものらしいですが、これは非公開のため詳細不明です。
2. 現在のrelay実装のようにPDSから通知してもらうことはできないかもしれませんが、勝手にクローリングする分には阻まれる要素はありません。
3. PDS管理者はこれとは別にアカウントを完全に削除する権限も持っていますが、この場合他PDSにバックアップデータを持っていけばほぼ変わりなく使えるでしょう。
4. 仮にlexiconに明記されていたとしても、実装に対する強制力はほぼ無いです。
5. 実装を流し見したところ、ちゃんと下流にtakedownイベントを流していました
6. 実は「Bluesky Social」が意味するものは不明瞭なので、ここではappviewの意味で扱います。規約的にはBluesky社が運用する全てを指すと考えた方が自然かもしれません。
7. この実験について、当時のDAUは現在の2割程度しかなかったこと、購読による負荷は考慮されていないことには留意が必要です。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment