HarmonyOS 6.1 AI深度融合:从“功能”到“智能”的大模型落地
系列智能化篇·第47篇。全场景篇后,有产品经理问:“现在的电商Demo功能齐全了,但感觉还是‘死’的。能不能接入AI,让它像真人客服一样聊天,或者自动生成商品文案?” 这正是生成式AI(GenAI)带来的变革。今天我们将电商Demo升级为“AI电商助手”,深度集成华为盘古大模型及MindSpore Lite端侧推理,实现智能客服对话、商品图文生成、个性化推荐、图像识别搜索。我们将解决大模型体积大、推理慢、隐私保护三大落地难题。全程基于API23,含官方文档未涉及的“端云协同推理架构”和“Prompt工程优化”技巧。
一、前言:为什么端侧AI是鸿蒙的“王炸”?
云端大模型(如ChatGPT)虽强,但存在延迟高、隐私泄露、断网不可用的问题。鸿蒙的端云协同AI架构给出了完美答案:
-
端侧:负责实时性要求高、隐私敏感的任务(如键盘输入预测、本地相册识别),使用轻量化模型(MindSpore Lite)。
-
云侧:负责复杂推理、知识问答(如盘古大模型),通过安全隧道传输数据。
-
协同:端侧预处理,云侧深度推理,端侧后处理,兼顾效果与效率。
今天,我们将把AI能力植入电商Demo的每一个毛孔,让它从“工具”进化为“助手”。
二、核心概念辨析(传统算法 vs 大模型)
|
维度 |
传统算法 (ML/DL) |
大语言模型 (LLM) |
|---|---|---|
|
能力 |
单一任务(分类、回归) |
通用任务(理解、生成、推理) |
|
数据 |
需要大量标注数据训练 |
预训练+Few-shot学习,少量样本即可 |
|
交互 |
输入特征,输出结果 |
自然语言对话,多轮交互 |
|
泛化 |
泛化能力弱,换场景需重训 |
泛化能力强,适应新场景 |
|
资源 |
轻量,适合端侧 |
庞大,通常需云侧支持 |
三、代码实现:从“功能”到“智能”
3.1 集成盘古大模型:智能客服
使用AGC的GenAI Kit调用盘古大模型,实现电商场景的智能客服。
创建entry/src/main/ets/ai/PanguChatService.ets:
import { genAi } from '@hw-agconnect/genai'
import { BusinessError } from '@kit.BasicServicesKit'
export interface ChatMessage {
role: 'user' | 'assistant' | 'system'
content: string
}
export class PanguChatService {
private chatSession: genAi.ChatSession | null = null
private systemPrompt: string = `
你是一个专业的电商智能助手,名为“鸿蒙购物助手”。
你的任务是帮助用户查找商品、解答售后问题、提供购物建议。
请遵循以下规则:
1. 回答简洁明了,不超过100字。
2. 如果不知道答案,请诚实告知,不要编造。
3. 优先推荐平台内的商品。
4. 语气友好,使用表情符号增加亲和力。
5. 当前平台主打电子产品,特别是华为鸿蒙生态产品。
`
/**
* 初始化聊天会话
*/
async init(): Promise<void> {
try {
// 1. 配置大模型参数
const config: genAi.SessionConfig = {
modelName: 'pangu-nlp-3.0', // 盘古NLP大模型
temperature: 0.7, // 控制随机性,越低越确定
maxTokens: 200, // 最大输出长度
topP: 0.9,
systemPrompt: this.systemPrompt
}
// 2. 创建聊天会话
this.chatSession = await genAi.createChatSession(config)
console.log('盘古大模型会话初始化成功')
} catch (err) {
console.error('初始化失败:', err)
}
}
/**
* 发送消息并获取回复
*/
async sendMessage(userInput: string): Promise<string> {
if (!this.chatSession) {
await this.init()
}
try {
// 1. 构建消息历史(实际应用中需维护完整的对话历史)
const messages: ChatMessage[] = [
{ role: 'user', content: userInput }
]
// 2. 调用大模型
const response = await this.chatSession.sendMessage(messages)
// 3. 提取回复内容
const reply = response.getContent()
console.log('AI回复:', reply)
return reply
} catch (err) {
console.error('发送消息失败:', err)
return '抱歉,AI助手暂时无法响应,请稍后再试。😥'
}
}
/**
* 流式对话(打字机效果)
*/
async sendMessageStream(
userInput: string,
onChunk: (chunk: string) => void,
onComplete: () => void
): Promise<void> {
if (!this.chatSession) {
await this.init()
}
try {
const messages: ChatMessage[] = [
{ role: 'user', content: userInput }
]
// 使用流式接口
const stream = this.chatSession.sendMessageStream(messages)
stream.on('data', (chunk: genAi.StreamChunk) => {
const text = chunk.getText()
onChunk(text)
})
stream.on('end', () => {
console.log('流式对话结束')
onComplete()
})
stream.on('error', (err: BusinessError) => {
console.error('流式对话错误:', err)
onChunk('抱歉,对话出错。')
onComplete()
})
} catch (err) {
console.error('启动流式对话失败:', err)
onChunk('抱歉,AI助手暂时无法响应。')
onComplete()
}
}
/**
* 清理会话资源
*/
destroy(): void {
if (this.chatSession) {
this.chatSession.destroy()
this.chatSession = null
}
}
}
3.2 端侧图像识别:拍照搜商品
使用MindSpore Lite在端侧运行轻量化图像识别模型,实现拍照搜商品。
创建entry/src/main/ets/ai/ImageSearchEngine.ets:
import { mindSporeLite } from '@kit.MindSporeLiteKit'
import { image } from '@kit.ImageKit'
import { fileIo } from '@kit.CoreFileKit'
export class ImageSearchEngine {
private model: mindSporeLite.Model | null = null
private labels: string[] = []
/**
* 加载模型和标签
*/
async loadModel(): Promise<void> {
try {
// 1. 加载模型文件(.ms模型)
const modelPath = `${getContext().filesDir}/mobilenet_v2.ms`
// 注:实际项目中需将模型文件放入rawfile目录,并复制到沙箱
await this.copyModelToSandbox()
// 2. 创建MSContext
const context = new mindSporeLite.Context()
context.target = ['cpu'] // 使用CPU推理,也可配置GPU/NPU
context.cpuThreadPoolNum = 4 // 线程数
context.cpuPowerMode = mindSporeLite.CpuPowerMode.BIG_CORES_FIRST
// 3. 加载模型
this.model = await mindSporeLite.Model.createFromFile(modelPath, context)
// 4. 加载标签文件
const labelPath = `${getContext().filesDir}/labels.txt`
const labelContent = fileIo.readTextSync(labelPath)
this.labels = labelContent.split('\n').map(line => line.trim())
console.log('图像识别模型加载成功,标签数:', this.labels.length)
} catch (err) {
console.error('模型加载失败:', err)
}
}
/**
* 复制模型文件到沙箱
*/
private async copyModelToSandbox(): Promise<void> {
const resourceManager = getContext().resourceManager
const modelData = await resourceManager.getRawFileContent('mobilenet_v2.ms')
const labelData = await resourceManager.getRawFileContent('labels.txt')
const modelPath = `${getContext().filesDir}/mobilenet_v2.ms`
const labelPath = `${getContext().filesDir}/labels.txt`
fileIo.writeSync(fileIo.openSync(modelPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY), modelData)
fileIo.writeSync(fileIo.openSync(labelPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY), labelData)
}
/**
* 识别图片并返回最可能的商品类别
*/
async recognizeImage(imagePixelMap: image.PixelMap): Promise<{ label: string, confidence: number }[]> {
if (!this.model) {
await this.loadModel()
}
try {
// 1. 图像预处理
const tensor = await this.preprocessImage(imagePixelMap)
// 2. 创建输入张量
const inputs: mindSporeLite.Tensor[] = [tensor]
// 3. 执行推理
const outputs = await this.model!.predict(inputs)
// 4. 后处理,解析结果
const results = this.postprocessOutputs(outputs)
return results.slice(0, 5) // 返回前5个最可能的结果
} catch (err) {
console.error('图像识别失败:', err)
return []
}
}
/**
* 图像预处理:缩放、归一化、格式转换
*/
private async preprocessImage(pixelMap: image.PixelMap): Promise<mindSporeLite.Tensor> {
// 1. 缩放到模型输入尺寸 (224x224)
const scaleOptions: image.ScalingOptions = {
size: { height: 224, width: 224 }
}
const scaledPixelMap = await image.createPixelMap(pixelMap, scaleOptions)
// 2. 读取像素数据
const pixelBytes = await scaledPixelMap.readPixelsToBuffer()
// 3. 转换为Tensor (NHWC格式,float32)
const tensor = mindSporeLite.Tensor.create([1, 224, 224, 3], mindSporeLite.DataType.FLOAT32)
// 4. 归一化处理 (像素值 / 255.0)
const floatData = new Float32Array(1 * 224 * 224 * 3)
for (let i = 0; i < pixelBytes.length; i += 4) {
const r = pixelBytes[i] / 255.0
const g = pixelBytes[i + 1] / 255.0
const b = pixelBytes[i + 2] / 255.0
// 跳过alpha通道
floatData[(i / 4) * 3] = r
floatData[(i / 4) * 3 + 1] = g
floatData[(i / 4) * 3 + 2] = b
}
tensor.setData(floatData.buffer)
return tensor
}
/**
* 后处理:解析输出张量,匹配标签
*/
private postprocessOutputs(outputs: mindSporeLite.Tensor[]): { label: string, confidence: number }[] {
const outputTensor = outputs[0]
const data = new Float32Array(outputTensor.getData())
// Softmax计算概率
const expData = data.map(x => Math.exp(x))
const sumExp = expData.reduce((a, b) => a + b, 0)
const probabilities = expData.map(x => x / sumExp)
// 创建索引-概率对并排序
const results = probabilities
.map((prob, index) => ({
label: this.labels[index] || `未知类别_${index}`,
confidence: prob
}))
.sort((a, b) => b.confidence - a.confidence)
return results
}
}
3.3 AI生成商品文案
使用大模型的生成能力,为商品自动生成营销文案。
export class ProductCopywriter {
private panguService: PanguChatService
constructor() {
this.panguService = new PanguChatService()
this.panguService.init()
}
/**
* 生成商品标题
*/
async generateTitle(productName: string, features: string[]): Promise<string> {
const prompt = `
请为以下商品生成一个吸引人的电商标题,要求:
1. 包含核心关键词:${productName}
2. 突出卖点:${features.join('、')}
3. 长度控制在20字以内
4. 使用感叹号或emoji增加吸引力
示例:华为FreeBuds Pro 3 → 🎧华为FreeBuds Pro 3!静谧通话,无损音质!
`
return await this.panguService.sendMessage(prompt)
}
/**
* 生成商品描述
*/
async generateDescription(productName: string, specs: Record<string, string>): Promise<string> {
const specStr = Object.entries(specs).map(([k, v]) => `${k}: ${v}`).join(';')
const prompt = `
请为商品${productName}撰写一段详细的电商描述,规格参数:${specStr}。
要求:
1. 分段落,每段一个小标题。
2. 语言生动,突出用户体验。
3. 包含使用场景建议。
4. 字数在200字左右。
`
return await this.panguService.sendMessage(prompt)
}
/**
* 生成社交媒体短文案
*/
async generateSocialMediaPost(productName: string, platform: 'weibo' | 'xiaohongshu'): Promise<string> {
const prompt = `
请为商品${productName}生成一条适合${platform}发布的文案。
${platform === 'xiaohongshu' ? '要求:包含emoji,使用小红书风格的语言,添加相关话题标签。' : ''}
${platform === 'weibo' ? '要求:简洁有力,包含热门话题,适合转发。' : ''}
`
return await this.panguService.sendMessage(prompt)
}
}
3.4 端云协同架构
设计一个高效的端云协同推理流程。
export class AICoordinator {
private cloudService: PanguChatService
private edgeEngine: ImageSearchEngine
private cache: Map<string, any> = new Map()
constructor() {
this.cloudService = new PanguChatService()
this.edgeEngine = new ImageSearchEngine()
}
/**
* 端云协同推理:智能问答
*/
async hybridChat(userQuery: string): Promise<string> {
// 1. 端侧意图识别(快速过滤)
const intent = await this.classifyIntent(userQuery)
if (intent === 'image_search') {
// 2. 如果是图像搜索,直接在端侧处理
return '请拍摄商品照片,我将为您搜索相似商品。'
} else if (intent === 'simple_faq') {
// 3. 简单FAQ,使用端侧小模型
return await this.answerWithEdgeModel(userQuery)
} else {
// 4. 复杂问题,调用云端大模型
return await this.cloudService.sendMessage(userQuery)
}
}
/**
* 端侧意图分类(简化版)
*/
private async classifyIntent(query: string): Promise<string> {
const keywords = {
image_search: ['拍照', '图片', '识别', '这是什么'],
simple_faq: ['多少钱', '在哪买', '营业时间', '退货政策']
}
for (const [intent, words] of Object.entries(keywords)) {
if (words.some(word => query.includes(word))) {
return intent
}
}
return 'complex_query'
}
/**
* 使用端侧小模型回答问题(模拟)
*/
private async answerWithEdgeModel(query: string): Promise<string> {
const faq: Record<string, string> = {
'多少钱': '商品价格请查看详情页,不同配置价格不同哦~',
'在哪买': '您可以在华为商城、京东、天猫官方旗舰店购买。',
'退货政策': '支持7天无理由退货,1年质保服务。'
}
for (const [question, answer] of Object.entries(faq)) {
if (query.includes(question)) {
return answer
}
}
return '这个问题有点难,让我问问云端专家...'
}
}
四、踩坑记录(官方文档没写的AI落地细节)
-
模型转换的“暗坑”:MindSpore Lite支持的模型格式是
.ms,通常需要将PyTorch/TensorFlow模型通过converter_lite工具转换。转换时要注意算子支持度,有些复杂算子可能不支持,需要替换或修改模型结构。 -
端侧推理的内存爆炸:在手机端加载大模型(即使是轻量版)也会占用大量内存。如果同时加载多个模型(如OCR+图像识别+NLP),极易触发OOM。解决方案:使用懒加载,按需加载模型;及时调用
model.destroy()释放资源;使用NAPI将推理放在Native层,减少JS堆压力。 -
Prompt工程的“玄学”:大模型的输出质量极度依赖Prompt的设计。同样的请求,不同的Prompt模板,效果天差地别。经验:给AI设定明确的角色(Role)、任务(Task)、约束(Constraints)和示例(Examples)。比如“你是一个专业的电商文案专家,请用小红书风格写一段文案,要求包含emoji,不超过100字”。
-
流式输出的UI卡顿:使用流式对话(打字机效果)时,如果每次收到一个字符就更新UI,高频刷新会导致UI线程阻塞。解决方案:使用节流(Throttle),每积累一定长度的文本(如10个字符)或每隔一定时间(如50ms)更新一次UI;或者使用
TaskPool将字符串拼接放在后台线程。 -
隐私合规红线:AI涉及大量用户数据(聊天记录、图片)。必须明确告知用户数据用途,并提供撤回同意和数据删除的入口。对于端侧AI,强调“数据不出端”;对于云侧AI,使用匿名化和脱敏技术,并遵守GDPR等法规。
更多推荐
所有评论(0)