现代职场邮件中,长篇周报、系统告警、会议邀约和客户催办混杂在一起,人工筛选效率低且容易漏掉关键待办。过去常见的方案是把邮件正文上传到云端大模型解析,但邮件往往涉及商业机密,直接上云存在数据出境和隐私稳定性风险。HarmonyOS 7.0(API 26)开放的Data Augmentation Kit,利用设备端NPU和本地小模型,提供文本特征提取、智能分类、长文本摘要、待办意图推理等端侧能力,让邮件可以在本地零延迟处理,不把敏感内容送出厂。
一、核心API与关键参数
Data Augmentation Kit对应模块为js-apis-data-augmentation,导出textProcessing对象。三个核心异步API分别覆盖摘要、分类和意图抽取:
- import { textProcessing } from '@kit.DataAugmentationKit';
- textProcessing.generateSummary(text: string, options?: SummaryOptions): Promise<string>;
- textProcessing.classifyText(text: string, categories: Array<string>): Promise<ClassificationResult>;
- textProcessing.extractIntent(text: string): Promise<IntentResult>;
复制代码
摘要接口通过SummaryOptions.maxLength控制输出长度,但NPU算力有限,maxLength设置过大会让耗时指数级上升。实测把目标摘要长度控制在30到50字符,能在阅读体验和推理耗时之间取得最佳平衡。分类接口的categories参数是实现零样本分类的关键,不需要在端侧微调模型,只需要传入“会议邀约”“报销审批”“系统通知”这类描述性标签,底层会自动计算文本特征向量与标签特征向量的余弦相似度,从而判断文本所属类别。
二、工程结构与服务封装
在示例“智能邮件助手”中,一封新邮件到达后,应用在毫秒级完成三件事:提取一句话摘要、判断邮件类别、抽取出行动意图(比如“周五前提交报告”)。核心工程结构如下:
- entry/src/main/ets/
- ├── pages/
- │ └── EmailInboxPage.ets
- ├── model/
- │ ├── EmailEntity.ets
- │ └── IntentCategory.ets
- └── service/
- ├── DataAugmentationService.ets
- └── NPUInferenceManager.ets
复制代码
为了避免UI线程卡顿,不要在邮件到达时把2000字正文直接丢给主线程上的NPU推理接口。合理的设计是利用并发机制,把文本处理放到异步任务中,由底层NPU调度引擎自行管理硬件队列。下面是核心封装DataAugmentationService.ets的实现,把分类、摘要和意图抽取整合为高内聚服务,并加入针对超长文本的防御性截断:
- import { textProcessing } from '@kit.DataAugmentationKit';
- import { hilog } from '@kit.PerformanceAnalysisKit';
- const TAG = 'DataAugmentationService';
- export interface EmailKnowledge {
- summary: string;
- category: string;
- intentAction: string | null;
- intentTime: string | null;
- }
- export class DataAugmentationService {
- private static readonly CATEGORIES = [
- '紧急待办', '会议邀约', '进度汇报', '系统告警', '日常闲聊'
- ];
- private static readonly MAX_PROCESS_LENGTH = 1500;
- public static async processEmailContent(rawText: string): Promise<EmailKnowledge> {
- const cleanText = this.preprocessText(rawText);
- hilog.info(0x0000, TAG, `开始处理邮件文本,截断后长度: ${cleanText.length}`);
- try {
- const [categoryRes, summaryRes, intentRes] = await Promise.all([
- this.fetchCategory(cleanText),
- this.fetchSummary(cleanText),
- this.fetchIntent(cleanText)
- ]);
- return {
- category: categoryRes,
- summary: summaryRes,
- intentAction: intentRes?.action || null,
- intentTime: intentRes?.targetTime || null
- };
- } catch (error) {
- hilog.error(0x0000, TAG, `文本处理发生稳定性风险: ${JSON.stringify(error)}`);
- return {
- category: '未知类别',
- summary: cleanText.substring(0, 30) + '...',
- intentAction: null,
- intentTime: null
- };
- }
- }
- private static preprocessText(text: string): string {
- if (!text) {
- return '';
- }
- let processed = text.replace(/[\r\n]+/g, ' ').replace(/\s+/g, ' ').trim();
- if (processed.length > this.MAX_PROCESS_LENGTH) {
- processed = processed.substring(0, this.MAX_PROCESS_LENGTH);
- }
- return processed;
- }
- private static async fetchCategory(text: string): Promise<string> {
- const result = await textProcessing.classifyText(text, this.CATEGORIES);
- if (result && result.topCategory && result.topScore > 0.5) {
- return result.topCategory;
- }
- return '常规邮件';
- }
- private static async fetchSummary(text: string): Promise<string> {
- const summary = await textProcessing.generateSummary(text, { maxLength: 40 });
- return summary || '无摘要';
- }
- private static async fetchIntent(text: string): Promise<{ action?: string, targetTime?: string } | null> {
- const result = await textProcessing.extractIntent(text);
- if (result && result.primaryAction) {
- return {
- action: result.primaryAction,
- targetTime: result.timeEntity || '待定'
- };
- }
- return null;
- }
- }
复制代码
UI层只需在收到邮件数据时调用processEmailContent,再把返回的EmailKnowledge映射到组件状态变量。数据计算与页面渲染彻底解耦,代码可维护性也更高。
三、避坑指南
1. 并行调用OOM
代码中通过Promise.all同时发起分类、摘要和意图抽取,在旗舰机上NPU资源充裕时调度器能完美并行;但在算力受限的老旧机型上,同时加载三个不同任务的权重可能触碰显存上限。如果强依赖低端机适配,建议改成串行await调用:先获取分类,如果是垃圾邮件则跳过后续的摘要与意图抽取,节省算力开销。
2. 零样本分类的标签设计
classifyText的categories参数需要传递语义明确的自然语言,不要传“TYPE_01”“TYPE_02”这类枚举代号。模型不认识代码符号,标签名应该像写Prompt一样,使用“需要回复的紧急工作”“无关紧要的通知”这种描述性强的词汇,分类准确率会明显提升。
3. 输入文本的“垃圾进,垃圾出”
邮件正文常包含Base64编码的内联图片、HTML标签、杂乱签名档。如果不对原始文本做preprocessText清洗,直接扔给extractIntent,特征提取引擎会被无意义字符淹没,拖慢提取速度,还容易产生“幻觉”或提取失败。因此必须先做换行折叠、空白压缩、长度截断等预处理。
四、总结
接入HarmonyOS 7.0的Data Augmentation Kit后,传统依赖云端的高成本NLP任务可以转化为端侧闭环的本地原生能力。从API设计到底层NPU调度,系统已经屏蔽了大量硬件复杂性。对于邮件、笔记、聊天记录这类隐私敏感文本,端侧处理既能保障数据不出设备,又能在无网弱网环境下提供流畅的智能体验,是应用走向“端智能”值得关注的方向。 |