
本文作者:张天宇,TRAE 开发者用户

写在前面
随着 AI 技术发展,大语言模型(LLM)已成为提升开发效率的利器,尤其擅长处理代码补全、重复逻辑生成等标准化工作,能显著降低人工成本、加快开发节奏。但 LLM 在需求开发全流程中存在局限:缺乏全局视角,仅聚焦当前生成任务,难以关联已有业务逻辑与架构规范,也无法预判对现有代码的兼容性影响。长期依赖易导致代码仓库混乱、冗余,增加维护成本。
因此,LLM 辅助开发需要人工介入把控:将开发流程拆分为目标明确、边界清晰的小步骤,让 LLM 在限定范围内逐步参与,既发挥其优势,又通过人工把控步骤衔接与代码兼容性,最终平衡效率与代码质量。

探索背景
我所在的商业平台团队负责建设广告投放平台,广告主可通过平台自主创建并投放广告计划以实现营销目标。"创编页面"作为核心载体,是一套承载复杂业务逻辑的表单系统(涵盖广告信息配置、定向筛选、出价设置、素材校验等),其功能与易用性直接影响广告主投放效率。
日常业务迭代中,创编表单相关需求高频出现:既有字段修改(如新增定向维度),也有新场景专属表单创建(如短视频广告表单)。这类需求虽场景相似,却需重复处理字段校验、逻辑关联、UI 适配等工作,既耗费人力,也易因重复劳动产生错误。
基于此,本文结合实践,以创编表单为切入点,探索引入 LLM 生成代码的方式,旨在辅助开发人员提升创编表单开发效率、降低重复开发风险,为业务高效迭代提供实践思路。

整体思路
由人工将 PRD 拆解,梳理为技术文档,将技术文档的片段分步骤输入给 LLM,配合 MCP 让 LLM 逐步生成代码,结合 TRAE 的代码审查能力,完成需求开发。

1. 由研发编写特定格式的技术文档
为什么是特定格式的技术文档?
-
现有的研发技术文档没有统一规范,书写风格也因人而异,因此无法作为标准输入给到 LLM。因此,需要规范输入的格式,来保证较为理想的输出效果。
-
开发人员需要对需求进行拆解与编排,保证 LLM 的生成效果。
2. 编写特定功能的 MCP,帮助 LLM 扩展上下文
LLM 的训练数据总是有限的,无法囊括超过过截止日期的的新生数据,也无法囊括一些私域数据。因此,我们需要在模型推理阶段将新的知识输入到模型的上下文中,然后模型通过充分利用其本身的上下文学习能力去完成代码输出。
3. 分步骤生成代码
为什么分步骤生成代码?
-
单个需求内容过多,LLM 容易产生一步错步步错
-
分步骤可以让 LLM 每次都有获取足够上下文,避免空中楼阁式代码生成
-
开发者可以及时干预生成结果

实现细节
让 LLM 了解如何生成表单代码
目前我们使用的创编表单方案是一个基于 Formily 的上层封装方案,可以简单理解为是一个强化表单物料写法的表单方案。
最初的做法是将表单已有的使用文档转化为 Markdown 格式,直接添加到 TRAE 的上下文,让 LLM 了解表单的使用方法。

这种使用方式有很大的弊端,一方面是封装后的表单的文档其实会经常性发生变更,以单一文件存储,不方便维护与共享,二是,单一的文件会造成 LLM 抓不住重点,无法按预期生成代码。
因此,有了第二版的方案,单独创建一个 MCP 仓库来维护表单的使用文档,同时以 MCP Tool 的形式,向 LLM 按需提供表单使用文档及 demo,让 LLM 能够更准确的生成可用的代码。
这个业务表单方案 MCP 目前有提供三个 TOOL:
| 工具名称 | 描述 | 备注 |
|---|---|---|
| QuickStart | 可以获取如下信息:1. 表单的基本介绍、使用引导。3. 表单的主要 API 的介绍。4. 推荐目录结构设计。 | 主要是为 LLM 提供对业务表单的最基础认知的入口文件 |
| BasicUsage | 获取业务表单方案的主要 API 的使用方法及示例 | 主要是提供单一 API 的详细描述以及示例 |
| Example | 获取 业务表单方案 的示例代码 | 获取一个文正的示例代码 |
目前的业务表单方案 MCP 结构

LLM 使用 业务表单 MCP 效果

可以看到,LLM 可以根据需求按需查看 业务表单方案 的使用方法。
这个环节的核心难点在于,如何消除因自然语言描述文档引发大语言模型(LLM)理解歧义,进而导致生产效果出现显著差异的问题。在实际落地过程中,需要依据代码生成效果,持续迭代调整 MCP 返回的文档内容,这一步骤在人力与时间上均消耗了较多成本。
创建的 MCP 可以手动添加到 TRAE 中:

2. 编写技术文档
技术文档的本质就是需求文档的的结构化描述,帮助研发同学理清需求细节,梳理研发流程。理论上只要格式是有规律的即可,LLM 都可以很好的理解技术文档中的需求点并完成代码生成。但是在使用特定工具或者框架的时候,需要规范描述用语,防止 LLM 理解产生歧义。
本文用来探索的需求是全店推广需求中的创编需求部分,为千川平台全店推广场景开发一套独立的小型创编表单,就是下面这个样子。


本需求的技术文档需要如下准备工作:
1. 梳理表单用到的所有字段
- 包含字段的所有类型、初始化逻辑、提交逻辑、联动逻辑、校验逻辑等
2. 梳理现有可用的物料
- UI 组件、枚举、工具函数等
3. 将上述所有内容结合需求点拆解为多个步骤,交给 LLM 去生成代码。
在探索过程中,直接将拆解后的技术文档保存在代码仓库中,方便添加到 TRAE 的对话框中使用。
具体文档内容见下文代码生成章节
为保障 LLM 代码输出效果与准确性,技术文档中引入了 业务表单方案 的特定概念。这虽会带来一定的理解成本,但仍是当前阶段最直接有效的解决方案。
3. 使用 TRAE 分步骤生成代码
步骤拆分的逻辑大致如下:
1. 先分步骤将表单的框架搭建出来,将所需要的字段填充进去
- 此步骤会先将部分逻辑代码留空或者使用替代逻辑占位
2. 将表单布局进行调整
3. 将已有的物料应用到表单中

代码生成验证
目前采用人工方式确认生成效果。后续可建设自动化流程提升效果效率。
技术文档
csharp
## 需求
基于业务表单方案实现一个表单。
你需要为个表单搭建最基础的能力,包括表单的提交,字段配置,表单渲染等。
每个字段的所有相关物料都需要收敛在相同的目录下,方便后续的维护。
为表单初始化一个 SubmitFn 函数,用于表单提交。这个函数直接打印出来表单的值即可。
这个表单有如下字段:
### 推广抖音号 awemeInfo
#### Model 物料
类型是 object,数据结构如下
```json
{
"userId": "1111",
"nickName": "千川大客版自动化测试账号企业店",
"avatar": "https://p11.douyinpic.com/img/aweme-avatar/aweme_default_avatar.png~c5_168x168.webp?from=3782654143",
"showId": "22222",
"authRole": 1,
"userTypes": [
3
],
"hasShopPermission": false,
}
```
#### Initializer 物料
使用一个异步函数模拟,直接返回上述 json
#### Transformer 物料
直接返回字段值本身即可
#### Component 物料
为字段生成一个vue组件,支持支持展示抖音号头像以及昵称
### 推广店铺 shopInfo
#### Model 物料
类型是 object,数据结构如下
```json
{
"shopName": "资管文具礼品专营店",
"shopId": "111",
"shopImg": "https://p3-ecom-qualification-sign.ecombdimg.com/tos-cn-i-6vegkygxbk/fbe26f8d1316487d86b20f72f70e02fe~tplv-6vegkygxbk-s:750.image?lk3s=c08c0450&x-expires=1778687541&x-signature=YsxT9Ywn8QM%2B2HRJuDMzf9UFdVI%3D",
},
```
#### Initializer 物料
使用一个异步函数模拟,直接返回上述 json
#### Transformer 物料
这个字段不参与表单提交,不需要 Transformer 物料
#### Component 物料
为字段生成一个vue组件,支持展示店铺图片以及店铺名称
### 排除商品 blockProductList
#### Model 物料
类型是 Array<string>
#### Initializer 物料
这个字段不需要单独的初始化物料,直接使用静态默认值即可,默认值是个空数组
#### Transformer 物料
直接返回字段值本身即可
#### Component 物料
为字段生成一个vue组件,只需要展示如下文案:
系统将为您自动投放店铺的可投潜力商品,默认开启智选素材。您可以选择排除无需投放的商品:
生成过程


生成结果

需求点完成情况:
1. 表单基础框架、目录生成 ✅
2. awemeInfo 字段:
- Model 物料 ✅
- Component 物料,用于展示抖音号头像和昵称 ✅
- Initializer 物料 ✅
- Transformer 物料 ✅
3. shopInfo 字段:
- Model 物料 ✅
- Initializer 物料 ✅
- Component 物料,用于展示店铺图片和名称 ✅
- 不参与提交,无 Transformer 物料 ✅
4. blockProductList 字段:
- Model 物料 ✅
- 无 Initializer 物料,直接使用静态默认值 ✅
- Transformer 物料 ✅
- Component 物料,用于展示屏蔽商品列表说明 ✅
5. 表单提交:创建了表单级别的 SubmitFn,用于提交表单数据,并应用到所有 Transformer,点击提交可正常打印 ✅
6. 表单渲染:创建了 useCreationForm hook 和 SubmitBtn 组件,在 index.vue 中渲染完整表单并且交互不报错 ✅
备注
会出现不参考 MCP 自由发挥的情况,一般会在调用刚开始时候。可以通过观察一下 MCP 调用情况,发现没有调用详细文档直接重试即可。
当 LLM 正确调用了 MCP 的前提下,基本有一半的测试情况可以无需任何代码修改直接跑通。
后续研究一下如何强制其严格按照 MCP 生成代码
技术文档
ruby
## 需求
在已有的业务表单中,追加如下字段
### 投放方式 smartBidType
#### Model 物料
类型是 SmartBidType 枚举类型,已存在仓库中,可以直接通过如下代码导入使用
`import { SmartBidType } from '@legacy-pmc/shared'`
通过上述语句导入的枚举类型如下
```ts
// 投放方式
export enum SmartBidType {
CUSTOM = 0, // 控成本投放
NO_BID = 7, // 放量投放
}
```
#### Initializer 物料
这个字段的默认值通过 `window.whiteList.XXX1` 的值来判断,
如果 `window.whiteList.XXX2` 为 true,那么这个字段的默认值是 `SmartBidType.NO_BID`,否则是 `SmartBidType.CUSTOM`
#### Transformer 物料
直接返回字段及其值即可
#### Component 物料
为字段生成一个vue组件,支持枚举的中文文案展示,并且支持点击切换枚举值,点击后,将新的值设置到表单中
#### Reaction 物料
为字段增加一个 reaction 用来控制显隐:
字段 smartBidType 会根据 `window.whiteList?.XXX1` 的值来判断是否展示。
如果 `window.whiteList?.XXX2` 为 `true` 那么这个字段展示,并且参与表单提交及其他联动逻辑,否则这个字段不展示,但是字段仍保留在表单中,参与表单提交及其他联动逻辑。
注意:
- 无需为 whiteList 添加全局类型定义
生成过程


生成结果

需求点完成情况:
1. smartBidType 字段:
- Model 物料,正确导入并引用仓库内已有的枚举 ✅
- Initializer 物料,根据 window.whiteList.hitProductNobidAllowList 的值判断,为 true 时默认值为 NO_BID ,否则为 CUSTOM ✅
- Transformer 物料 ✅
- Reaction 物料,正常调用 setDisplay API 控制字段显示/隐藏,但始终参与表单提交 ✅
- Component 物料,正确支持中文文案展示和点击切换功能 ✅
2. 表单集成
- 未将字段追加到表单末尾,在表单中随意插入字段 ❓
备注
本次需求的复杂点在于正确生成
Reaction 物料中对于字段显隐逻辑的控制。
在 Gemin-2.5-pro 模型中,此处基本上没有生成错误
在 Kimi-k2 模型中,此出有一定概率生成错误。
正确示例:
api.setDisplay('visible')
api.setDisplay('hidden')
错误示例:
api.setDisplay('visible')
api.setDisplay('none')
另外,对于追加字段的要求, Gemin-2.5-pro 每次都是在表单末尾追加,无需额外说明,但是 Kimi-k2 会经常出现随机插入的情况。
此处应该优化技术方案中的描述,明确字段插入位置
技术文档
shell
## 需求
在已有的 业务表单 表单中,追加如下字段
### 日预算 budget
#### Model 物料
number 类型
有三个额外的字段依赖:smartBidType、blockProductList、awemeInfo
#### Initializer 物料
这个字段不需要单独的初始化物料
#### Transformer 物料
直接返回字段及其值即可
#### Component 物料
为字段生成一个vue组件,支持展示字段的中文名,以及字段值,并展示输入框,最后展示字段值的单位 "元"
#### Reaction 物料
增加一个 reaction 用来更新字段的值以及更新UI组件依赖的字段值:
当表单中 smartBidType、blockProductList、awemeInfo 三个字段值变化时,需要做如下操作:
1. 获取 budget 字段的最新的建议值并回填到表单中,获取值的过程可以直接使用一个异步函数来模拟,值为随机数。
2. 将这三个字段的值更新到 budget 字段的 Model 中,以便 budget 字段的UI组件可以访问到这三个字段的最新值,从而更新UI组件的展示。
#### Validator 物料
当字段的未输入时,需要返回一个错误文案,文案内容为 "请输入日预算",并展示在 UI 组件下方
生成过程


生成结果

需求点完成情况:
1. budget 字段:
- Model 物料,正确注册依赖 ✅
- 无 Initializer 物料
- Transformer 物料 ✅
- Reaction 物料,可监听依赖变化做出正确操作 ✅
- Component 物料,交互正常,展示正常,文件引用路径有误,校验错误信息展示异常 ❓
2. 表单集成
- 未将字段追加到表单末尾,但是加载了上一个字段的后面 ❓
备注
本次需求的复杂点在于正确生成联动逻辑。
Kimi-k2 出现了不按照文档自由发挥的情况。
Gemin-2.5-pro 出现了文件路径引用错误的低级问题。
校验错误信息展示异常的问题在于 MCP 提供的文档没有提供完整的例子导致
此处应该完善 MCP 文档,补充 Validator 相关事例
技术文档
shell
## 需求
在已有的业务表单中,追加如下字段
### 整体支付ROI目标 ecpRoi2Goal
#### Model 物料
类型是 number 类型
#### Initializer 物料
这个字段不需要单独的初始化物料
#### Transformer 物料
直接返回字段及其值即可
#### Component 物料
为字段生成一个vue组件,支持展示字段的中文名,以及字段值,并展示输入框
#### Reaction 物料
1. 增加一个 reaction 用来控制显隐:
字段 ecpRoi2Goal 会根据字段 smartBidType 的值来决定是否展示。如果 smartBidType 的值是 `SmartBidType.NO_BID`,那么 ecpRoi2Goal 字段就不展示。否则,ecpRoi2Goal 字段就展示。当 ecpRoi2Goal 字段不展示时,字段值会被清空,不参与表单提交及其他联动逻辑
1. 增加一个 reaction 用来更新字段的值并更新UI组件依赖:
当字段 smartBidType、blockProductList、awemeInfo 三个字段的值准备好或变化时,需要做如下操作:
1. 获取 ecpRoi2Goal 字段的最新的建议值并回填到表单中,获取值的过程可以直接使用一个异步函数来模拟,值为随机数。
2. 将这三个字段的值更新到 ecpRoi2Goal 字段的 Model 中,以便 ecpRoi2Goal 字段的UI组件可以访问到这三个字段的最新值,从而更新UI组件的展示。
#### Validator 物料
当字段的值为空时,需要返回一个错误文案,文案内容为 "请输入整体支付ROI目标",并展示在 UI 组件下方
生成过程


生成结果

需求点完成情况:
1. ecpRoi2Goal 字段:
- Model 物料,正确注册依赖 ✅
- 无 Initializer 物料
- Transformer 物料,出现 API 使用错误 ❌
- Reaction 物料,可监听依赖变化做出正确操作,可以正确控制显隐 ✅
- Component 物料,交互正常,展示正常,校验错误信息展示异常 ❓
2. 表单集成
- 未将字段追加到表单末尾,但是加载了上一个字段的后面 ❓
备注
本次需求的复杂点在于正确生成联动逻辑。
Kimi-k2 和 Gemin-2.5-pro 均出现出现了一些 API 使用类的低级错误
技术文档
php
## 需求
在已有的业务表单中,追加如下字段
### 推广即享 safeguardAndEstimate
#### Model 物料
这个字段类型如下
```ts
interface SafeguardAndEstimate {
isShowEstimate: boolean,
minEstimateConvert: string,
maxEstimateConvert: string,
estimateConvert: string,
minEstimateRoi: number,
maxEstimateRoi: number,
estimateRoi: number,
}
```
#### Initializer 物料
不需要
#### Transformer 物料
直接返回字段及其值即可
#### Reaction 物料
为这个字段增加 reaction 用来感知依赖变化:
1. 增加一个 reaction 用来更新字段值
当字段 smartBidType、blockProductList、awemeInfo 的值变化时,需要做如下操作:
1. 获取 safeguardAndEstimate 字段的最新的建议值并回填到表单中,获取值的过程可以直接使用一个异步函数来模拟,返回如下结构的数据
```json
{
"isShowEstimate": true,
"transDay": "7",
"transBaseMoney": "210",
"minEstimateConvert": "24",
"maxEstimateConvert": "35",
"minEstimateRoi": 0.22,
"maxEstimateRoi": 0.34,
"estimateRoi": 0.28,
"estimateConvert": "29",
"isUpdate": false,
"lastUpdateTime": "0",
"isZero": false,
}
```
2. 增加一个 reaction 用来感知依赖变化:
当字段 smartBidType 的值准备好或变化时,需要做如下操作:
1. 将 smartBidType 字段的最新值更新到 safeguardAndEstimate 字段的 Model 中,以便 safeguardAndEstimate 字段的UI组件可以访问到这三个字段的最新值,从而更新UI组件的展示。
#### Component 物料
为字段生成一个vue组件,展示字段中文名,组件展示的内容会根据字段 smartBidType 的值来决定。
如果 smartBidType 的值是 `SmartBidType.NO_BID`,那么组件展示格式为:
根据保障规则享保障福利,计划按oCPM展示付费
整体支付ROI:{{minEstimateRoi}} ~ {{maxEstimateRoi}}
订单量:{{minEstimateConvert}} 单 ~ {{maxEstimateConvert}} 单
否则,组件展示为一个文案:
默认启用智能优惠券,享平台额外补贴。根据保障规则享福利,计划按oCPM展示付费
#### Validator 物料
不需要
生成过程


生成结果


需求点完成情况:
1. safeguardAndEstimate 字段:
- Model 物料,注册依赖有冗余 ❓
- 无 Initializer 物料
- Transformer 物料 ✅
- Reaction 物料,可监听依赖变化做出正确操作,生成的代码有冗余 ❓
- Component 物料,没有正常引用枚举 ❓
2. 表单集成
- 字段追加到表单末尾 ✅
备注
本次实现出现了多次代码冗余,虽然不影响实际功能,但是会造成代码冗余,需要手动删除。
此处应该优化技术方案中的描述,明确需求,避免生成多余代码
同时在组件的生成时出现了枚举依赖未引入,这个和技术方案中的描述有比较大关系,需要后续优化。
此处应该优化技术方案中的描述,明确枚举引用等描述
技术文档
markdown
## 需求
在已有的业务表单中,追加如下逻辑。
### 表单字段排版
1. 增加一个排版容器组件,所有的表单字段排版都用这一个组件实现,组件的需求如下:
- 容器组件支持插槽,用于传入若干个元素,元素可以是表单字段,也可以是排版容器组件
- 容器宽度默认是 100%,支持外部传入参数自定义宽度
- 布局方式默认是横向排列(可以配置为纵向排列),参考 flex 的布局方式
- 支持额外传入一个 style 对象,用来设置容器组件的其他样式
2. 表单字段的排版规则如下:
- 第一个区块分为两行
- 第一行是横向排版的 awemeInfo 字段、 shopInfo 字段
- 第二行是 blockProductList 字段
- 第二个区块只有一行
- 在这一行里是横向排版的两个子区块
- 第一个子区块是横向排版的 smartBidType 字段、budget 字段、ecpRoi2Goal 字段
- 第二个子区块是 safeguardAndEstimate 字段
3. 所有区块均使用白色背景,区块间距 20px
生成过程


生成结果

需求点完成情况:
-
布局组件 ✅
-
按需求调整字段布局 ✅
-
正确展示复杂嵌套布局 ✅
备注
一个测试 LLM 进行字段排版的需求,因为没有 D2C 能力,所以看起来比较潦草,需要人工补充 CSS。
如果未来可以有比较靠谱的 D2C 能力,生成效果就会好很多。
技术文档
yaml
## 需求
在已有的业务表单中,追加如下逻辑。
目前有如下表单物料列表:
```json
{
getUniPromSuggestBudgetV2: {
type: 'AsyncFunction',
desc: '获取建议预算',
importStatement: "import { getUniPromSuggestBudgetV2 } from '@legacy-pmc/request'",
params: {
awemeId: {
desc: '抖音号id',
required: true,
},
smartBidType: {
desc: '投放方式',
required: true,
},
marGoal: {
desc: '营销目标',
defaultValue: 1,
required: false,
},
isUniPromShop: {
desc: '是否是全店推广',
defaultValue: true,
required: false,
},
externalAction: {
desc: '转化目标',
defaultValue: 96,
required: false,
},
},
returnValue: {
budget: {
desc: '建议预算',
},
}
},
getUniPromotionROISuggestionV2: {
type: 'AsyncFunction',
desc: '获取建议ROI',
importStatement: "import { getUniPromotionROISuggestionV2 } from '@legacy-pmc/request'",
params: {
authorId: {
desc: '抖音号id',
required: true,
},
marGoal: {
desc: '营销目标',
defaultValue: 1,
required: false,
},
isUniPromShop: {
desc: '是否是全店推广',
defaultValue: true,
required: false,
},
blockProductList: {
desc: '排除商品',
defaultValue: [],
required: false,
},
},
returnValue: {
ecpRoi2Goal: {
desc: '建议ROI',
},
}
},
getUniPromSuggestEstimateV2: {
type: 'AsyncFunction',
desc: '获取预估数据',
importStatement: "import { getUniPromSuggestEstimateV2 } from '@legacy-pmc/request'",
params: {
awemeId: {
desc: '抖音号id',
required: true,
},
smartBidType: {
desc: '投放方式',
required: true,
},
marGoal: {
desc: '营销目标',
defaultValue: 1,
required: false,
},
isUniPromShop: {
desc: '是否是全店推广',
defaultValue: true,
required: false,
},
blockProductList: {
desc: '排除商品',
defaultValue: [],
required: false,
},
budget: {
desc: '预算',
required: true,
},
},
returnValue: {
desc: '预估值',
},
}
}
```
### 使用已有的表单物料
#### 替换建议预算
将 budget 字段联动关系中已存在的模拟异步获取建议预算的函数,替换上述物料列表中的真实函数。
awemeId 可以使用抖音号的 userId
#### 替换建议ROI
将 ecpRoi2Goal 字段联动关系中已存在的模拟异步获取建议ROI的函数,替换上述物料列表中的真实函数。
authorId 可以使用抖音号的 userId
#### 替换预估数据
将 safeguardAndEstimate 字段联动关系中已存在的模拟异步获取预估数据的函数,替换上述物料列表中的真实函数。
awemeId 可以使用抖音号的 userId
生成过程


生成结果

需求点完成情况:
1. 替换 budget 字段联动关系中的模拟请求为真实请求 ✅
2. 替换 ecpRoi2Goal 字段联动关系中的模拟请求为真实请求 ✅
3. 替换 safeguardAndEstimate 字段联动关系中的模拟请求为真实请求 ✅
- 根据接口入参自动补充 budget 入参 ✅
备注
一个测试将已有物料进行应用的需求,使用一个简易的 JSON 数据来模拟数据源,让 LLM 自己匹配使用。
这是一个为领域化最铺垫的需求。当领域化物料库建设到足够丰富的时候,让 LLM 搭建新的表单就会像拼乐高一样。
技术文档
yaml
## 需求
在已有的业务表单中,追加如下逻辑。
目前有如下表单物料列表:
```json
{
UniPromShopBudgetPopover: {
type: 'component',
desc: '预算修改',
importStatement: "import UniPromShopBudgetPopover from '@/pages/uni/components/uni-prom-shop/creation-wrapper/creation-form/budget/uni-prom-shop-budget-popover.vue'
",
params: {
value: {
desc: '预算值',
type: 'string | number',
required: true,
},
smartBidType: {
desc: '投放方式',
type: 'SmartBidType',
typeEnumImportStatement: "import { SmartBidType } from '@legacy-pmc/shared'",
required: true,
},
entry: {
desc: '入口',
defaultValue: 'list',
required: false,
},
scene: {
desc: '场景',
defaultValue: 'uniPromShopCreation',
required: false,
},
isUniPromShop: {
desc: '是否是全店推广',
defaultValue: true,
required: false,
},
awemeId: {
desc: '抖音号id',
required: true,
},
blockProductList: {
desc: '排除商品',
defaultValue: [],
required: false,
},
},
events: {
change: {
desc: '值改变',
type: "(event: 'change', val: string | number): void;",
},
}
},
UniPromShopEcpRoi2GoalPopover: {
type: 'component',
desc: '支付ROI目标修改',
importStatement: "import UniPromShopEcpRoi2GoalPopover from '@/pages/uni/components/uni-prom-shop/creation-wrapper/creation-form/ecpRoi2Goal/uni-prom-shop-ecp-roi2-goal-popover.vue'
",
params: {
value: {
desc: '支付ROI目标值',
type: 'string | number',
required: true,
},
scene: {
desc: '场景',
defaultValue: 'uniPromShopCreation',
required: false,
},
isUniPromShop: {
desc: '是否是全店推广',
defaultValue: true,
required: false,
},
awemeId: {
desc: '抖音号id',
required: true,
},
blockProductList: {
desc: '排除商品',
defaultValue: [],
required: false,
},
},
events: {
change: {
desc: '值改变',
type: "(event: 'change', val: string | number): void;",
},
}
},
}
```
### 使用已有的表单物料
#### 替换建议预算
在 budget 字段的 UI 组件中,字段值的展示及修改逻辑替换为 UniPromShopBudgetPopover 组件。
注意:
1. 保留组件中错误信息展示的逻辑
2. awemeId 可以使用抖音号的 userId
3. budget 字段的相关代码在 apps/uni-pmc/src/pages/uni/components/uni-prom-shop/creation-wrapper/creation-form-v2/budget 目录下
#### 替换建议支付ROI目标
在 ecpRoi2Goal 字段的 UI 组件中,字段值的展示及修改逻辑替换为 UniPromShopEcpRoi2GoalPopover 组件。
注意:
1. 保留组件中错误信息展示的逻辑
2. awemeId 可以使用抖音号的 userId
3. ecpRoi2Goal 字段的相关代码在 apps/uni-pmc/src/pages/uni/components/uni-prom-shop/creation-wrapper/creation-form-v2/ecpRoi2Goal 目录下
生成过程




生成结果

需求点完成情况:
1. 引入并替换 budget 字段组件 ✅
- 正确传入组件参数 ✅
2. 引入并替换 ecpRoi2Goal 字段组件 ✅
- 正确传入组件参数 ✅
3. 替换原有逻辑 ✅
备注
本次测试内容是组件物料的应用,LLM 可以很好的按照使用文档使用组件,并自动传入组件所需的参数

阶段总结
最开始

步骤 1

步骤 2

步骤 3

步骤 4

步骤 5

步骤 6

步骤 7

步骤 8

最终形态

可以看到分步骤实现的效果,每一步都在更接近最终效果。
-
在引入 业务表单 MCP 后,LLM 对 业务表单方案的应用处于一个比较好的水准。
-
结合特定格式的技术文档后,需求点完成程度处于一个比较高的水准。
-
在引入一些物料列表后,LLM 可以比较好的应用已有物料。

后续的一些想法
业务表单 MCP 持续优化
结合 业务表单方 文档及代码库,产出更加 AI Friendly 的文档以及更自动化的 业务表单 MCP 更新流程
同时考虑将 业务表单方案 文档 RAG 化,尝试进一步提升 LLM 代码生成准确率
持续规范完善技术文档标准及规范
目前探索过程中所产生的技术文档,并未形成体系明确的标准以及规范。
考虑在需求功能点描述中引入 Ghkerin (cucumber.io/docs/gherki...
更高效的评测体系
1. 结合 业务表单方案 单元测试,产出自动化的评测体系。也可以考虑 UI 自动化测试等能力,辅助验证生成效果。
2. 建立打分体系,用于量化生成质量
3. 评测大致可以为几个维度:
-
模型的思考过程
-
代码产物:是否有语法不规范、API 使用错误、代码报错等
-
最终效果:需求是否有完整实现
还有哪些可抽象的重复性开发任务?
1. 领域化物料的生成。
- 以本文为例,围绕 业务表单方案 的各种物料(Reaction、Validator、Transformer、Initializer 等)都可以生成
2. 接口请求类代码生成
- 结合 BAM 平台提供的能力,生成 BFF、FE 接口请求代码
3. 框架升级改造
- 比如将 vue2 项目升级为 vue3 项目

写在最后
除了精确的为 LLM 提供上下文信息外,如何准确的描述需求也是一个值得探索的命题。在上述探索过程中,常因自然语言的歧义性,导致 LLM 生成的代码效果差异显著。
编程语言的设计初衷,正是通过高度抽象的语法规则,消除自然语言因灵活性带来的歧义,确保指令能被机器精准执行。这一特性也决定了:自然语言撰写的 PRD 中,一句看似简洁的需求描述,往往需要拆解为大量逻辑严谨的代码才能落地 ------ 本质是将 "模糊的自然语言意图" 转化为 "无歧义的机器可执行逻辑"。
而 LLM 在理解自然语言时,同样会受限于这种歧义性:自然语言的多义性、语境依赖性,可能导致 LLM 误读需求核心,进而生成不符合预期的代码。因此,若想让 LLM 更精准地生成代码,就需要主动放弃一部分自然语言的随意性(而非单纯 "灵活性"),通过更结构化的约束降低理解成本。
简言之,我们需要探索一种介于编程语言(强语法、无歧义)与自然语言(易理解、高灵活)之间的 "中间层语法格式",用它来规范需求描述、知识库内容等输入 ------ 既保留自然语言的可读性,又通过适度约束消除歧义,为 LLM 提供更精准的 "生成依据"。
另外,除了本文提到的表单方案外,理论上所有技术方案的实践都可以按本文思路去探索实现。