Hello~ ProChat 1.0 : 会话组件中 的“亿” 点点细节

简介: Hello~ ProChat 1.0 : 会话组件中 的“亿” 点点细节

本文来源:支付宝体验科技公众号




ProChat 官网地址直达:https://pro-chat.antdigital.dev/


嗨~TechUI 的家人们,欢迎来到 TechUI 的冬季产品发布稿现场!今天我们将带给你们一点有趣又实用的东西 😎 —— ProChat 1.0。




正如预告所言,今年最火 🔥 的技术是什么?想必回答一定会是大模型。而我们所做的 ProChat 正是一款开箱即用的大模型对话前端解决方案,提供类 ProTable 的 request 接口和 useProChat 等方便的编程式操作控制,帮助你用 80 行代码 3 分钟 快速搭建 AI 对话产品。


当然,现在市面上已经有很多大模型的前端解决方案了,你可能会问,为什么我要使用 ProChat ,它有什么优势吗?而这个答案,也就在本文的标题中 —— 因为我们所关注的“亿”点点细节。我知道,“亿”这个字眼可能会让人觉得太过庞大和遥不可及,但在 ProChat 里,每一个“小细节”都值得被放大镜仔细端详。


让我们开始吧!


  ProChat 体验细节

默认的流式输出支持


由 ChatGPT 率先实现的流式输出在用户体验上远超传统的 HTTP 请求,SSE(Server Send Event)这项技术也可以说正式登上了主流技术圈的视野中。ProChat 作为 AI 会话的前端解决方案,自然默认集成了这项流式输出的能力。


只需要在 request 中配置一个返回流式文本的 Response (Web标准的 Response 对象),就可以轻松实现流式效果的集成。


import { ProChat } from '@ant-design/pro-chat';
import { MockResponse } from '../mocks/streamResponse';
export default () => {
  const theme = useTheme();
  return (
    <ProChat
      request={async (messages) => {
        const mockedData: string = `这是一段模拟的流式字符串数据。本次会话传入了${messages.length}条消息`;
        const mockResponse = new MockResponse(mockedData, 50);
        return mockResponse.getResponse();
      }}
    />
  );
};


效果如下:



而同样的,ProChat 的 request api 也兼容传统的非流式请求:


/**
 * description: 消息将在等待 5s 后返回
 */
import { ProChat } from '@ant-design/pro-chat';
const delay = (text: string) =>
  new Promise<string>((resolve) => {
    setTimeout(() => {
      resolve(text);
    }, 5000);
  });
export default () => {
  
  return (
    <ProChat
      request={async (messages) => {
        const text = await delay(
          `这是一条模拟非流式输出的消息的消息。本次会话传入了${messages.length}条消息`,
        );
        return new Response(text);
      }}
      style={{ height: '100vh' }}
    />
  );
};


完备的 Markdown、代码块展示


大模型可以通过 Markdown 的语法输出格式化的文本,因此 Markdown 的展示与渲染是一个AI会话组件必不可少的模块。ProChat 中已经完整支持基础的 Markdown 语法,并增强支持了代码块、LaTeX 数学公式等特性。完整效果一览如下:




其中我们特别优化了代码块的交互与体验。


其中:针对单行代码,我们使之更加贴近命令行执行风格,以符合常见的代码块使用习惯。




而针对多行代码块,我们则强化了代码块组件的交互能力,使之具有折叠展开、更换高亮语言等进阶功能,进而帮助你在日常使用 AI 大模型中更好地查看AI生成的代码。




当然,如果你希望在其他场景使用如此丰富与强大的 Markdown 与代码块组件,完全没有问题!ProChat 的 Markdown 语法高亮和代码块借助了 ProEditor 的 Markdown 组件 与 Highlight 组件 得以实现。而你也可以轻松地在你的项目中集成与使用。



会话消息的编辑与重新发送


如果经常使用 AI 大模型会话的同学,应该经常会感受到有时候大模型的输出存在一些瑕疵,导致体验极其不好。譬如上述的代码块场景。能够展示代码块的前提是 ai 标记输出了代码块的语法。但如果此时 AI 直接输出了纯文本,连代码块都没有呈现,请问阁下又该如何应对?




如果你在使用 ChatGPT ,那么你唯一能做的就只是让 AI 包含 Markdown 格式进行重新输出。这个体验并不理想。


而 ProChat 则给了用户一个新的选择:直接改它!

image.png


是的没错,在我们这大半年的实践中,我们发现可编辑的 AI 消息,对于用户操作的便捷性与易用度来说都非常有用,体验上更是能有一个巨大的体验。


与此同时,懂行的同学估计也知道,在 Chat 组件中实现可编辑消息的难度和复杂度,也比单纯的展示消息要高出很多。


而这正是 ProChat 的交互前瞻性与技术先进性的体现。


  快速上手


好了,既然看了那么多 ProChat 的,那我们就看看如何快速上手使用吧!


安装 & 使用


直接使用 tnpm 进行安装,如果是非内部使用,也可以用 pnpmyarnbun 这类进行安装


tnpm install @ant-design/pro-chat --save
tnpm install @ant-design/antd-style --save


依赖需求


peerDependencies: {
  "antd": "^5",
  "antd-style": "^3",
  "react": "^18"
}


组件使用如下:最简单的情况下,你只需要一个 Request 的 Api 就可以了,详细使用和参考可以看下面的内容。


<ProChat
  request={async (messages) => {
    // request 发送,Mesaage 作为 参数传入
    return Response; // 支持流式 & 非流式
  }}
/>


80 行 3 分钟接入通义千问大模型


这是一个快速接入通义千问的例子,这里展示的是 NextJs 项目,如果是 umi 的话,需要一个服务端,目前通义千问还不支持客户端请求(OpenAI 是支持的)


import { ProChat } from '@ant-design/pro-chat';
export default () => {
  return (
    <ProChat
        style={{
          height: "100vh",
          width: "100vw",
        }}
        request={async (messages) => {
          const response = await fetch("/api/qwen", {
            method: "POST",
            body: JSON.stringify({ messages: messages }),
          });
          const data = await response.json();
          return new Response(data.output?.text);
        }}
      />
  );
};


import { NextResponse } from "next/server";
export async function POST(request: Request) {
  const { messages = [] }: Partial<{ messages: Array<any> }> =
    await request.json();
  try {
    const apiKey = "Your-Api-Key"; // 你的 API 密钥
    const response = await fetch(
      "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation",
      {
        method: "POST",
        headers: {
          Authorization: "Bearer " + apiKey,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          model: "qwen-turbo",
          input: {
            messages: [
              {
                role: "system",
                content: "You are a helpful assistant.",
              },
              ...messages,
            ],
          },
          parameters: {},
        }),
      }
    );
    const data = await response.json();
    return NextResponse.json(data);
  } catch (error) {
    return NextResponse.error();
  }
}


因为我们担心使用个人 Key 给大家体验会有些奇怪的问题,我们结合 CodeFuse 的通义千问接口,给大家搭建了这样一个体验地址,后续会在 TechUI Studio 中持续完善,请关注我们。👇 戳我体验 ProChat + 通义千问


程序化控制


如果你需要使用程序化的方式控制,我们还提供了 chatRefuseProChat 两种方式,供你获取 proChat 实例,进而实现程序化控制:


import { ProChat, ProChatInstance } from '@ant-design/pro-chat';
import { useRef } from 'react';
import { Button } from 'antd';
import { MockResponse } from '@/ProChat/mocks/streamResponse';
import { example } from '../mocks/basic';
export default () => {
  const proChatRef = useRef<ProChatInstance>();
  return (
    <div>
      <Button
        type={'primary'}
        onClick={() => {
          if (!proChatRef.current) return;
          const messages = proChatRef.current.getChatMessages();
          const { id, content } = messages[0] || {};
          if (!id) return;
          proChatRef.current.setMessageContent(id, content + '👋');
        }}
      >
        修改首条消息,添加表情:👋
      </Button>
      <ProChat
        initialChats={example.chats}
        chatRef={proChatRef}
        request={async (messages) => {
          const mockedData: string = `这是一段模拟的流式字符串数据。本次会话传入了${messages.length}条消息`;
          const mockResponse = new MockResponse(mockedData, 100);
          return mockResponse.getResponse();
        }}
      />
    </div>
  );
};


image.png


针对更加复杂的场景,使用 useProChat  hooks 来获取 proChat 实例对象,进而实现更加丰富的业务逻辑:


import { ProChat, ProChatProvider, useProChat } from '@ant-design/pro-chat';
const Control = () => {
  const proChat = useProChat();
  return (
    <Flex style={{ padding: 24 }} gap={8} justify={'space-between'}>
      <Flex gap={8}>
        <Button
          type={'primary'}
          onClick={() => {
            proChat.sendMessage('这是程序化发送的消息');
          }}
        >
          发送一条消息
        </Button>
        <Button
          onClick={() => {
            const messages = proChat.getChatMessages();
            const msg = messages.at(-1);
            if (msg) {
              message.info(msg.content);
            } else {
              message.warning('会话为空');
            }
          }}
        >
          获取最新会话消息
        </Button>
      </Flex>
      <Button
        onClick={() => {
          const messages = proChat.getChatMessages();
          const { id, content } = messages[0] || {};
          if (!id) return;
          proChat.setMessageContent(id, content + '👋');
        }}
      >
        修改首条消息,添加表情:👋
      </Button>
      <Flex gap={8}>
        <Button
          danger
          onClick={() => {
            const messages = proChat.getChatMessages();
            proChat.deleteMessage(messages[0].id);
            message.success('已删除第一条消息');
          }}
        >
          删除第一条消息
        </Button>
        <Button
          type={'primary'}
          danger
          onClick={() => {
            proChat.clearMessage();
          }}
        >
          清空消息
        </Button>
      </Flex>
    </Flex>
  );
};
export default () => (
  <ProChatProvider initialChats={example.chats}>
    <Control />
    <Divider>🔼 程序化控制 | 🔽 用户控制</Divider>
    <Chat />
  </ProChatProvider>
);


image.png 注意:useProChat hooks 必须在包裹 ProChatProvider 后方可使用。


  开源地址 & 联系我们



接下去的一段时间,我们会继续根据用户反馈持续优化产品体验,修复和完善产品功能。

相关文章
|
3月前
|
前端开发 图形学 开发者
【独家揭秘】那些让你的游戏瞬间鲜活起来的Unity UI动画技巧:从零开始打造动态按钮,提升玩家交互体验的绝招大公开!
【9月更文挑战第1天】在游戏开发领域,Unity 是最受欢迎的游戏引擎之一,其强大的跨平台发布能力和丰富的功能集让开发者能够迅速打造出高质量的游戏。优秀的 UI 设计对于游戏至关重要,尤其是在手游市场,出色的 UI 能给玩家留下深刻的第一印象。Unity 的 UGUI 系统提供了一整套解决方案,包括 Canvas、Image 和 Button 等组件,支持添加各种动画效果。
166 3
|
4月前
|
存储 人工智能 机器人
工作3年,还分不清文件大小单位关系的?就看这篇吧!
工作3年,还分不清文件大小单位关系的?就看这篇吧!
文本,学习方法,必须做,快的学习方法,统计汇总写法,比如你要构思一个数学库,需要写一个汇总,主动获取标题统计,主动生成文章跳转链接,然后将它打入文章资料当中:
文本,学习方法,必须做,快的学习方法,统计汇总写法,比如你要构思一个数学库,需要写一个汇总,主动获取标题统计,主动生成文章跳转链接,然后将它打入文章资料当中:
聊天框(番外篇)—如何实现@功能的整体删除
上一篇文章中,我们已经初步实现了聊天输入框,但其@功能是不完善的,例如无法整体删除、无法获取除用户名以外的数据(假设用户名不是唯一的)。有问题就要想办法解决,在网上百度了一圈后,倒是有一些收获。本文就着重解决@的整体删除以及获取额外数据。
1131 0
聊天框(番外篇)—如何实现@功能的整体删除
|
存储 小程序 前端开发
【易售小程序项目】小程序私聊页面完善(带尾巴聊天气泡组件封装、滑至顶端获取历史聊天数据逻辑优化)【后端基于若依管理系统开发】
【易售小程序项目】小程序私聊页面完善(带尾巴聊天气泡组件封装、滑至顶端获取历史聊天数据逻辑优化)【后端基于若依管理系统开发】
68 0
|
vr&ar 开发工具 图形学
Unity引擎更新收费模式:从收入分成转向游戏安装量,将会有哪些影响呢
Unity引擎更新收费模式:从收入分成转向游戏安装量,将会有哪些影响呢
|
前端开发
给大家科普一泛二级程序前端几十套模板随机切换
​ 今天给大家分享几个小旋风蜘蛛池的泛二级程序网站站群模板,是无备案 新域名都可以用 老域名备案域名效果更好, 文章自动配图 关键词自动配图 泛二级程序模板是一款专门为了要从事相关工程方面工作的
129 0
|
关系型数据库 MySQL 应用服务中间件
独立博客、文档类网站消亡倒计时
独立博客、文档类网站消亡倒计时
142 0
独立博客、文档类网站消亡倒计时
|
JSON 数据可视化 JavaScript
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(一)
UI库提供了很多组件,组件又带有很多属性,有一些常用属性我们可以记住并且手撸,但是有些不常用的属性,或者需要设置多个属性,这样的情况下写起来就麻烦了,有时候还要打开帮助文档看看属性是怎么设定的,需要设置什么样的属性值。那么有没有优雅的方式来设置组件的各种属性呢?我做了一个在线小工具,可以方便的设置属性,并且可以实时看到效果。
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(一)
|
JSON JavaScript 数据可视化
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(二)
UI库提供了很多组件,组件又带有很多属性,有一些常用属性我们可以记住并且手撸,但是有些不常用的属性,或者需要设置多个属性,这样的情况下写起来就麻烦了,有时候还要打开帮助文档看看属性是怎么设定的,需要设置什么样的属性值。那么有没有优雅的方式来设置组件的各种属性呢?我做了一个在线小工具,可以方便的设置属性,并且可以实时看到效果。
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(二)