OpenHarmony 英语学习 App 实战:TTS、端侧 AI 与元服务能力集成思路
OpenHarmony 英语学习 App 实战:TTS、端侧 AI 与元服务能力集成思路
摘要
AI 不应该只是学习 App 里的一个“智能问答按钮”。在真实学习流程中,AI 更适合被拆进每个关键环节:单词读音、语境讲解、错题分析、难度调整、作文批改、学习报告和口语陪练。🤖📖
本文以我的 OpenHarmony/HarmonyOS 英语学习项目「英语视界 YingYu」为例,分享当前项目中已经实现的 TTS 语音朗读能力,以及后端预留的 AI Agent 接口设计。同时,也会讨论后续如何扩展端侧 AI、人脸识别开放能力和元服务能力。
需要说明的是:当前项目已经具备 TTS 和 AI 接口预留,人脸识别与元服务属于后续集成思路,本文不会把未完成能力写成已上线功能。
一、项目中的 AI 能力应该服务哪些学习场景?
「英语视界」是一个面向中小学生的英语学习 App,核心功能包括:
- 词汇学习;
- 听力训练;
- 每日一句;
- 语法专题;
- 短语学习;
- 趣味英语;
- 自定义生词本;
- 艾宾浩斯复习;
- 学习成就系统。
这些功能背后有很多适合 AI 介入的点:
| 学习场景 | AI 能力 |
|---|---|
| 不会读单词 | TTS 标准发音 |
| 不理解单词 | AI 语境讲解 |
| 做错语法题 | AI 错因分析 |
| 题目太简单/太难 | 自适应难度 |
| 写作文 | AI 作文批改 |
| 学习坚持困难 | AI 学习陪伴 |
| 复习效率低 | 端侧复习计划 |
因此我更倾向于把 AI 做成“学习流程增强器”,而不是一个单独页面。
二、已实现能力:TTS 英语听力朗读
项目中已经有 ListeningTtsHelper.ets,用于听力材料和英文文本朗读。它基于 @kit.CoreSpeechKit 的 textToSpeech 能力实现。
import { textToSpeech } from '@kit.CoreSpeechKit'
import { BusinessError } from '@kit.BasicServicesKit'
创建引擎时,优先使用在线引擎:
const initParams: textToSpeech.CreateEngineParams = {
language: 'en-US',
person: 0,
online: 1,
extraParams: {
'style': 'interaction-broadcast',
'locate': 'US',
'name': 'ListeningTts'
}
}
textToSpeech.createEngine(initParams, (err: BusinessError, engine: textToSpeech.TextToSpeechEngine) => {
if (err) {
console.error(`[ListeningTts] createEngine(online) failed: ${err.code} ${err.message}`)
this.createEngineOffline(callback)
return
}
this.ttsEngine = engine
this.attachListener()
onReady()
})
这个设计比较实用:在线引擎效果通常更好,但如果失败,可以降级到离线引擎,保证学习流程不中断。
三、离线兜底:弱网环境下也能学习
在线引擎失败时,项目会尝试创建离线引擎:
private createEngineOffline(
callback: (err: BusinessError, engine: textToSpeech.TextToSpeechEngine) => void
): void {
const initParams: textToSpeech.CreateEngineParams = {
language: 'en-US',
person: 0,
online: 0,
extraParams: {
'style': 'interaction-broadcast',
'locate': 'US',
'name': 'ListeningTts'
}
}
textToSpeech.createEngine(initParams, (err, engine) => {
callback(err, engine)
})
}
对学习 App 来说,离线兜底非常重要。因为用户可能在地铁、学校、宿舍等网络环境不稳定的地方学习,如果语音朗读完全依赖网络,就会影响连续性。
四、播放监听:让 UI 状态可控
创建 TTS 引擎后,需要监听播放状态:
private attachListener(): void {
if (!this.ttsEngine) return
this.ttsEngine.setListener({
onStart: (_rid, _resp) => {
console.info('[ListeningTts] onStart')
this.clearSafetyTimer()
this.startSafetyTimer(() => {
this.safeStop()
this.invokeEnd()
})
},
onComplete: (_rid, _resp) => {
console.info('[ListeningTts] onComplete')
this.invokeEnd()
},
onStop: (_rid, _resp) => {
console.info('[ListeningTts] onStop')
this.invokeEnd()
},
onError: (_rid, code: number, msg: string) => {
console.error(`[ListeningTts] onError code=${code} msg=${msg}`)
this.invokeError()
}
})
}
这样页面就可以根据播放状态切换按钮:
- 播放中;
- 已完成;
- 播放失败;
- 用户主动停止。
学习类产品要特别注意这种状态控制,否则用户可能不知道当前到底是在加载、播放还是失败。
五、安全定时器:避免静默失败
语音播放中最难受的问题是:用户点击播放后没有声音,但按钮一直处于播放状态。为了解决这个问题,项目加入了安全定时器。
private startSafetyTimer(onTimeout: () => void): void {
this.clearSafetyTimer()
this.safetyTimerId = setTimeout(() => {
this.safetyTimerId = -1
console.error('[ListeningTts] safety timer fired, triggering timeout')
onTimeout()
}, this.SAFETY_TIMEOUT_MS) as number
}
如果超过指定时间还没有正常完成,就主动触发兜底逻辑:
this.startSafetyTimer(() => {
console.warn('[ListeningTts] safety timeout after onStart, stopping')
this.safeStop()
this.invokeEnd()
})
这类细节虽然不起眼,但非常影响体验。特别是听力练习,如果播放状态不可靠,用户会对整个功能失去信心。
六、朗读参数:适配英语学习场景
项目在朗读时设置了语速、音量、音高和语言上下文:
const params: textToSpeech.SpeakParams = {
requestId: `s_${Date.now()}`,
extraParams: {
'queueMode': 0,
'speed': 0.92,
'volume': 1,
'pitch': 1,
'languageContext': 'en-US',
'soundChannel': 0,
'playType': 0
}
}
this.ttsEngine.speak(text, params)
这里把语速设置为 0.92,比正常语速稍慢一点,更适合学生跟读和听力训练。后续还可以做成用户可配置项:
- 慢速;
- 标准;
- 快速;
- 美音/英音;
- 单句循环;
- 跟读模式。
七、后端 AI Agent 接口预留
除了端侧 TTS,项目后端也预留了 AI Agent 路由,集中在 web/backend/src/routes/ai.ts。
单词讲解接口:
router.post('/explain-word', authenticate, asyncHandler(async (req, res) => {
const { word, context } = req.body
if (!word) {
return res.status(400).json({
success: false,
error: { message: 'Word is required' }
})
}
const explanation = await explainWord(word, context)
res.json({
success: true,
data: { explanation }
})
}))
自适应难度接口:
router.post('/adaptive-difficulty', authenticate, asyncHandler(async (req, res) => {
const { recentResults } = req.body
if (!recentResults || !Array.isArray(recentResults)) {
return res.status(400).json({
success: false,
error: { message: 'Recent results array is required' }
})
}
const difficulty = await getAdaptiveDifficulty(recentResults)
res.json({
success: true,
data: { difficulty }
})
}))
这些接口虽然目前部分仍是预留或占位,但架构已经把 AI 能力拆成多个学习服务,而不是写成一个泛化接口。
八、单词讲解:从查词典升级为讲语境
wordExplainer.ts 中定义了单词讲解返回结构:
interface WordExplanation {
word: string
phonetic?: string
definition: string
partOfSpeech: string
usage: string
tips: string
synonyms?: string[]
antonyms?: string[]
examples: Array<{
sentence: string
translation: string
}>
collocations: string[]
level: string
}
这个结构比普通词典更适合学习,因为它不仅有释义,还包括:
- 使用场景;
- 记忆技巧;
- 近义词;
- 反义词;
- 例句;
- 常见搭配;
- CEFR 等级。
后续接入真实 AI 服务后,就可以根据用户年级和上下文生成更适合学生理解的解释。
九、自适应难度:端侧规则算法先打底
AI 不一定所有地方都要依赖大模型。项目中的 adaptiveDifficulty.ts 就使用了规则算法,根据最近答题正确率和响应时间调整难度。
const recent = recentResults.slice(-10)
const correctCount = recent.filter(r => r.correct).length
const accuracy = correctCount / recent.length
const avgResponseTime =
recent.reduce((sum, r) => sum + r.responseTime, 0) / recent.length
const avgDifficulty =
recent.reduce((sum, r) => sum + r.difficulty, 0) / recent.length
难度调整逻辑:
if (accuracy >= 0.9 && avgResponseTime < 3000) {
newLevel = Math.min(5, Math.round(avgDifficulty) + 1)
recommendations.push('表现优秀,建议挑战更高难度')
} else if (accuracy >= 0.8) {
newLevel = Math.round(avgDifficulty)
recommendations.push('继续保持当前节奏')
} else if (accuracy < 0.6) {
newLevel = Math.max(1, Math.round(avgDifficulty) - 1)
recommendations.push('建议回到基础题目重新学习')
}
这种方案很适合端侧 AI 思路:
- 本地快速判断;
- 不依赖网络;
- 成本低;
- 隐私友好;
- 可以和云端 AI 结合生成解释。
十、推荐 AI 架构:端侧轻判断 + 云端深分析
结合当前项目,后续 AI 架构可以这样演进:
ArkUI 页面
-> AppStorage / Preferences 保存学习状态
-> 本地算法生成复习计划和难度建议
-> TTS 提供听力朗读和跟读反馈
-> 后端 AI 提供单词讲解、错题分析、作文批改
-> 学习报告汇总用户表现和下一步建议
端侧适合做:
- 学习进度统计;
- 今日任务生成;
- 艾宾浩斯复习计划;
- 自适应难度初判;
- TTS 播放控制;
- 离线学习状态维护。
云端或大模型适合做:
- 复杂语义解释;
- 错因分析;
- 作文批改;
- 口语对话;
- 学习报告;
- 个性化建议生成。
这样可以兼顾体验、成本和隐私。
十一、人脸识别开放能力的集成思路
当前项目没有接入人脸识别,因此不能把它写成已完成功能。但从教育产品角度看,人脸识别可以作为“可选能力”用于低侵入场景:
- 学生模式和家长模式快速切换;
- 学习打卡时确认本人;
- 多学生共用平板时识别学习档案;
- 家长授权进入高级设置。
不过,人脸能力必须非常谨慎:
- 不默认开启;
- 不保存原始人脸图像;
- 提供账号密码等替代方案;
- 明确展示用途;
- 未成年人场景需要监护人授权;
- 设置页提供关闭和删除入口。
我的建议是:人脸识别不应该被设计成“学习功能本身”,而应该作为身份确认或模式切换的辅助能力。
十二、元服务能力:把学习入口做轻
英语学习任务通常很碎片化,非常适合元服务或轻量入口:
- 今日 10 个单词;
- 1 条每日一句;
- 3 分钟听力;
- 5 个待复习词;
- 一键查看学习报告;
- 快速打卡。
结合当前项目,可以拆出以下轻入口:
| 元服务方向 | 对应页面 |
|---|---|
| 今日任务 | DailyTask |
| 复习卡片 | ReviewCenter |
| 每日一句 | DailySentence |
| 听力训练 | ListeningContent |
| 学习报告 | ShareCenter |
元服务的价值在于:用户不一定每次都要完整打开 App,也能完成一次小学习任务。对于英语学习这种高频低时长场景,非常适合。
十三、AI 能力落地路线图
结合项目现状,我会按下面路线推进:
第一阶段:稳定已有能力
- 优化 TTS 播放体验;
- 增加语速设置;
- 增加单词朗读;
- 增加听力循环播放;
- 完善播放失败兜底。
第二阶段:接入文本 AI
- 单词语境讲解;
- 错题原因分析;
- 语法知识点解释;
- 学习报告生成;
- 作文批改。
第三阶段:端侧智能化
- 本地学习画像;
- 本地复习计划;
- 本地难度调整;
- 离线可用的学习建议;
- 更细粒度的学习统计。
第四阶段:系统级入口
- 元服务每日任务;
- 实况窗学习进度;
- 近场分享学习成果;
- 多设备续学;
- 可选人脸身份确认。
这条路线不会一上来就堆满 AI 功能,而是从学习流程中最刚需的点开始逐步增强。
十四、实现时的注意事项
1. AI 输出要适合学生年龄
同一个单词,对小学生和高中生的解释方式应该不同。后续接入 AI 时,要把年级、难度和上下文作为参数。
2. TTS 要考虑失败和弱网
语音能力不能只处理成功路径。超时、失败、停止、重复点击都要有兜底。
3. 端侧能解决的不要都丢给云端
难度调整、复习计划、学习统计这类任务,本地算法完全可以先做一版,响应更快,也更省成本。
4. 人脸识别一定要可选
教育类应用不能为了“高级能力”牺牲隐私边界。身份识别能力必须谨慎、透明、可关闭。
5. 元服务要聚焦一个任务
元服务不是迷你版完整 App,而是一个明确任务入口。例如“复习 5 个单词”就比“打开学习中心”更有价值。
十五、小结
本文结合「英语视界 YingYu」项目,梳理了 OpenHarmony/HarmonyOS 英语学习 App 的 AI 能力设计:
- 当前已实现 TTS 英文朗读;
- TTS 引擎支持在线优先、离线兜底;
- 播放流程加入监听和安全定时器;
- 后端预留了单词讲解、错题分析、自适应难度等 AI 接口;
- 自适应难度可以先用本地规则算法实现;
- 推荐“端侧轻判断 + 云端深分析”的架构;
- 人脸识别适合作为可选身份能力;
- 元服务适合承载每日任务、复习卡片和每日一句。
AI 在教育场景里的价值,不是让 App 看起来更炫,而是让学习更连续、更个性化、更容易坚持。OpenHarmony/HarmonyOS 的端侧能力、分布式能力和系统级入口,正好可以把 AI 从一个按钮扩展成一套完整的学习陪伴系统。🌟

更多推荐


所有评论(0)