让每一条动态都有“声音”:手把手教你用 bskyScribe 给 Bluesky 做媒体无障碍描述

想象一下:你在 Bluesky 上刷到一段 45 秒的视频,创作者没留下任何文字说明;或者一张信息图,字小得看不清。对视力受限、听力受限,或只是通勤路上没带耳机的用户来说,这些内容就像上了锁。
bskyScribe 就是一把小巧却趁手的钥匙——它 24 小时蹲守通知栏,一旦有人召唤,就自动把图片、音频、视频翻译成一段 250 字以内的贴心摘要,再贴回评论区,让任何人都能“秒懂”。

这篇文章会带你走完从安装、配置到真正跑起来的全过程,不堆术语、不画大饼,每一步都给出可直接复制的命令和可感知的“为什么”。如果你刚刚专科或本科毕业,对 Python 只是“会用 pip”,也能顺利跟上。


1. 为什么我们需要“媒体描述机器人”?

场景 没有描述 有 bskyScribe
视力障碍用户 只能知道“这里有张图” 听到或读到“图里是三只柯基在草地追飞盘”
地铁里静音刷手机 视频自动播放,没字幕 评论区出现“视频里主讲者用 30 秒介绍新款键盘的静音轴”
多语言社群 日语图表看不懂 直接给出中文要点:“图表显示 2024 年手机出货量比 2023 上涨 7%”

bskyScribe 的价值不是炫技,而是把信息平权落到每一次回复。它用 Google Gemini 做大脑,用 AT Protocol 做耳朵和嘴巴,把原本需要人工撰写的“alt text”自动化、规模化,却又不牺牲可读性。


2. 项目全景:一张图看懂流程

流程图:通知→拉取→AI 分析→回帖
图:bskyScribe 的五步循环

  1. 监听:像安静的图书管理员,只在有人“点名”时才抬头。
  2. 抓取:把原帖里的图片、视频、音频一次性拉回本地内存,不占硬盘。
  3. 思考:丢给 Google Gemini,让它判断是“描述画面”“读文字”还是“总结语音”。
  4. 精简:把可能上百字的分析压缩到 250 字符以内(Bluesky 单条限制)。
  5. 回复:自动回帖,并在日志里留下一条“已完成”的绿钩。

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——免费又省心

  1. 用 GitHub 账号登录 render.com
  2. New → Background Worker → 绑定仓库。
  3. 环境变量页粘贴 .env 内容。
  4. 保存,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. 如何贡献:从“用的人”到“一起养的人”

  1. Fork 仓库 → 新建分支 feature/emoji-support
  2. 改完跑通 python -m pytest tests/
  3. 发 Pull Request,标题格式:Add emoji support for video summaries (#42)
  4. 维护者会在 48 小时内 review,合并后发 release 并 @ 你致谢。

15. 结语:让信息不再“沉默”

bskyScribe 不是最复杂的 AI 项目,却可能是最贴近日常善意的那一个。它把昂贵的多模态大模型拆成一条 250 字的便签,贴在每一扇可能关上的门前。
如果你也愿意让自己的帖子“开口说话”,不妨今天就试试。装好环境、填好密钥,@ 它一句 “describe this”,你会第一次发现——技术原来可以这么温柔

盲道与阳光
图:无障碍不是额外功能,而是让每个人都能走在阳光下。