做工具类应用,迟早会走到一个岔路口:用户的操作越来越重复,想“存下来批量跑”;AI 能力越来越强,想“一句话搞定”。这时常见的答案有两个:
- 节点编排优先:给用户一张画布,拖节点、连线、配参数,像 ComfyUI、n8n、各类低代码平台那样。
- 提示词优先:用户说一句话,模型直接给出结果,中间过程是个黑盒。
两者都能用,也各有短板。节点画布把编排变成了用户要迈的第一步:得先学会画流程图,才能开始干活,这道门槛足以劝退大部分人。提示词直出则把过程藏了起来,结果不满意只能重新抽卡,没法稳定复现,更难保证“某些东西绝对不能动”。至于更朴素的写脚本、录宏,可复现是做到了,却只照顾到会写代码、或者愿意折腾的少数人。
这篇文章想聊另一条路。它最早是我在设计一个垂直图像处理工具时想清楚的,后来越想越觉得它不局限于图片,于是抽出来单独写。一句话概括:
人照常动手,编排是操作的沉淀;AI 只提方案,不直接出结果;调度器决定每一步在哪里执行。
一、三条路线放在一起看
| 路线 | 用户的第一步 | 可复现 | 可控 | 上手门槛 | 实现成本 |
|---|---|---|---|---|---|
| 节点编排优先 | 画流程图 | 强 | 强 | 高 | 中 |
| 提示词优先 | 写一句话 | 弱 | 弱 | 低 | 低 |
| 操作优先(本文) | 照常操作 | 强 | 强 | 低,进阶能力按需打开 | 高 |
关键差别在于编排出现的时机。它不是入口,而是用户做完一遍之后自然留下来的东西,有点像 Excel 的“录制宏”或 Photoshop 的“动作”。不过这里多走了几步:录下来的每一步都有明确的输入输出类型和约束,AI 能读懂、能改写,调度器也能把它拆开,分到不同的地方去执行。
代价是实现成本高:用户感受到的简单,是靠背后多出来的 DSL、校验器和调度器换来的。第九节再细说。
二、整体结构:四层
桌面端、移动端和服务端共享同一套编排 DSL、算子规范和内核;差别只在交互形态、本地有哪些算子实现,以及调度策略。
先约定几个说法,免得后文混淆:算子是编排里的原子,也就是最小的计算单元;编排指一份用 DSL 描述的算子连接图;AI 给出的候选编排叫方案;用户确认后固化下来、可以反复运行的编排叫模板。
还有一点要分清:文中说“AI 提方案”,指的是负责编排的大模型;抠图、超分、文字识别这类模型,则被封装成普通算子,和其他算子一样受校验和调度管理。前者决定“怎么做”,后者只负责“做其中一步”。
三、算子:最小的可复现单元
算子当然要能复用,但更要紧的是能复现:同样的输入和参数,在容差范围内得到一致的输出。对抠图、超分这类模型算子来说,这意味着要固定模型版本和随机种子。
每个算子带一份元信息:
- 基础信息:ID、名称、入参出参 Schema、版本、说明;
- 运行环境:能在哪里跑,比如
desktop-local、mobile-local、serverless; - 默认路由:
auto/prefer-local/prefer-serverless; - 成本权重:在不同环境下运行的代价;
- 约束标签:能否批量、是否依赖大模型、是否有内存上限,以及是否
local-only(数据不允许离开本机)。
还有一条边界必须先划清:可录制操作和一次性操作要分开。
缩放到 800×800、亮度 +10、按某列去重,这类参数化、可复现的动作会映射成算子,进入录制链路。自由手绘、随手拖动、手工改某一格数据,这些动作和当时的上下文强绑定,硬录下来只会得到一条没法复用的编排。所以它们照样可以用,只是不进编排。这条线划清楚,录下来的东西才能直接拿来复用。
四、域隔离:复杂度和幻觉的第一道防线
如果所有算子都放进一个全局大池子,会发生两件事:
- 算子数量持续膨胀,每个新需求都“顺手加一个”,最后没人说得清哪些还在用;
- AI 编排时面对几百个候选算子,搜索空间太大,乱组合、编造参数的概率明显上升。
所以我的做法是单内核、多域包。每个垂直场景是一个封闭的域资产包,里面有这个域的算子白名单、数据类型、编排规则(比如“导出前必须压缩”)、给 AI 用的提示词和示例,以及场景模板。
域与域默认隔离,算子不能跨域直接调用。确实需要互通时,只提供少量桥接算子(比如导出文件、加载文件),而且必须由用户显式触发,AI 不能自行把两个域串起来。
新需求来了,先问一句:能不能用现有的域消化掉?比如用已有算子组合成一个复合算子。只有确实是全新的场景,才新建一个域。这条纪律往往比技术手段更管用。
五、编排从哪来:录制为主,画布为辅
大多数时候,用户只是在熟悉的界面里正常干活,系统在背后记录语义化的算子调用,自动生成编排。录制也不是照单全收:撤销掉的步骤不记,同一个参数反复调整只留最终值。留下来的应该是意图,而不是过程。
进阶用户可以打开画布,增删节点、调整连线、设置分支;改完之后回放,主界面的预览随之更新。两边是双向同步的:
双向同步有一个边界要提前想好:一次性操作不在编排里,如果用户在画布上改了上游节点,下游那些手工修补可能就对不上了。这时要明确提示用户,不能悄悄沿用。
以图片场景为例,用户做完一张商品图后,录下来的 DSL 大致长这样:
domain: ecommerce-product-image
nodes:
- id: cutout
op: matting.remove-background
- id: canvas
op: canvas.center
params: { width: 800, height: 800, padding: 0.08 }
- id: shadow
op: effect.drop-shadow
params: { blur: 12, opacity: 0.25 }
- id: export
op: export.multi-size
params: { sizes: [800, 400, 200], format: webp }
edges:
- [cutout, canvas]
- [canvas, shadow]
- [shadow, export]
注意 DSL 里没有写“在哪执行”,只描述数据怎么流、参数是什么,执行位置交给调度器决定。所以同一份编排在桌面端和手机上都能跑,只是每一步跑在哪里可能不同。
录下来的参数都是具体值,比如 800×800。固化成模板时,把需要变化的参数(尺寸、背景色、导出格式)提升为模板参数,其余写死。后面说的“参数微调”,调的就是这些。
六、AI 交方案,不交成品
这是整套思路里我最看重的一点。AI 不直接产出最终结果,它产出的是方案:
几个要点:
- AI 只能看到当前域的算子。搜索空间从源头就限定了。DSL 本身有 Schema,可以直接用结构化输出约束模型,格式层面的错误在生成阶段就被排除。
- 校验先于人审。格式对了不代表合理:算子是否属于本域、参数取值是否越界、是否违反域规则,这些语义检查由校验器负责,不合格的方案到不了用户面前。
- 一次给两三套方案。比如一套只用轻量算子,成本低,大多能在本地跑;另一套用了重型模型算子,质量更高,但多半要上云。用户可以对比,也可以从两套里各挑几个节点拼起来。
- 人做终审。确认后的方案固化成模板,之后批量运行不再经过编排模型。它的成本和不确定性只在生成方案时出现一次,批量跑一千张也不会再多。
比方案机制更要紧的,是另一件事:把约束从提示词里拿出来,做成算子。
以人像为例。如果把修图交给生成式模型,只在提示词里写“不要改人脸”,它大概率会遵守,偶尔不遵守;而在批量处理几千张图时,“偶尔”就是灾难。更稳妥的做法是做一个人脸保护算子:检测人脸生成掩码,处理完后把原图人脸区域贴回去并做边缘融合,再比对处理前后的人脸特征向量,相似度低于阈值就判定失败。
这条约束也不该由 AI 来决定要不要用,而是写进域规则:只要方案里有重绘类节点,校验器就要求必须带上人脸保护。AI 只负责把它放到正确的位置。
靠提示词约束,是在和概率讨价还价;把约束做成算子,就没有价可讲了。
七、调度器:同一份编排,不同的执行地点
调度器综合几方面信息决定每个算子的去向:当前设备类型、算子的运行环境和默认路由、成本权重,以及用户偏好。
默认规则很朴素:
- 默认本地优先:本地有实现就本地跑,省钱,也保护隐私;没有实现,或算子声明了
prefer-serverless,就交给云端; - 桌面端开放偏好切换:优先本地 / 优先云端 / 全部云端;
- 手机端不暴露复杂配置,自动路由,只显示预计消耗;
- 标记为批量异步的任务,不管从哪个端发起,统一进云端队列。
但有一条硬约束凌驾于所有偏好之上:标记为 local-only 的算子或域,任何偏好和批量规则都不能把它送上云。隐私只能是硬规则,不能是默认值。
性能上还有两个细节:相邻的云端算子打包成子图一次提交,避免大文件在本地和云之间来回传;云端算子之间只传资源引用 ID,不传二进制。
最后是一致性兜底。同一个算子的本地版本和云端版本,要维护一组基准用例,持续对比两边的输出是否在容差内一致。否则用户会发现同一个模板在电脑上和手机上出来不一样,信任就没了。
八、不止图片:五个场景
前面一直拿图片举例,因为它最直观。但这套结构几乎不用改,就能套到很多垂直场景上。下面每个场景都回答四个问题:域里有哪些算子,什么录、什么不录,哪条约束要做成确定性算子,本地和云端怎么分。
场景一:电商商品图
- 算子:抠图、居中画布、投影、调色、压缩、多规格导出,模特图还需要人脸保护;
- 录 / 不录:参数化的调色、裁剪进录制;手绘修补不进;
- 确定性约束:模特图的人脸保护、品牌色校验;
- 本地 / 云端:编解码、缩放、调色和轻量抠图在本地;复杂边缘抠图、超分、AI 修复、背景重构上云。
前文已经展开过,这里不再赘述。
场景二:结构化数据清洗
- 算子:解析(CSV / JSON / Excel)、Schema 校验、字段映射、去重、类型转换、空值填充、导出;
- 录 / 不录:“按手机号去重”“日期统一转 ISO 8601”进录制;手工改某一格的错别字不进;
- 确定性约束:Schema 校验算子,不符合约定结构的数据直接拦下,不靠模型自觉;
- 本地 / 云端:单文件几百 MB 以内都可以在浏览器里跑(借助 DuckDB-Wasm 这类工具),数据不出本机;需要调用外部接口补全数据时,必须由用户明确授权,并且只上传必要的字段。
这个场景里,隐私是本地执行的主要理由,比成本更重要。
场景三:文档出稿
- 算子:Markdown 规范化、标题层级检查、链接与引用检查、图表渲染、主题样式、导出 PDF / 长图;
- 录 / 不录:“套用某主题”“A4 页边距 15mm”进录制;正文内容的修改不进;
- 确定性约束:链接检查、敏感词检查都是规则算子,结果可以审计;
- 本地 / 云端:文本处理和图表渲染在本地;需要稳定分页和字体嵌入的打印级 PDF 放服务端(无头浏览器或排版引擎)。
这个场景看重可审计:每一份稿子过了哪些检查、结果如何,都能追溯。
场景四:合规脱敏
- 算子:PII 识别(手机号、身份证、邮箱、人名、地址)、掩码、替换为假数据、生成审计日志;
- 录 / 不录:“手机号保留前三后四”“身份证全部掩码”进录制;人工豁免某个字段不进录制,但必须写进审计日志;
- 确定性约束:结构化 PII 用正则和校验位算法识别;人名、地址这类非结构化信息交给一个本地运行的 NER 识别算子,结果要人工抽检,并持续跟踪召回率,因为合规场景最大的风险是漏识别;
- 本地 / 云端:整个域标记为
local-only。要脱敏的数据,本来就不该先上传再脱敏。
这里负责编排的大模型尤其克制:它只帮你组合脱敏规则,不接触原始数据。
场景五:发布前检查
- 算子:配置 Diff、密钥泄露扫描、格式校验、依赖漏洞与许可证检查、变更摘要生成;
- 录 / 不录:一次发布前的检查步骤可以沉淀为模板;临时跳过某项检查不进模板,但要留痕;
- 确定性约束:密钥扫描、格式校验都是硬性门禁;变更摘要由模型生成,但只给人看,不参与放行判断;
- 本地 / 云端:密钥扫描必须在本地 push 之前跑(比如 pre-commit),推上远端就已经算泄露了;耗时长、需要统一环境或组织级凭据的检查(漏洞库、许可证)放到 CI,这里的 CI 就相当于“云端”。
这个场景离生产环境最近,所以确定性门禁最多,模型的权限也最小。
把这五个场景放在一起,能看出一个规律:模型越接近“生成方案”和“写说明”,越安全;越接近“直接改数据”,越需要被确定性算子包起来。
九、代价与边界
这套思路的代价不小,至少有三处:
- 前期投入大。算子规范、DSL、校验器、调度器,每一层都要做扎实,第一个域的成本远高于直接写一个功能。
- 跨端一致性需要长期维护。本地和云端两套实现,基准测试一旦松懈就会出问题。
- 交互复杂度要主动控制。画布默认隐藏,手机端只做模板运行和参数微调,不提供自由编排。
它也有明确不适用的场景:
- 一次性、创意驱动的任务。没有重复,就没有沉淀的价值。
- 需求极度发散、无法划域的场景。域划不出来,隔离就无从谈起,AI 幻觉也无从约束。
- 算子很少的小工具。五六个功能的工具,再加一层编排就是过度设计。
判断标准可以很简单:用户是否会反复做同一类事情,并且在意每次结果一致? 如果是,这套结构值得考虑;如果不是,老老实实做好单个功能就够了。
即便值得做,也不必一开始就把四层搭全。比较稳妥的顺序是:先挑一个域,把算子规范和录制做扎实,让用户能把操作存成模板;确认模板真的被反复使用之后,再接入 AI 方案;最后才是跨端调度。前两步就已经能交付价值,后两步是放大器。
结语
回头看,这套思路说到底是几次“让位”:
- 编排给人的操作让位:先动手,后沉淀;
- AI 给人的判断让位:它提方案,人来拍板;
- 提示词给确定性算子让位:能用代码保证的,就不要交给概率;
- 通用性给垂直域让位:宁可窄,也要稳。
最后真正留下来的,不是某个抠图或去重算子(这些谁都能做),而是一套贴合具体场景、能复现、能批量跑的编排。编排文件本身并不难抄,难抄的是它背后对场景的理解:哪些步骤该录,哪些约束必须做成算子,哪些数据绝不能离开本机。