Kazy智能助手-基于HarmonyOS的星火大模型集成方案
1.作品简介
《Kazy智能助手》是一款基于讯飞星火大模型的智能聊天应用,提供多模型切换、暗夜模式、实时对话等功能。通过封装鸿蒙网络模块实现与AI服务的稳定通信,具备流畅的交互体验和安全的API通信机制。
2.作品信息
开发环境:DevEco Studio 5.0.4
SDK版本:SDK 5.0.4(16)
编程语言:ArkTS
框架和库:HarmonyOS(鸿蒙操作系统)、@ohos.net.http(用于网络请求)
3.作品亮点
3.1 智能对话系统
首先,需要在module.json5文件中申请网络权限:
"requestPermissions": [{"name": "ohos.permission.INTERNET"}]
并在需要使用http网络请求的地方调用@ohos.net.http库
import http from "@ohos.net.http"
3.1.1 HTTP返回值封装
由于@ohos.net.http调取http网络请求时http.HttpResponse接口返回对象的内容很多,且大部分为本作品开发不需要的,因此通过自定义的HttpResponse接口,将复杂的数据处理逻辑和接口调用细节隐藏在内部,对外提供统一、简洁的接口。通过封装,可以提升代码的可靠性、可维护性和可扩展性,同时降低前后端开发的耦合度。具体代码如下:
export class HttpResponse { code : number = 0 message1 : string = '' sid : string = '' choices : choice[] = [] } class choice { message : message = { role : '',content : ''} index : number = 0 } class message { role : string = '' content : string = '' }
3.2.2 HTTP调用星火大模型接口
通过封装use_ai方法,实现HarmonyOS集成星火大模型。首先通过@ohos.net.http的createHttp方法创建接口请求,接着使用request方法对星火大模型的api接口地址发起请求,请求头需要包含从控制台获取的APIKEY。接着,在请求体extraData中设定大模型相关参数以数组形式传入前端传入的问题。当API请求完成后,会接收到星火大模型返回的数据,这部分数据以3.1.1封装的返回值格式返回,通过对返回code进行判断是否调用成功,若是,则将choices中包含的AI回答的内容返回给ArkUI前端进行显示。具体代码如下:
function use_ai(question:string, page: ChatPage){ page.isEnter=false // 1 createHttp接口创建请求 let httpRequest = http.createHttp(); // 2 发起请求 httpRequest.request( // 请求地址 "https://spark-api-open.xf-yun.com/v1/chat/completions", // 请求options: HttpRequestOptions { // 请求方式 method: http.RequestMethod.POST, // 请求头 header: { "Content-Type": "application/json", "Authorization": "Bearer xxx" // xxx替换为自己的APIPassword }, // 请求体 extraData: { "max_tokens": 4096, "temperature": 0.5, "top_k": 4, "model": page.selectedModel, // 使用选择的模型 "messages": [ { "role":"system", "content":"你是kazy智能助手" }, { "role": "user", "content": question // 请求发起方传入的问题 }] } }, (err, data: http.HttpResponse) => { if (err) { httpRequest.destroy(); } else { let res: HttpResponse = JSON.parse(data.result.toString()); httpRequest.destroy(); if (res && res.choices && res.choices.length > 0 && res.choices[0].message) { page.messages.push({ text: res.choices[0].message.content, isLeft: true }); } else { page.messages.push({ text: "获取AI回答失败,请重试!", isLeft: true }); } page.isEnter=true } }) }
3.2.3 模型切换功能
用户可以通过界面上的单选按钮在“lite”模型和“generalv3”模型之间进行切换。当用户选择一个模型后,应用会更新状态并显示相应的欢迎消息,同时后续的对话将使用所选模型进行响应。这种设计使用户能够根据需要选择合适的模型,从而获得更精准或更全面的对话体验。该功能由selectedModel状态变量控制,通过Picker组件让用户能够从预设的模型列表中选择。当用户做出选择时,onSelected事件处理函数会被触发,更新selectedModel状态,并调用updateHelloMessage()函数来更新调用模型和欢迎消息。具体代码如下:
Row() { Radio({ value: 'lite', group: 'modelGroup' }) .checked(this.selectedModel === 'lite') .enabled(this.isEnter) .onChange((isChecked: boolean) => { if (isChecked) this.selectedModel = 'lite'; this.messages=[ {text: this.helloMessage1, isLeft: true}, ]; }) Text('lite模型') .fontSize(14) .fontColor(this.isDarkMode ? '#FFFFFF' : '#000000') .margin({ left: 5 }) Radio({ value: 'generalv3', group: 'modelGroup' }) .checked(this.selectedModel === 'generalv3') .enabled(this.isEnter) .onChange((isChecked: boolean) => { if (isChecked) this.selectedModel = 'generalv3'; this.messages=[ {text: this.helloMessage2, isLeft: true}, ]; }) .margin({ left: 15 }) Text('generalv3模型') .fontSize(14) .fontColor(this.isDarkMode ? '#FFFFFF' : '#000000') .margin({ left: 5 }) } .backgroundColor(this.isDarkMode ? '#333333' : '#FFFFFF') .width('100%') .padding({top:5,left:10})
3.2 对话组件封装与打字机效果
3.2.1 对话组件封装
ChatBubble组件的主要目的是在聊天应用中展示消息内容,同时为用户提供更直观的视觉体验。它通过调整气泡的属性isLeft判断消息来源,动态调整气泡的位置,来区分消息的发送方,左侧气泡AI发送的消息,而右侧气泡用于显示用户发送的消息。
为了实现将用户气泡组件右对齐,通过onAreaChange获取了气泡组件的宽度,并通过屏幕宽度与之作差,计算出组件位置,使用offset方法指定在水平方向上的偏移量,以实现气泡组件右对齐的效果。具体代码如下:
@Component export struct ChatBubble { @Prop text: string = '' @Prop isLeft: boolean = true @Prop bubbleColor: ResourceColor = $r('app.color.leftBubbleColor') @Prop wid: number =0 @State displayedText: string = '' @State intervalID: number = 0 aboutToAppear() { if (this.intervalID) { clearInterval(this.intervalID) } this.displayedText = '' let position = 0 this.intervalID = setInterval(() => { position = position + 2 this.displayedText = this.text.substring(0, position) if (this.displayedText.length >= this.text.length) { clearInterval(this.intervalID) } }, 100) } aboutToDisappear() { if (this.intervalID) { clearInterval(this.intervalID) } } build() { Column() { Row() { Text(this.isLeft?this.displayedText:this.text) .fontSize(18) .fontColor(Color.White) .fontWeight(FontWeight.Medium) .padding(12) .width('auto') .onAreaChange((oldValue: Area, newValue: Area) => { //获取当前文本长度 this.wid=Number(newValue.width) console.log(`${this.wid}`) }) } .borderRadius(16) .backgroundColor(this.bubbleColor) .width('auto') .justifyContent(FlexAlign.Center) .offset(this.isLeft ? {x:20}:{x: 330-this.wid})//如果是用户发的消息,就用屏幕宽度减掉文本宽度,就可以确定位置 .margin({ top: 10, }) .constraintSize({maxWidth:280}) } } }
3.2.2 打字机效果实现
打字机效果是一种模拟人工打字时字符逐个出现的动画效果,为用户带来更自然的阅读体验。在ChatBubble组件中,该效果通过初始化一个空字符串状态变量displayedText和一个定时器状态变量intervalID来实现。当组件即将出现时,aboutToAppear()方法会被调用,它首先清除任何现有的定时器,然后将displayedText清空,并设置一个新的定时器。定时器函数中定义了一个位置变量position,初始值为0,用于指示当前应该显示到文本中的哪个字符。每次定时器触发时,position增加2,并将text属性中从开始到position的子字符串赋值给displayedText,使得文本逐渐显示,形成打字机效果。当displayedText的长度达到或超过text的长度时,定时器被清除,打字机效果结束。当组件即将消失时,aboutToDisappear()方法会被调用,它清除定时器,确保资源得到正确释放。通过这种方式,打字机效果在组件可见时启动,在组件不可见时停止,实现了高效且流畅的动画效果。打字机效果只运用于isleft为true的情况,即AI发送的信息。具体代码如下:
aboutToAppear() { if (this.intervalID) { clearInterval(this.intervalID) } this.displayedText = '' let position = 0 this.intervalID = setInterval(() => { position = position + 2 this.displayedText = this.text.substring(0, position) if (this.displayedText.length >= this.text.length) { clearInterval(this.intervalID) } }, 100) } aboutToDisappear() { if (this.intervalID) { clearInterval(this.intervalID) } }
3.3 界面设计
3.3.1 暗夜模式
暗夜模式允许用户切换界面颜色主题,从而在深色背景下显示内容,减少强光对眼睛的刺激,特别是在夜间或弱光环境下使用时,提供更舒适的视觉体验。通过定义一个状态变量 isDarkMode 来控制开启与关闭。当 isDarkMode 为 true 时,表示暗夜模式已开启,界面将采用深色背景和浅色文本。用户可以通过界面中提供的切换按钮来改变 isDarkMode 的值,从而实现暗夜模式的切换。此外,项目还考虑了设备特殊区域(如刘海屏或底部导航栏)对界面内容的遮挡问题,通过 expandSafeArea 方法并设置 SafeAreaType.KEYBOARD 和 SafeAreaType.SYSTEM 参数,确保界面内容不会被键盘或系统导航栏遮挡,从而优化了用户在不同设备上的使用体验。具体代码如下:
Image(this.isDarkMode?$rawfile('ic_gallery_create _white.png'):$rawfile('ic_gallery_create_black.png')) .width(24) .height(24) .margin({left: '20%'}) .padding({bottom:5}) .onClick(() => { this.isDarkMode = !this.isDarkMode; })
3.3.2 安全区设置
安全区设置(Safe Area)是一种用于优化用户界面布局的功能,主要目的是确保应用内容不会因设备特殊区域(如刘海屏、圆角屏或底部导航栏)而被遮挡。本代码通过安全区设置,保证暗夜模式可以覆盖整个UI界面,相关代码如下:
.expandSafeArea([SafeAreaType.KEYBOARD, SafeAreaType.SYSTEM])
4.项目意义
《Kazy智能助手》作为一款基于鸿蒙操作系统的智能聊天应用,不仅展示了鸿蒙系统在智能应用开发方面的潜力,也体现了讯飞星火大模型在自然语言处理和对话系统领域的先进性。项目的开发遵循了鸿蒙系统的开发规范,利用了其提供的丰富功能和API,实现了多模型切换、暗夜模式等实用功能,为用户提供了一个高效、便捷的智能聊天体验。同时,项目中的HTTP返回值封装、对话组件封装与打字机效果等技术实现,通过简化大模型集成流程、提供多主题适配参考方案、验证鸿蒙网络模块的稳定性,为HarmonyOS生态提供开箱即用的AI对话解决方案。
共同學(xué)習(xí),寫下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章