運行環(huán)境
(后面附有API9版本,可修改后在HarmonyOS4設備上運行)
DAYU200:4.0.10.16
SDK:4.0.10.15
IDE:4.0.600
在DAYU200:4.0.10.16上運行
一、創(chuàng)建應用
1.點擊File->new File->Create Progect
2.選擇模版
【OpenHarmony】Empty Ability
3.填寫項目名,WenXinTalk,應用包名com.WenXinTalk,應用存儲位置XXX(不要有中文,特殊字符,空格)
Compile SDK10,Model :Stage
Device Type 默認就可以。
node,建議16.20.1
完成以上配置以后點擊Finish
4.選擇在新窗口打開,等待依賴加載完畢。如圖所示。
如果大家加載依賴報錯的話,檢查自己的網絡。
二、運行HelloWord
1.給開發(fā)板供電,并連接開發(fā)板到電腦,如圖所示
2.簽名
簽名的步驟:
點擊File->Project struct
點擊Apply或者ok就可以,。
現在點擊按鈕運行項目。
控制臺打印信息
01/12 16:13:40: Launching com.myapplication
$ hdc uninstall com.myapplication
$ hdc shell mkdir data/local/tmp/39ca9a16978647c98d8ac8bdf4a45279
$ hdc file send "E:studyHarmonyOSprojectWenXinTalkentrybuilddefaultoutputsdefaultentry-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
證明項目已經成功運行在開發(fā)板上。
如果報錯
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
{
"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的時候,修改中文目錄下的就可以
{
"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就可以。
"requestPermissions": [{
"name": "ohos.permission.INTERNET"
}],
五、定義數據模型
1.在ets目錄下新建model文件夾
2.新建TS File
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獲取 |
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,系統(tǒng)會依次遺忘最早的歷史會話,直到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 | 否 | 表示最終用戶的唯一標識符,可以監(jiān)視和檢測濫用行為,防止接口惡意調用 |
在這個WenXinTalk App中我們主要使用參數messages
測試接口
測試如圖所示
返回數據
{
"id": "as-7gxj35bftb",
"object": "chat.completion",
"created": 1705068746,
"result": "您好,我是文心一言,英文名是ERNIE Bot。我能夠與人對話互動,回答問題,協(xié)助創(chuàng)作,高效便捷地幫助人們獲取信息、知識和靈感。",
"is_truncated": false,
"need_clear_history": false,
"finish_reason": "normal",
"usage": {
"prompt_tokens": 3,
"completion_tokens": 33,
"total_tokens": 36
}
}
創(chuàng)建HTTP請求
1.導入http模塊
import http from '@ohos.net.http';
import { BusinessError } from '@ohos.base';
2.創(chuàng)建createHttp
let httpRequest = http.createHttp();
3.填寫HTTP地址
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.對網絡數據的處理
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中的標識,用以后續(xù)循環(huán)渲染
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.在應用程序里測試網絡請求
build() {
Column() {
Button("測試網絡請求").onClick(() = > {
this.httpData()
})
}.width("100%").height("100%").justifyContent(FlexAlign.Center)
}
}
如圖所示
測試成功
如果2300006錯誤碼,請檢查網絡
如果201錯誤碼,請檢查module.json中網絡權限是否配置!
七、UI
數據獲取到之后,我們就剩在頁面上顯示了。
首頁
U I布局如圖所示。
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) //循環(huán)渲染時,鍵值匹配規(guī)則使用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)
}
}
八、完整源碼
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 >) {
let httpRequest = http.createHttp();
httpRequest.request(
"https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=24.c8909e4016b8a223464e02f463f1d1ac.2592000.1707464478.282335-46746495",
{
method: http.RequestMethod.POST,
header: [{
'Content-Type': 'application/json'
}],
extraData: {
"messages": MsgArray
}
}, (err: BusinessError, data: http.HttpResponse) = > {
if (!err) {
let MsgReturn: WenXinReturn = JSON.parse(data.result.toString())
this.MsgResult.content = MsgReturn.result
let MsgIn: MsgInput = new MsgInput()
MsgIn.role = "assistant"
MsgIn.content = this.MsgResult.content
MsgIn.id = this.MsgArray.length.toString()
this.MsgArray.push(MsgIn)
httpRequest.destroy();
} else {
this.message = JSON.stringify(err)
console.error('error:' + JSON.stringify(err));
httpRequest.off('headersReceive');
// 當該請求使用完畢時,調用destroy方法主動銷毀
httpRequest.destroy();
}
}
)
}
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中開發(fā)時的不同,相同點不在贅述)
運行環(huán)境
HUAWEI Mate 40 : HarmonyOS 4.0.0
SDK:3.1.0(API 9)
IDE:4.0.600
一、在創(chuàng)建應用時選擇第一個
如圖
二、簽名
簽名時選擇support HarmonyOS
需要登錄華為賬號后繼續(xù)簽名
三、注釋掉源碼中不支持API 9的部分
網絡聲明時直接使用即可
其余部分與在開發(fā)板上運行都相同,直接運行即可
九、總結
本文我們學習使用了基本組件的使用,網絡請求以及狀態(tài)管理,使用了ForEach循環(huán)渲染來構建對話界面。并且在HarmonyOS設備上成功運行, 更多的鴻蒙開發(fā)實戰(zhàn)學習,可以前往我的主頁學習更多,下面分享鴻蒙的開發(fā)知識體系曲線圖 :
鴻蒙OpenHarmony技術進階包看主頁
十、FAQ
2300006 域名解析失敗
錯誤信息
Couldn’t resolve host name.
錯誤描述
服務器的域名無法解析。
可能原因
1.傳入的服務器的URL不正確。
2.網絡不通暢。
處理步驟
1.請檢查輸入的服務器的URL是否合理。
2.請檢查網絡連接情況
201錯誤碼
檢查moudle.json5的網絡權限是否添加
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
],
審核編輯 黃宇
-
AI
+關注
關注
87文章
30728瀏覽量
268874 -
鴻蒙
+關注
關注
57文章
2339瀏覽量
42804 -
OpenHarmony
+關注
關注
25文章
3713瀏覽量
16251 -
文心一言
+關注
關注
0文章
124瀏覽量
1275
發(fā)布評論請先 登錄
相關推薦
評論