让每一条动态都有“声音”:手把手教你用 bskyScribe 给 Bluesky 做媒体无障碍描述
想象一下:你在 Bluesky 上刷到一段 45 秒的视频,创作者没留下任何文字说明;或者一张信息图,字小得看不清。对视力受限、听力受限,或只是通勤路上没带耳机的用户来说,这些内容就像上了锁。
bskyScribe 就是一把小巧却趁手的钥匙——它 24 小时蹲守通知栏,一旦有人召唤,就自动把图片、音频、视频翻译成一段 250 字以内的贴心摘要,再贴回评论区,让任何人都能“秒懂”。
这篇文章会带你走完从安装、配置到真正跑起来的全过程,不堆术语、不画大饼,每一步都给出可直接复制的命令和可感知的“为什么”。如果你刚刚专科或本科毕业,对 Python 只是“会用 pip”,也能顺利跟上。
1. 为什么我们需要“媒体描述机器人”?
场景 | 没有描述 | 有 bskyScribe |
---|---|---|
视力障碍用户 | 只能知道“这里有张图” | 听到或读到“图里是三只柯基在草地追飞盘” |
地铁里静音刷手机 | 视频自动播放,没字幕 | 评论区出现“视频里主讲者用 30 秒介绍新款键盘的静音轴” |
多语言社群 | 日语图表看不懂 | 直接给出中文要点:“图表显示 2024 年手机出货量比 2023 上涨 7%” |
bskyScribe 的价值不是炫技,而是把信息平权落到每一次回复。它用 Google Gemini 做大脑,用 AT Protocol 做耳朵和嘴巴,把原本需要人工撰写的“alt text”自动化、规模化,却又不牺牲可读性。
2. 项目全景:一张图看懂流程
图:bskyScribe 的五步循环
-
监听:像安静的图书管理员,只在有人“点名”时才抬头。 -
抓取:把原帖里的图片、视频、音频一次性拉回本地内存,不占硬盘。 -
思考:丢给 Google Gemini,让它判断是“描述画面”“读文字”还是“总结语音”。 -
精简:把可能上百字的分析压缩到 250 字符以内(Bluesky 单条限制)。 -
回复:自动回帖,并在日志里留下一条“已完成”的绿钩。
3. 准备工作:一分钟清单
你需要的 | 如何获取 |
---|---|
Python 3.9+ | 官网或 Anaconda |
Google Gemini API Key | Google AI Studio 免费申请 |
Bluesky 账号 + App 密码 | Bluesky Settings → App Passwords |
一台能联网的电脑 | 本地、云服务器均可 |
小提示:
App 密码 ≠ 登录密码,它是一串 16 位小写字母,专门给第三方程序用,用完可随时吊销,安全又省心。
4. 安装:三步到位
4.1 把代码抱回家
git clone https://github.com/your-org/bskyScribe.git
cd bskyScribe
4.2 造一个“隔离仓”——虚拟环境
python -m venv venv
source venv/bin/activate # Windows 用 venv\Scripts\activate
为什么要虚拟环境?
就像给项目单独一间书房,避免和其他项目的“书籍”混放,升级或卸载库时不误伤。
4.3 一次性装完依赖
pip install -r requirements.txt
看到一排 Successfully installed… 就安心继续。
5. 配置:两行密钥,一行用户名
5.1 复制模板
cp .env.example .env
5.2 用你最顺手的编辑器打开 .env
GEMINI_API_KEY=你的_40_位字符串
BLUESKY_USERNAME=你的账号.bsky.social
BLUESKY_PASSWORD=你的_16_位_app_密码
图:把敏感信息写进 .env
,而不是代码,方便后期换号或开源。
6. 跑起来:两种姿势
6.1 一次性“点读”某条帖子
适合调试,或只想帮朋友描述某张图。
from bots.transcriptionBot import MediaProcessingBot
bot = MediaProcessingBot() # 自动读取 .env
post_url = "https://bsky.app/profile/naomi.dev/post/3jx..."
result = bot.transcribe_post(post_url) # 本地跑 3~15 秒
print(bot.format_transcription_reply(result))
终端会输出类似:
{"response": "图片是一杯拉花拿铁,旁边放着翻开的笔记本,阳光从左侧窗户照进来。"}
确认无误后,再发出去:
bot.post_transcription_reply(post_url)
6.2 7×24 小时守护
适合挂在云服务器,成为公共资源。
from daemon import Scribe
scribe = Scribe()
scribe.monitor_mentions() # 阻塞式运行,Ctrl+C 停止
图:Render 免费实例即可跑,内存占用 < 100 MB。
7. 看懂返回:JSON 里的五个字段
字段 | 示例值 | 说明 |
---|---|---|
thinking | “用户上传了一段 12 秒视频,背景噪音低,主讲英语,关键词 keyboard” | 开发调试时可看,生产可隐藏 |
request_type | SUMMARIZE | 告诉前端这是“总结”而非“读图” |
media_type | VIDEO | 决定图标或朗读语气 |
response_character_count | 245 | 确保不会超限 |
response | “视频总结:作者演示新键盘的静音红轴,打字 10 秒几乎无声。” | 最终呈现给用户的文字 |
8. 项目结构:像拆开一台随身听
bskyScribe/
├── clients/
│ ├── bluesky.py # 负责“听”和“说”
│ └── gemini.py # 负责“想”
├── bots/
│ └── transcriptionBot.py # 把两者缝在一起
├── prompt/
│ └── prompt.txt # 写给 Gemini 的“作业题”
├── daemon.py # 守护进程
├── render.yaml # 一键上云
├── Procfile # Heroku/Render 启动脚本
├── requirements.txt # 依赖清单
└── .env # 你的私密便签
-
bluesky.py 用 AT Protocol 的 subscribeRepos
监听新通知,再用getPostThread
拉原帖。 -
gemini.py 把媒体转成 base64 或临时 URL,连同 prompt.txt 一起 POST 到 https://generativelanguage.googleapis.com/v1beta/models/gemini-pro-vision:generateContent
。 -
transcriptionBot.py 决定何时“读文字”何时“总结语音”:如果检测到图片里有可识别文本且占比高,就走 OCR;否则走纯视觉描述。音频/视频先抽音轨,再转录。
9. Prompt 设计:让 AI 说“人话”
prompt.txt 只有 10 行,却决定机器人是“啰嗦老学究”还是“简明小助手”。核心段落:
- 请用中文回答,控制在 250 字以内。
- 先一句话概括整体,再补充 2-3 个关键细节。
- 遇到文字优先读文字,遇到人脸不猜身份,遇到暴力/血腥内容用“画面可能引起不适”代替。
经验:限制字数最有效的方式不是“请简短”,而是“中文 250 字以内”,大模型会自行截断。
10. 部署:从 0 到线上的 10 分钟
10.1 选 Render——免费又省心
-
用 GitHub 账号登录 render.com。 -
New → Background Worker → 绑定仓库。 -
环境变量页粘贴 .env
内容。 -
保存,Deploy。第一次拉包 2~3 分钟,之后每次 push 自动上线。
10.2 观察日志
Render 的“Logs”标签实时滚动,出现:
INFO:root:👂 Mention detected from @naomi.dev
INFO:root:✅ Reply posted, length 238 chars
说明万事俱备。
11. 运行成本与性能
资源 | 免费额度 | 实际消耗 |
---|---|---|
Render Worker | 512 MB 内存 | 约 90 MB |
Google Gemini | 每分钟 60 请求 | 一条帖子 1 请求 |
网络出口 | 100 GB/月 | 音频视频拉流 < 5 MB/帖 |
换句话说,每天处理 500 条帖子仍不会花一分钱。如果帖子暴增,Render 会自动排队,不丢消息。
12. 常见问题 FAQ
Q1:机器人会泄露我的私聊吗?
A:不会。它只处理公开帖子,且只在被 @ 时出现。代码开源,可自行审计。
Q2:音频里有个人隐私怎么办?
A:bskyScribe 默认不存储文件,分析完立即释放内存。你可以在 prompt.txt 里加一条“忽略人名”。
Q3:能否支持多语言回复?
A:把 prompt.txt 里的“请用中文”改成“请用用户母语”,Gemini 会自动识别原帖语言并匹配。
13. 进阶玩法:让机器人更像“你”
-
自定义签名:在 format_transcription_reply
末尾加一句 “—— by 小描” 就能让粉丝一眼认出。 -
过滤 NSFW:在 transcriptionBot.py
里加文字关键词检测,发现敏感词直接回复“内容不适合公开描述”。 -
批量历史补描述:遍历自己 2023 年的帖子,把没写 alt 的图片一次性补全,提升旧内容可访问性。
14. 如何贡献:从“用的人”到“一起养的人”
-
Fork 仓库 → 新建分支 feature/emoji-support
。 -
改完跑通 python -m pytest tests/
。 -
发 Pull Request,标题格式: Add emoji support for video summaries (#42)
。 -
维护者会在 48 小时内 review,合并后发 release 并 @ 你致谢。
15. 结语:让信息不再“沉默”
bskyScribe 不是最复杂的 AI 项目,却可能是最贴近日常善意的那一个。它把昂贵的多模态大模型拆成一条 250 字的便签,贴在每一扇可能关上的门前。
如果你也愿意让自己的帖子“开口说话”,不妨今天就试试。装好环境、填好密钥,@ 它一句 “describe this”,你会第一次发现——技术原来可以这么温柔。
图:无障碍不是额外功能,而是让每个人都能走在阳光下。