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对话解决方案。
共同学习,写下你的评论
评论加载中...
作者其他优质文章