跳转到内容

工作原理概览

DevLingo 的核心是一个智能的”查询分层”系统:从本地快速查询开始,逐级升级到 AI 推理。这样大多数查询在毫秒内完成,复杂查询也不超过 2 秒。

用户在任意应用中选中文本
[触发] 按下 ⌘⇧D 快捷键
[提取] TextExtractor 获取:
• 选中的文本本身
• 前后 50 字的上下文(用于 AI 理解语境)
• 当前应用 bundleIdentifier(Xcode / Slack / GitHub 等)
[分类] InputTypeDetector 判断输入类型:
• 中文 → Express 模式
• 单词 → Word 模式
• 2-4 词且无句子结构 → Phrase 模式
• 完整句子 ≤20词 → Sentence 模式
• 多句或 >20词 → Paragraph 模式
[查询] LookupCoordinator 分层查询(详见下)
[渲染] FloatingPanelController:
• 在鼠标下方弹出 NSPanel 浮窗
• 显示 skeleton screen(加载动画)
• 根据模式选择对应的 View 子类(WordView / PhraseView / SentenceView 等)
• 数据到达后,平滑淡入结果
[交互] 用户可以:
• 点击播放按钮听发音
• 点击单词做递归查询
• 保存到"生词本"(SwiftData)
• 关闭浮窗继续工作

这是 DevLingo 性能的关键。按优先级依次查询,找到结果即返回:

第一层:本地技术词汇库(<50ms)

Section titled “第一层:本地技术词汇库(<50ms)”

对于英文输入,首先在本地 SQLite 数据库中查询。预置了 85+ 常见的开发术语:

idempotent, deployment, microservice, containerization,
latency, throughput, cache invalidation, API gateway,
circuit breaker, distributed tracing, ...

命中率约 30% 的开发词汇查询。极速响应。

第二层:本地开发短语库(<100ms)

Section titled “第二层:本地开发短语库(<100ms)”

对于 2-4 词的短语,查询本地短语数据库(50+ 预置短语):

yak shaving, bikeshedding, rubber ducking, code smell,
low-hanging fruit, technical debt, nerd sniping, ...

命中率约 20% 的短语查询。

用户之前查过的词汇、短语、句子都缓存在本地 SwiftData 中。如果找到,直接返回。

用户查过 "idempotent" → 下次查询 <10ms

命中率约 50%(取决于使用历史)。

如果前三层都未命中,调用 Claude API 获取结构化响应。

请求:{
"text": "gracefully degrade",
"mode": "phrase",
"context": "when upstream dependencies are unavailable",
"sourceApp": "Xcode",
"userLanguage": "zh-CN"
}
响应:{
"type": "phrase", // compound verb
"definition_en": "...",
"definition_zh": "...",
"examples": [...],
"pronunciation": {...},
"register": "technical",
"l1_tips": "..."
}

:::note 为什么分层设计

  • 95% 的常用词汇 命中前三层,<100ms 返回
  • 5% 的冷门或新词汇 才需要 Claude API,但也只是 1-2 秒
  • 无网络时 仍然能查询本地库和缓存
  • 节省用户配额 Claude API 价格按使用次数计,分层减少了 95% 的 API 调用 :::

DevLingo 后端部署在 Cloudflare Workers 边缘节点上,处理 API 请求。

Mac 应用
↓ HTTPS (Bearer token)
Cloudflare Workers (Edge)
├─ API Gateway (Hono 路由)
├─ Auth Middleware (JWT 验证)
├─ Lookup Endpoint (/api/lookup)
│ └─ Claude API Client (代理 AI 请求)
├─ TTS Endpoint (/api/tts)
│ └─ Google Cloud TTS (代理发音合成)
└─ Data Sync Endpoints
└─ Cloudflare D1 (用户数据库)
  • Hono 框架:轻量级 HTTP 框架,专为 Cloudflare Workers 优化
  • D1 数据库:SQLite on Cloudflare,存储用户的生词本、同步数据
  • KV 存储:会话令牌、速率限制缓存、API 响应缓存
  • Claude API 代理:Mac 应用通过 Workers 代理对 Claude 的请求,避免在本地暴露 API 密钥

TextExtractor 利用 AXUIElement(macOS 无障碍 API)获取:

用户在 Slack 中选中:"idempotent"
提取结果:
{
"selectedText": "idempotent",
"beforeContext": "We need to make sure this endpoint is ",
"afterContext": " for retry requests.",
"sourceApp": "com.tinyspeck.slackmacgap", // Slack
"fullSentence": "We need to make sure this endpoint is idempotent for retry requests."
}

这个上下文被发送给 Claude,帮助 AI 理解:“idempotent 在这里是 API 设计语境”,而不是其他。

if 文本包含中文:
→ Express 模式
elif 词数 == 1:
→ Word 模式
elif 词数 in [2, 3, 4]:
if 包含完整句子结构:
→ Sentence 模式
else:
→ Phrase 模式
elif 句数 > 1 or 词数 > 20:
→ Paragraph 模式
else:
→ Sentence 模式

:::tip 智能检测 输入检测在本地瞬间完成,无 API 调用。确保用户永远感受不到”判断输入类型”这一步的延迟。 :::

FloatingPanelController 创建一个 NSPanel(浮窗):

特性:
• 显示在所有应用上层(Level: screenSaver)
• 位置:鼠标正下方(y offset +20px,避免遮挡)
• 初始状态:skeleton screen(加载骨架)
• 数据到达:淡入,销毁 skeleton
• 交互:完全透传鼠标(不阻止后台应用)
• 关闭方式:点击外部、按 ESC、5 分钟无操作自动关闭
  • 本地库查询:<50ms(99 百分位)
  • 缓存命中:<10ms
  • 完整端到端(含 API):<2s(99 百分位)
  • 浮窗出现时间:<300ms(用户感知的快)
  • TTS 音频生成:首次 <2s,后续缓存 <100ms

:::note 缓存策略 TTS 音频也被缓存在本地和 KV,同一单词的发音只合成一次。 :::

用户文本
Mac 应用 (HTTPS 加密)
Cloudflare Edge (即时处理)
├─ Claude API 请求(临时,不用于训练)
└─ 结果缓存到 KV(自动过期)
结果返回到 Mac
本地 SwiftData 存储(设备内,可选云同步到 D1)

文本内容不被存储,除非用户主动保存到生词本。详见数据隐私与安全

DevLingo 的架构设计理念是:“快速为主,AI 为辅,隐私第一”。