{
  "$type": "com.whtwnd.blog.entry",
  "theme": "github-light",
  "title": "atprotoモデレーション概論 Bluesky編",
  "content": "## atprotoモデレーション概論 Bluesky編\n\n[atprotoモデレーション概論 目次](https://whtwnd.com/did:plc:qi6xg6zplzivyu7zrylxuugk/3lb4xttmcxw2m)\n\nここまでは全て仕様の話だったが、最後に実装と運用の話。Bluesky Socialと公式実装に固有の事情について簡単に説明する。\n\n### bsky appviewとlabeler\n\n公式appview実装では、[全てのlabelを`subscribeLabels`で取得する](https://github.com/bluesky-social/atproto/discussions/2885#discussioncomment-10988873)。呼ぶタイミングは未確認。\n\n取得したlabelはappviewで保持して、APIが呼ばれたらローカルで参照する仕組み。そのため、一度発行したlabelは、明示的に`neg`で取り下げない限り残り続ける。\n\n### mod service\n\n公式[PDS実装](https://github.com/bluesky-social/atproto/blob/c34426fc55e8b9f28d9b1d64eab081985d1b47b5/packages/pds/src/config/env.ts#L90)や[appview実装](https://github.com/bluesky-social/atproto/blob/c34426fc55e8b9f28d9b1d64eab081985d1b47b5/packages/bsky/src/config.ts#L115)は、mod serviceというものが設定できる。\n\nこれは管理者権限のうちモデレーション関連のみを委任されたサーバだと思えばいい。雑に言えば、外部からtakedownできるということ。また、PDSへの通報もmod serviceに転送されるようになる。\n\n沢山存在する公式PDSのモデレーションを一元化した上で、モデレータチームに過剰な権限を与えないための機構という感じ。\n\nmod serviceはlabelerを兼ねることが多く、認証用の鍵はlabelerの場合と同じもの(service ID `#atproto_labeler`)を使うことになっている。\n\n### Ozone\n\n公式PDS/appviewが使っているmod serviceの実装はOzoneという名前で[公開されている](https://github.com/bluesky-social/ozone)[^ozonecode]。labelerアカウントは[@moderation.bsky.app](https://web.plc.directory/did/did:plc:ar7c4by46qjdydhdevvrndac)。\n\n[^ozonecode]: サードパーティlabelerの雛形としても使われるが、本題から外れるのでここではおいておく。\n\nこれは公式appciew+公式PDS全てのモデレーションを一括管理しているため、公式PDS(bsky.social)を使っている場合、bsky appviewでのtakedown≒PDSでのtakedownとなる。基本的には通報(公式クライアントにおける「投稿を報告」というやつ)を受けて、モデレータが判断する仕組み。\n\nOzoneもXRPCで操作できるようになっており、[`tools.ozone`](https://github.com/bluesky-social/atproto/tree/main/lexicons/tools/ozone)という独自lexiconを持つ。また、基本的にはbskyコンテンツを対象としているため、モデレーション対象確認のために`getPostThread`等のbsky APIも備えている。\n\nmoderation.bsky.appはlabelerとしても強い権限を持っており、公式SDK(@atproto/apiパッケージ)を使うと、自動的に`atproto-accept-labelers`指定に追加される。しかも`redact`付き。つまり公式appview以外でも、少なくとも公式クライアントを使う限りはlabel(特に`!takedown`)が反映される。\n\n[モデレーションアカウントの設定画面](https://bsky.app/profile/moderation.bsky.app)を見れば分かるように、基本的なlabel[^labelsetting]は大体ここで付けられている。\n\n[^labelsetting]: 余談だが、この設定画面ではglobal labelの設定は見えるだけで変更できない。これはおそらく、self labelや他labelerと設定が共通であることを意識させるため。[クライアント設定](https://bsky.app/moderation)から一括で設定するようになっている。\n\n### 自動モデレーション\n\natprotoにlabelerの仕組みが導入される以前から動いている仕組みとして、[`automod`](https://github.com/bluesky-social/indigo/tree/main/automod)(もしくは`hepa`)と呼ばれる機構が存在する。これは、NGワード検出や、[Hive AI](https://thehive.ai/)による画像判定を使って、自動的にモデレーション対象を検出するもの。\n\n検出したものは、報告としてOzoneに送られる模様。人手を挟まず自動承認している気がするが、詳細は追ってない。\n\n一時期話題になったslur handleもautomodの範疇のはず。一方で有名企業のなりすまし等を防ぐ[reserved handle](https://github.com/bluesky-social/atproto/blob/bac9be2d3ec904d1f984a871f43cf89aca17289d/packages/pds/src/handle/reserved.ts)はPDS単位で管理している。\n\n### 地域別labeler\n\n公式クライアントでは、地域によって[追加のlabelerを指定する](https://github.com/bluesky-social/social-app/blob/aa55798e5582518f80e8d71dad12688ebd8e6a2b/src/state/session/additional-moderation-authorities.ts#L6-L13)場合がある。国毎の法令に応じて閲覧制限を行ったり、言語別の問題に対処するためではないかと思われるが、詳細未確認。\n\n[実際のlabeler](https://bsky.app/profile/did:plc:ekitcvx7uwnauoqy5oest3hm)を覗いてみると、labelは一切宣言しておらず、`!takedown`のみの運用ではないかと思われる。\n\n### その他のlabeler\n\n有志labelerまとめが幾つかあるのでそちらを参照。例えば以下。\n\nhttps://www.bluesky-labelers.io/\n\n実装はOzoneベースのものの他、labeler作成キット[skyware](https://github.com/skyware-js/labeler)などもある。[Bluesky Labeler Starter Kit](https://github.com/aliceisjustplaying/labeler-starter-kit-bsky)から使うと便利そう。\n\nトレンドとして、自己申告型のlabelerが数多く出ている。モデレーションというよりはタグに近い用途で、モデレーションコストがかからない分ハードルも低いのだろう。\n\n### レート制限\n\n少しだけlabeler以外も見ると、スパム対策として、公式PDSやrelayはレート制限が設けられている。詳細は以下参照。\n\nhttps://docs.bsky.app/docs/advanced-guides/rate-limits\n\n### Next\n\n[実践編](https://whtwnd.com/did:plc:qi6xg6zplzivyu7zrylxuugk/3lb4yacmaah2m)\n",
  "createdAt": "2024-11-18T01:46:40.622Z",
  "visibility": "public"
}