【阻力 7】双向同步覆盖冲突与人机协同合并
这就聊到了“AI + 低代码”进入深水区后,最让人抓狂的交互与数据对齐问题。行业内给这个阻力起了一个名字,叫 “双向编排冲突(Bidirectional Sync Conflict)”。 如果处理不好,就会出现:运营好不容易肉眼微调了半小时的字体、边距、图片,结果对 AI 说了一句“把优惠券换成绿色的”,AI 重新生成一段 JSON,直接把运营之前手工改的内容全覆盖了。运营直接崩溃,这套系统也就没人敢用了。 作为前端架构师,要解决这种“人类微调 20% + AI 迭代 80%”的无缝融合,在底层需要设计一套类似 Git 版本的代码合并与意图识别机制。以下是硬核的解法:
架构边界:本方案的「双向同步」指 单运营 + AI Agent 交替改同一 pageSchema,不是 Figma / Google Docs 式的多人实时同屏协同。因此 不需要 Yjs、Automerge 等 CRDT/OT 方案——JSON Patch + 3-Way Merge +
source锁足够;若未来两个运营同时拖同一画布,再单独评估 CRDT,那是另一类需求。
一、 核心底座:不能使用全量覆盖,必须全面采用“指令化(Patch)”通信
大模型(LLM)天生喜欢“一步到位”,如果你让它改一个组件,它倾向于把整个页面的新 JSON 全量吐给你。前端架构层必须拒绝接收全量 JSON,强迫大模型输出或者由中间件转换为“增量修改指令(JSON Patch)”。
- 什么是 JSON Patch(RFC 6902 规范)? 这是一种用 JSON 描述数据改动的标准协议。它不用发整个文件,只发送“在哪个路径、做了什么操作、改了什么值”。
- 举个例子:
运营对 AI 说:“把中间的倒计时组件改成国潮风”。
- 错误做法:AI 吐出包含全页面的新 JSON。
- 正确做法:AI 或前端中间层(通过比较新旧 JSON)只生成如下的精简指令集:
[
{ "op": "replace", "path": "/components/1/props/theme", "value": "national_tide" },
{ "op": "replace", "path": "/components/1/props/backgroundColor", "value": "#D42G11" }
]
- 优势:由于大模型只修改了
/components/1(倒计时组件)的路径,那么运营之前手动修改的/components/3(商品列表组件)的粉色背景,就完全不会被波及。
二、 进阶难题:如果 AI 和人类同时改了同一个字段,怎么办?(冲突域隔离)
上面的 JSON Patch 能解决“你改你的,我改我的”的非冲突场景。但如果发生冲突呢?
- 场景:运营手动把标题改成“端午大促”;随后运营又对 AI 说:“帮我起一个更有煽动性的标题”。此时 AI 想把标题改成“狂欢端午,全场1元起”。两者撞车了。
大厂的低代码平台对此有两层防御设计:
1. 属性级的三色标记(元数据锁机制)
前端在低代码的数据模型(Store)中,为每个属性不仅存储 value(值),还存储 source(来源占位符)。
source: "system"(默认值)source: "ai"(AI 生成的)source: "human"(人类手动改的)
核心策略:人类拥有最高解释权(Human-First)。
当运行增量合并逻辑时,系统会进行权限判断:如果 AI 试图去 replace 一个已经被标记为 "human" 的属性,系统会直接拦截该条指令,并保留人类的选择。同时,系统在后台对 AI 说:“该字段已被人类锁定,请忽略对此字段的修改”。
2. “反向引导”的 UI 交互设计
在人机协同的界面上,不能像程序员用 Git 那样弹出复杂的 <<<<<<< HEAD 冲突代码块给运营看。前端需要设计直观的交互:
- 当 AI 试图修改运营改过的东西时,在画布上弹出一个闪烁提示:“AI 帮您想了一个更好的标题:‘狂欢端午,全场1元起’,是否替换您手写的‘端午大促’?”
- 给予运营 [采用AI] 或 [维持手写] 的单选按钮,把冲突的决定权以极简的 UI 形式交还给人类。
三、 终极姿态:语义化 AST Diff(防止 AI 破坏布局结构)
除了属性的值冲突,最怕的是 “结构破坏”。比如运营手动用一个“容器组件(Container)”把商品卡片和倒计时包裹在了一起。接着运营让 AI 加一个优惠券。AI 如果不懂这个容器,可能会把优惠券错误地插到容器外面,导致页面布局直接散架。 为了解决结构合并,大厂前端会引入类似虚拟 DOM(Virtual DOM)的 语义化 Diff 算法:
- 树形结构对比:将页面的低代码 JSON 视为一棵组件树(Tree)。
- 三方合并(3-Way Merge):
就像 Git 一样,系统会保存三个版本的 JSON:
- Base:最初由 AI 生成的原始版本。
- Mine:运营手工拖拽修改后的版本。
- Theirs:AI 听到新口令后生成的新版本。
- 系统运行一个专为低代码设计的 3-Way Tree Merge 算法,比对组件的 id。如果发现组件 id 一致但层级被人类改变了(比如被放进了容器),算法会智能地在 AI 新生成的版本中,把该组件重新归位到人类指定的容器内部。
四、编辑态回滚(L0):与阻力 8 发布回滚的分工
3-Way Merge 解决冲突,不解决整段撤销。每次 AI 应用 JSON Patch 前,应自动 push 草稿快照(或 Patch 入栈),支持运营 Undo/Redo。发布前 Checkpoint(L1)与线上 pageSchema@vN 一键回滚(L2)、运行时熔断(L3)、组件 schemaPins(L4)共同构成成套回滚体系,详见 阻力 8 第四道防线。
五、为什么不用 Yjs / CRDT?
| 方案 | 典型场景 | 本方案 |
|---|---|---|
| Yjs / OT / CRDT | 多人在线同时编辑同一份文档,毫秒级合并 | ❌ 不需要 |
| JSON Patch + 3-Way Merge + source 锁 | 人类改完 → AI 再改 → 按回合合并 | ✅ 采用 |
- 冲突模型不同:这里是离散回合(运营拖完 → 对 AI 说一句话 → AI 出 Patch),不是并发字符流;每轮合并有明确 Base / Mine / Theirs,和 Git 同构。
- 数据结构更适合树合并:pageSchema 是带 stable
component.id的 JSON 树,3-Way Tree Merge 语义清晰、可审计;CRDT 的「最终一致」难以回答「这行配置谁负责的」。 - Human-First 需要显式决策:
source: human拦截 + [采用AI] / [维持手写] 是有意设计的人工确权,不是 CRDT 自动揉合。 - 工程成本:Yjs 要带 Provider、awareness、协同服务端,和 AI 批处理 Patch、发布风控链路不对齐,属于过度设计。
结论:阻力 7 的「双向」= 人机双向,不是 人人实时双向。当前方案栈已闭环,无需引入 Yjs。
🚀 总结
通过 “JSON Patch 指令化 + 属性来源标记锁 + 3-Way Tree Merge”,我们成功在前端架构上构建了一个“人机协同不会打架”的精密闭环。AI 负责出大轮廓,人类负责精雕细琢,两者可以反复迭代。 现在,组件标准化搞定了,仿真预览搞定了,人机协同代码合并也搞定了。 我们终于来到了发布前的最后一道生死关卡:【阻力 8:信任壁垒与风控兜底审核】。 电商涉及真金白银。如果 AI 在半夜自动配置活动时,不小心把“满100减10元”配成了“满10减100元”,或者页面产生了黑灰产漏洞,大厂如何设计前端和网关层的“自动化熔断与资金风控”兜底机制? 我们要不要给这个庞大的系统加上最后一道“安全带”?