半小时实现GPT纯血鸿蒙版

2024-01-13 04:04

本文主要是介绍半小时实现GPT纯血鸿蒙版,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

仅需半小时,即可实现纯血鸿蒙版本的ChatGPT!

废话少说,先看效果图:

如上图所示,这个小Demo实现了AI智能问答。靠右加粗的文本是用户点击底部提交按钮后出现的;后面靠左对齐的普通文本是来自AI的回答内容。当然,整个内容是可滑动浏览的,当内容被滑动时,屏幕右侧将出现滚动条。最后,为什么UI是英文呢?因为鸿蒙的模拟器目前没有内置中文输入法,恰好这个AI服务也可以用英文来回答。

值得注意的是:这个小Demo之所以我称其为Demo,是因为它的功能实在是太简单了。只有一个基础的AI对话功能,如果要做成一个产品,我觉得起码得有个数据持久化的过程,而且还能支持文本的编辑、复制、删除,还要提供收藏功能。更重要的,UI也需要好好美化一下……

所以,这篇文章就权当抛砖引玉,让大家体会一下开发原生纯血鸿蒙版本的App是有多么轻松。

前置条件

  1. DevEco 3.1.1 Release;
  2. 在百度智能云控制台上创建好应用,保存好API Key和Secret Key。
  • 关于1:下载和安装文档链接;
  • 关于2:百度智能云控制台地址链接。

创建项目(5分钟)

使用DevEco创建项目仅需两步,第一步选择类型,第二步填写项目信息。

对于第一步,我们选择Application(应用程序)->Empty Ability(空白Ability);

对于第二步,我们选择迄今为止最新的Compile SDK,即3.1.0(API 9),Model选择Stage,不开启“Enable Super Visual”。其余的内容大家根据自身环境配置进行填写就好。

编码实现(20分钟)

整个编码过程分为三个步骤,首先添加权限,然后实现UI,最后实现网络操作。

添加权限(2分钟)

在整个App的项目结构中,找到默认创建的entry模块,依次定位到src->main->module.json5,权限在该文件中进行配置。

这个Demo功能非常简单,但仍需对其添加必要的网络访问权限,以确保可以打开网络套接字,完成HTTP请求和响应。

代码片段如下:

"requestPermissions": [{"name": "ohos.permission.INTERNET",}
],

UI实现(10分钟)

回过头来看本文最上方的截图,经过布局分析后,可以得到如下结论:整个界面是纵向布局,由两个部分构成。一是可滚动的对话历史;二是下方的输入框和提交按钮。

因此,整个UI布局最外层应该是一个Column,表示纵向布局。其中,占据90%高度的对话历史区域,占据10%高度的输入框和按钮区域。

先来看对话历史区域,它其实本质上也是一个Column,每个item就是一段文字。根据文字的类型来判断是居左还是居右。在这个Column之外,为了让整个对话历史区域可以上下滚动查看,因此还需要Scroll组件将整个Column组件包裹起来。

代码片段如下:

@State messagesList: Object[] = [{ 'role': 'user', 'content': 'What can I help you with?' }]
// 历史问答
Scroll() {Column() {ForEach(this.messagesList, (item: Object) => {if (item['role'] == 'user') {Text(item['content']).fontSize(20).fontWeight(FontWeight.Bold).width('100%').textAlign(TextAlign.End)} else {Text(item['content']).fontSize(20).width('100%').textAlign(TextAlign.Start)}})}.width('100%').alignItems(HorizontalAlign.Center)
}
.scrollable(ScrollDirection.Vertical)
.scrollBar(BarState.Auto)
.scrollBarColor(Color.Gray)
.scrollBarWidth(10)
.edgeEffect(EdgeEffect.Fade)
.height('90%')
.width('100%')

请注意这段代码中的messagesList,它是一个对象数组。role表示角色,即该条消息是用户发送的,还是服务器返回的;content表示文字内容。

在由Scroll包裹的Column组件之中,使用了ArkTS提供的ForEach渲染方式进行逐条消息的渲染,并使用if…else…条件判断语句对角色来源进行区分。

再来看底部的输入框和操作按钮,由于它们是横向排列的,所以使用Row组件进行布局。在此,我将文本输入框设定了80%的宽度,提交按钮设定了20%的宽度。

代码片段如下:

@State questionStr: string = ''
// 文本输入和提交
Row() {TextInput({ placeholder: 'Please input your question', text: this.questionStr }).type(InputType.Normal).onChange((value: string) => {this.questionStr = value}).width('80%')Button('提交').type(ButtonType.Capsule).onClick(() => {this.messagesList.push({ 'role': 'user', 'content': this.questionStr })getAnswer(this.questionStr, this.messagesList)this.questionStr = ''}).width('20%')
}.height('10%').width('100%')

在这段代码中,questionStr表示输入框中的文字字符串。getAnswer()函数发起并接收HTTP请求,向服务器提交用户问题字符串,并等待接收响应内容,将问题的回答放入messagesList对象数组之中,完成整个问答流程。

最后,将上述Scroll组件和Row组件一并放入Column内,完成整个UI绘制。

网络访问(8分钟)

根据百度官方的开发文档,完成整个AI问答过程至少需要两个步骤:获取access_token和获取问题答案。

获取access_token的过程在程序一开始就可以进行了,因为在后续的操作中都要用到access_token。因此,我声明了access_token的全局变量,并将获取该值的方法封装为getToken()函数,具体代码如下:

var access_token: string = ''
function getToken() {let httpRequest = http.createHttp();httpRequest.on('headersReceive', (header) => {console.info('header: ' + JSON.stringify(header));});httpRequest.request("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=[你的应用的API Key]&client_secret=[你的应用的Secret Key]",{method: http.RequestMethod.POST,header: {'Content-Type': 'application/json',},expectDataType: http.HttpDataType.OBJECT,usingCache: true,priority: 1,connectTimeout: 60000,readTimeout: 60000,usingProtocol: http.HttpProtocol.HTTP1_1,}, (err, data) => {if (!err) {access_token = data.result['access_token']} else {httpRequest.off('headersReceive')httpRequest.destroy()}});
}

getToken()函数我在回调的onPageShow()函数中使用,即程序启动后,就获取access_token。

最后,我们来实现getAnswer()函数,它是向服务器提交问题和接收响应的函数,具体代码如下:

function getAnswer(questionStr: string, messageList: Object[]) {let httpRequest = http.createHttp();httpRequest.on('headersReceive', (header) => {console.info('header: ' + JSON.stringify(header));});httpRequest.request("https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/yi_34b_chat?access_token=" + access_token,{method: http.RequestMethod.POST,header: {'Content-Type': 'application/json'},extraData: { "messages": [{"role": "user","content": questionStr}] },expectDataType: http.HttpDataType.OBJECT,usingCache: true,priority: 1,connectTimeout: 60000,readTimeout: 60000,usingProtocol: http.HttpProtocol.HTTP1_1,}, (err, data) => {if (!err) {messageList.push({ 'role': 'assist', 'content': data.result['result'] })} else {httpRequest.off('headersReceive')httpRequest.destroy()}});
}

还需要做些别的吗?

答案是:没有了,真的不用了。

运行项目(5分钟)

无论是本地模拟器,还是真机,抑或是远程模拟器,只需要启动其中一个,然后让这个程序跑起来吧!如无意外,你将会得到一个超级简易的AI问答机器人,纯血鸿蒙版。

当然,这里我写了需要5分钟,是包括了下载模拟器镜像的时间,如果你有真机或是使用远程模拟器的话,那就会更快了。

最后,我们来对比一下。我完成上述功能,Index.ets一共117行,你的呢?

这篇关于半小时实现GPT纯血鸿蒙版的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/600183

相关文章

python使用watchdog实现文件资源监控

《python使用watchdog实现文件资源监控》watchdog支持跨平台文件资源监控,可以检测指定文件夹下文件及文件夹变动,下面我们来看看Python如何使用watchdog实现文件资源监控吧... python文件监控库watchdogs简介随着Python在各种应用领域中的广泛使用,其生态环境也

el-select下拉选择缓存的实现

《el-select下拉选择缓存的实现》本文主要介绍了在使用el-select实现下拉选择缓存时遇到的问题及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录项目场景:问题描述解决方案:项目场景:从左侧列表中选取字段填入右侧下拉多选框,用户可以对右侧

Python pyinstaller实现图形化打包工具

《Pythonpyinstaller实现图形化打包工具》:本文主要介绍一个使用PythonPYQT5制作的关于pyinstaller打包工具,代替传统的cmd黑窗口模式打包页面,实现更快捷方便的... 目录1.简介2.运行效果3.相关源码1.简介一个使用python PYQT5制作的关于pyinstall

使用Python实现大文件切片上传及断点续传的方法

《使用Python实现大文件切片上传及断点续传的方法》本文介绍了使用Python实现大文件切片上传及断点续传的方法,包括功能模块划分(获取上传文件接口状态、临时文件夹状态信息、切片上传、切片合并)、整... 目录概要整体架构流程技术细节获取上传文件状态接口获取临时文件夹状态信息接口切片上传功能文件合并功能小

python实现自动登录12306自动抢票功能

《python实现自动登录12306自动抢票功能》随着互联网技术的发展,越来越多的人选择通过网络平台购票,特别是在中国,12306作为官方火车票预订平台,承担了巨大的访问量,对于热门线路或者节假日出行... 目录一、遇到的问题?二、改进三、进阶–展望总结一、遇到的问题?1.url-正确的表头:就是首先ur

C#实现文件读写到SQLite数据库

《C#实现文件读写到SQLite数据库》这篇文章主要为大家详细介绍了使用C#将文件读写到SQLite数据库的几种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录1. 使用 BLOB 存储文件2. 存储文件路径3. 分块存储文件《文件读写到SQLite数据库China编程的方法》博客中,介绍了文

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

JAVA利用顺序表实现“杨辉三角”的思路及代码示例

《JAVA利用顺序表实现“杨辉三角”的思路及代码示例》杨辉三角形是中国古代数学的杰出研究成果之一,是我国北宋数学家贾宪于1050年首先发现并使用的,:本文主要介绍JAVA利用顺序表实现杨辉三角的思... 目录一:“杨辉三角”题目链接二:题解代码:三:题解思路:总结一:“杨辉三角”题目链接题目链接:点击这里

基于Python实现PDF动画翻页效果的阅读器

《基于Python实现PDF动画翻页效果的阅读器》在这篇博客中,我们将深入分析一个基于wxPython实现的PDF阅读器程序,该程序支持加载PDF文件并显示页面内容,同时支持页面切换动画效果,文中有详... 目录全部代码代码结构初始化 UI 界面加载 PDF 文件显示 PDF 页面页面切换动画运行效果总结主

SpringBoot实现基于URL和IP的访问频率限制

《SpringBoot实现基于URL和IP的访问频率限制》在现代Web应用中,接口被恶意刷新或暴力请求是一种常见的攻击手段,为了保护系统资源,需要对接口的访问频率进行限制,下面我们就来看看如何使用... 目录1. 引言2. 项目依赖3. 配置 Redis4. 创建拦截器5. 注册拦截器6. 创建控制器8.