GPT-6 Intelligent UI 会让传统前端开发消失吗?

AI 能生成界面,但生不出确定性:动态 UI 的边界与落地取舍

能生成的放界面,不能生成的放引擎

text 复制代码
[读者] 前端与平台架构师,正在评估 AI 生成页面
[痛点] 生成很快,但权限、状态与交易没人敢签字
[现在读] 需求已经压到页面上,再靠人肉写表单顶不住
[读完] 能划出可变边界,并落一个确定性的最小 V1
text 复制代码
[旧方案] 每张报表手写页面 + 直连业务写接口
    |
    v
[新需求] 页面按需生成,配置交付从天级压到小时级
    |
    v
[冲突] 生成物是概率性的,业务规则必须是确定性的
    |
    v
[后果] 页面越灵活,权限与交易越不可审计

我是老李,在深圳带一个企业数据平台的前端与中台小组。这套系统管着三百多张报表和配置台页面,客户是结算、预算、运营三类业务方。

每张页面背后都是真业务:结算口径、审批状态、预算冻结。以前需求两周一批,现在业务方的期望是今天提、明天看到。于是团队开始试一条更激进的路线------让模型直接吐页面描述。

生成式界面到底把成本降在哪一层?

如果页面描述是模型写的,谁为它的越权和重复提交负责?

先从哪类场景切,才不至于上线当天就回滚?

01、故事

季度结算前的第三个礼拜,结算组负责人在群里发了一张截图:某张「资金冻结配置页」上,一个本不该出现的「确认划扣」按钮被点了下去。

这个按钮不是我们写的。它是上一轮「动态页面」试验里,由模型根据一段业务描述生成的。

我们当时正在做的事,任务是:两周内把 20 张结算配置页从手写 React 改成「描述生成 + 动态渲染」,同时不能动权限和审批的任何一条规则。

当时的方案很朴素:页面代码在前端仓库,每张报表一个组件;写操作直接打后端 REST,权限靠前端隐藏按钮,后端只做参数校验。这套方案撑了三年,靠的是需求少、人熟、节奏慢。

变量出现在今年:业务方开始频繁调整口径,一张配置页一个月改四五次。手写页面的成本不是「写一次」,而是「改十次」。于是我们把页面描述交给模型,前端只保留一个通用渲染器。

第一次跑通很快,一下午就生成了 8 张页面。问题也来得很快:生成器不知道我们的权限模型,也不知道「冻结」和「划扣」之间隔着一条状态机。它只知道:业务描述里写了「确认划扣」,那就该有一个按钮。

页面是生成了,但生成出来的不是页面,是一个没有边界的入口。

需求催人急

手写难为继

页面可生成

规则不可移

02、问题

旧方案失效的地方很具体:不是页面写不出来,而是页面里的「可写动作」没人管。

业务影响是直接的:一次误点让冻结金额记错,结算窗口被拖了两天,最后靠人工冲正。

技术表现更值得记录:校验散落在三个地方------前端隐藏按钮、后端参数校验、数据库约束;权限判断依赖前端;写接口没有幂等键;状态迁移没有前置条件;页面描述本身没有任何 schema 约束,模型给什么就渲染什么。

所以这一轮改造的完成标准必须是可验证的,而不是「感觉更灵活了」:

  1. 页面描述必须先通过一份固定 schema 校验才能下发,未通过的比例可统计;
  2. 所有写动作必须命中服务端注册表,未注册一律拒绝;
  3. 任意写动作必须携带幂等键,同键重放不产生第二次副作用;
  4. 状态迁移必须由前置条件判定,非法迁移返回明确错误码;
  5. 每一次动作都能在审计日志里还原「谁、在哪个页面、用什么参数、改了什么状态」。

这五条里,前两条解决「不该出现的按钮」,后三条解决「按钮被点两下」。

旧路已到头

新路待验证

标准先落纸

再谈快与省

03、原理

这一节只讲本篇真正用得上的原理:把系统拆成「描述」和「语义」两层。

描述层是 UI schema:页面长什么样、有哪些字段、按钮叫什么。它的特征是------可生成、可丢弃、可重放、允许不确定。改错了重新生成一份就行。

语义层是动作定义、权限、状态迁移、幂等、事务。它的特征是------必须唯一、必须确定、必须可审计。同一件事只能有一个真源。

反直觉判断:动态生成的范围越大,确定性执行引擎的边界就要收得越窄。

直觉上,既然页面都能生成了,顺手把动作也生成出来似乎更省事。但动作一旦被生成,系统就失去了唯一真源:同一个操作在 A 页面叫 submit、在 B 页面叫 confirm,权限对不上、幂等对不上、审计也对不上。生成能力越强的团队,越容易踩这个坑,因为「能生成」的诱惑太大了。

第二个反直觉判断:生成界面的收益不在「少写页面」,而在把页面从代码降级为数据。

代码要评审、要发版、要回滚;数据可以校验、可以拒绝、可以按租户下发。只有页面变成数据,配置交付的节奏才会真正变化。而数据必须配一份 schema,否则它只是「另一份更难懂的代码」。

为什么低风险场景先行的成本更低?报表、配置台、数据分析这三类场景的共同点是读多写少、副作用可逆、失败可重试,它们的语义面很薄。反过来,交易、扣款、结算这类场景语义面极厚,任何一处不确定都要用对账去补。

关于外部模型能力:本篇参考的模型页面在写作时无法访问核验,因此凡涉及该来源的具体能力描述,均需按当前官方文档核验,本文不引用其结论。

描述可重放

语义须唯一

越自由生成

越收紧执行

04、架构

text 复制代码
[输入] AI 生成的 UI Schema + 用户动作请求
    |
    v
[模块] Schema 校验层 / 组件白名单 / 动作注册表
    |
    v
[数据/状态] 规范化 IR + 权限策略 + 状态机 + 幂等表
    |
    v
[处理] 渲染 → 动作分发 → 参数校验 → 事务执行
    |
    v
[输出] 界面 / 状态变更 / 审计日志

边界:校验层是唯一入口,前端渲染器不做业务兜底;动作注册表只存在于服务端;状态变更只能由状态机产生,页面不许直接改状态。

收益:页面交付从「发版」变成「下发」;权限、幂等、审计三件事集中到一处,改动有单点;违规描述在下发前就被拒绝,前端不需要写防御式代码。

代价:schema 的表达力被主动限制,复杂交互只能退回手写;每新增一个组件要改白名单并评审;渲染器需要长期维护,且它本身成了关键路径。

适用条件:读多写少、副作用可逆、业务规则相对稳定、业务方愿意接受「先配置后定制」的交付方式。任何一条不满足,收益都会被风险吃掉。

输入皆有界

中间设关卡

状态归一处

输出可追溯

05、实战一次

这一节落一个最小但完整的 V1:一份能校验的页面描述,加一个确定性的动作入口。

环境与依赖:Node.js 20 LTS、TypeScript 5.x、Express 4.x、Ajv 8.x,具体版本需按各自官方文档核验当前发布。

初始化:

bash 复制代码
mkdir dynamic-ui-v1 && cd dynamic-ui-v1
npm init -y
npm i express ajv
npm i -D typescript tsx @types/express @types/node
npx tsc --init --target es2022 --module nodenext --moduleResolution nodenext --outDir dist --strict

三个文件:src/actions.ts 放动作注册表,src/ui-schema.ts 放描述校验,src/server.ts 放 HTTP 入口。

核心实现一,UI 描述校验与组件白名单:

ts 复制代码
import Ajv from 'ajv';

const ajv = new Ajv({ allErrors: true, strict: false });

export const COMPONENT_WHITELIST = ['table', 'form', 'text', 'number', 'select', 'button'] as const;

const nodeSchema = {
  type: 'object',
  required: ['component'],
  properties: {
    component: { type: 'string', enum: [...COMPONENT_WHITELIST] },
    children: { type: 'array', items: { type: 'object' } },
    props: { type: 'object' },
  },
  additionalProperties: false,
};

const pageSchema = {
  type: 'object',
  required: ['pageId', 'root'],
  properties: {
    pageId: { type: 'string', pattern: '^[a-z0-9._-]{1,64}$' },
    title: { type: 'string', maxLength: 64 },
    root: nodeSchema,
  },
  additionalProperties: false,
};

const validatePage = ajv.compile(pageSchema);

export function validateUiSchema(doc: unknown) {
  if (!validatePage(doc)) {
    throw new Error('UI_SCHEMA_REJECTED: ' + ajv.errorsText(validatePage.errors));
  }
  return doc as { pageId: string; title?: string; root: Record<string, unknown> };
}

注意这里的 children 只做了浅校验,递归校验是 V1 的已知缺口,第六章会因为这个缺口出一次故障。

核心实现二,动作注册表:

ts 复制代码
export type ActionCtx = {
  user: string;
  roles: string[];
  idempotencyKey: string;
};

export type ActionDef<P> = {
  name: string;
  roles: string[];
  params: object;
  run: (params: P, ctx: ActionCtx) => Promise<unknown> | unknown;
};

const registry = new Map<string, ActionDef<any>>();

export function defineAction<P>(def: ActionDef<P>) {
  if (registry.has(def.name)) throw new Error('DUPLICATE_ACTION: ' + def.name);
  registry.set(def.name, def);
}

export function getAction(name: string) {
  return registry.get(name);
}

核心实现三,唯一的写入口:

ts 复制代码
import express from 'express';
import Ajv from 'ajv';
import { randomUUID } from 'node:crypto';
import { defineAction, getAction, type ActionCtx } from './actions.js';
import { validateUiSchema } from './ui-schema.js';

const ajv = new Ajv({ allErrors: true, strict: false });
const app = express();
app.use(express.json({ limit: '256kb' }));

// V1 用内存表;生产必须换成带唯一索引的持久表
const idempotency = new Map<string, unknown>();
const orders = new Map<string, { state: string; amount: number }>([
  ['O-1', { state: 'draft', amount: 1200 }],
]);

defineAction<{ orderId: string; memo?: string }>({
  name: 'order.submit',
  roles: ['finance'],
  params: {
    type: 'object',
    required: ['orderId'],
    properties: {
      orderId: { type: 'string', minLength: 1 },
      memo: { type: 'string', maxLength: 128 },
    },
    additionalProperties: false,
  },
  run: (params) => {
    const order = orders.get(params.orderId);
    if (!order) throw new Error('ORDER_NOT_FOUND');
    if (order.state !== 'draft') throw new Error('ILLEGAL_STATE_TRANSITION');
    order.state = 'submitted';
    return { orderId: params.orderId, state: order.state };
  },
});

// 页面描述下发前必须先过校验
app.post('/api/pages', (req, res) => {
  try {
    const page = validateUiSchema(req.body);
    return res.json({ code: 'OK', pageId: page.pageId });
  } catch (e) {
    return res.status(422).json({ code: 'UI_SCHEMA_REJECTED', message: (e as Error).message });
  }
});

// 唯一写入口:动作必须注册,参数必须校验,权限必须在服务端判
app.post('/api/action/:name', async (req, res) => {
  const action = getAction(req.params.name);
  if (!action) return res.status(404).json({ code: 'ACTION_NOT_REGISTERED' });

  const ctx: ActionCtx = {
    user: req.header('x-user') ?? 'anonymous',
    roles: (req.header('x-roles') ?? '').split(',').filter(Boolean),
    idempotencyKey: req.header('x-idempotency-key') ?? randomUUID(),
  };

  if (!action.roles.some((r) => ctx.roles.includes(r))) {
    return res.status(403).json({ code: 'FORBIDDEN' });
  }

  const validate = ajv.compile(action.params);
  if (!validate(req.body)) {
    return res.status(400).json({ code: 'INVALID_PARAMS', errors: validate.errors });
  }

  const cacheKey = `${ctx.user}:${action.name}:${ctx.idempotencyKey}`;
  if (idempotency.has(cacheKey)) {
    return res.json({ code: 'OK', replayed: true, data: idempotency.get(cacheKey) });
  }

  try {
    const data = await action.run(req.body, ctx);
    idempotency.set(cacheKey, data);
    return res.json({ code: 'OK', replayed: false, data });
  } catch (e) {
    return res.status(409).json({ code: (e as Error).message });
  }
});

app.listen(3000, () => console.log('listening on :3000'));

启动与第一条验证:

bash 复制代码
npx tsx src/server.ts
# 示例输出
# listening on :3000

curl -s -X POST localhost:3000/api/action/order.submit \
  -H 'content-type: application/json' \
  -H 'x-user: u1' -H 'x-roles: finance' -H 'x-idempotency-key: k-1' \
  -d '{"orderId":"O-1"}'
# 示例输出
# {"code":"OK","replayed":false,"data":{"orderId":"O-1","state":"submitted"}}

同一个幂等键再发一次,模拟按钮被点两下或网络重放:

bash 复制代码
curl -s -X POST localhost:3000/api/action/order.submit \
  -H 'content-type: application/json' \
  -H 'x-user: u1' -H 'x-roles: finance' -H 'x-idempotency-key: k-1' \
  -d '{"orderId":"O-1"}'
# 示例输出
# {"code":"OK","replayed":true,"data":{"orderId":"O-1","state":"submitted"}}

越权与未注册动作:

bash 复制代码
curl -s -X POST localhost:3000/api/action/order.submit \
  -H 'content-type: application/json' -d '{}'
# 示例输出
# {"code":"FORBIDDEN"}

curl -s -X POST localhost:3000/api/action/order.delete \
  -H 'content-type: application/json' -d '{}'
# 示例输出
# {"code":"ACTION_NOT_REGISTERED"}

未在当前环境实测,以上为预期结果。

V1 到此跑通了三件事:页面描述能被拒绝,动作能被白名单拦住,重复提交不会产生第二个副作用。同时留下三个明确缺口------描述里的 children 没有递归校验、幂等表在内存里、渲染器还没有对未知组件的处理策略。

先跑一条线

再谈千张页

最小可验证

胜过全蓝图

06、排查

上线第三天,两条故障链同时来了。

诊断链一:页面白屏。现象是 8 张生成页面里有 2 张打开即白屏,控制台只有一行 Unknown component: raw-html。怀疑是渲染器的动态 import 路径写错,或者打包漏了组件。检查方式是先把落库的页面描述原样打出来看一眼。证据是:描述里 root.children[0].component 的值是 raw-html,且 props 里带着一整段 HTML 字符串。根因有两个:渲染器对白名单外的组件没有拒绝策略,走的是「查不到就渲染成空」的分支;入库前的校验只校验了最外层,没有递归校验 children。修复方向是把校验层放到入库前并且递归,渲染器对未知组件渲染为可审计占位而不是静默为空。

错误尝试: 我们一开始的做法是在渲染器里包一层 try/catch,出错就渲染兜底页。这是错的,因为校验被放到了渲染期------错误发生时页面已经进过一次不确定的渲染,而且错误只有前端日志看得见,服务端完全不知道有人下发了一份非法描述。校验的位置比校验的强度更重要。

诊断链二:同一张单据被提交两次。现象是结算组反馈,同一张 draft 单据出现了两条 submitted 记录,间隔 12 毫秒。怀疑是数据库事务没生效,或者后端并发写没有加锁。检查方式是捞审计日志,按 orderId 聚合,对比两条记录的入参与请求头。证据是:两条记录入参完全一致,且都没有 x-idempotency-key 请求头------服务端在缺省时用 randomUUID() 生成,等于每次请求都是新键。根因有两个:幂等键由服务端生成而不是调用方给定,等价于没有幂等;动作内部只判断了「单据存在」,没判断状态迁移是否合法,所以第二次提交时状态已经是 submitted 也照样通过。修复方向是幂等键必须由页面在渲染时生成并随动作提交,服务端只负责存储与判重;动作内部必须显式校验状态前置条件。

两条链的共同根因其实是同一个:我们把「正确性」交给了运行时兜底,而不是交给入口处的约束。

现象莫轻信

证据定根因

兜底非校验

白名单是墙

07、优化

V2 完全基于第六章的证据,一共四处修改。

修改一,描述校验变成递归,并且前置到入库。根因是校验只到第一层、且落在渲染期。修改方式是让 validateUiSchema 递归遍历 root 与 children,逐层校验 component 是否在白名单内、props 是否属于该组件允许的字段。这样做的原因是非法描述在入库前就被拒绝,服务端留下记录,前端不再需要防御式代码。新行为是:POST /api/pages 对含未注册组件的描述返回 422,错误信息里带路径。验证方式是两条用例------children 里塞 raw-html 期望 422,合法描述期望 200 并能拿到 pageId。

修改二,幂等键由页面生成、服务端持久化。根因是服务端生成幂等键等于没有幂等。修改方式是页面在渲染按钮时生成一个 UUID,随请求头一起提交;服务端把幂等结果写进 (user, action, key) 唯一索引的表里。这样做的原因是重复提交的唯一识别点应该在调用方,服务端只做存储与判重。新行为是并发两次同键请求,只有一次进入业务逻辑。验证方式是并发发两次同键请求,检查动作审计表里只有一条状态变更记录。

修改三,状态迁移集中到状态机。根因是状态判断散落在每个动作内部,容易漏写。修改方式是抽出一张声明式迁移表,例如 order.submit 只允许从 draft 到 submitted,执行引擎在调用 run 之前统一校验。新行为是非法迁移返回 ILLEGAL_STATE_TRANSITION,且不进入业务逻辑。验证方式是对已 submitted 的单据再次提交,期望 409 加该错误码。

修改四,渲染降级为可审计占位。根因是未知组件静默为空导致白屏不可诊断。修改方式是渲染器遇到白名单外组件,渲染一块带组件名的错误占位,并上报一条前端事件。新行为是即便非法描述漏网到前端,也能一眼看出是哪个组件、来自哪个页面。

四处修改都不追求复杂,只追求同一件事:错误在入口处被拦住,在日志里被看见。

根因既已明

改在入口处

幂等加状态

一次即一次

08、演进

text 复制代码
[同一输入] 用户点击「提交」按钮
    |
    +--[V1] 直连业务写接口,前端隐藏按钮做权限
    |       幂等键服务端随机生成 / 无状态前置条件
    |       代价:重复提交、非法迁移、白屏不可诊断
    |
    +--[V2] 动作注册表 → 权限 → 参数校验 → 状态机 → 幂等 → 事务
    |       代价:多一层校验与注册维护成本,描述表达力受限
    |
[Trade-off]
得到:可校验、可判重、可审计的确定性写入口
失去:页面描述的自由度;每加一个动作要改服务端
适用边界:读多写少、副作用可逆、业务规则相对稳定的场景

逐项对比。正确性上,V1 依赖前端自觉和并发运气,V2 由状态机与幂等表保证。稳定性上,V1 白屏只有前端日志,V2 未知组件有占位与上报。复杂度上,V1 代码更少,但心智负担分散在每个人手里;V2 集中了一个校验层和一个注册表,需要有人长期维护。成本上,V1 省下的是开发时间,付出的是线上对账;V2 付出的是约束,省下的是事故。适用范围上,V2 适合配置台、报表、数据分析;强交互的编辑器类页面会把 schema 撑爆,不如老实手写。遗留问题有三个:描述的多租户下发、schema 的版本兼容、以及生成侧的反馈闭环。

同入不同路

取舍各分明

得在快与省

失在自由度

09、洞见

9.1 界面可以生成,业务语义不能生成

反直觉判断:AI 让「写页面的成本」下降,但真正决定这次改造成败的,是那些它根本不该碰的部分。

页面是描述,描述错了可以重生成;权限和状态是语义,语义错了要靠对账和后置修正。所以架构的第一刀不是切「哪些页面接进来」,而是切「哪些东西永远不生成」。

9.2 校验的位置比校验的强度更重要

反直觉判断:一个放在渲染期的强校验,不如一个放在入库期的弱校验。

第六章里两次故障的根因是同一个------我们用运行时兜底替代了入口处的约束。try/catch 看起来更鲁棒,实际上把错误的可见性和可追溯性一起吞掉了。校验层必须是唯一入口,且必须在写路径之前。

9.3 生成能力越强,越要有一个确定性执行引擎

反直觉判断:模型越强,服务端的约束应该越硬,而不是越松。

因为生成能力的提升会让调用面迅速扩大:今天生成页面,明天生成表单,后天生成工作流。如果底层没有一个幂等、可审计、状态唯一的执行引擎,上面生成得越快,下面崩得越快。确定性引擎不是创新的阻碍,而是创新的安全垫。

9.4 低风险场景先行是控制爆炸半径

报表、配置台、数据分析三类场景的共同特征是读多写少、可重试、失败可回滚。先用它们验证三件事:生成的描述能不能被稳定校验、动作注册表够不够用、业务方能不能接受「先配置后定制」。这三件事验证完,再去碰交易。

生成非交付

边界即架构

低险先行试

高险缓一步

10、系统落地

原来有什么:手写页面加直连写接口,权限靠前端隐藏按钮,页面改动必须发版。

本篇新增什么:一个 UI Schema 校验层,含组件白名单与递归校验,在入库前拒绝非法描述;一个服务端动作注册表,动作名唯一、角色绑定、参数 schema 齐全;一个由状态机加幂等表组成的确定性执行引擎;一个对未知组件的可审计降级策略。

现在能做什么:页面描述可以下发、可以拒绝、可以灰度;写动作有唯一入口,重复提交不产生第二次副作用;每一次状态变更都能在审计里还原到参数级。

还缺什么:描述的版本兼容与多租户下发;生成侧还没有接上校验层的反馈闭环,模型仍会生成未注册组件;渲染器的组件覆盖率与性能没有量化;面向不可逆写场景的语义面校验尚未验证。

下一步如何演进:把校验层拒绝的原因回灌给生成侧,让模型在生成时就知道哪些组件不存在;把动作注册表升级为按租户可配置;在低风险场景跑够周期之后,再评估是否放一两个可逆写场景进来。

关于外部资料:本篇参考的模型能力页面在写作时无法访问核验,凡涉及该来源的具体能力表述均需按当前官方文档核验,本文不引用其结论作为论据。

原有手写页

今添约束层

能跑能审计

待补版本账

11、小结

text 复制代码
Q1 → 生成式界面降的是「页面描述」的成本,不是业务语义的成本
Q2 → 越权与重复提交由服务端动作注册表 + 状态机 + 幂等表负责,不由模型负责
Q3 → 从报表、配置台、数据分析切,读多写少、副作用可逆、失败可重试
状态 → 一套可校验、可白名单、可幂等的动态 UI V1,并带有明确的已知缺口清单

三问皆有答

状态可交付

边界已划清

引擎定乾坤

12、作业

12.1 理解题:为什么幂等键必须由调用方生成,而不是服务端?

参考答案:幂等的前提是「同一个操作」能被同一个标识识别。服务端在缺省时生成随机键,每次请求都是新键,等价于没有幂等。调用方在渲染动作时生成键,同一个按钮实例的重复点击与网络重试共享同一个键,服务端才有判重的可能。

12.2 实战题:给第五章的 validateUiSchema 加上递归校验,并给出两条验证用例。

参考答案:递归遍历 root 与 children,对每个节点套用同一份 nodeSchema,同时把 props 的允许字段按组件类型做白名单。用例一:children 中塞入 component: 'raw-html',期望抛出 UI_SCHEMA_REJECTED 且错误里带节点路径;用例二:合法描述,期望返回 200 并能拿到 pageId。

12.3 排障题:某张生成页面点击按钮后返回 200,但数据没变。你会按什么顺序排查?

参考答案:先看审计日志里有没有这次动作记录。没有记录,说明请求没打到动作路由,检查按钮绑定的动作名是否注册;有记录但 replayed 为 true,说明幂等键被复用,检查键是在渲染期生成还是在点击期生成;有记录且 replayed 为 false 但状态没变,检查状态机前置条件是否命中了未生效分支,以及事务是否真的提交。

12.4 架构判断题:业务方要求「把资金划扣页面也接进动态生成」,你是否同意?说明理由和前置条件。

参考答案:不同意直接接入。划扣属于不可逆写、语义面厚、失败要靠人工对账,与本篇的适用边界冲突。若必须做,前置条件是动作注册表覆盖全部划扣动作并经过评审、状态机与幂等表落库并通过并发用例、审计可还原到参数级、存在灰度与回滚路径,并且先在可逆场景跑够周期。

学会划边界

练会写校验

排障看证据

判断守确定

13、思考

回到最初那个画面:一个不该存在的按钮被点了下去。它提醒的不是「模型不可靠」,而是我们把两件不同的事混在了一起------生成界面是描述问题,权限与交易是语义问题。

描述可以交给模型,因为它可重放、可丢弃、可重生成;语义必须留给确定性执行引擎,因为它要唯一、要幂等、要被审计。这两层的边界画在哪儿,决定了这次改造是提效还是事故。

所以我的判断是:先问「这个动作错了会怎样」,再决定「这个页面能不能生成」。可逆的、读多的、失败能重试的,先上;不可逆的、写多的、要对账的,等引擎稳了再说。

二阶思维不是想得更远,而是先问一层「那接下来会发生什么」。

生成是手段

确定是底线

先小后大走

慢即是快行

相关推荐
数智工坊1 小时前
视觉SLAM第2讲|初识SLAM:经典框架、传感器选型与工程环境全梳理
人工智能·深度学习·数码相机·机器人
旖旎夜光1 小时前
【LangGraph实战】LangGraph 学习笔记(四):持久化——从线程记忆到跨会话长期记忆
人工智能·笔记·python·学习·ai编程·langgraph
workflower1 小时前
汽车自动驾驶9 要素
人工智能·机器学习·重构·云计算·汽车·无人机
hhb_6182 小时前
大模型工具链选型实战方案
人工智能
2601_950760792 小时前
GDF-15重组蛋白:从孕期免疫耐受到多发性硬化神经保护的关键调控因子
人工智能·蛋白
一切皆是因缘际会2 小时前
穿透多维场景
人工智能
七牛云行业应用2 小时前
Dots 完整教程:从安装入口、跑第一个任务到给 Codex 派活(2026 年 10 月)
人工智能·大模型·agent
镜象科技5 小时前
AI情感大模型应用场景全解:从校园到医院再到企业的落地地图
人工智能
Joshua-a6 小时前
工程数学-理解卷积的含义_线性时不变系统的冲激响应与卷积
人工智能·深度学习