AI 辅助低代码生成

拆解 AI 辅助低代码生成:自然语言到 Schema 的转换路径、结构化输出与上下文工程、模型生成页面与业务逻辑的边界、生成结果的校验与自动修复循环、人在回路的评审与修订、迭代式生成与差异合并、质量评测指标,以及幻觉与提示词注入的防范,回答如何把大模型接入低代码而不失控。

引言

低代码把门槛从「写代码」降到了「配元数据」,但配元数据本身仍有门槛:得知道平台有哪些字段类型、关系怎么建、表达式怎么写、页面怎么排。对一个只想描述业务需求的运营或产品来说,这个门槛并不低。

大模型恰好擅长「把模糊意图翻译成结构化产物」。于是「说一句话生成一个应用」成了低代码平台的新入口,也成了这两年被问得最多的问题:能不能让模型直接产出 Schema?

难点在于可控性。模型输出的东西可能语法正确但语义荒谬:编造平台不支持的字段类型、引用不存在的实体、生成看起来合理但业务上错的审批规则。而低代码的元数据一旦落库就会立刻生效,没有编译期兜底。因此这个功能的技术核心不是「怎么调模型」,而是怎么把不可控的输出约束在可控的边界内。

本文按「三个落点 → 结构化输出 → 上下文工程 → 页面与逻辑生成 → 可控性 → 校验与修复 → 人在回路 → 迭代合并 → 质量评测 → 安全防范」展开,给出可落地的生成管线设计。读完后你应当能判断:AI 生成该从哪里切入,以及哪些环节必须由平台而非模型来把关。

目录

  1. AI 在低代码中的三个落点
  2. 自然语言到 Schema
  3. 上下文与提示词工程
  4. 生成页面与业务逻辑
  5. 生成结果的可控性
  6. Schema 校验与自动修复
  7. 人在回路与修订
  8. 迭代式生成与差异合并
  9. 质量评测体系
  10. 幻觉与安全风险防范

1. AI 在低代码中的三个落点

不是所有「生成」都同等安全,先把落点按可控性排个序。

落点 A:数据建模
  "做一个客户管理,客户有名称、联系人、行业、合同金额"
  → Entity + Field 列表

落点 B:页面与表单
  "给客户列表加搜索和新增按钮"
  → Page Schema(表格 + 工具栏 + 表单弹窗)

落点 C:逻辑与流程
  "合同金额超过 50 万要总监审批"
  → gateway 条件 + 任务分配规则

三个落点的可控性递减:数据建模的结构最固定、校验最容易、用户收益最直接;流程逻辑的自由度最高、语义最模糊、边界最多。

落点结构固定度校验难度用户收益建议顺序
A 数据建模高低高1
B 页面与表单中中高2
C 逻辑与流程低高中3

建议从落点 A 切入,用最小的风险验证整条管线的可行性,再逐步扩展到 B 和 C。一次性把三个落点全做,等于在可控性最差的地方最先暴露问题。

2. 自然语言到 Schema

生成管线的一端是自由文本,另一端必须是严格的 Schema。中间靠结构化输出约束。

interface GenRequest {
  intent: string;                          // 用户输入
  target: 'entity' | 'page' | 'flow';
  context: GenContext;                     // 已有模型、命名规范、字段类型清单
}
const TOOL_SCHEMA = {
  name: 'create_entity',
  parameters: {
    type: 'object',
    properties: {
      name: { type: 'string', pattern: '^[a-z][a-z0-9_]{2,31}$' },
      label: { type: 'string' },
      fields: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            name: { type: 'string' },
            type: {
              enum: ['string', 'text', 'integer', 'decimal',
                     'boolean', 'date', 'enum', 'ref'],
            },
            required: { type: 'boolean' },
          },
          required: ['name', 'type'],
        },
      },
    },
    required: ['name', 'fields'],
  },
};

关键点:不要让模型输出自由文本再由平台解析,用函数调用或结构化输出把它的输出空间限制成「只能吐 Schema」。字段类型用 enum 收窄到平台真正支持的范围,模型就不会编造出 currency 或 attachment 这类不存在的类型。

3. 上下文与提示词工程

同样的模型,上下文给得对与不对,一次通过率能差出一倍。

必给的上下文:
  1. 字段类型清单(enum,与平台能力严格一致)
  2. 命名规范(表名单复数、字段 snake_case、长度上限)
  3. 已有实体摘要(避免重复建模、支持 ref 关联)
  4. 两三个范例 Schema(few-shot,比规则描述有效得多)
  5. 平台硬约束(字段数上限、不支持的类型、保留字)

不要给的:
  1. 与本次任务无关的实体全文
  2. 内部实现细节(物理表名、列名、索引名)
  3. 历史生成结果(会把上一轮的幻觉带进来)

上下文长度与准确率不是线性关系:塞进大量无关实体反而会让模型「张冠李戴」,引用到错误的对象。经验做法是按任务相关性做检索,只把可能被引用的实体摘要放进去,而不是把整个数据字典塞满窗口。

4. 生成页面与业务逻辑

页面 Schema 比实体复杂,因为它有层级、有引用、有绑定关系。

{
  "type": "page",
  "layout": { "kind": "list-detail" },
  "blocks": [
    {
      "type": "table",
      "entity": "customer",
      "columns": ["name", "industry", "amount"],
      "toolbar": [{ "action": "create", "form": "customer_form" }]
    }
  ]
}
生成业务逻辑的三档(风险递增):
  L1 声明式规则:生成 gateway 条件这类结构化规则
     可控、可校验、可静态分析 → 推荐
  L2 表达式:生成表达式字符串
     必须过表达式校验器(字段存在性、类型、语法)
  L3 代码:生成 JS/TS 片段
     风险最高,必须人工评审后才允许启用

尽量把生成结果往 L1 压。用户说「金额超过 50 万要审批」,正确产物是一个结构化的条件对象,而不是一段 if (amount > 500000) {...} 的代码。结构化产物可校验、可在可视化编辑器里改、可被静态分析;代码产物则把可控性一次性让渡出去了。

5. 生成结果的可控性

可控性来自五条约束,缺一条都会漏。

1. 结构化输出:JSON Schema / 函数调用,杜绝自由文本解析
2. 白名单:字段类型、组件类型、函数名都取自平台注册表
3. 引用既有对象:优先 ref 已有实体,而不是每次都新建
4. 幂等:相同输入给相同输出(温度 0 + 结果缓存)
5. 增量:只生成缺失部分,不覆盖用户已修改的内容

第 4 条容易被忽略。用户点了两次生成,得到两个不同的 Schema,会直接摧毁信任。做法是:温度设为 0,并对「意图 + 上下文哈希」做结果缓存,同一请求短时间内返回同一结果。

5.1 白名单要覆盖到每一层

白名单不止约束字段类型,还要约束所有会被写进 Schema 的「名字」:

const ALLOWED = {
  fieldTypes: new Set(['string', 'text', 'integer', 'decimal',
                       'boolean', 'date', 'enum', 'ref']),
  components: new Set(['table', 'form', 'chart', 'tabs', 'detail']),
  functions:  new Set(['len', 'round', 'sum', 'upper', 'now']),
};

一旦某一层漏了白名单,模型就会从那一层钻进来:字段类型限住了,它可能在组件类型上编造 gantt;组件限住了,它可能在表达式里调用不存在的 formatCurrency。白名单必须与平台注册表同源,而不是手抄一份。

6. Schema 校验与自动修复

生成结果绝不能直接落库,必须先过与手工创建完全相同的校验管线。

function validateGenerated(schema: unknown): Issue[] {
  const issues: Issue[] = [];
  for (const e of entities(schema)) {
    if (!/^[a-z][a-z0-9_]{2,31}$/.test(e.name)) {
      issues.push({ level: 'error', path: e.name, msg: '命名不规范' });
    }
    const names = new Set<string>();
    for (const f of e.fields) {
      if (names.has(f.name)) {
        issues.push({ level: 'error', path: `${e.name}.${f.name}`, msg: '字段重名' });
      }
      names.add(f.name);
      if (f.type === 'ref' && !entityExists(f.target)) {
        issues.push({ level: 'error', path: f.name, msg: '引用的实体不存在' });
      }
    }
  }
  return issues;
}

6.1 自动修复循环

把校验错误回灌给模型让它修,是提升一次通过率最有效的手段,但必须有上限。

async function generateWithRepair(req: GenRequest, maxRounds = 3) {
  let out = await callModel(req);
  for (let i = 0; i < maxRounds; i++) {
    const issues = validateGenerated(out);
    if (!issues.some((x) => x.level === 'error')) return { out, issues };
    out = await callModel({ ...req, previous: out, errors: issues });
  }
  return { out, issues: validateGenerated(out) };
}

没有上限的修复循环会失控:模型可能在第 3 轮引入新错误,第 5 轮又改回去,成本与延迟一起涨。经验值是 2 到 3 轮,超过就交给人处理。

7. 人在回路与修订

三种交互形态:
  1. 确认制:生成 → 预览 → 用户点「采用」才落库
  2. 编辑制:生成 → 落到草稿 → 用户在可视化编辑器里改
  3. 对话制:生成 → 用户说「把金额改成必填」→ 局部重生成

推荐编辑制:生成的产物直接进入可视化编辑器,用户改的是元数据而不是提示词。这样做有三个好处:用户不必懂提示词工程;改动被版本管理系统完整记录,可追溯可回滚;用户改完之后,平台对这份 Schema 的理解与手工创建的完全一致,后续所有能力(校验、联动、发布)都能正常作用。

对话制适合作为补充:当用户想改的地方在编辑器里操作繁琐时,一句话比点十下更快。它的实现要点是局部重生成,而不是整份重来:

async function refine(patch: PatchRequest) {
  const scope = locateScope(schema, patch.targetPath);   // 只取目标子树作上下文
  const next = await callModel({ intent: patch.instruction, scope });
  return applyPatch(schema, patch.targetPath, next);     // 只替换该子树
}

把上下文收窄到目标子树,既省 token,也大幅降低模型「顺手改坏别处」的概率。

8. 迭代式生成与差异合并

真正棘手的问题是:用户已经在生成结果上改过了,重新生成会覆盖。

三种策略:
  A. 只生成缺失项(增量)
  B. 生成时保留用户已修改的路径(按路径级标记)
  C. 生成结果走 diff 预览,用户逐条接受
function mergeGenerated(base: Schema, generated: Schema, touched: Set<string>) {
  // touched 记录用户手工改过的路径,这些路径一律不覆盖
  return deepMerge(base, generated, { skip: (path) => touched.has(path) });
}

这与 代码生成与领域特定语言 里的「生成基类 + 手写子类」是同一类问题的两种形态:生成与手写之间必须有清晰的、机器可判定的边界。区别只是低代码场景下的「手写」表现为「在可视化编辑器里改过的路径」。

9. 质量评测体系

没有基准集,AI 功能的迭代就是凭感觉调提示词,改好一处坏一处。

评测维度:
  1. 结构合法率:生成结果能通过 Schema 校验的比例
  2. 语义正确率:人工标注,生成是否符合意图
  3. 一次通过率:不需要修复循环的比例
  4. 采用率:用户接受生成结果的比例
  5. 修订轮数:用户接受前改了几次
  6. 成本:每千次生成的 token 与端到端延迟

基准集构建:
  用真实需求整理 200~500 条「意图 → 期望 Schema」样本
  覆盖简单建模、多实体关联、含枚举、含校验规则等分层难度
  每次换模型、改提示词、调参数都完整跑一遍

采用率是最贴近业务价值的指标,但它有滞后性,不适合做日常迭代的快速反馈。日常迭代看「结构合法率 + 一次通过率」,季度回顾看「采用率 + 修订轮数」。

参考目标(以数据建模落点为例):
  结构合法率   > 95%     低于此值说明输出约束没做够
  一次通过率   > 80%     低于此值说明上下文或提示词有问题
  采用率       > 60%     低于此值说明模型没抓住业务意图
  平均修订轮数 < 1.5     高于此值说明首次生成质量不足

这些阈值不是行业标准,而是用来做回归判断:换了模型或改了提示词之后,指标掉出阈值就必须回滚,而不是「感觉还行」。

10. 幻觉与安全风险防范

幻觉的典型表现:
  - 编造不存在的字段类型(用 enum 限定可治)
  - 编造实体引用(校验器可治)
  - 生成看似合理但业务上错的规则(只能靠人在回路)
  - 把示例数据当真实数据写进模型(上下文隔离可治)

安全风险:
  - 提示词注入:用户输入里夹带「忽略以上指令」
  - 数据泄露:上下文里带了用户无权查看的数据
  - 越权生成:生成的内容超出当前用户的权限范围

防范的核心原则是:生成侧不做权限判断,落库侧必须再过一遍权限。模型只是在帮用户「更快地表达」,它产出的候选必须和用户手工创建走完全相同的授权、校验、审计流程。任何「因为是 AI 生成的所以跳过检查」的捷径,都会在半年内变成一次安全事故。

权衡取舍

决策点选项 A选项 B建议
输出形式自由文本再解析结构化输出结构化,杜绝解析脆弱性
生成范围全量重生成增量生成增量,保留用户修改
落库方式直接落库草稿 + 确认草稿,可撤销
修复循环无限重试上限 3 轮上限,控成本与延迟
权限校验生成时判断落库时判断落库时,生成不做权限
迭代依据凭感觉调参基准集评测基准集,否则无法收敛

常见坑清单

  1. 让模型输出自由文本再正则解析:格式一变就崩,必须用结构化输出约束。
  2. 字段类型不限定 enum:模型编造平台不支持的类型,落库即报错。
  3. 无校验直接落库:重名字段、悬空引用直接进生产环境。
  4. 修复循环无上限:模型反复引入新错,成本与延迟一起失控。
  5. 全量重生成覆盖用户修改:手工改动被吞掉,必须增量或按路径跳过。
  6. 无基准集:提示词改动凭感觉,改好一处坏一处。
  7. 生成侧做权限判断:与落库口径不一致,出现越权或误拒。
  8. 上下文塞无关实体:模型张冠李戴,引用到错误的对象。
  9. 生成的表达式不过校验器:语法对但引用了不存在的字段,运行时才炸。
  10. 示例数据混入上下文:模型把假数据当成真实数据生成进模型。

小结

AI 辅助低代码生成的骨架是「落点划分 → 结构化输出 → 上下文工程 → 校验与修复 → 人在回路 → 迭代合并 → 质量评测 → 安全防范」。最核心的一条原则是模型只负责生成候选,平台负责校验与落库:生成侧不碰权限、不直接写库,所有产物都要过一遍与手工创建完全相同的校验管线。另一条是评测先行:没有基准集,AI 功能的迭代无法收敛。

落点上建议从数据建模切入,它的结构最固定、校验最容易、用户收益最直接;页面与流程生成的自由度更高,需要更强的校验与更细的人在回路设计。

生成结果最终也是元数据,因此其品质上限取决于 元数据驱动架构设计 的 Schema 表达力;当生成物需要导出为可独立维护的代码时,见 代码生成与领域特定语言 。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「低代码」更多文章

  1. 自定义代码与逃生舱
  2. 低代码应用测试与质量
  3. 连接器与 API 编排