AIGC 和低代码结合应用全栈研发实践总结 | 得物技术
目录
一、背景
二、思考
三、具象思考
四、对低代码的“吐槽”
五、主要方案设计
1. 简化组件配置
2. 高效初始化页面
2.1 通过页面模版初始化
2.2 通过接口元数据生成页面
2.3 根据 PRD 描述快速生成页面
3. 智能答疑
六、大模型训练和应用
七、对低代码应用的看法
八、功能架构图
九、问题和规划
十、参考
一、背景
电商供应链的系统建设,往往偏向数据管理类型。这类系统有一个非常突出的问题——前后端研发的沟通成本,相对研发总成本而言,简直高得惊人。尤其是那些只是加加减减字段的简单诉求,沟通成本甚至能占到 50% 以上。怎么把这部分沟通成本降下来,同时保证高质量交付,成了眼下急需解决的难题。
对需求和系统页面进行一番梳理后,发现了几组有意思的数据:
- 供应链里 ≤ 2 人日的需求,投入工时占了将近 50%。一个两周的迭代周期里,前端同学甚至能接到 10+ 个需求,时间碎片化特别严重。而这些需求其实很简单——字段加减、单选改多选、增加导入导出之类。
- 供应链中七成的页面都属于标准的列表类型(也就是常说的 CQUD:查询、新建、编辑、删除)。这类页面交互简单、功能标准,常见功能包括查询、新建、编辑、批量处理、上下线/删除、导入/导出、查看操作日志、查看详情等。
一句话总结:
需求简单,但沟通成本大!
二、思考
这里的“沟通成本大”,是相对简单需求的开发成本而言的。单独看绝对投入可能还好,但架不住需求量太大,造成的资源浪费依然可观。我们需要探索更高效的需求交付方式。
解决沟通问题,有很多思路。其中比较有效的一个,是得物技术正在推进的 Mooncake 平台。它已经和发布系统打通,代码部署后所有接口和出入参的描述信息都会上传到 Mooncake,统一以文档方式满足接口出入参说明诉求。推行后确实有不错收益,但还是存在两个问题:
- 所谓的“契约精神”——什么时间交付接口描述、描述是否清晰?现实中很难确定。服务端什么时候能上传接口说明,时间不确定;即使确定了,也可能因为各种因素不符合预期。很多时候,一个人觉得已经描述清楚了,但另一个人并不一定理解,这就是信息差。而要真正让另一个人理解,服务端需要付出更多成本,有些人会认为没必要。
- 服务端会修改出入参格式但忘记沟通,往往到了联调甚至测试阶段才发现,而且屡禁不止。
在这种背景下,最直接的做法就是让
服务端一个角色全栈搞定前后端开发
需求中前端部分相对简单很多
三、具象思考
说到全栈,肯定不是直接把前端工作扔给服务端去做。得物研发目前的工作压力不小,需要一种低成本的全栈方案,让服务端快速上手。低成本的前提就是把复杂的前端开发变得简单。初期考虑了三条路:
- 通过低代码配置化代替源码开发,大大降低学习成本。
- 聚焦在标准化的 CQUD 页面类型,减少发散,用更低成本覆盖最多的页面。
- 结合当下火的大模型 AIGC 方向,降低全栈学习成本。
低代码代替源码开发的好处是,服务端在配置一两个页面后就能快速掌握配置技能,认知成本低,学习周期短。下面这张图或许更能说明问题。
源码和低码学习成本趋势图
另外,在知乎上看到一张很有意思的图,虽然有点夸张,但能帮助理解低代码的学习成本。
低代码和几种跨界工具的学习成本对比
各大厂在低代码领域已经非常成熟。列举两个做得比较好的:
- 阿里低代码引擎:https://lowcode-engine.cn/index ,强调可视化配置生成页面;
- 百度 Amis:https://aisuda.bce.baidu.com/amis/zh-CN/docs/index ,强调 JSON 配置生成页面。
最终选择了 Amis 作为基础渲染引擎,原因如下:
- Amis 的 JSON 配置能力更强。和 Lowcode Engine 相比,后者需要写很多脚本来满足稍微复杂的场景;而 JSON 配置学习成本更低,更适合服务端同学快速上手。
- Amis 的文档功能强大,可以直接编辑 JSON 并查看修改结果,极大方便了开发学习 API。
关于与 AIGC 结合,重点看低代码在全栈场景下能解决什么问题——比如脚本编辑、UI 布局等,这些一定会成为痛点。后面会随着问题的展开逐渐应用起来。
四、对低代码的“吐槽”
在介绍方案之前,先来“吐槽”一下低代码/零代码。很多人说不好用,甚至有人说低代码是“行业毒瘤”。翻看了大量总结性文章,结合自身经验,理性总结如下:
- B 端低代码产品的绝大部分用户是前端。专业人士用低代码多少有点抵触情绪。给别人用之前一定要想清楚:他为什么会用?或者说他因为什么才会用?给前端提供低代码工具做 B 端系统,大概率行不通——也许有效率提升,但专业降级及蹩脚的研发体验可能不值一提。
没有认清使用人群:
- 遇到某种逻辑时,用起来会非常蹩脚或者根本做不下去。正所谓“一行代码难倒英雄汉”,只能再源码开发一遍。这种不断尝试后的返工,体验确实很差。这通常是因为组件不支持或低代码引擎不够灵活。
灵活性不足:
- 做好一个页面,要考虑联调、页面管理、发布/回滚、菜单、权限等多方面问题。那些体验割裂、流程分散在不同平台的方式,一定会被吐槽。
功能不完备:
- 比如常用组件的一种配置,有多种属性命名方式;功能实现不符合大众认知,导致 API 理解和学习成本巨大。
缺乏设计理念:
- 以服务端全栈场景为例,他们甚至不知道组件的概念,也不理解所谓的数据驱动。拿到 PRD 时,往往只有一段文字描述,连个像样的线框图都没有。新手如何把这样的需求还原成标准交互页面?是很大的考验,这些细节都必须考虑并解决。
认知成本高:
五、主要方案设计
不打算过多介绍低代码配置实现的原理,想了解的可以搜索一下。整个全栈方案有一个统一的名字叫 Wizard,包括渲染引擎、组件、在线配置、发布流程、AI 答疑、AI Proto 等一系列工具,下面挑重点介绍。
特殊说明:初期全栈覆盖的页面类型主要聚焦在 CQUD,没有扩散。核心原因是此类页面占比高达 72%,且交互形式足够收敛。页面类型收敛能大幅降低成本,后期可以根据需要选择性覆盖更多页面类型。
针对上面提到的前 4 个槽点,没什么好办法,只能
认清事实,持续去做
三步:简化组件配置、高效初始化页面、智能答疑
简化组件配置
得物的基础组件建设得益于 Antd 和 ProComponents。好的东西直接复用,核心工作是把得物的设计标准和业务组件沉淀下来。组件注册到 Wizard 时,最重要的是将复杂属性转换成 JSON 配置可用的形式,比如接口请求、表单联动、数据格式化等。这一步做不好,会导致部分功能被阉割,所以花费了较大精力去设计实现。以表单联动为例效果如下:
选择显示姓名,姓名展示;选择禁用密码,姓名隐藏,密码禁用
源码实现:
import React, { useState } from 'react';
import { Radio, Form, Input } from 'antd';
type FieldType = {
username?: string;
password?: string;
type?: number;
};
const App: React.FC = () => {
const [form] = Form.useForm();
const [hiddenName, setHiddenName] = useState(false);
const [diablePassword, setDiablePassword] = useState(false);
const onValuesChangeHandler = (values: FieldType) => {
setHiddenName(values.type !== 1);
setDiablePassword(values.type === 2);
};
return (
name="type" wrapperCol={{ offset: 8, span: 16 }}>
显示姓名
禁用密码
{!hiddenName && (
label="姓名" name="username">
)}
label="密码" name="password">
);
};
export default App;
Wizard 配置实现:
{
"type": "form",
"body": [
{
"type": "radio",
"name": "type",
"label": "类型",
"options": [
{"label": "显示姓名", "value": 1},
{"label": "禁用密码", "value": 2}
]
},
{
"type": "text",
"name": "username",
"label": "姓名",
"visibleOn": "${type == 1}"
},
{
"type": "password",
"name": "password",
"label": "密码",
"disabledOn": "${type == 2}"
}
]
}
上面的 Wizard 代码中,type 代表组件类型,同级的其他属性代表组件 API,body 是通用属性用于设置子元素。注意 Wizard 针对禁用和显隐增加了 disabledOn 和 visibleOn 属性,并支持写简单表达式。这种标准属性是对所有组件统一实现的(所有组件都支持 visibleOn,所有表单类组件都支持 disabledOn),表达式是引擎统一实现的。为了更好支持配置化,Wizard 引擎还支持数据域、数据链、模板、数据映射、表达式、函数、行为等。
另一种复杂情况是组件自带的数据请求能力,比如 ProTable、Select、Form 等,一般都需要解决数据处理问题——查询前对入参进行格式调整,拿到数据后对出参进行格式校准。统一设计了 api 配置,除了基本的 url、method、data 设置,还支持请求前后的 adaptor 设置。这里需要写脚本,也是目前 Wizard 唯一需要写脚本的地方。这部分借助 AI 能力,只需配置
当前数据格式和要转换的数据格式
有了大模型后,实现这种功能变得很简单,只需设计合理的 prompts 即可。虽然输出的脚本有时略显啰嗦,但准确率和稳定性都比较高。
// adaptor 脚本生成 prompts
你扮演一个纯函数代码生成器,你负责生成数据格式转换代码,你负责接收函数出入参的文本指令,根据要求生成 ja vascript 代码,取变量值和给变量赋值的时候请做好容错处理,处理容错时不要提前返回 undefined 或 null
帮我生成一个 js 函数: function formatData(payload, response, api) {},要求最终返回处理好的数据
response 参数: ${before}, 返回数据为: ${target},
只输出函数代码,不要输出其他无关的东西,函数代码中的注释保持中文输出,其他无关信息不要输出
输出代码缩进 2 个空格
高效初始化页面
俗话说“万事开头难”,页面从 0 到 1 的成本如何降到最低,是提升全栈门槛的关键。主要通过以下三个手段:
通过页面模版初始化
针对 CQUD 场景,沉淀了大量示例,基本能覆盖系统常见的交互和功能诉求。全栈同学选择模板创建后,修改配置即可满足页面需求。
通过接口元数据生成页面
前面提到的 Mooncake 平台沉淀了得物所有接口的出入参信息。Wizard 可以选择接口和页面类型生成页面描述——根据接口类型,选择生成列表、表单、详情,复制到页面中成为页面主体或一部分。
根据 PRD 描述快速生成页面
这是为了解决上面“吐槽”中的第 5 点。很多 PRD 对中后台需求的描述过于简单,没有草图说明;即使有草图,全栈同学也不一定知道怎么还原 UI。Wizard 训练了自有的大模型(模型训练见后文),做到对 Wizard 足够了解,可以结合 PRD 描述快速生成页面效果(插件 Wizard Proto)。只需要提供标准描述页面功能的文本格式,产品同学按格式填空书写页面结构即可。具体细节参考“大模型在产品原型生成中的应用实践”,以下视频说明使用方式:
<iframe allowfullscreen="" frameborder="0" src="https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&action=mpvideo&auto=0&vid=wxv_3431253292116934657"></iframe>通过 Proto 生成的页面,既能帮产品用最低成本还原页面原型,又能帮研发快速还原 UI。视频中给予产品一定的 UI 配置能力,但这远远不够。长远看,大模型在此步的应用只是为了快速生成,后续仍需提供更完备的可视化配置能力来完成页面 UI 和交互配置(或者说,大模型的应用是为了让产品和技术快速上手),并且这部分配置可以沿用到全栈开发。理想状态是 CQUD 的 UI 工作在 PRD 阶段搞定,全栈同学只需做接口配置和功能校准。当然这很理想,但希望将全栈研发同学的单页面输出成本降低到 0.5 人日以下,同时不增加产品的成本。
智能答疑
前面提到的 Wizard 自有大模型,还承担着另一个重要角色——辅助全栈同学答疑,比如:
- 快速了解某个组件怎么使用或概念;
- 复杂表单联动关系;
- 根据需求生成或修改页面结构;
- 帮助理解页面配置。
同时支持对回答内容进行正向和负向反馈,这些反馈会丰富训练池,让大模型准确率越来越高。
这部分能力目前使用率还不够高,根本问题还是准确率。关于下一步规划,下面会提到。
六、大模型训练和应用
Wizard 应用的基础大模型是更擅长代码生成的 DeepSeek Coder,使用的版本参数个数是 6.7b。模型准确率如何,核心在于训练的数据源。Wizard 不像 Antd 或 React 那样属于应用广泛的开源产品,社区有大量代码和文章供 ChatAIGC 训练。Wizard 的训练数据需要自己整理,思路如下:
- 根据文档中的组件示例、组件 API 描述、概念描述、示例、存储的 QA 问题等,快速生成种子问题。
- Proto 和智能答疑的正负向反馈都会被作为训练数据放入种子问题中。
- 种子问题数量有限(1000 以内),所以会经过一轮人工验证。比如发现 SearchPage 组件相关的问答不够准确,可以搜索处理并矫正种子问题。下面是一个简单的种子问题校准工具。
- 针对种子问题,通过成熟大模型进行扩展生成多条问题,实现数据集成倍增长,兼容对同一个问题的不同表达,提升模型的兼容度。主要扩展思路如下:
- 问题扩充——同一个问题换说法;
- 根据答案生成问题。
具体怎么生成要看场景,核心思路是把大模型当做一个记忆力和理解能力超强的人看待——你用哪些信息能让它快速理解怎么使用一个组件,然后决定怎么准备组件 QA 池。
- 对训练模型准确度进行综合评估。智能答疑和 Proto 都会有正负反馈,能部分说明模型准确性。更精细的评估目前还没有做,如果要评估可以参考 Ragas 评估(https://zhuanlan.zhihu.com/p/675777378),整理数据集时留一部分 QA 不参与训练,用于准确度评估即可。
综合流程整理如上。
目前大模型在 Wizard 的核心应用场景如下。
七、对低代码应用的看法
- 上述五种应用场景中的三种都起到了作用,还在考虑通过大模型实现数据 Mock 能力——只要把上下文数据和 type Interface 全部给出,可以用较低成本实现 CQUD 的接口。但每一种应用在方案设计中都不是必经路径。核心是,研发这条路上,模型的准确率没有想象中那么高,很多情况下需要人为纠正。这是实践中非常明显的认知——不要想着把大模型训练得特别牛、准确率特别高,ROI 不一定合理。从辅助研发的角度,达到 70% 以上已经非常了不起了(Wizard 大模型目前准确率 60%)。除非成立专业团队长时间投入。
有用,但适可而止:
- 很多情况下太泛的应用会影响准确度。实际场景中,结合严谨的 prompts 和 TypeChat 这类工具,缩小大模型回答的范围,因为指向越明确,回答越精确。像上文提到的数据格式转换脚本生成,一般很少出问题——除非从人的角度没法理解转换意图,那就说明输入有问题了。
增强针对性:
- AIGC 一定是未来趋势,各行各业都可能发生变革,包括研发。一味按固有思维去解决问题或者不愿去了解,未来大概率会吃亏。不一定要学会怎么训练大模型,但至少要掌握两点:大模型的成长性新闻以及应用场景。未来简单页面的开发工作可能真的会被生成式 AI 替代。如果现在的工作就是在做类似简单 CQUD 的事情,那真的要焦虑一下了,快去多翻翻社区。一个现实的例子:“十年梦碎,苹果放弃造车转 AI”——不造车可以理解成对新能源不看好或认为已经很饱和,但转生成式 AI,一定是对未来的深刻信心和期许。
不要逃避:
八、功能架构图
Wizard 的更多细节功能可以参考如下架构图。
功能架构图
- Wizard 提供 3 种新建页面方式,根本目的是尽可能降低页面从 0 到 1 的成本。研发可以选择合适的方式或组合使用:
- 通过示例模板创建页面;
- 通过 Mooncake 元数据创建页面;
- Proto 工具实现根据 PRD 智能生成页面。
- Mock 能力使 Proto 生成的页面效果更逼真,包括动态枚举、列表数据、表单提交等,既方便产品丰富页面原型,又降低研发复用创建页面的成本。
- Migrate 用于结合 AIGC 将 ProTable、ProForm 等常用组件的配置转换成 Wizard 配置,进一步降低旧页面迁移成本,提升全栈占比。
- 基于天网和统一配置中心,完善调试、发布、回滚、下线、菜单和权限管理等能力。
- Wizard 根据文档和日常答疑,结合 AI 输出大量 QA 训练自有大模型,在全栈过程中提供帮助:
- 帮助产品画原型图,生成的页面可用于进一步配置;
- 全栈答疑,降低认知成本;
- 分析源码转换成 Wizard 页面,降低页面迁移成本;
- 后期还会考虑通过需求描述做页面功能修改,进一步降低认知成本;
- 通过训练大模型解决复杂表达式生成问题,进一步降低联动配置成本。
九、问题和规划
- Proto 和智能答疑的应用占比不高,组件 API 查看率 70%。评估下来与准确度有较大关系。对此,做法是从 JSON 配置向可视化配置转换,减少认知成本。
- 通过智能答疑和 Proto 的正负向反馈,不断训练模型,提升准确度,目标至少 70%。
- 增强 Proto 的配置能力,提升产品同学使用 Proto 输出页面的比例,争取 PRD 阶段输出 UI,进一步提升页面输出效率。
- 提供产品能理解的可视化配置版本,实现在业务系统上直接进入配置界面创建需求——从原来的截图说明需求,变成直接配置生成草稿和变更说明,并与得物的需求创建流转流程关联,进一步降低一个需求从提出到上线各角色参与的成本,缩短交付周期。
需求提出流程
需求评估和交付流程
十、参考
https://www.zhihu.com/question/457292482
https://mp.weixin.qq.com/s/Bqca6JrBlAoGlAXhey18HQ
https://mp.weixin.qq.com/s/udeE32EKlHPMjcirl6i-mQ
https://mp.weixin.qq.com/s/IxsLmaxHmR63tR2sehxwbg
https://blog.shizhuang-inc.com/article/MTQ0MTQ
https://zhuanlan.zhihu.com/p/675777378
https://arxiv.org/abs/2310.13671
https://arxiv.org/abs/2212.10560
https://arxiv.org/abs/2305.19915
https://arxiv.org/abs/2310.17876
https://arxiv.org/abs/2311.15653