observing-atproto
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseObserving ATProtocol
ATProtocol网络观测
Firehose Access
Firehose接入
Jetstream endpoint:
wss://jetstream2.us-east.bsky.network/subscribeSimplified JSON stream (~50 posts/sec on Bluesky). Easier than raw CAR files.
Jetstream端点:
wss://jetstream2.us-east.bsky.network/subscribe简化的JSON流(Bluesky平台约50条帖子/秒)。比原始CAR文件更易用。
Quick Pulse
快速脉冲采集
python
import asyncio
import json
import websockets
from datetime import datetime, timezone
async def pulse(duration_seconds=15):
uri = 'wss://jetstream2.us-east.bsky.network/subscribe'
posts, likes, follows = 0, 0, 0
hashtags = {}
start = datetime.now(timezone.utc)
async with websockets.connect(uri) as ws:
while (datetime.now(timezone.utc) - start).seconds < duration_seconds:
try:
msg = await asyncio.wait_for(ws.recv(), timeout=1)
data = json.loads(msg)
commit = data.get('commit', {})
collection = commit.get('collection', '')
if collection == 'app.bsky.feed.post':
posts += 1
# Extract hashtags
text = commit.get('record', {}).get('text', '')
for word in text.split():
if word.startswith('#'):
tag = word[1:].lower().rstrip('.,!?')
hashtags[tag] = hashtags.get(tag, 0) + 1
elif collection == 'app.bsky.feed.like':
likes += 1
elif collection == 'app.bsky.graph.follow':
follows += 1
except asyncio.TimeoutError:
continue
return {
'duration': duration_seconds,
'posts': posts,
'likes': likes,
'follows': follows,
'posts_per_min': posts * 60 // duration_seconds,
'top_hashtags': sorted(hashtags.items(), key=lambda x: -x[1])[:5]
}python
import asyncio
import json
import websockets
from datetime import datetime, timezone
async def pulse(duration_seconds=15):
uri = 'wss://jetstream2.us-east.bsky.network/subscribe'
posts, likes, follows = 0, 0, 0
hashtags = {}
start = datetime.now(timezone.utc)
async with websockets.connect(uri) as ws:
while (datetime.now(timezone.utc) - start).seconds < duration_seconds:
try:
msg = await asyncio.wait_for(ws.recv(), timeout=1)
data = json.loads(msg)
commit = data.get('commit', {})
collection = commit.get('collection', '')
if collection == 'app.bsky.feed.post':
posts += 1
# Extract hashtags
text = commit.get('record', {}).get('text', '')
for word in text.split():
if word.startswith('#'):
tag = word[1:].lower().rstrip('.,!?')
hashtags[tag] = hashtags.get(tag, 0) + 1
elif collection == 'app.bsky.feed.like':
likes += 1
elif collection == 'app.bsky.graph.follow':
follows += 1
except asyncio.TimeoutError:
continue
return {
'duration': duration_seconds,
'posts': posts,
'likes': likes,
'follows': follows,
'posts_per_min': posts * 60 // duration_seconds,
'top_hashtags': sorted(hashtags.items(), key=lambda x: -x[1])[:5]
}Using tools/firehose.py
使用tools/firehose.py
bash
undefinedbash
undefinedQuick network sample
Quick network sample
uv run python -m tools.firehose sample 30
uv run python -m tools.firehose sample 30
Network analysis
Network analysis
uv run python -m tools.firehose analyze 60
undefineduv run python -m tools.firehose analyze 60
undefinedMonitoring Feeds
信息流监控
The Atmosphere Feed
Atmosphere信息流
Cameron's curated ATProtocol discussion feed:
python
feed_uri = 'at://did:plc:gfrmhdmjvxn2sjedzboeudef/app.bsky.feed.generator/the-atmosphere'
async with httpx.AsyncClient() as client:
resp = await client.get(
'https://public.api.bsky.app/xrpc/app.bsky.feed.getFeed',
params={'feed': feed_uri, 'limit': 20}
)
posts = resp.json().get('feed', [])Cameron策划的ATProtocol讨论信息流:
python
feed_uri = 'at://did:plc:gfrmhdmjvxn2sjedzboeudef/app.bsky.feed.generator/the-atmosphere'
async with httpx.AsyncClient() as client:
resp = await client.get(
'https://public.api.bsky.app/xrpc/app.bsky.feed.getFeed',
params={'feed': feed_uri, 'limit': 20}
)
posts = resp.json().get('feed', [])Recording Observations
记录观测结果
bash
undefinedbash
undefinedRecord observation as a cognition thought
Record observation as a cognition thought
uv run python -m tools.cognition thought "Network pulse: {posts_per_min} posts/min, {likes_per_min} likes/min. Top tags: #atproto, #bluesky"
undefineduv run python -m tools.cognition thought "Network pulse: {posts_per_min} posts/min, {likes_per_min} likes/min. Top tags: #atproto, #bluesky"
undefinedNetwork Statistics (typical)
典型网络统计数据
- ~50 posts/sec (~3000/min)
- ~250 events/sec total
- ~65% of events are likes
- Engagement ratio (likes:posts) typically 4-6:1
- Higher engagement ratio = healthy interaction patterns
- ~50条帖子/秒(约3000条/分钟)
- 总计~250个事件/秒
- 约65%的事件为点赞
- 互动率(点赞数:帖子数)通常为4-6:1
- 互动率越高,代表互动模式越健康
Best Practices
最佳实践
- Sample for at least 15 seconds for meaningful data
- Note time of day - activity varies
- Cultural events drive spikes (e.g., BBB26, sports)
- Record observations as records
network.comind.observation - Compare pulses over time to identify patterns
- 采样时间至少15秒以获取有意义的数据
- 记录采样时间——活跃度随时段变化
- 文化活动会引发流量峰值(如BBB26、体育赛事)
- 将观测结果记录为记录
network.comind.observation - 对比不同时段的脉冲数据以识别模式