当前位置: 首页 > news >正文

一个命令行工具,让背单词变成一件很酷的事

anki-vocab:一个命令行工具,让背单词变成一件很酷的事

查词 → LLM 生成解析 → TTS 发音 → 存入 Anki → 还能生成考研英语阅读理解练习

GitHub: https://github.com/zhchoice123/anki-vocab


前言

背单词这件事,我折腾了很久。

用了很多 App,要么卡片太简陋(只有单词+中文释义),要么复习流程太机械。我想做的是:把每个单词都变成一张"有温度"的卡片——有英文释义、有使用场景、有记忆技巧、有发音,还有地道的例句。

于是一口气做了这个 CLI 工具:anki-vocab。它把 Claude(LLM)、OpenAI TTS、Anki 串成了一条流水线,按下一个命令,所有事情自动完成。

更妙的是,我发现光"存卡片"还不够。记过的单词得用起来。于是我又加了一个阅读理解练习模式,从你的单词库里抽取词汇,让 Claude 生成一篇考研英语风格的阅读文章,你在浏览器里阅读、做题,鼠标悬停就能看词义。


功能一览

功能 说明
🤖 AI 制卡 调用 Claude 生成结构化单词卡片(英文释义、用法、记忆技巧、Collins 释义、中文翻译)
🔊 AI 发音 OpenAI TTS 生成地道美音,即时播放并嵌入卡片
🃏 一键入库 自动存入 Anki,支持创建/更新/去重
📡 AnkiConnect 通过 HTTP API 与 Anki 交互,无需手动导入
💾 离线缓存 Anki 没开?自动写入 SQLite,下次自动同步
📖 阅读练习 生成考研英语风格阅读理解(400-500 词,5 道题),鼠标悬停查词义
🎯 错题追踪 答错的单词自动记录,下次优先练习弱词
🔌 可插拔 TTS TTS 层完全解耦,换 ElevenLabs 只需一行代码

安装

git clone https://github.com/zhchoice123/anki-vocab.git
cd anki-vocab
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt# 配置 API Key
cp .env.example .env
# 编辑 .env,填入 ANTHROPIC_API_KEY 和 OPENAI_API_KEY

前置条件:

  • Python 3.11+
  • Anki 桌面版 + AnkiConnect 插件
  • 一个名为 英语单词模板(vocab配色) 的 Note Type(10 个字段)

用法一:查词制卡

最简单的方式:

./word tenacious

终端会显示一张漂亮的 Rich 渲染卡片:

╭──────────────────────────────────────────────────────────────╮
│                                                              │
│   tenacious  adj.顽强的;坚韧不拔的                          │
│                                                              │
│   ★★★★☆                                                      │
│                                                              │
│   1. SIMPLE MEANING                                          │
│   Someone who keeps trying and never gives up.               │
│                                                              │
│   2. KEY IDEA                                                │
│   It shows very strong will and determination.               │
│                                                              │
│   ...                                                        │
│                                                              │
│   🔊  ✓  Saved to Anki                                       │
╰──────────────────────────────────────────────────────────────╯

同时你会听到 TTS 朗读 "tenacious"。卡片已自动存入 Anki。

如果这个词已经在牌组里了,它会直接播放已有音频并展示卡片,不会重复调用 API。

支持短语:

./word "give up"

支持参数覆盖:

./word --deck "My Deck" serenity      # 指定牌组
./word --speed 0.8 verbose            # 慢速发音,更清晰
./word -v tenacious                   # 开启 debug 日志

用法二:阅读理解练习

这是我个人最喜欢的功能。

./word practice

它会做以下几件事:

  1. 从你的单词库中智能选词(优先选你答错过的弱词,不足再补新词)
  2. 调用 Claude 生成一篇阅读文章——题材随机(经济、科技、历史、政治、文化…),400-500 词,4-6 段,考研英语难度
  3. 生成 5 道选择题,覆盖考研五大题型:主旨大意、细节理解、推理判断、词义猜测、作者态度
  4. 启动本地 Web 服务http://127.0.0.1:8766),自动打开浏览器

页面效果:

  • 🌙 深色主题,护眼
  • 目标单词蓝色高亮,鼠标悬停弹出英文简单释义
  • 做完提交后即时判分,标出对错并显示解析
  • 📝 错题自动写入 SQLite,下次优先复习
./word practice -n 8               # 只用 8 个词生成文章
./word practice --port 8767        # 换端口
./word practice --no-browser       # 不自动打开浏览器

错题追踪原理

每次你答错一道题,系统会读取这道题的 target_word(它考察的是哪个单词),然后在 SQLite word_errors 表中记录一次错误。

下次运行 ./word practice 时,WordSelector 会:

  1. 先按 error_count DESC, last_error DESC 取出弱词
  2. 再用最新添加的单词补足到 10 个

也就是说,你的弱词会被反复"照顾",直到你真正掌握。


离线也能用

Anki 没开?完全没问题。

当你执行 ./word tenacious 时,如果 AnkiConnect 连不上,工具会静默把完整卡片 + 音频 Base64 写入 ~/.anki-vocab/pending.db

下次运行任意命令时,后台线程会自动把这些 pending 的卡片推送到 Anki,并提示:

[sync] synced 3 pending word(s) to Anki

技术架构

这个项目代码量不大(约 2000 行 Python),但结构比较清晰:

anki-vocab/
├── add_word.py              # CLI 入口,子命令路由
├── config.py                # 环境变量配置
├── models.py                # 数据模型(WordCard、ReadingMaterial…)
├── anki/
│   ├── repository.py        # AnkiConnect HTTP 客户端
│   ├── cache.py             # LRU 缓存装饰器
│   ├── formatter.py         # WordCard ↔ Anki 字段映射
│   └── local_store.py       # SQLite 离线缓存 + 错题追踪
├── llm/
│   ├── base.py              # LLM 抽象基类
│   └── claude.py            # Claude 提供商(查词 + 阅读生成)
├── tts/                     # TTS 完全解耦
│   ├── base.py              # TTS 抽象基类
│   ├── openai_tts.py        # OpenAI TTS 实现
│   ├── player.py            # 跨平台音频播放
│   └── utils.py             # PCM → WAV 工具
├── services/
│   └── word_service.py      # 业务编排层
├── practice/                # 阅读理解练习模式
│   ├── selector.py          # 智能选词(错题优先)
│   ├── generator.py         # 阅读生成器
│   ├── server.py            # Flask Web 服务
│   ├── templates/
│   │   └── practice.html    # 阅读 UI
│   └── static/
│       └── style.css        # 深色主题 + Tooltip
├── display/
│   └── renderer.py          # Rich 终端渲染
└── tests/└── test_core.py         # 单元测试(40+ 测试用例)

设计亮点

  1. Repository + Decorator 模式CachingAnkiRepository 给 Anki 操作加了 LRU 缓存,find 读缓存,save/update 写穿缓存
  2. TTS 完全解耦TTSProvider.generate() 只返回 (filename, audio_bytes),播放和存储由上层决定。换 ElevenLabs 只需实现一个类
  3. Round-trip 序列化:Anki 卡片的 vocabulary扩展 字段里藏了一个 <span id="raw"> 元素,里面存了完整 JSON。下次查询时可以直接反序列化回 WordCard,不用重新调 LLM
  4. 并行调用:查词时 LLM 和 TTS 通过 ThreadPoolExecutor 并发执行,节省等待时间

扩展:接入其他 TTS

如果你想用 ElevenLabs 替代 OpenAI TTS:

# tts/elevenlabs_tts.py
from tts.base import TTSProviderclass ElevenLabsTTS(TTSProvider):def generate(self, word: str) -> tuple[str, bytes]:# 调用 ElevenLabs APIreturn filename, audio_bytes

然后在 add_word.py 中替换:

from tts.elevenlabs_tts import ElevenLabsTTS
tts = ElevenLabsTTS(voice_id="your-voice-id")

WordServiceAudioPlayer、测试全部无需改动。


image
image


总结

这个工具解决了我背单词流程中的几个痛点:

  • 不想手动做卡片 → Claude 自动生成结构化内容
  • 不想只听机器发音 → OpenAI TTS 生成自然语音
  • 不想手动导入 Anki → AnkiConnect 一键入库
  • 不想背了就忘 → 阅读练习模式把单词放进语境中使用
  • 不想重复记已经会的词 → 错题追踪优先复习弱词

如果你也在用 Anki + LLM 学英语,欢迎试试这个项目,提 Issue 或 PR 都可以。

GitHub: https://github.com/zhchoice123/anki-vocab

http://www.jsqmd.com/news/734412/

相关文章:

  • 快速上手KLayout:7步掌握开源版图设计工具
  • 从蓝牙耳机到智能音箱:深入聊聊PCM音频数据流在真实设备里的‘旅程’
  • 座舱式个人飞行器 - 接线图解与电气连接
  • 30岁还在写增删改查,我不想卷了,也不想躺了
  • Midscene.js:用AI视觉模型轻松实现跨平台智能自动化
  • MCP 2026国产化迁移成本黑洞:3类隐性开销未计入预算(附工信部认证TCO测算模板V2.6)
  • AI功能上线即超支?Laravel 12服务编排层成本熔断机制,精准拦截83%隐性支出
  • 高效视频对比工具video-compare:5个专业技巧深度解析
  • ESP32-S3开发板WiFIRCard:智能家居与工业控制解决方案
  • file 浏览
  • 为什么92%的量子算法工程师在Docker 27升级后遭遇qubit仿真失败?——NIST认证的5步诊断协议曝光
  • 别再只会删.condarc了!Miniconda在Linux服务器上遇到‘An unexpected error‘的三种深度排查思路
  • XGP存档提取器:3分钟实现Xbox Game Pass游戏进度无损迁移
  • ElasticSearch 项目实战,ES 如何使用,ES 的作用,代码已发布 Gitee
  • 终极指南:5分钟在Photoshop中集成AI绘画功能
  • 避开这个坑!Proteus 仿真 STM32 ADC 采样值为0的排查与解决思路
  • 从UI交互到数据绑定:详解Unity 2D日期选择器组件的设计与事件处理逻辑
  • 2026年5月阿里云部署OpenClaw/Hermes Agent详解+百炼token Plan速成攻略
  • 手把手教你用VirtualBox虚拟盘给ZFS zpool做缓存测试,安全又方便
  • 【AVRCP】规范精讲[7]: 打通AVCTP互操作底层,吃透事务标签与分片规则
  • 通过环境变量为Hermes Agent配置Taotoken自定义模型提供商
  • 生态研究者的GEE实战:如何用MOD17A2H数据精准提取植被生长季GPP?
  • R语言做LLM偏见检测必须掌握的5种统计检验法:卡方校准、Wald偏差分解、贝叶斯后验偏移诊断,全链路代码开源
  • DDR3内存验证技术:挑战、解决方案与应用实践
  • AI专著生成大揭秘!4款工具推荐,高效完成20万字专著写作!
  • 终极NVIDIA显卡优化指南:用Profile Inspector解锁隐藏性能
  • ARM开发板远程调试避坑大全:从交叉编译GDBServer到解决‘GLIBC版本不匹配’实战记录
  • HTML怎么创建引用_HTML blockquote与cite使用【说明】
  • Arduino中断避坑指南:为什么你的拉线编码器读数总跳变?从AB相信号处理说起
  • 考虑天气因素的城市负荷预测方法研究附Matlab代码