1. 从一句话到三维模型:text-to-cad 到底在解决什么问题
第一次听到 “text-to-cad” 这个词,很多人脑子里蹦出来的画面可能是:对着电脑说一句“给我画个法兰盘”,屏幕上就自动生成一张工程图。这个想象方向没错,但真正的落地形态比“语音画图”要务实得多。text-to-cad 的核心,是把自然语言描述或结构化文本,转换成 CAD 软件能够识别和编辑的几何模型文件,常见的输出格式包括 STEP、DXF、URDF 等。它解决的不是“替代设计师”,而是“把重复性建模劳动自动化”。
我最早接触这个方向,是因为手头有一批参数化零件需要批量出图。每个零件的差别只有几个尺寸,但要在 CAD 里一个个改草图、拉伸、倒角,一天下来眼睛都花了。后来我尝试用脚本读取表格里的参数,自动生成 DXF 轮廓,再导入 CAD 做后续处理。这套思路其实就是 text-to-cad 的雏形——用文本承载设计意图,用程序驱动几何生成。
它适合什么人?如果你是会写一点 Python 的工程师、需要批量处理图纸的工艺员、做机器人仿真需要生成 URDF 的开发者,或者单纯想从“手工点鼠标建模”升级到“脚本化建模”的 CAD 使用者,这个方向都值得花时间研究。它不要求你是计算机专业出身,但需要你愿意理解“几何描述语言”和“CAD 文件结构”这两件事。
目前 text-to-cad 的典型应用场景有这么几类:一是参数化标准件库的批量生成,比如螺栓、法兰、型材截面;二是机器人领域的 URDF 模型快速搭建,用文本描述连杆尺寸和关节位置;三是二维图纸的自动化绘制,比如根据坐标点生成 DXF 轮廓用于激光切割;四是概念阶段的快速几何验证,把文字描述转成 STEP 模型,先看大体形状对不对,再进 CAD 精修。
注意:text-to-cad 不是“AI 一键出图”那种营销概念。它更像是一套“文本到几何”的翻译规则,你需要定义清楚文本的语法、几何的生成逻辑、以及输出文件的格式规范。做得好不好,取决于你对 CAD 几何内核和文件格式的理解深度。
2. 核心思路拆解:文本如何变成几何
2.1 三种主流技术路线对比
把文本变成 CAD 模型,目前有三条比较成熟的路子,各有各的适用场景和坑。
| 路线 | 核心原理 | 输出格式 | 适合场景 | 上手难度 |
|---|---|---|---|---|
| 参数化脚本驱动 | 用 Python 等语言调用 CAD 的 API,按参数生成几何 | STEP、DXF、原生格式 | 标准件批量生成、参数化建模 | 中等 |
| 几何描述语言解析 | 定义一套文本语法,解析后映射为几何图元 | DXF、SVG | 二维轮廓、切割图纸 | 较低 |
| 模板替换法 | 预置 CAD 模板文件,用文本替换其中的参数变量 | 原生格式、STEP | 系列化产品改型 | 较低 |
我个人的经验是,如果你要做三维实体,参数化脚本驱动最稳;如果只是二维轮廓,几何描述语言解析更快;如果公司已经有成熟的模板体系,模板替换法落地成本最低。三条路线不是互斥的,实际项目里经常混着用。
2.2 为什么 STEP 和 DXF 是两大核心输出格式
热词里反复出现 STEP 和 DXF,这不是偶然。STEP 是三维实体交换的事实标准,几乎所有主流 CAD 软件都能读写,它记录的是 B-rep(边界表示)几何,包含完整的曲面和实体信息。你用脚本生成的 STEP 文件,丢进 SolidWorks、中望 CAD、Fusion 360 里都能打开继续编辑。
DXF 则是二维图纸和轮廓数据的通用格式,激光切割、线切割、钣金展开这些工序,基本都认 DXF。它的结构比 STEP 简单得多,本质上是“图层 + 图元”的集合,图元包括直线、圆弧、多段线、文字等。用 Python 的ezdxf库就能直接写 DXF,不需要装 CAD 软件。
URDF 则是机器人领域的专用格式,全称是 Unified Robot Description Format。它用 XML 描述机器人的连杆、关节、坐标系和碰撞体。热词里“urdf导入coppeliasim”说明很多人是在做仿真时遇到这个需求的。URDF 本身不包含复杂曲面,主要是用基本几何体(立方体、圆柱、球)和网格文件来近似机器人结构。
提示:如果你生成的 STEP 模型要在 CAD 里做后续特征操作,注意检查曲面的连续性和实体的封闭性。脚本生成的几何经常出现“面没缝合”或“实体不封闭”的问题,导入后会变成曲面片而不是实体。
2.3 文本描述的结构化设计
text-to-cad 能不能用好,关键看你的文本描述设计得够不够“机器友好”。纯自然语言比如“画一个直径 50 毫米、厚度 10 毫米的圆盘”,对人来说很直观,但对程序来说歧义太多。更靠谱的做法是设计一套结构化文本格式,比如 JSON 或 YAML:
{ "type": "flange", "outer_diameter": 100, "inner_diameter": 50, "thickness": 10, "bolt_holes": { "count": 6, "diameter": 8, "pcd": 75 } }这种格式的好处是:字段名明确、单位统一、嵌套结构清晰。程序解析时不需要做自然语言理解,直接按字段取值就行。如果你确实想用自然语言,建议至少加上关键词提取和参数映射这一层,把“直径 50”映射到diameter: 50,把“厚度 10”映射到thickness: 10。
我试过用正则表达式从中文描述里提取尺寸参数,对于格式比较固定的输入(比如“外径100 内径50 厚10 6个直径8的孔 节圆75”),提取准确率能到 90% 以上。但一旦描述方式变化,比如“100外径,50内径,厚度10mm,均布6个8mm孔”,规则就要重新写。所以结构化文本是正路,自然语言是辅助。
3. 实操环境搭建与工具选型
3.1 Python 生态里的 CAD 工具链
做 text-to-cad,Python 是目前最顺手的选择。几个核心库你得知道:
- ezdxf:读写 DXF 文件的首选,API 设计得很直观,文档也全。画直线、圆弧、多段线、标注、图层管理都支持。
- cadquery:基于 OpenCASCADE 的参数化建模库,用 Python 代码描述三维实体,输出 STEP、STL 等格式。语法接近自然语言,学习曲线平缓。
- build123d:cadquery 的“精神续作”,API 更现代,支持上下文管理器和代数模式两种写法。
- numpy:做几何计算时离不开,坐标变换、向量运算、矩阵操作都靠它。
- trimesh:处理网格文件(STL、OBJ)的利器,做 URDF 的碰撞体简化时会用到。
安装这些库不算复杂,但cadquery 和 build123d 依赖 OpenCASCADE 的底层库,在 Windows 上偶尔会遇到编译问题。我的建议是直接用 conda 装 cadquery,能省掉很多依赖麻烦:
conda create -n text2cad python=3.10 conda activate text2cad conda install -c conda-forge cadquery pip install ezdxf numpy trimesh如果你不想折腾环境,也可以直接用FreeCAD 的 Python 控制台,它内置了 OpenCASCADE 和 Draft 模块,能直接写脚本生成几何。缺点是 FreeCAD 的 API 文档不如 cadquery 友好,很多用法要靠翻源码和论坛。
3.2 二维 DXF 生成的最小可用示例
先从一个最简单的例子入手:用 ezdxf 画一个带螺栓孔的法兰盘二维轮廓。
import ezdxf import math doc = ezdxf.new('R2010') msp = doc.modelspace() outer_r = 50 inner_r = 25 bolt_count = 6 bolt_r = 4 pcd_r = 37.5 # 画外圆和内圆 msp.add_circle((0, 0), outer_r) msp.add_circle((0, 0), inner_r) # 画螺栓孔 for i in range(bolt_count): angle = 2 * math.pi * i / bolt_count x = pcd_r * math.cos(angle) y = pcd_r * math.sin(angle) msp.add_circle((x, y), bolt_r) doc.saveas('flange.dxf')这段代码跑完,你会得到一个flange.dxf文件,用任何 CAD 软件都能打开。关键点在于:所有尺寸都是变量,改几个数字就能生成不同规格的法兰。这就是 text-to-cad 的基本形态——文本(代码)驱动几何。
注意:ezdxf 默认的 DXF 版本是 R2010,兼容性比较好。如果你要发给用老版本 CAD 的同事,可以改成
R2000。另外,DXF 里的圆是用圆心和半径定义的,但有些激光切割机只认多段线,这时候需要用add_lwpolyline把圆离散成多段线。
3.3 三维 STEP 生成的 cadquery 示例
二维轮廓只能算“图纸自动化”,真正体现 text-to-cad 价值的是三维实体。用 cadquery 生成一个法兰盘实体:
import cadquery as cq outer_d = 100 inner_d = 50 thickness = 10 bolt_count = 6 bolt_d = 8 pcd = 75 result = ( cq.Workplane("XY") .circle(outer_d / 2) .circle(inner_d / 2) .extrude(thickness) .faces(">Z") .workplane() .polarArray(pcd / 2, 0, 360, bolt_count) .hole(bolt_d) ) cq.exporters.export(result, "flange.step")这段代码的逻辑很清晰:在 XY 平面上画两个同心圆,拉伸成环,然后在顶面上用极坐标阵列打孔。cadquery 的链式调用让几何构建过程读起来像一句话,这也是它比直接调 OpenCASCADE API 友好的地方。
生成的 STEP 文件可以用中望 CAD、SolidWorks 等软件打开,也能直接丢进切片软件做 3D 打印。如果你要做 URDF,可以把 STEP 转成 STL,再用 trimesh 简化网格,最后写进 URDF 的<collision>和<visual>标签里。
4. 完整实操流程:从参数表到批量 DXF 图纸
4.1 需求场景与数据准备
假设你接到一个任务:有一批钣金件需要激光切割,每个零件的轮廓形状相同,但长宽和孔位不同。工艺员给了你一张 Excel 表,里面有 20 个规格的尺寸参数。你要做的是:根据这张表,批量生成 20 个 DXF 文件,每个文件对应一个规格。
Excel 表的结构大概是这样:
| 零件编号 | 长度 | 宽度 | 孔1_X | 孔1_Y | 孔2_X | 孔2_Y | 孔直径 |
|---|---|---|---|---|---|---|---|
| P001 | 200 | 100 | 20 | 20 | 180 | 80 | 8 |
| P002 | 250 | 120 | 25 | 25 | 225 | 95 | 10 |
| ... | ... | ... | ... | ... | ... | ... | ... |
这种表在制造业很常见,手工画图的话,20 个规格至少要半天。用脚本做,写好模板后,跑一遍只要几秒钟。
4.2 脚本实现与关键细节
我用 pandas 读 Excel,用 ezdxf 画图,核心代码如下:
import pandas as pd import ezdxf df = pd.read_excel('parts.xlsx') for _, row in df.iterrows(): doc = ezdxf.new('R2010') msp = doc.modelspace() length = row['长度'] width = row['宽度'] hole_d = row['孔直径'] # 画外轮廓矩形 msp.add_lwpolyline([ (0, 0), (length, 0), (length, width), (0, width), (0, 0) ]) # 画两个孔 msp.add_circle((row['孔1_X'], row['孔1_Y']), hole_d / 2) msp.add_circle((row['孔2_X'], row['孔2_Y']), hole_d / 2) doc.saveas(f"output/{row['零件编号']}.dxf")这段代码有几个细节值得说:
第一,外轮廓用add_lwpolyline而不是四条add_line。多段线在激光切割里更友好,因为切割路径是连续的,不需要抬刀。而且多段线可以设置闭合标志,避免首尾点重复。
第二,孔的坐标是绝对坐标。如果你的 Excel 里给的是相对坐标,需要先做坐标变换。我一般会在脚本里加一个判断:如果坐标值小于长度和宽度,就认为是绝对坐标;如果出现负数,就认为是相对某个基准点的偏移。
第三,输出目录要提前创建。doc.saveas不会自动建目录,如果output/不存在会报错。加一行os.makedirs('output', exist_ok=True)就能解决。
提示:批量生成 DXF 时,建议在文件名里带上关键尺寸,比如
P001_200x100.dxf。这样后期核对时不用打开文件就能知道规格,省很多事。
4.3 从 DXF 到 STEP 的进阶处理
二维 DXF 只能满足切割需求,如果你要做三维装配验证,还需要把 DXF 轮廓拉伸成实体。这一步可以用 FreeCAD 的 Python 脚本做,也可以用 cadquery 重新构建几何。
我一般倾向于在 cadquery 里重新构建,而不是从 DXF 导入。原因是 DXF 导入后经常出现线段不连续、圆弧方向错误等问题,修复起来比重新画还麻烦。重新构建的好处是几何干净、参数可控,而且可以直接输出 STEP。
如果你确实需要从 DXF 转 STEP,FreeCAD 的Draft和Part模块可以做到:
import FreeCAD import Draft import Part shape = Draft.import_dxf('input.dxf') wire = Draft.makeWire(shape) face = Part.Face(wire) solid = face.extrude(FreeCAD.Vector(0, 0, 10)) Part.export([solid], 'output.step')这段代码在 FreeCAD 的 Python 控制台里能跑,但对 DXF 的图层和闭合性有要求。如果 DXF 里的轮廓没有闭合,Part.Face会失败。所以批量处理前,最好先用 ezdxf 检查一下多段线的闭合标志。
5. URDF 生成与机器人仿真对接
5.1 URDF 的文本结构解析
URDF 本质上是 XML,描述的是机器人连杆和关节的树状结构。一个最简单的两连杆机械臂 URDF 长这样:
<robot name="arm"> <link name="base_link"> <visual> <geometry> <cylinder radius="0.05" length="0.1"/> </geometry> </visual> </link> <link name="link1"> <visual> <geometry> <box size="0.3 0.05 0.05"/> </geometry> </visual> </link> <joint name="joint1" type="revolute"> <parent link="base_link"/> <child link="link1"/> <origin xyz="0 0 0.1" rpy="0 0 0"/> <axis xyz="0 0 1"/> <limit lower="-1.57" upper="1.57" effort="10" velocity="1"/> </joint> </robot>关键字段是<origin>和<axis>。<origin>定义子连杆坐标系相对于父连杆的位置和姿态,<axis>定义关节的旋转轴。这两个字段搞错了,机器人在仿真里就会“散架”或者“乱转”。
热词里“urdf导入coppeliasim”说明很多人是在 CoppeliaSim 里做仿真。CoppeliaSim 对 URDF 的支持还算友好,但有几个坑:一是网格文件的路径问题,URDF 里引用的 STL 文件必须用相对路径,而且要和 URDF 文件放在同一个目录下;二是关节类型,CoppeliaSim 对continuous类型的关节支持最好,revolute需要设置好上下限。
5.2 用脚本生成 URDF 的实操方法
手工写 URDF 对于简单机器人还行,一旦连杆数量超过 5 个,手写就容易出错。用 Python 脚本生成 URDF 是更靠谱的做法。我一般用jinja2模板引擎,先写一个 URDF 模板,再用参数填充。
模板文件robot.urdf.j2:
<robot name="{{ robot_name }}"> {% for link in links %} <link name="{{ link.name }}"> <visual> <geometry> <box size="{{ link.size }}"/> </geometry> </visual> </link> {% endfor %} {% for joint in joints %} <joint name="{{ joint.name }}" type="{{ joint.type }}"> <parent link="{{ joint.parent }}"/> <child link="{{ joint.child }}"/> <origin xyz="{{ joint.origin }}" rpy="{{ joint.rpy }}"/> <axis xyz="{{ joint.axis }}"/> </joint> {% endfor %} </robot>Python 脚本读取参数表,渲染模板,输出 URDF 文件。这种方式的优势是:连杆尺寸和关节位置可以来自 Excel 或数据库,改参数不用改模板。对于系列化机器人产品,这套方法能省大量时间。
注意:URDF 里的单位是米和弧度,不是毫米和度。如果你从 CAD 里导出的尺寸是毫米,记得除以 1000。我见过有人直接把毫米写进 URDF,结果机器人在仿真里大了 1000 倍,找了半天才发现是单位问题。
5.3 网格文件与碰撞体的处理技巧
URDF 的<visual>和<collision>可以用基本几何体,也可以用网格文件。基本几何体计算快,但形状不精确;网格文件精确,但会拖慢仿真速度。我的经验是:视觉用网格,碰撞用简化几何体。
具体做法是:用 cadquery 生成精确的 STEP 模型,导出 STL 作为<visual>;然后用 trimesh 对 STL 做凸包或简化,生成一个低面数的碰撞网格,或者直接用包围盒作为<collision>。
import trimesh mesh = trimesh.load('link1.stl') hull = mesh.convex_hull hull.export('link1_collision.stl')凸包的好处是计算快、不会出现穿透,缺点是对于凹形零件会“填平”凹陷。如果你的零件有重要的凹槽,可以用trimesh.decomposition做凸分解,生成多个凸包组合。
6. 常见问题与排查技巧实录
6.1 DXF 文件打开后图形错位或缺失
这是最常见的问题,原因通常有三个:
一是单位设置不一致。ezdxf 默认的 DXF 单位是“无单位”,但有些 CAD 软件会按英寸解释。解决办法是在创建 DXF 时设置$INSUNITS变量:
doc.header['$INSUNITS'] = 4 # 4 表示毫米二是图层被冻结或关闭。脚本生成的图元默认在0图层,如果 CAD 当前图层被关闭,图形就看不见。可以在脚本里显式创建图层并设置颜色:
doc.layers.add('轮廓', color=7) msp.add_lwpolyline(..., dxfattribs={'layer': '轮廓'})三是坐标值超出视图范围。如果图形画在 (10000, 10000) 附近,打开时可能显示空白。用 CAD 的“缩放全部”命令就能看到,或者在脚本里把图形移到原点附近。
6.2 STEP 文件导入后不是实体
脚本生成的 STEP 文件,导入 CAD 后有时是一堆曲面片,而不是一个完整的实体。原因通常是曲面没有缝合或者实体没有封闭。
cadquery 生成的实体一般是封闭的,但如果你做了布尔运算(比如打孔、切除),可能会产生微小的缝隙。解决办法是在导出前做一次“缝合”和“修复”:
result = result.clean()clean()会尝试合并共面的面、修复微小的缝隙。如果还不行,可以用result.fix()做更彻底的修复,但速度会慢一些。
提示:如果你用的是 FreeCAD 的 Part 模块,可以用
Part.Solid检查实体是否有效,用Part.Shell检查曲面是否封闭。无效的实体在后续布尔运算中会出各种奇怪的问题。
6.3 URDF 导入仿真环境后关节方向不对
URDF 的关节方向由<axis>决定,但轴的方向和坐标系的原点位置有关。如果<origin>的rpy设置不对,即使<axis>写的是0 0 1,关节也可能绕错误的轴旋转。
我的排查方法是:先在 URDF 里把每个连杆的<visual>设成不同颜色,导入仿真后观察连杆的相对位置。如果某个连杆的位置明显偏了,就是<origin>的xyz或rpy有问题。建议先用简单的方块和圆柱搭一个最小模型,确认关节方向正确后,再替换成精确的网格文件。
另外,CoppeliaSim 导入 URDF 时,默认会把所有关节设为passive模式,需要手动改成motor或position才能驱动。这个在 CoppeliaSim 的关节属性里改一下就行,不是 URDF 的问题。
6.4 批量生成时文件命名冲突或覆盖
批量处理时,如果两个零件的编号相同,后生成的会覆盖先生成的。建议在文件名里加入时间戳或哈希值,或者在脚本里加一个检查:
import os filename = f"output/{part_id}.dxf" if os.path.exists(filename): filename = f"output/{part_id}_1.dxf"更稳妥的做法是用零件编号 + 规格的组合命名,比如P001_200x100.dxf。这样即使编号重复,规格不同也不会覆盖。
6.5 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决措施 |
|---|---|---|---|
| DXF 打开空白 | 图形在视图外或图层关闭 | 缩放全部、检查图层 | 移动图形到原点、打开图层 |
| STEP 导入是曲面 | 实体未封闭或曲面未缝合 | 检查实体有效性 | 执行 clean/fix 修复 |
| URDF 关节乱转 | origin 或 axis 设置错误 | 用彩色方块验证 | 调整 rpy 和 axis |
| 批量生成覆盖 | 文件名重复 | 检查输出目录 | 加入规格或时间戳 |
| 尺寸差 1000 倍 | 单位不一致 | 检查 CAD 单位设置 | 统一用毫米或米 |
| 孔位偏移 | 坐标系原点不同 | 对比图纸和脚本坐标 | 统一基准点 |
7. 我踩过的坑与实操心得
7.1 不要追求“全自动”,半自动往往更实用
我一开始的想法很激进:能不能用自然语言处理把工艺员的描述直接转成 CAD 模型?试了两个月,发现准确率始终上不去。问题不在于 NLP 技术不行,而在于工艺描述本身就有歧义。“打几个孔”到底是几个?“均布”的起始角度是多少?这些信息在人脑里是默认的,但程序不知道。
后来我改成“半自动”方案:工艺员填一张结构化表格,脚本读表格生成模型。表格的列名固定,单位固定,歧义就消除了。text-to-cad 的“text”不一定是自然语言,结构化文本才是更可靠的输入。
7.2 几何内核的坑比编程语言的坑多
写 Python 脚本本身不难,难的是理解几何内核的行为。比如布尔运算的顺序会影响结果,倒角的半径不能大于相邻边的长度,抽壳的厚度不能超过最小壁厚。这些限制在 CAD 软件里是交互式提示的,但在脚本里只会抛一个异常,有时候异常信息还看不懂。
我的应对方法是:把复杂几何拆成简单步骤,每一步都做有效性检查。比如先拉伸一个方块,检查是不是实体;再打孔,检查孔是不是穿透;最后倒角,检查倒角有没有失败。这样出问题时能快速定位是哪一步的几何操作有问题。
7.3 版本兼容性是个隐形杀手
DXF 有 R12、R2000、R2010 等多个版本,STEP 有 AP203、AP214、AP242 等协议。不同 CAD 软件对版本的支持程度不一样。我遇到过用 R2010 生成的 DXF,在老版本 CAD 里打不开;也遇到过 AP242 的 STEP,在某些软件里丢失颜色信息。
现在的做法是:DXF 统一用 R2000,兼容性最好;STEP 统一用 AP214,支持颜色和图层,大多数软件都认。如果客户有特殊要求,再单独调整。
7.4 脚本要留日志,不然出了问题没法查
批量生成 100 个文件,如果第 57 个失败了,没有日志的话你根本不知道是哪个参数出了问题。我在脚本里加了简单的日志:
import logging logging.basicConfig(filename='generate.log', level=logging.INFO) for _, row in df.iterrows(): try: # 生成逻辑 logging.info(f"成功生成 {row['零件编号']}") except Exception as e: logging.error(f"生成 {row['零件编号']} 失败: {e}")这样跑完一遍,打开日志就知道哪些成功了、哪些失败了、失败原因是什么。日志不用写得很复杂,但一定要有。
7.5 输出目录结构要提前规划
批量生成的文件如果全堆在一个目录里,找起来很痛苦。我一般按日期或批次建子目录:
output/ 2024-01-15/ P001_200x100.dxf P002_250x120.dxf logs/ generate_2024-01-15.log这样每次生成的成果和日志分开存放,回溯的时候很方便。如果文件要发给别人,直接打包整个日期目录就行。
8. 这个方向还能怎么扩展
text-to-cad 的边界远不止“生成 DXF 和 STEP”。往深了做,有几个方向值得探索。
一是和 PLM/PDM 系统对接。生成的模型自动上传到产品数据管理系统,带上版本号和审批状态。这需要理解 PLM 的 API 和数据结构,但一旦打通,设计到生产的链路就短了很多。
二是加入几何约束求解。现在的脚本生成是“参数驱动”,尺寸改了模型就重建。但如果能加入约束求解,比如“孔始终在边的中点”“两个面始终平行”,模型的鲁棒性会更强。OpenCASCADE 有约束求解器,但 Python 绑定不太完善,需要花时间研究。
三是用大语言模型做参数提取。虽然纯自然语言驱动 CAD 还不成熟,但用 LLM 从工艺描述里提取参数是可行的。比如把“外径100,内径50,厚10,6个8mm孔均布在直径75的圆上”丢给 LLM,让它输出 JSON,准确率比正则表达式高很多。LLM 负责理解,脚本负责生成几何,这个分工比较合理。
四是和 3D 打印切片软件联动。生成的 STEP 直接转 STL,自动导入切片软件,设置好打印参数,输出 G-code。对于小批量定制化零件,这条链路能省掉很多手工操作。
我在实际项目里用得最多的还是“表格到 DXF”和“参数到 STEP”这两条链路。它们不炫酷,但稳定、可控、容易维护。text-to-cad 的价值不在于替代设计师,而在于把设计师从重复劳动里解放出来,让他们有时间做真正需要创造力的工作。如果你也在做类似的事情,建议先从一个小场景入手,跑通一条完整链路,再逐步扩展。