Demo介绍
本demo对接阿里云和百度的大模型API,实现一个简单的对话应用。
DecEco Studio版本:DevEco Studio 3.1.1 Release
HarmonyOS SDK版本:API9
关键点:ArkTS、ArkUI、UIAbility、网络http请求、列表布局、层叠布局
定义接口响应数据
根据大模型对话应用(一)中接口返回JSON格式,定义大模型接口返回数据
export class ALiYunResponse {request_id: stringoutput: ALiYunResp_outputusage: ALiYunResp_usage
}class ALiYunResp_output {text: string
}class ALiYunResp_usage {output_tokens: stringinput_tokens: string
}
输入框发送消息
在 ChatPageALiYun.ets文件,struct ChatPage { ... } 结构中,定义两个变量 submitMsg 和 textInputMsg
- submitMsg:提交消息绑定变量,用于保存输入框输入文本信息,
- textInputMsg:输入框输入信息绑定变量,可控制在发送消息后,清除文本输入框内容
@State submitMsg: string = ''
@State textInputMsg: string = ''
完善输入文本框TextInput的 .onChange() 方法和.onSubmit() 方法
.onChange()方法中,当输入框内容变化时,同步更新this.submitMsg和this.textInputMsg的值
.onSubmit()方法中,当输入框内容提交时,表示消息发送。
- 将 this.textInputMsg 变量置空,会驱动输入框显示内容更新为空
- 将输入框输入的文本加入页面展示的聊天列表集合this.messageArr 之中,页面展示我方发送 的消息
- 页面展示聊天消息的列表滑动至底端,展示最新消息
- 使用输入框输入的文本作为参数,调用大模型http接口,发起对话请求
- 调用大模型http接口成功后,将接口返回的对话文本加入页面展示的聊天列表集合this.messageArr 之中,页面展示对方(大模型)应答的消息
- 页面展示聊天消息的列表滑动至底端,展示最新消息
@Builder function inputBox(scroller: Scroller, messageArr: MessageVO[]) {Row() {Stack() {TextInput({placeholder: '有问题尽管问我~', text: this.textInputMsg}).height(50).enterKeyType(EnterKeyType.Send).onChange((text) => {this.submitMsg = textthis.textInputMsg = text}).onSubmit(() => {this.textInputMsg = '' // 点击发送后 输入框置空this.messageArr.push(new MessageVO(MessageRoleEnum.Mine, this.submitMsg)) // 立刻展示我方对话scroller.scrollEdge(Edge.Bottom) // 消息发送后 将列表滚动到底端// 发送http请求ALiYunHttpUtils.request(this.submitMsg, (responseText: string) => {this.messageArr.push(new MessageVO(MessageRoleEnum.Other, responseText)) // 展示对方对话scroller.scrollEdge(Edge.Bottom) // 消息显示后 将列表滚动到底端})})Image($r('app.media.ic_public_send')).margin({right:10}).height(35).onClick(() => {// 参照文本输入框TextInput 的onSubmit事件实现})}.alignContent(Alignment.End).height('10%')}.width('90%')
}
ALiYunHttpUtils处理回调
完善先前写好的ALiYunHttpUtils,为request() 方法入参添加一个回调函数,用于更新页面数据
import http from '@ohos.net.http';
import hilog from '@ohos.hilog';
import { ALiYunResponse } from '../model/ALiYunResponse';
class ALiYunHttpUtils {request(question: string, callback: Function) {hilog.info(0x0000, 'testTag', 'ALiYunHttpUtils request invoke. question: %{public}s', question);// 1 createHttp接口创建请求let httpRequest = http.createHttp();// 2 发起请求httpRequest.request(// 请求地址"https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation",// 请求options: HttpRequestOptions{// 请求方式method: http.RequestMethod.POST,// 请求头header: {"Content-Type": "application/json",// 这里的Authorization 就是刚才工作台查看的 API-KEY"Authorization": "sk-0bxxxxxxxxx1c3"},// 请求体extraData: {"model": "qwen-plus", // 指定用于对话的通义千问模型名"input": {"messages": [{"role": "user","content": question // 请求发起方传入的问题}]}}}, (err, data: http.HttpResponse) => {if (err) {hilog.error(0x0000, 'testTag', 'Failed to request ALiYun. Cause: %{public}s', JSON.stringify(err) ?? '');httpRequest.destroy();} else {hilog.info(0x0000, 'testTag', 'Request ALiYun success. data: %{public}s', JSON.stringify(data.result));let resp: ALiYunResponse = JSON.parse(data.result.toString())hilog.info(0x0000, 'testTag', 'Request ALiYunHttpUtils-Result. data: %{public}s', JSON.stringify(resp.output.text));httpRequest.destroy();callback(resp.output.text)}})}
}
export default new ALiYunHttpUtils;
预览效果
打开预览器,在输入文本框中输入内容后,敲击Enter键,可与大模型进行简单的对话
真机(pad)调试效果:
petal_20240203_171933
至此,一个简单的对话Demo就实现完成了;
本项目仅实现了很基础的简单功能,仍有许多细节需要完善,如:等待接口返回过程的加载交互动效、接口异常处理、数据持久化、对话头像的设置等。
有更精巧、更兼容的实现方案,欢迎大家评论指正~