Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
nostrbuzzsのしくみ
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Yoji Shidara
March 10, 2023
Technology
620
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
nostrbuzzsのしくみ
Yoji Shidara
March 10, 2023
More Decks by Yoji Shidara
See All by Yoji Shidara
Searchnos & Search on Nostr
dara
0
350
searchnos について
dara
0
470
How nostrbuzzs works
dara
0
170
About searchnos
dara
0
160
HOME, GOPATH and me
dara
3
1.7k
The First Step for Building Groonga Bindings with Golang
dara
6
1.5k
まほうのひととき - The Magic Hour
dara
7
990
JDK CHRONICLE
dara
2
8.9k
Timelapse Introduction
dara
1
700
Other Decks in Technology
See All in Technology
LLM・AIエージェントシステムベストプラクティス
shibuiwilliam
6
1.1k
研究開発部の紹介 / Sansan R&D Profile
sansan33
PRO
4
24k
クラウドセキュリティ入門 ~安全なクラウド利用のための基礎知識~
lhazy
13
8.6k
社内の7割が使うデータ基盤を、 データチーム2人で回すためにやったこと
koh_yoshi
4
1.3k
[しろおび夏祭り2026] チャットするAIから、作業するAIへ - 使われ方の変化と、その裏側で起きていること
kk0n
0
1.7k
FDEの心得
noriakioji
4
4.8k
SmartHR Engineering Team Deck
smarthr
1
2k
ハーレムエンジニアリング
kazuma777777
0
130
生成 AI の基礎 〜 サンプル実装で学ぶ基本原理
enakai00
7
4.4k
Head First モブプログラミング / Head First Mobprogramming
takaking22
10
12k
20260807_第6回_関東kaggler会LT_claw系bot xangiと始める、"寂しくない" kaggle
sugupoko
0
260
Forza Horizon 6 のテレメトリ機能で 自動運転に使えそうな学習データを集める話
henjin0
0
170
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Skip the Path - Find Your Career Trail
mkilby
1
180
Building AI with AI
inesmontani
PRO
1
1.1k
Side Projects
sachag
455
43k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
480
What does AI have to do with Human Rights?
axbom
PRO
1
2.3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.9k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
370
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Transcript
nostrbuzzs のしくみ npub1q7qyk7rvdga5qzmmyrvmlj29qd0n45snmfuhkrzsj4rk0sm4c4psvqwt9c 2023-03-10 Nostr 勉強会 #1
@darashi Twitter のイマを切り取るサービス buzztter.com ( 運用終了) の作者です。 nostr の イマを切り取るサービス
nostrbuzzs をつくりました。 (NEW! Nostr 村放送局をつくりました。)
nostrbuzzs https://nostrbuzzs.deno.dev/
全体の構成 deno deploy fly.io nostrverse kind:1 kind:1 recent notes phrase
frequency kind:38225 kind:38225 static assets nostrbuzzs.deno.dev indexer analyzer ElasticSearch nostr-rs-relay relay.damus.io nos.lol web-browser
Indexer deno deploy fly.io nostrverse kind:1 kind:1 recent notes phrase
frequency kind:38225 kind:38225 static assets nostrbuzzs.deno.dev indexer analyzer ElasticSearch nostr-rs-relay relay.damus.io nos.lol web-browser リレーに接続して kind1 を収集します。 content の言語推定を行い、日本語と推定されたものだけ Elasticsearch にイン デックスします。 言語推定には https://github.com/pemistahl/lingua-go をつかっています。
Elasticsearch deno deploy fly.io nostrverse kind:1 kind:1 recent notes phrase
frequency kind:38225 kind:38225 static assets nostrbuzzs.deno.dev indexer analyzer ElasticSearch nostr-rs-relay relay.damus.io nos.lol web-browser https://www.elastic.co/ をそのまま使っています。 Indexer から送られたデータを保持します。 Analyzer が分析するために必要な情報を提供します。 解析のため、形態素等でトークナイズせず N-gram でインデックスします。
Analyzer deno deploy fly.io nostrverse kind:1 kind:1 recent notes phrase
frequency kind:38225 kind:38225 static assets nostrbuzzs.deno.dev indexer analyzer ElasticSearch nostr-rs-relay relay.damus.io nos.lol web-browser Elasticsearch からデータをとって buzzphrases を求めます。 解析結果を Relay に Parameterized Replaceable Events (NIP-33) で送ります。
Web UI deno deploy fly.io nostrverse kind:1 kind:1 recent notes
phrase frequency kind:38225 kind:38225 static assets nostrbuzzs.deno.dev indexer analyzer ElasticSearch nostr-rs-relay relay.damus.io nos.lol web-browser いわゆる SPA です。 Fresh https://fresh.deno.dev/ で書きました。 当初は API サーバも実装していたので deno deploy に置いてありますが、静的な サイトです。
Analyzer の処理について、もうすこし詳しく
Analyzer 1/2 -- 頻出フレーズ抽出 1. Elasticsearch から直近2 時間分の note を取得する。
2. SimHash [1] ( 実装は https://crates.io/crates/simhash) を用いて note 間の類似性を 計算し、類似度の高い note は 1 つを残して削除する。 3. Sudachi で形態素に分解する。 4. PrefixSpan [2] ( 自前実装) を用いて、頻出フレーズを求める。 [1] Charikar, Moses S. "Similarity estimation techniques from rounding algorithms." Proceedings of the thiry-fourth annual ACM symposium on Theory of computing. 2002. [2] Han, Jiawei, et al. "Prefixspan: Mining sequential patterns efficiently by prefix- projected pattern growth." Proceedings of the 17th international conference on data engineering. IEEE, 2001.
Analyzer 2/2 -- スコア計算 5. 頻出フレーズの正規化(大文字小文字、NFKC )を行い、その結果が同一になるフ レーズ群の出現をまとめる。出現頻度が最大の表記を代表として採用する。 6. あるフレーズについて、同一
pubkey で複数の言及が有る場合は、最新の note に 代表させる。 7. 解析開始時刻とフレーズの出現時刻の差をみて、直近の出現が高い重みを持つよ うに重み付けする(ついでに解析窓の過去側の端がなめらかになるようにす る)。 8. Elasticsearch に問い合わせて、過去のフレーズの出現数を求め、直近の出現が多 く、過去の出現が少ないフレーズに高いスコアを与える。 9. 解析結果を relay に送信する。
Nostr 的おもしろポイント NIP-33 をつかった解析結果の受け渡し https://github.com/nostr-protocol/nips/blob/master/33.md
具体例 解析結果を JSON で content に入れます。 kind は 38225 で
buzz-phrases:jp というタグをつけています。 自前のリレーに送っています。 ❯ echo '["REQ", "_", {"kinds": [38225] }]' | nostcat --stream wss://example.com | jq . [ "EVENT", "_", { "content": "{\"phrases\":[{\"text\":\"bluesky といえば\"}, ... 中略... ,{\"text\":\"Windows100\"}],\"created_at\":\"2023-02-26T08:36:14.559572950+00:00\",\"language\":\"ja\"}", "created_at": 1677400574, "id": "789cdedc73c7472428c40a39ada18177fa44a1996c30783f0ec0b194ca676cb8", "kind": 38225, "pubkey": "fe295340106bb7b8f5b08f8b7c22000862abc9731dbb86f2f141301e13b4d024", "sig": "f5c6aaf310cd0b6c631bdaf1f909563b1ebf7f45c5db8cced25ab3fced93fba6d8337a03277f23e2e58a1e7aaf1c94cf9996daa58d97a6e80bbde64829fda4f9", "tags": [ [ "d", "buzz-phrases:ja" ] ] } ]
この構成のいいところ ブラウザに解析結果を返すための API サーバが不要です。 この API サーバでは、 新たにつなぎに来たブラウザには、キャッシュしてある最新の結果を即時で返す Analyzer から新たな結果が来たら、接続中のブラウザ全部に通知する
という処理が必要です。単純だけど、ストレージが必要だったりしてちょっと面倒。 (初期バージョンはそういう実装になっていました) これが NIP-33 で解決します。
NIP-33: Parameterized Replaceable Events 「kind, pubkey, d タグが同じイベントが来たら、古いイベントを置き換える」 要するに、 Relay
は最新の 1 件だけ保持して返してくれる。 めっちゃ便利。 しかも複数のリレーに publish するだけで冗長構成を取れます。
応用例 誰でもバズフレーズを受け取って表示するサイトを作れます。 予告なく仕様が変わるかもしれませんが... もし、誰かが別の解析エンジンを実装したとして、それが同じプロトコルを実装 していれば、ユーザは切り替えて使用できるかもしれません。 たとえば pubkey で区別できます。 何を以て「トレンド」とするか。誰でもトレンドを発信できる。 人と人のコミュニケーションするためのイベントが主流だけど、Nostr
を介してサービ スとサービスがやりとりする世界観のも面白いのでは。
専用リレーの運用 nostr-rs-relay を使うとすぐできる。 config.toml の [authorization] セクショ ンの pubkey_whitelist に
Analyzer の pubkey を追加するだけ。 自サービス専用だと思うと気が楽 吊るしで使えるリアルタイム API サーバー
まとめ Nostr の buzz を解析して、表示するサービス nostrbuzzs をつくりました。 Relay を活用することで、 Nostr
っぽいアーキテクチャでつくりました。