AIGCDesign 开放式跨端 AI 组件解决方案
一、我们为什么要做这样的一件事情?
如果说2022年11月30日发生了什么值得标记的事,那一定是OpenAI团队发布了全新的ChatGPT模型。一个简洁的聊天交互界面,就能完成回答问题、撰写文本、翻译语言、编写代码等多种任务——这种能力跃迁,直接给整个AI行业带来了一场巨变。搜索热度的持续攀升,也从侧面印证了这一点。
AIGC搜索热度-数据来自Google Trends
能力跃升的背后,必然伴随着新产品、新模式的爆发机遇。作为一线的业务研发,我们需要思考的是:如何承接住这股技术革新带来的业务需求激增?过往的经验告诉我们,如果要快速交付大量同类型应用,关键在于分层抽象的、类型丰富的组件沉淀。有了这些组件的复用能力,再结合LowCode/NoCode平台,就能通过“搭积木”的方式快速产出应用。
基于这个判断,我们调研了业界已经初具规模的6类AIGC组件库,梳理了它们的共性与差异,同时也盘点了京东内部现有的平台能力。最终,在京东零售前端通道的支持下,我们启动了一个基于内源共建的开放式跨端AI组件解决方案项目——给它取了个名字:
AIGCDesign
二、前期调研:当前AIGC行业内前端AI组件库的进展
项目启动之初,我们对行业内开源的高Star组件和应用做了一次摸底。从可拓展性、组件覆盖度、端支持、框架支持等多个维度进行了评测,具体如下表:

从这些对比里,我们提炼出几个关键能力项:
- 轻量、快速开发、开箱即用
- 覆盖TailWind、React、Vue、Native
- 会话组件、多模态录入
- 响应式布局
结合京东内部多种多样的业务形态,以及灵活支持定制的需求,我们的组件库必须具备Native、Web、MP、PC等多端能力,同时要支持React、Vue、Android、iOS等多种技术框架。综合以上考量,我们最终明确了方案的核心定位和目标:
三、AIGCDesign的技术实现
有了核心目标,接下来就是技术选型、技术架构和具体实现细节的落地。
3.1 整体技术架构
组件库借助Taro的跨端能力,输出MP和H5组件。通过Web端的响应式方案,同时支持H5和PC端的内容输出,单React应用也能跑得起来。
在内部,组件库集成了AI接口请求能力(京东言犀)。开发者只需要引用容器组件,做几项简单的配置,就能“开箱即用”地输出一个AI应用。当然,如果某些组件的功能不足以覆盖业务形态,组件库也预留了大量的自定义接口,开发者可以进行高定制化开发,灵活对接私域大模型服务。
整体架构分为三层:
- :提供AI平台对接相关功能,包括各类基础模块和API。可以在容器或者组件中引用,也可以在项目中独立使用。
核心层
- :支持多端多框架的应用容器,内部对接大模型平台,提供基础的AI会话交互,并且开放会话区域的高度自定义能力。
容器层
- :集合基础组件、业务组件和自定义组件,供容器层渲染使用。通过组件映射的方式,在容器组件中完成渲染。
组件层
在原生实现方面,我们采用的是基于JDHybrid的混合架构:
- 对经常变更的业务组件或模块,通过H5接入;
- 对不经常变更的容器组件、基础组件,通过原生开发;
- 业务侧的Taro组件,可以快速复用到Native项目中。
核心实现因此拆分成三部分:
- :包含弹层、语音交互、Toast提示、自定义头部、底部输入框、工具箱等。
原生基础组件
- :负责整体事件、UI、接口请求等配置,是AIGC组件的核心模块。
原生容器组件
- :负责H5与原生容器组件的交互和消息通信。
JDHybrid扩展协议和AIGC JSSDK
3.2 应用生命周期
容器组件提供了完整的应用生命周期方法。开发者可以在每一个流程节点进行事件监听,实时获取最新的应用状态。结合生命周期函数和容器属性,可以进行定制化逻辑开发,灵活支持各类业务形态。生命周期的主要特性包括:
- 容器组件提供全流程生命周期事件,调用方可以随时获取最新的应用上下文和数据
- 默认提供了京东言犀平台的对接模块,基础配置即可解锁完整的AI会话交互流程
- 通过容器组件属性配置,可以灵活添加自定义流程控制:模型检索、会话渲染、生命周期等
主要支持以下生命周期Hooks:
- :容器组件加载前执行
beforeLaunch
- :容器组件加载完成后执行
onLaunch
- :用户点击发送按钮后,请求大模型前执行
onSubmit
- :大模型数据返回后执行,用于在组件外部获取返回数据
onLLMResult
- :组件更新完成后执行,代表本次会话更新完成
onChatUpdate
3.3 用户交互和数据流转流程
交互界面和数据流转流程如下图所示:
3.4 最小化配置和自定义配置方案
组件库内置了AI聊天全流程的交互,少量入参就能实现基础功能。当然,也可以结合生命周期事件和相关属性做定制化配置。
调用方引入容器组件,配置言犀平台的apiKey和大模型平台路径,就可以输出聊天记录界面:
import AiContainer from "@aigcui/container";
...
// 言犀平台apiKey
apiKey='xxx'
// 大模型接口的路径
aiPath='/ChatRhino/api/v1/chat/completions'
/>
...
结合生命周期事件和相关属性配置,可以自定义以下功能:
- :调用方可以自行发起大模型接口请求,并将会话数据注入容器,容器根据注入的数据进行会话区域渲染
大模型请求
- :会话区域可以完全交由调用方自定义渲染
会话区域渲染
- :支持自定义配置,还能实现展开收起功能
会话输入区域扩展图标
- :输入框上方支持快捷操作区域的自定义渲染
快捷操作区域
- :会话卡片的头部和底部都支持自定义渲染
会话卡片头尾区域
3.5 Web平台多框架支持方案
为了实现对多开发框架的支持,除了借助Taro跨端解决方案,组件库还提供了UMD产物。通过加载JS文件的方式,可以将组件渲染到指定DOM节点,同时结合AutoBots平台能力,进行AI应用的输出。
UMD组件基于React开发框架。如果项目内已经全局挂载了React环境,可以引用纯组件代码包;如果全局没有React环境,则可以引用组件库全包进行渲染。全包内部集成了React框架代码,会自动处理React应用和组件的初始化流程,接入方直接在项目内调用组件渲染方法就能输出应用。
全包引用的代码示例如下:
<script src="https://storage.jd.com/taro/aigc-ui/1.0.6/aigcjdfe-autobots-full.umd.js"></script>
window['autobots-full'].renderAiChatBubble({
width: 500,
height: 500,
chatInfo: {
agentId: 'xxx',
token: 'xxxxxx',
}
}, 'app')
四、业务接入案例
基于上述共建形式,目前已经有多端案例接入:


五、AIGCDesign长期努力的方向和价值
组件库目前已经支持MP、Web、Hybrid、Android的AI会话基础能力。通过自定义配置,可以覆盖大部分AI聊天交互场景。最新版本为1.0.6,提供了MP端8个会话组件和Web端14个业务组件。Autobots组件除了NPM包引入方式,还支持UMD方式接入,实现了技术栈无关的全量适配能力。
接下来的时间,我们将在以下两个方面加大对AIGCDesign的投入:
1、根据架构设计,持续完善核心能力
- 平台能力建设:支持高度灵活的配置化能力,提供便捷的组件产出和搭建能力
- 多端多框架能力建设:提供NPM/UMD等多种形式产物,输出多端容器和组件,实现技术栈无关的接入能力
- 底层能力扩充:逐步融合OCR、ASR/TTS、Agent、知识库等多种底层能力
2、2B端/2C端多业务形态支持,多场景交互形式拓展
- 场景化能力扩展:支持B/C端通用的场景化AI交互能力和组件,极低成本快速接入
- 通用能力支持:结合AI能力,拓展非对话框场景的交互能力。提供高度可配置化交互组件,支持数据源配置和交互定制化,配合投放平台,满足营销、办公等各类场景
可以确定的是,在京东零售前端通道内源共建小组的努力、内外部贡献者的协同建设,以及京东丰富业务场景的加持下,AIGCDesign一定能够交付更多优秀的能力和组件,为研发提效和业务赋能带来更大的价值。
附、流式处理技术点扩展
1、流式数据接收和处理
1.1 在与AI对话的过程中,比较常用的方式是通过请求支持流式数据的API来获取数据。这种方式的优势很明显——用户可以更快地看到响应数据和输入过程。
1.2 在前端,通过fetch实现流式接口数据请求,依赖的是ReadableStream接口。逐块读取数据并进行处理,可以实现对流式数据的高效处理。同时,使用AbortController可以实现请求的中止,提供更灵活的控制。
async function fetchStream(url, params) {
const { onmessage, onclose, ...otherParams } = params;
const response = await fetch(url, otherParams);
const reader = response.body.getReader();
const decoder = new TextDecoder();
let result = '';
while (true) {
const { done, value } = await reader.read();
if (done) {
onclose?.();
break;
};
result = decoder.decode(value, { stream: true });
// 处理接收到的数据块
onmessage?.(result);
}
console.log('Stream complete');
}
const controller = new AbortController();
const signal = controller.signal;
fetchStream('https://example.com/stream-endpoint', {
signal,
onmessage: (text) => { console.log(text); }
onclose: () => { console.log('Stream abort'); }
});
// 如果需要提前结束输入,通过调用以下中止请求和修改输入结束状态实现
controller.abort();
流式处理数据的方式主要有两种:
- :触发onmessage时,把拼装好的数据传入handleData方法,实时调用
正常按照流式的方式处理
- :等流式接口返回已完成标识后,再把拼装好的数据一次性调用handleData
按非流式的方式处理
2、流式Markdown渲染
AIGC Web端组件库已经实现了流式Markdown渲染。通过react-markdown组件包裹输入内容,配合rehype-highlight等工具实现markdown格式的内容展示。通过components属性,可以自定义markdown标签的渲染方式。
const BubbleMarkdown: React.FC<{ children?: string }> = ({ children }) => {
return (
{
const href = aProps?.href || "";
const isInternal = /^/#/i.test(href);
const target = isInternal ? "_self" : aProps?.target ?? "_blank";
return ;
},
}}
>
{children}
);
};
对话框支持以下几种接口返回和渲染方式。无论是流式还是非流式返回,都支持打字机和全量渲染效果:

流式数据处理方式会持续渲染对话框,因此需要对以下几点交互做单独的优化处理:
- 对话渲染过程中,不要引起父组件重新渲染
- 建议使用模拟输入效果,平缓地控制输入节奏
- 当对话内容超出屏幕时,需要向上滚动页面。这种情况需要通过节流控制滚动节奏,避免页面闪动
- 对话输入过程中,要禁止用户的输入行为。如果需要继续对话,可以点击中止后再进行用户输入
useEffect(() => {
if (!isEnd) {
// 如果服务端返回数据结束,且当前展示文本等于服务端返回文本,则停止输入
setEntering(!(responseEnded && content === text));
// 如果是模拟输入,且当前展示文本不等于服务端返回文本,则继续输入
if (
simulate &&
content &&
content !== text &&
// 以下逻辑解决流式数据接入且为模拟输入时,文本长度重复触发文本更新问题
text.length === len.current
) {
const { time, char } = getInputTimeAndChar(
content,
simulateSpeed,
inputTimeAndCharMap,
);
const randomLen = getRandomInt(
char?.[0] || 2,
char?.[1] || 6
);
len.current +=
len.current + randomLen > content.length
? content.length - len.current
: randomLen;
timeout.current = setTimeout(() => {
setText(content?.slice(0, len.current) || "");
}, getRandomInt(time?.[0] || 60, time?.[1] || 200));
}
// 非模拟输入,直接展示服务端返回文本
if (!simulate) {
setText(content || "");
}
}
}, [
responseEnded,
text,
content,
simulate,
isEnd,
simulateSpeed,
inputTimeAndCharMap,
]);
