【HarmonyOS学习笔记】2026-07-24 | textProcessing 实体识别与踩坑实录


date: 2026-07-24
tags: [HarmonyOS, textProcessing, 实体识别, NaturalLanguageKit, ArkTS, 触摸事件, 异步回调]
type: 技术参考+踩坑实录

Part 1:textProcessing 实体识别技术参考

HarmonyOS NaturalLanguageKit textProcessing.getEntity() 的 10 种实体类型完整技术参考
since 5.0.0(12)

API 概览

import { textProcessing, EntityType } from '@kit.NaturalLanguageKit'

const entities = await textProcessing.getEntity(text: string, entityConfig?: EntityConfig)

interface Entity {
  text: string        // 实体原文本
  charOffset: number  // 实体在原文本中的字符偏移
  type: EntityType    // 实体类别
  jsonObject: string  // 结构化信息(JSON字符串,需JSON.parse解析)
}

interface EntityConfig {
  entityTypes?: EntityType[]  // 指定只识别哪些类型,默认全选
}

关键特性:

  • since 5.0.0(12),API 24 完全可用
  • 无权限要求
  • init() 非必须,调用可减少首次延迟
  • jsonObject 是 JSON 字符串,需 JSON.parse() 解析
  • 文本长度不超过 1000 字符
  • 支持语言:简体中文、英文、繁体中文
  • 不支持模拟器

10 种实体一览

#枚举名枚举值中文名说明
1EntityType.DATETIME'datetime'时间识别日期、时间、周期、节日,返回 startTimestamp/endTimestamp 时间戳和 repeat 周期
2EntityType.EMAIL'email'邮箱识别电子邮件地址,jsonObject 为空,原文即邮箱
3EntityType.EXPRESS_NO'expressNo'快递单号识别快递单号,返回 isTailNum 判断是否仅尾号
4EntityType.FLIGHT_NO'flightNo'航班号识别航班号(如 CA1234),jsonObject 为空,原文即航班号
5EntityType.LOCATION'location'地点识别地点,返回结构化地址(省/市/区/道路),含 isAbstract 判断是否抽象地点
6EntityType.NAME'name'姓名识别人名,返回 type 区分正式姓名(nr)/昵称(nrn)/称谓(nrt)/其他(nrx)
7EntityType.PHONE_NO'phoneNo'手机号识别手机号和固话,返回 type 区分手机(1)/固话(0),含分机号 extNumber
8EntityType.URL'url'URL识别网址链接,jsonObject 为空,原文即 URL
9EntityType.VERIFICATION_CODE'verificationCode'验证码识别验证码,返回 type(验证码内容) 和 supplier(提供商)
10EntityType.ID_NO'idNo'身份证号识别证件号,返回 type 区分身份证(0)/护照(1),含 isComplete 判断是否完整

1. DATETIME — 时间实体

测试输入:

"明天要交报告"
"下周一去北京出差"
"下午3点开会"
"8月15号前完成"
"每天早上跑步"
"这周末"
"国庆节"
"今天跑了5公里"
"后天"
"明天下午5点到7点"

jsonObject 结构:键名 "time",值为 JSONArray:

{
  "time": [{
    "repeat": "每天",
    "rrule": "",
    "start": "2026-07-23T08:00:00",
    "suggestStart": "2026-07-23T08:00:00",
    "startTimestamp": 1784736000000,
    "end": "2026-07-23T12:00:00",
    "suggestEnd": "2026-07-23T12:00:00",
    "endTimestamp": 1784750400000,
    "maxSection": "P",
    "minSection": "P",
    "isContainFuzzyTime": false,
    "containFuzzySection": "",
    "inferType": "",
    "rangeDecoration": "",
    "rangeText": "",
    "isFestival": false,
    "normalFestival": "",
    "isLunarTime": false,
    "startLunarTime": "",
    "isSolarTerm": false,
    "isIllegal": false,
    "isChangedIllegal": false,
    "isPlusTwelveHour": false,
    "sequence": 1,
    "oriFestival": "",
    "timestampZone": "",
    "originTimestamp": 1784736000000
  }]
}

字段说明:

字段类型说明
repeatstring周期文本(“每天”、"每周一"等)
startstring开始时间 ISO 格式
suggestStartstring具体开始时间
startTimestampnumber开始时间戳(毫秒)
endstring结束时间 ISO 格式
suggestEndstring具体结束时间
endTimestampnumber结束时间戳(毫秒)
maxSectionstring最大时间粒度(P=精确, M=早晨, F=上午, N=中午, A=下午, L=傍晚, E=晚上, W=凌晨)
minSectionstring最小时间粒度
isContainFuzzyTimeboolean是否包含模糊时间
containFuzzySectionstring模糊时间粒度
inferTypestring时间推理类型
rangeDecorationstring范围描述
rangeTextstring带范围描述的文本
isFestivalboolean是否节日
normalFestivalstring节日归一化值
isLunarTimeboolean是否农历
startLunarTimestring农历时间
isSolarTermboolean是否节气
isIllegalboolean是否非法时间
isChangedIllegalboolean是否自动修正
isPlusTwelveHourboolean是否包含天以内模糊时间
sequencenumber实体出现频率
oriFestivalstring包含的节日文本
timestampZonestring时区
originTimestampnumber入参文本时间戳

2. EMAIL — 邮箱实体

测试输入:"发邮件到test@example.com"

jsonObject 结构:键名 "email",值为空字符串。jsonObject 无额外结构化信息,实体原文即邮箱地址。


3. EXPRESS_NO — 快递单号实体

测试输入:"快递单号SF1234567890"

jsonObject 结构:键名 "expressNo",值为 JSONArray:

{
  "expressNo": [{
    "isTailNum": 0
  }]
}
字段类型说明
isTailNumnumber0=完整单号, 1=仅尾号

4. FLIGHT_NO — 航班号实体

测试输入:"我坐CA1234的航班"

jsonObject 结构:键名 "flightNo",值为空字符串。jsonObject 无额外结构化信息,实体原文即航班号。


5. LOCATION — 地点实体

测试输入:

"下午去国贸开会"
"北京朝阳区万达广场"
"我在上海"
"去趟南京路"
"公司楼下星巴克"

jsonObject 结构:键名 "location",值为 JSONArray:

{
  "location": [{
    "type": "",
    "coreLocation": {
      "oriText": "国贸",
      "value": "国贸",
      "province": "北京市",
      "city": "北京市",
      "county": "朝阳区",
      "district": "",
      "subDistrict": "",
      "town": "",
      "village": "",
      "subVillage": "",
      "region": "",
      "road": "",
      "default": "国贸",
      "location": ""
    },
    "adornLocation": {},
    "isAbstract": 0
  }]
}

外层字段:

字段类型说明
typestring地点类型
coreLocationobject核心地点信息
adornLocationobject修饰核心地点的信息
isAbstractnumber0=非抽象地点, 1=抽象地点

coreLocation 字段:

字段类型说明
oriTextstring原文
valuestring归一化值
provincestring省
citystring市
countystring区/县
districtstring区域
subDistrictstring子区域
townstring镇
villagestring村
subVillagestring子村
regionstring地区
roadstring道路
defaultstring默认显示名称
locationstring定位信息

6. NAME — 姓名实体

测试输入:"老王电话13812345678" / "张三说明天开会" / "李医生说要注意休息"

jsonObject 结构:键名 "name",值为 JSONArray:

{
  "name": [{
    "type": "nr"
  }]
}
字段类型说明
typestringnr=正式姓名, nrn=昵称, nrt=称谓, nrx=其他

7. PHONE_NO — 手机号实体

测试输入:"老王电话13812345678" / "打给010-88888888" / "联系电话13812345678分机1234"

jsonObject 结构:键名 "phoneNum",值为 JSONArray:

{
  "phoneNum": [{
    "type": 1,
    "number": "13812345678",
    "extNumber": ""
  }]
}
字段类型说明
typenumber0=固话, 1=手机
numberstring号码(去除分机号)
extNumberstring分机号

8. URL — URL 实体

测试输入:"访问https://example.com查看详情"

jsonObject 结构:键名 "url",值为空字符串。jsonObject 无额外结构化信息,实体原文即 URL。


9. VERIFICATION_CODE — 验证码实体

测试输入:"验证码123456" / "你的验证码是888999"

jsonObject 结构:键名 "verificationCode",值为 JSONArray:

{
  "verificationCode": [{
    "type": "123456",
    "supplier": "某平台"
  }]
}
字段类型说明
typestring验证码内容
supplierstring验证码提供商(可选)

10. ID_NO — 身份证号实体

测试输入:"身份证号110101199001011234" / "护照号12345678"

jsonObject 结构:键名 "idNo",值为 JSONArray:

{
  "idNo": [{
    "number": "110101199001011234",
    "sequence": 1,
    "type": 0,
    "isComplete": 1
  }]
}
字段类型说明
numberstring证件号码
sequencenumber出现频率
typenumber0=身份证, 1=护照
isCompletenumber1=完整证件号, 0=含*等字符

错误码参考

错误码说明
200运行超时,请稍后重试
401参数检查失败
1011200001运行失败,请重试
1011200002服务异常

init/release 生命周期

方法说明
init()预热引擎,减少首次调用延迟。非必须,不调则首次 getEntity 自动初始化
release()释放引擎资源

两者共享同一个引擎,对 getEntity 和 getWordSegment 都生效。

推荐方案:onForeground → init(),onBackground → release()。前台时引擎常驻内存,提取无延迟;切后台释放资源给其他应用;回前台重新预热(100-300ms)。


输出格式示例

输入:"明天下午3点去国贸找老王,他电话13812345678"

📅 时间:明天下午3点
  → {"time":[{"start":"2026-07-24T15:00:00","startTimestamp":1784828400000,...}]}
📍 地点:国贸
  → {"location":[{"type":"","coreLocation":{"oriText":"国贸","default":"国贸",...},"isAbstract":0}]}
👤 姓名:老王
  → {"name":[{"type":"nrn"}]}
📞 手机:13812345678
  → {"phoneNum":[{"type":1,"number":"13812345678","extNumber":""}]}

Part 2:踩坑实录

Bug 1:划走松开仍发送消息

现象:按住按钮说话,手指划出按钮区域后松开,消息仍然被发送。期望划走松开应丢弃。

根因:HarmonyOS TouchEvent 机制:

用户操作系统触发开发者预期
原地松开TouchType.Up发送消息 ✅
手指划出区域松开TouchType.Up ❌以为是 Cancel
系统拦截(弹窗遮盖等)TouchType.Cancel丢弃消息 ✅

Cancel 是系统级事件,不是用户级事件。 手指划出组件区域后松开,系统仍然触发 Up 而非 Cancel。只有系统拦截(权限弹窗、手势冲突等)才会触发 Cancel。

修复:记录 Down 坐标,Up 时算位移距离,>50vp 走 cancel(),≤50vp 走 stop():

@Local touchStartX: number = 0
@Local touchStartY: number = 0

.onTouch((event: TouchEvent) => {
  if (event.type === TouchType.Down) {
    this.touchStartX = event.touches[0].x
    this.touchStartY = event.touches[0].y
    this.inputService.start()
  } else if (event.type === TouchType.Up) {
    const dx = event.touches[0].x - this.touchStartX
    const dy = event.touches[0].y - this.touchStartY
    const distance = Math.sqrt(dx * dx + dy * dy)
    if (distance > 50) {
      this.inputService.cancel()
    } else {
      this.inputService.stop()
    }
  } else if (event.type === TouchType.Cancel) {
    this.inputService.cancel()
  }
})

教训:不要假设 Cancel = 手指划出。Cancel 是系统级事件不是用户级事件。需要用坐标位移来判断用户意图。


Bug 2:权限弹窗后按钮保持红色

现象:首次按住按钮 → 弹出权限对话框 → 授权后关闭 → 按钮仍然红色 → 直到点击任意位置才恢复。

根因:时序分析:

1. Down → start() → _holding=true → 按钮变红
2. await PermissionHelper.request() → 弹出权限对话框
3. 用户在对话框上操作 → 手指离开按钮 → 但 touch 事件被对话框拦截
4. Up/Cancel 事件没发到按钮 → stop()/cancel() 没被调用
5. _holding 仍然是 true → 按钮保持红色 ❌
6. 权限授权成功 → startRecording() → 引擎开始录音 → 但用户不知道
7. 直到用户点击任意位置 → 触发新的 touch → 按钮才恢复

核心问题:权限弹窗期间 touch 事件被系统对话框拦截,按钮收不到 Up/Cancel,_holding 无法恢复。

修复:start() 中先同步检查权限(getSelfPermissionStatus),已授权直接录音;未授权才弹窗,弹窗后 _holding=false 恢复 UI,本次录音作废:

async start(): Promise<void> {
  const atManager = abilityAccessCtrl.createAtManager()
  const permStatus = atManager.getSelfPermissionStatus('ohos.permission.MICROPHONE')
  const alreadyGranted = permStatus === abilityAccessCtrl.PermissionStatus.GRANTED

  this._holding = true
  this.onHoldingChange?.(true)

  if (alreadyGranted) {
    await this.startRecording()
    return
  }

  const granted = await PermissionHelper.request(context, 'ohos.permission.MICROPHONE')
  this._holding = false
  this.onHoldingChange?.(false)

  if (!granted) { return }
  // 授权成功但手指已不在按钮上,用户重新按住即可(第二次不弹权限)
}

教训:await 弹窗类操作会打断 touch 事件流。弹窗期间组件收不到 touch 事件,需要在弹窗返回后主动恢复 UI 状态。区分"同步检查已授权"和"需要弹窗授权"两种路径。


Bug 3:cancel() 后 onComplete 仍发送消息

现象:调用 cancel() 取消后,onComplete 回调仍然触发了发送,导致消息被发出。

根因:engine.cancel() 是异步触发回调的,时序不确定:

cancel() → _holding=false
                ↓ (异步)
           onResult(isFinal=true) → 追加 _accumulatedText  ← cancel还没清空文本
                ↓ (异步)
           onComplete → sendAccumulated() → 发送了!
cancel() → _accumulatedText='', _currentPartial=''  ← 清空太晚了

engine.cancel() 的回调可能在 cancel() 方法体执行完之前触发,也可能在之后。时序不可预测。

修复:新增 _cancelled 标志位,cancel() 时设 true,sendAccumulated() 检查到就不发送:

private _cancelled: boolean = false

cancel(): void {
  this._cancelled = true
  this._holding = false
  this.onHoldingChange?.(false)
  if (this.engine !== undefined) {
    this.engine.cancel(this.currentSessionId)
    this.engine.shutdown()
    this.engine = undefined
  }
  this._accumulatedText = ''
  this._currentPartial = ''
}

start(): void {
  this._cancelled = false
  ...
}

private sendAccumulated(): void {
  if (this._cancelled) {
    this._accumulatedText = ''
    this._currentPartial = ''
    return
  }
  ...
}

教训:引擎回调是异步的,不能假设调了 cancel()/shutdown() 后回调就不会执行。需要用标志位防御,在回调入口检查当前状态是否仍然合法。


Bug 4:Entity 不是 Kit 顶级导出

现象:

import { textProcessing, EntityType, Entity } from '@kit.NaturalLanguageKit'

编译报错:Module '"@kit.NaturalLanguageKit"' has no exported member 'Entity'

根因:Entity 是 textProcessing 命名空间下的子类型,不是 Kit 的顶级导出。EntityType 是枚举,作为顶级导出;Entity 是接口,挂在命名空间下。

修复:

// 报错
import { textProcessing, EntityType, Entity } from '@kit.NaturalLanguageKit'
const entities: Entity[] = await textProcessing.getEntity(text)

// 正确
import { textProcessing, EntityType } from '@kit.NaturalLanguageKit'
const entities: textProcessing.Entity[] = await textProcessing.getEntity(text)

教训:Kit 的顶级导出和命名空间子类型是不同的。枚举通常顶级导出,接口/类可能在命名空间下。不确定时先看 .d.ts 或搜索文档。


Bug 5:Map 构造函数 + 对象字面量 = arkts-no-untyped-obj-literals

现象:

private formatMap: Map<string, EntityFormatItem> = new Map([
  ['datetime', { emoji: '📅', label: '时间' }],
  ['phoneNo', { emoji: '📞', label: '手机' }],
])

编译报错:Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)

根因:ArkTS 要求所有对象字面量必须有显式类型声明,包括 Map 构造函数参数中的嵌套对象。即使 Map 的泛型已经声明了 EntityFormatItem,构造函数参数中的 { emoji, label } 仍然被视为 untyped object literal。

修复:放弃 Map,改用数组 + Record 索引:

interface EntityFormatItem {
  emoji: string
  label: string
}

private formatItems: EntityFormatItem[] = [
  { emoji: '📅', label: '时间' },
  { emoji: '📞', label: '手机' },
]

private typeIndexMap: Record<string, number> = {
  'datetime': 0,
  'phoneNo': 1,
} as Record<string, number>

教训:ArkTS 中 Map 的构造函数参数不属于类型推断上下文。需要对象字面量时,优先用有类型声明的数组,或用 Record + as 断言。


Bug 6:Map 不能 as Record 转换

现象:

return new Map<string, Object>() as Record<string, Object>

编译报错:Conversion of type 'Map<string, Object>' to type 'Record<string, Object>' may be a mistake because neither type sufficiently overlaps with the other

根因:Map 和 Record 是不同的数据结构。Map 没有索引签名,不能直接转换为 Record。ArkTS 的 as 断言要求两边有足够的类型重叠。

修复:用空对象字面量替代:

const EMPTY_RECORD: Record<string, Object> = {} as Record<string, Object>

private safeParse(json: string): Record<string, Object> {
  if (json === '' || json === '{}') {
    return EMPTY_RECORD
  }
  ...
}

教训:Map ≠ Record,不能互相转换。需要键值对结构时统一用 Record,不要混用 Map。


Bug 7:JSON.parse() 返回 any 被禁止

现象:

const parsed = JSON.parse(json)
if (typeof parsed === 'object') {
  return parsed as Record<string, Object>
}

编译报错:Use explicit types instead of "any", "unknown" (arkts-no-any-unknown)

根因:JSON.parse() 的 TypeScript 签名返回 any,ArkTS 禁止 any 类型。不能直接使用 JSON.parse() 的返回值,也不能对 any 做 as 断言。

修复:两步 as 转换——先 as Object(合法,Object 是所有引用类型的基类),再 as Record<string, Object>:

const parsed: Object = JSON.parse(json) as Object
if (parsed !== null && typeof parsed === 'object') {
  return parsed as Record<string, Object>
}

教训:ArkTS 中 JSON.parse() 必须先 as Object 再 as 具体类型。不能直接使用返回值或一步到位。这是 ArkTS 对 any 类型的硬限制。


设计变更 1:筛选字段 → 返回完整数据

最初对每种实体只提取"最有价值"的字段(PHONE_NO → 只返回 number,LOCATION → 只返回 default 等),对应的 extractDetail() + 4 个 extractXxx() + safeParse() 约 100 行代码。

后来发现用户要的是完整 jsonObject 数据,不要代码帮他筛选。删除所有提取方法,formatEntity() 改为直接输出完整 jsonObject,代码从约 200 行降到约 130 行。

教训:不要替用户做选择。数据筛选是业务逻辑,不属于提取层。提取层应返回完整数据,让上层决定怎么用。


设计变更 2:init/release 生命周期

最初没有调用 textProcessing.init() 和 textProcessing.release(),每次 getEntity() 自动初始化引擎。

后来发现:init() 首次调用可减少 100-300ms 延迟;不 release 会一直占几十 MB 内存。改为 EntityExtractor 暴露 init()/release() 方法,EntryAbility 在 onForeground/onBackground 中调用。

教训:引擎类 API 的 init/release 要主动管理,不要依赖自动初始化。自动初始化只是兜底,主动 init 能优化首次体验,主动 release 能避免内存浪费。生命周期选择:onForeground/onBackground > aboutToAppear/aboutToDisappear > onCreate/onDestroy。


设计变更 3:maxLines 限制与动态内容

消息气泡有 maxLines(20) + textOverflow(Ellipsis) 限制。当显示实体识别的完整 jsonObject 数据时,DATETIME 实体 20+ 个字段一行就超长,20 行限制导致数据被截断。删除 maxLines 和 textOverflow,文本完整显示。

教训:显示限制要和内容匹配。之前硬编码固定文本时 20 行足够,现在显示动态数据就要重新评估限制。


通用教训

异步代码的三类陷阱
陷阱类型表现防御方法
回调时序不确定cancel/shutdown 后回调仍触发标志位防御(_cancelled、_sessionGeneration)
系统弹窗打断事件流await 弹窗期间 touch 事件丢失弹窗返回后主动恢复 UI 状态
系统事件语义≠用户认知Cancel ≠ 手指划出用坐标位移判断用户真实意图
ArkTS 编译的三类陷阱
陷阱类型表现防御方法
Kit 命名空间Entity 不在顶级导出用 textProcessing.Entity,不确定就查 .d.ts
对象字面量无类型Map 构造函数参数报错用有类型上下文的数组,或 Record + as
JSON.parse 返回 any禁止直接使用返回值先 as Object 再 as Record,两步转换
设计层面的三类陷阱
陷阱类型表现防御方法
替用户做选择筛选字段 vs 完整数据提取层返回完整数据,业务层决定怎么用
忽略生命周期init/release 不管理引擎类 API 主动管理,onForeground/onBackground
显示限制与内容不匹配maxLines 截断动态数据显示限制随内容变化重新评估
7 条经验法则
  1. 遇到 await — 想一想:这期间外部状态会变吗?事件会丢失吗?
  2. 遇到回调 — 想一想:回调触发时,我预设的状态还成立吗?需要标志位吗?
  3. 遇到系统弹窗 — 想一想:弹窗期间 UI 状态需要手动恢复吗?
  4. 遇到系统事件 — 想一想:事件语义和用户认知一致吗?不一致就自己判断
  5. 遇到 Kit 导入 — 先确认类型在命名空间下还是顶级导出,不要猜
  6. 遇到对象字面量 — 确保有类型上下文,没有就声明 interface
  7. 遇到 JSON.parse — 记住两步 as:as Object → as Record<string, Object>

先画时序图再写代码,先查 .d.ts 再写 import,能省很多调试时间。


能看到这里的应该算是至爱亲朋,手足兄弟了。既然来都来了,下面准备了点薄礼,拿走不谢:

HarmonyOS 端侧 AI 能力全景

所有端侧 AI Kit 及其核心能力,全部离线可用,无需联网

CoreSpeechKit — 语音能力

能力模块说明since
语音识别(ASR)speechRecognizer语音→文字,支持 long/short 模式,recognitionMode=0 引擎自己录音5.0.0(12)
语音合成(TTS)textToSpeech文字→语音,支持多音色/语速/音调/音量,≤10000字5.0.0(12)
AI字幕AICaption实时语音转字幕5.0.0(12)
文本朗读textReader无障碍场景文本朗读5.0.0(12)
import { speechRecognizer, textToSpeech } from '@kit.CoreSpeechKit'

NaturalLanguageKit — 自然语言能力

能力模块说明since
实体抽取textProcessing.getEntity10种实体识别(时间/地点/人名/手机号等)5.0.0(12)
分词+词性标注textProcessing.getWordSegment中文分词,返回词语+词性(名词/动词/形容词等)5.0.0(12)
import { textProcessing, EntityType } from '@kit.NaturalLanguageKit'

DataAugmentationKit — 端侧大模型能力

能力模块说明since
端侧LLM对话localChatModel端侧大语言模型,支持流式/非流式问答,问题≤4500字节6.0.0(20)
检索增强生成ragRAG 检索增强生成6.0.0(20)
知识检索retrieval知识库检索6.0.0(20)
向量化knowledgeProcessor文本向量化处理(仅PC可用)6.0.0(20)
import { localChatModel } from '@kit.DataAugmentationKit'

CoreVisionKit — 视觉能力

能力模块说明since
文字识别(OCR)textRecognition图片中识别文字,支持中/英/日/韩/繁体中文4.0.0(10)
人脸检测faceDetector检测人脸2D/3D轮廓、表情、年龄、性别5.0.0(12)
人脸比对faceComparator人脸特征比对,输出相似度5.0.0(12)
主体分割subjectSegmentation前景/背景分割,抠图5.0.0(12)
多目标识别objectDetection通用物体检测与位置识别5.0.0(12)
骨骼点检测skeletonDetection人体骨架关键点检测5.0.0(12)
图像超分imageSuperResolution1x去噪/3x放大增强5.0.0(12)
文本搜图textSearchImage通过文本描述搜索图片5.0.0(12)
import { textRecognition, faceDetector, subjectSegmentation } from '@kit.CoreVisionKit'

VisionKit — 场景化视觉服务

能力模块说明since
活体检测interactiveLiveness动作活体检测(点头/张嘴/眨眼),抵御照片/视频攻击5.0.0(12)
import { interactiveLiveness } from '@kit.VisionKit'

MindSporeLiteKit — 自定义模型

能力模块说明since
端侧推理mindSporeLite加载 .ms 模型文件执行推理,支持 CPU/GPU/NPU5.0.0(12)
端侧训练mindSporeLite端侧迁移学习微调模型5.0.0(12)
import { mindSporeLite } from '@kit.MindSporeLiteKit'

AgentFrameworkKit — 意图框架

能力模块说明since
意图执行insightIntent系统反向调度App(小艺语音→App执行意图)5.0.0(12)
意图实体定义InsightIntentEntity定义App可被系统调度的意图和数据结构5.0.0(12)
import { insightIntent } from '@kit.AbilityKit'

能力全景速查

输入→输出Kit能力
语音→文字CoreSpeechKitspeechRecognizer
文字→语音CoreSpeechKittextToSpeech
文字→实体NaturalLanguageKittextProcessing.getEntity
文字→分词NaturalLanguageKittextProcessing.getWordSegment
文字→智能回答DataAugmentationKitlocalChatModel
图片→文字CoreVisionKittextRecognition (OCR)
图片→人脸CoreVisionKitfaceDetector / faceComparator
图片→抠图CoreVisionKitsubjectSegmentation
图片→物体CoreVisionKitobjectDetection
图片→骨架CoreVisionKitskeletonDetection
图片→超分CoreVisionKitimageSuperResolution
自定义模型MindSporeLiteKitmindSporeLite 推理/训练
系统→AppAgentFrameworkKitinsightIntent 反向调度

学习小结:textProcessing.getEntity() 提供 10 种实体识别,无需权限无需联网,是端侧 NLP 的核心能力。踩坑集中在三个方面——异步回调时序不确定(需要标志位防御)、ArkTS 编译规则(命名空间导出、对象字面量、JSON.parse 两步 as)、设计选择(完整数据优于筛选、生命周期要主动管理)。7 条经验法则的核心是:先画时序图再写代码,先查 .d.ts 再写 import。

懿路向前 · AI辅助整理
2026-07-24

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐