动动小手学鸿蒙 HarmonyOS APP(04)AI聊天页面

ChatGpt类产品在输出答案的时候有一个明显特征,回答问题的文字是一个一个字蹦出来的。这种展示方式基于人工智能答案生成原理而设计。因为大语言模型在生成答案时就是逐字逐句一点点生成的。如果等整篇答案完全生成后再返回给前端,用户等待的时间就太长了。会严重影响用户体验。

根据ChatGpt介绍可以了解到,前端请求并不是使用webSocket,由于WebSocket需要client和server都持续占用一个socket,server侧成本比较高。ChatGPT使用的是一种折中方案: server-sent event(简称SSE).

SSE 模式下,client只需要向server发送一次请求,server就能持续输出,直到需要结束。 SSE仍然使用HTTP作为应用层传输协议,充分利用HTTP的长连接能力,实现服务端推送能力。

从代码层面来看,SSE模式与单次HTTP请求不同的点有:

  1. client端需要开启 keep-alive,保证连接不会超时。
  2. HTTP响应的Header包含 Content-Type=text/event-stream,Cache-Cnotallow=no-cache 等。
  3. HTTP响应的body一般是 "data: ..." 这样的结构。
  4. HTTP响应里可能有一些空数据,以避免连接超时。

看到这里,我们可以了解到通过这种SSE请求的方式,前端正是逐字得到的答案,所以在展示时就是按请求返回来展示出陆陆续续得到的文本答案。

了解了原理,本篇主要展示在鸿蒙中模拟展示这种逐字文本展示的AI聊天界面。

先看下效果:

本demo中仅实现UI效果,并未真正发送请求来获得数据。通过预置文本和定时器来实现一个字一个字蹦出来的效果。

聊天页面中外层为Stack布局,底部是输入TextInput和发送按钮,上部按顺序展示用户输入和系统回答文本。

正式项目中需要考虑加入加载动画,请求异常处理,代码以及表格图片等展示组件,聊天区域的滚动展示等问题。

非常简单,就直接贴代码了

ts 复制代码
build() {
  Stack({ alignContent: Alignment.Bottom }) {
    Column() {
      Row() {
        Text('你好呀我是聊天助手,有什么话想对我说吗?希望可以和你一起分享生活中的点点滴滴!')
          .fontSize(18)
          .fontColor('#1a1c1f')
          .padding(12)
          .backgroundColor('#f4f6f9')
          .margin({top: 12})
          .clip(new Rect({ width: '100%', height: '100%', radius: 12 }))
      }
      .width('100%')
      .justifyContent(FlexAlign.Start)

      if (this.answer.length > 0) {
        Row() {
          Text(this.question)
            .fontSize(18)
            .fontColor('#fefbf9')
            .padding(12)
            .margin({top: 12})
            .backgroundColor('#2e74f7')
            .clip(new Rect({ width: '100%', height: '100%', radius: 12 }))
        }
        .width('100%')
        .justifyContent(FlexAlign.End)

        Row() {
          Text(this.answer)
            .fontSize(18)
            .fontColor('#1a1c1f')
            .padding(12)
            .backgroundColor('#f4f6f9')
            .margin({top: 12})
            .clip(new Rect({ width: '100%', height: '100%', radius: 12 }))
        }
        .width('100%')
        .justifyContent(FlexAlign.Start)
      }
    }
    .height('100%')
    .width('100%')
    .padding(12)

    Row() {
      TextInput()
        .fontSize(18)
        .width('80%')
        .fontColor('#fefbf9')
        .padding(12)
        .clip(new Rect({ width: '100%', height: '100%', radius: 12 }))

      Blank().width(12)

      Text('发送')
        .fontSize(18)
        .padding(8)
        .fontColor('#fefbf9')
        .backgroundColor('#2e74f7')
        .clip(new Rect({ width: '100%', height: '100%', radius: 12 }))
        .onClick(() => {
          this.answer = '';
          this.pos = 0;
          clearInterval(this.intervalID);
          setTimeout(() => {
            this.intervalID = setInterval(() => {
              if (this.pos < this.text.length) {
                this.answer = this.answer.concat(this.text.charAt(this.pos))
                this.pos += 1;
              } else {
                clearInterval(this.intervalID);
              }
            }, 100)
          }, 500);
        })
    }
    .width('100%')
    .height(80)
    .padding({left: 12, right: 12})
    .alignItems(VerticalAlign.Center)
    .justifyContent(FlexAlign.End)
  }
}

通过本例可以熟悉这些知识:基础组件布局组件定时器等常用鸿蒙开发知识。

边学边写,欢迎留言。感谢各位大佬点赞

相关推荐
想你依然心痛2 小时前
HarmonyOS 6(API 23)实战:基于悬浮导航、沉浸光感与HMAF的“数智视界“——PC端AI智能体沉浸式数据可视化分析工作台
华为·ar·harmonyos·智能体
晓梦林9 小时前
cp520靶场学习笔记
android·笔记·学习
前端不太难10 小时前
从单页面到系统化:鸿蒙 App 演进路径
华为·状态模式·harmonyos
想你依然心痛11 小时前
HarmonyOS 6(API 23)实战:基于悬浮导航、沉浸光感与HMAF的“文思智脑“——PC端AI智能体沉浸式智能写作工作台
人工智能·ar·harmonyos·ai写作
小雨青年11 小时前
鸿蒙 HarmonyOS 6 | Pura X Max 鸿蒙原生适配 09:展开态列表增加字段但不变复杂
华为·harmonyos
richard_yuu11 小时前
鸿蒙治愈游戏模块实战|四大轻量解压游戏、ArkTS动画交互与低功耗落地
游戏·交互·harmonyos
有味道的男人12 小时前
Open Claw对接1688平台
android·rxjava
_李小白13 小时前
【android opencv学习笔记】Day 17: 目标追踪(MeanShift)
android·opencv·学习
用户860225046747214 小时前
AI 分析头部APP系统优化框架
android
用户860225046747214 小时前
AI分析头部APP优化框架
android