前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >鸿蒙原生应用WenXinTalk

鸿蒙原生应用WenXinTalk

作者头像
徐建国
发布2024-01-18 14:44:54
3640
发布2024-01-18 14:44:54
举报
文章被收录于专栏:个人路线

作者:哈工程HEU社长 团队:坚果派 团队介绍:坚果派由坚果创建,团队拥有8个华为HDE,以及若干其他领域的三十余位万粉博主运营。

运行环境

DevEco Studio:4.0Release

OpenHarmony SDK API11

开发板:润和DAYU200

OpenHarmony+文心一言对话APP WenXinTalk

鸿蒙融合智能力,AI助力人生梦!

创新科技迎未来,文心一言给接口!

我们今天来看一下文心一言和鸿蒙的结合,会有什么样的火花。

运行环境

(后面附有API9版本,可修改后在HarmonyOS4设备上运行)

DAYU200:4.0.10.16

SDK:4.0.10.15

IDE:4.0.600(4.0Release)

在DAYU200上运行

一、创建应用

1.点击File->new File->Create Progect

i

2.选择模版

【OpenHarmony】Empty Ability

3.填写项目名,WenXinTalk,应用包名com.WenXinTalk,应用存储位置XXX(不要有中文,特殊字符,空格)

Compile SDK10,Model :Stage

Device Type 默认就可以。

node,建议16.20.1

完成以上配置以后点击Finish

4.选择在新窗口打开,等待依赖加载完毕。如图所示。

如果大家加载依赖报错的话,检查自己的网络。

二、运行HelloWord

1.给开发板供电,并连接开发板到电脑,如图所示

2.签名

签名的步骤:

点击File->Project struct

点击Apply或者ok就可以,。

现在点击按钮运行项目。

控制台打印信息

代码语言:javascript
复制
01/12 16:13:40: Launching com.myapplication
$ hdc uninstall com.myapplication
$ hdc shell mkdir data/local/tmp/39ca9a16978647c98d8ac8bdf4a45279
$ hdc file send "E:\study\HarmonyOS\project\WenXinTalk\entry\build\default\outputs\default\entry-default-signed.hap" "data/local/tmp/39ca9a16978647c98d8ac8bdf4a45279"
$ hdc shell bm install -p data/local/tmp/39ca9a16978647c98d8ac8bdf4a45279 
$ hdc shell rm -rf data/local/tmp/39ca9a16978647c98d8ac8bdf4a45279
$ hdc shell aa start -a EntryAbility -b com.myapplication

证明项目已经成功运行在开发板上。

如果报错

代码语言:javascript
复制
01/09 14:38:39: Install Failed: error: failed to install bundle.
code:9568320
error: no signature file.
Open signing configs
Error while Deploy Hap

则需要去签名

三、修改图标和名称

修改应用图标和名称:

目录在AppScope/app.json5

代码语言:javascript
复制
{
  "app": {
    "bundleName": "com.myapplication",
    "vendor": "example",
    "versionCode": 1000000,
    "versionName": "1.0.1",
    "icon": "$media:iconAi",
    "label": "$string:app_name"
  }
}

修改完毕之后如图所示

修改成功之后,如图所示

打开方式,在设置-应用管理一栏。

修改桌面图标和名称

修改src/main/module.json5中如图所示的label和icon。

我们修改label的时候,修改中文目录下的就可以

代码语言:javascript
复制
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ],
    "name": "entry",
    "type": "entry",
    "description": "$string:module_desc",
    "mainElement": "EntryAbility",
    "deviceTypes": [
      "default",
      "tablet"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "$string:EntryAbility_desc",
        "icon": "$media:iconAi",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "skills": [
          {
            "entities": [
              "entity.system.home"
            ],
            "actions": [
              "action.system.home"
            ]
          }
        ]
      }
    ]
  }
}

修改中文目录的即可

修改结果如下

四、添加相关权限

因为需要用到网络数据,所以添加initent权限。

在src/main/module.json5中modele中添加配置,然后按sync就可以。

代码语言:javascript
复制
   "requestPermissions": [{
      "name": "ohos.permission.INTERNET"
    }],

五、定义数据模型

1.在ets目录下新建model文件夹

2.新建TS File

i

代码语言:javascript
复制
export class WenXinReturn {
  id: string = ""
  object: string = ""
  created: string = ""
  result: string = ""
  is_truncated: Boolean = false
  need_clear_history: Boolean = false
  finish_reason: string = ""
  usage: Usage = new Usage()
}

export class Usage {
  prompt_tokens: number = 0
  completion_tokens: number = 0
  total_tokens: number = 0
}

export class MsgOutput {
  content: string = ""
}

export class MsgInput {
  id: string = ""
  role: string = ""
  content: string = ""
}

六、加载网络数据

接口说明

准备好数据,

接口地址:https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro

请求方法:POST

请求参数:

Header参数

名称

Content-Type

application/json

Query参数

名称

类型

必填

描述

access_token

string

通过API Key和Secret Key获取的access_token,参考Access Token获取[1]

Body参数

名称

类型

必填

描述

messages

List(message)

聊天上下文信息。说明:(1)messages成员不能为空,1个成员表示单轮对话,多个成员表示多轮对话 (2)最后一个message为当前请求的信息,前面的message为历史对话信息 (3)必须为奇数个成员,成员中message的role必须依次为user(or function)、assistant (4)最后一个message的content长度(即此轮对话的问题)不能超过2400 token;如果messages中content总长度大于2400 token,系统会依次遗忘最早的历史会话,直到content的总长度不超过2400 token

temperature

float

说明:(1)较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定 (2)默认0.95,范围 (0, 1.0],不能为0 (3)建议该参数和top_p只设置1个 (4)建议top_p和temperature不要同时更改

top_p

float

说明:(1)影响输出文本的多样性,取值越大,生成文本的多样性越强 (2)默认0.8,取值范围 [0, 1.0] (3)建议该参数和temperature只设置1个 (4)建议top_p和temperature不要同时更改

penalty_score

float

通过对已生成的token增加惩罚,减少重复生成的现象。说明:(1)值越大表示惩罚越大 (2)默认1.0,取值范围:[1.0, 2.0]

stream

bool

是否以流式接口的形式返回数据,默认false

system

string

模型人设,主要用于人设设定,例如,你是xxx公司制作的AI助手,说明:(1)长度限制1024个字符 (2)如果使用functions参数,不支持设定人设system

user_id

string

表示最终用户的唯一标识符,可以监视和检测滥用行为,防止接口恶意调用

在这个WenXinTalk App中我们主要使用参数messages

测试接口

测试如图所示

返回数据

代码语言:javascript
复制
{
    "id": "as-7gxj35bftb",
    "object": "chat.completion",
    "created": 1705068746,
    "result": "您好,我是文心一言,英文名是ERNIE Bot。我能够与人对话互动,回答问题,协助创作,高效便捷地帮助人们获取信息、知识和灵感。",
    "is_truncated": false,
    "need_clear_history": false,
    "finish_reason": "normal",
    "usage": {
        "prompt_tokens": 3,
        "completion_tokens": 33,
        "total_tokens": 36
    }
}

创建HTTP请求

1.导入http模块

代码语言:javascript
复制
import http from '@ohos.net.http';
import { BusinessError } from '@ohos.base';

2.创建createHttp

代码语言:javascript
复制
let httpRequest = http.createHttp();

3.填写HTTP地址

代码语言:javascript
复制
   httpRequest.request(
      `https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=${access_token}`,
      {
        method: http.RequestMethod.POST,
        header: [{
          'Content-Type': 'application/json'
        }],
        extraData: {
          "messages": MsgArray
        }
      }

4.对网络数据的处理

代码语言:javascript
复制
    if (!err) {
        
        let MsgReturn: WenXinReturn = JSON.parse(data.result.toString())
        this.MsgResult.content = MsgReturn.result
        let MsgIn: MsgInput = new MsgInput()
        MsgIn.role = "assistant" //文心一言返回的结果中令role为"assistant"
        MsgIn.content = this.MsgResult.content
        MsgIn.id = this.MsgArray.length.toString() //id作为MsgArray中的标识,用以后续循环渲染
        this.MsgArray.push(MsgIn) //将文心一言返回的结果同样作为参数加入到MsgArray的末尾
        httpRequest.destroy();
      } else {
        this.message = JSON.stringify(err)
        console.error('error:' + JSON.stringify(err));
        httpRequest.off('headersReceive');
        // 当该请求使用完毕时,调用destroy方法主动销毁
        httpRequest.destroy();
      }

完成以上配置以后

5.在应用程序里测试网络请求

代码语言:javascript
复制
  build() {

    Column() {

      Button("测试网络请求").onClick(() => {
        this.httpData()
      })
    }.width("100%").height("100%").justifyContent(FlexAlign.Center)
  }
}

如图所示

测试成功

如果2300006错误码,请检查网络

如果201错误码,请检查module.json中网络权限是否配置!

七、UI

数据获取到之后,我们就剩在页面上显示了。

首页

U I布局如图所示。

代码语言:javascript
复制
 build() {
    Column() {
      Column() {
        Scroll() {
          Column() {
            ForEach(this.MsgArray, (item: MsgInput, index: number) => {
              if (item.role == "user") {
                Row() {
                  Text(item.content)
                    .width("50%")
                    .padding(15.5)
                    .backgroundColor("#95EC69")
                    .borderRadius(4)
                  Image($r("app.media.user"))
                    .backgroundColor(Color.White)
                    .objectFit(ImageFit.Fill)
                    .width(50)
                    .height(50)
                    .borderRadius(4)
                    .margin({ left: 8, right: 8 })
                }
                .margin({ top: index === 0 ? 0 : 12 })
                .width("100%")
                .alignItems(VerticalAlign.Top)
                .justifyContent(FlexAlign.End)
              } else if (item.role == "assistant") {
                Row() {
                  Image($r("app.media.iconAi"))
                    .backgroundColor(Color.White)
                    .objectFit(ImageFit.Fill)
                    .width(50)
                    .height(50)
                    .borderRadius(4)
                    .margin({ left: 8, right: 8 })
                  Text(item.content)
                    .width("50%")
                    .padding(15.5)
                    .backgroundColor(Color.White)
                    .borderRadius(4)
                    .margin({ right: 0 })
                }
                .margin({ top: index === 0 ? 0 : 12 })
                .width("100%")
                .alignItems(VerticalAlign.Top)
                .justifyContent(FlexAlign.Start)
              }
            }, (item: MsgInput) => item.id) //循环渲染时,键值匹配规则使用item.id
          }
          .padding({ top: 12, bottom: 12 })
        }

        .width("100%")
      }
      .backgroundColor("#EDEDED")
      .layoutWeight(1)

      Row() {
        TextInput({
          placeholder: "来和文心一言聊天吧", text: this.message
        })
          .backgroundColor(Color.White)
          .layoutWeight(8)
          .height(60)
          .onChange((msg: string) => {
            this.message = msg
          })
          .margin({ top: 10, bottom: 10, left: 4, right: 4 })
        Button("提交")
          .margin(4)
          .layoutWeight(2)
          .onClick(() => {
            let MsgIn: MsgInput = new MsgInput()
            MsgIn.id = this.MsgArray.length.toString()
            MsgIn.role = "user"
            MsgIn.content = this.message
            this.MsgArray.push(MsgIn)
            this.httpData(this.MsgArray)
            this.message = ""
          })
      }
      .backgroundColor("#F7F7F7")
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.SpaceBetween)
  }
}

八、完整源码

代码语言:javascript
复制
import { MsgInput, MsgOutput, WenXinReturn } from '../model/WexXinClass';
import http from '@ohos.net.http';
import { BusinessError } from '@ohos.base';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @State WXReturn: WenXinReturn = new WenXinReturn()
  @State MsgResult: MsgOutput = new MsgOutput()
  @State MsgInputSample: MsgInput = new MsgInput()
  @State MsgArray: Array<MsgInput> = []

  aboutToAppear() {
    this.message = "请介绍一下你自己"
  }

  httpData(MsgArray: Array<MsgInput>) {
 

  }

  build() {
    Column() {
      Column() {
        Scroll() {
          Column() {
            ForEach(this.MsgArray, (item: MsgInput, index: number) => {
              if (item.role == "user") {
                Row() {
                  Text(item.content)
                    .width("50%")
                    .padding(15.5)
                    .backgroundColor("#95EC69")
                    .borderRadius(4)
                  Image($r("app.media.user"))
                    .backgroundColor(Color.White)
                    .objectFit(ImageFit.Fill)
                    .width(50)
                    .height(50)
                    .borderRadius(4)
                    .margin({ left: 8, right: 8 })
                }
                .margin({ top: index === 0 ? 0 : 12 })
                .width("100%")
                .alignItems(VerticalAlign.Top)
                .justifyContent(FlexAlign.End)
              } else if (item.role == "assistant") {
                Row() {
                  Image($r("app.media.iconAi"))
                    .backgroundColor(Color.White)
                    .objectFit(ImageFit.Fill)
                    .width(50)
                    .height(50)
                    .borderRadius(4)
                    .margin({ left: 8, right: 8 })
                  Text(item.content)
                    .width("50%")
                    .padding(15.5)
                    .backgroundColor(Color.White)
                    .borderRadius(4)
                    .margin({ right: 0 })
                }
                .margin({ top: index === 0 ? 0 : 12 })
                .width("100%")
                .alignItems(VerticalAlign.Top)
                .justifyContent(FlexAlign.Start)
              }
            }, (item: MsgInput) => item.id)
          }
          .padding({ top: 12, bottom: 12 })
        }

        .width("100%")
      }
      .backgroundColor("#EDEDED")
      .layoutWeight(1)

      Row() {
        TextInput({
          placeholder: "来和文心一言聊天吧", text: this.message
        })
          .backgroundColor(Color.White)
          .layoutWeight(8)
          .height(60)
          .onChange((msg: string) => {
            this.message = msg
          })
          .margin({ top: 10, bottom: 10, left: 4, right: 4 })
        Button("提交")
          .margin(4)
          .layoutWeight(2)
          .onClick(() => {
            let MsgIn: MsgInput = new MsgInput()
            MsgIn.id = this.MsgArray.length.toString()
            MsgIn.role = "user"
            MsgIn.content = this.message
            this.MsgArray.push(MsgIn)
            this.httpData(this.MsgArray)
            this.message = ""
          })
      }
      .backgroundColor("#F7F7F7")
    }
    .width("100%")
    .height("100%")
    .justifyContent(FlexAlign.SpaceBetween)
  }
}

在HarmonyOS 4.0设备上运行

(主要介绍与在OpenHarmony中开发时的不同,相同点不在赘述)

运行环境

HUAWEI Mate 40 : HarmonyOS 4.0.0

SDK:3.1.0(API 9)

IDE:4.0.600

一、在创建应用时选择第一个

如图

二、签名

签名时选择support HarmonyOS

需要登录华为账号后继续签名

三、注释掉源码中不支持API 9的部分

网络声明时直接使用即可

其余部分与在开发板上运行都相同,直接运行即可

九、总结

本文我们学习使用了基本组件的使用,网络请求以及状态管理,使用了ForEach循环渲染来构建对话界面。

并且在HarmonyOS设备上成功运行

十、FAQ

2300006 域名解析失败

错误信息

Couldn’t resolve host name.

错误描述

服务器的域名无法解析。

可能原因

1.传入的服务器的URL不正确。

2.网络不通畅。

处理步骤

1.请检查输入的服务器的URL是否合理。

2.请检查网络连接情况

201错误码

检查moudle.json5的网络权限是否添加

代码语言:javascript
复制
"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET"
  }
],

参考链接

错误码[2]

参考资料

[1]

Access Token获取: https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Ilkkrb0i5

[2]

错误码: https://docs.openharmony.cn/pages/v4.0/zh-cn/application-dev/reference/errorcodes/errorcode-net-http.md/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-01-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大前端之旅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 运行环境
  • OpenHarmony+文心一言对话APP WenXinTalk
    • 运行环境
      • 在DAYU200上运行
        • 一、创建应用
        • 二、运行HelloWord
        • 三、修改图标和名称
        • 修改应用图标和名称:
        • 修改桌面图标和名称
        • 四、添加相关权限
        • 五、定义数据模型
        • 六、加载网络数据
        • 接口说明
        • 测试接口
        • 创建HTTP请求
        • 七、UI
        • 首页
        • 八、完整源码
      • 在HarmonyOS 4.0设备上运行
        • 运行环境
        • 一、在创建应用时选择第一个
        • 二、签名
        • 三、注释掉源码中不支持API 9的部分
        • 其余部分与在开发板上运行都相同,直接运行即可
      • 九、总结
        • 十、FAQ
          • 2300006 域名解析失败
          • 201错误码
        • 参考链接
        相关产品与服务
        腾讯云服务器利旧
        云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档