1. 背景:为什么需要抽象模型
在交互式数字孪生(digital twin)系统里,经常遇到一种典型任务:筛选异常实体并在前端高亮。看起来是“查询 + 过滤 + 操作 UI”,但随着场景规模(实体数、属性体量、动态性)上升,工程方案的差异会被放大:
- 延迟会不会爆炸?
- 失败发生在哪里、修复成本多高?
- 方案是否可迁移到其他交互场景?
为了避免讨论停留在用经验不断试错,我采用分层抽象模型来描述与对比两种范式:
- MCP(tool-based)
- Code-as-MCP(代码执行/沙箱范式)
目标给出在特定交互约束下,方案差异从何而来。
2. 结构层:交互系统的最小骨架
我们先忽略实现语言与框架,仅抽象交互任务所必需的概念:
- ($S_t$):第 (t) 步的真实世界状态(后端数据、前端场景、权限、缓存等)
- ($a_t$):第 (t) 步采取的动作(查询、筛选、UI 控制等)
- ($\varepsilon_t$):不可控扰动(并发、异步、部分成功、网络抖动、分页/限流等)
- ($O_t$):第 (t) 步的可观测反馈(返回值、ack、错误、摘要)
交互系统最关键的两条关系是:
$S_{t+1}=\delta(S_t,a_t,\varepsilon_t), \qquad O_{t+1}=h(S_{t+1})$
含义是:
- 世界如何变化,不仅由我们做了什么决定,还会受到不可控因素影响。
- 我们只能通过观测函数 $h(\cdot)$ 看到状态的一部分(返回值/ack/错误等),而不是状态本身。
这两条关系引出一个事实:
只要下一步行动依赖于新的观测 ($O_{t+1}$),那么交互过程就天然是多轮闭环的——多轮不是实现选择,而是结构约束。
3. 例子:异常实体筛选为什么“自然多轮”
以“筛选异常 building 并高亮”为例(异常条件可替换,这里只关注流程结构):
- 目标:筛出满足条件的一组实体并在前端执行高亮
- 现实约束:
- schema 可能不完全稳定(有些实体缺字段)
- 查询可能分页、限流、或部分成功
- 前端执行可能返回部分失败/拒绝/不可操作集合
因此,一个常见的闭环会是:
- 探测/确认字段与数据可用性(比如 height 是否存在、覆盖率如何)
- 基于探测结果做条件化查询/过滤(只对可用子集做筛选)
- 评估返回结果是否可接受(partial 是否要继续补全)
- 前端高亮并读取 ack(可能部分失败)
- 如有必要继续补救(补全/重试/降级)
注意,这不是“工程师不够聪明没写成一步”,而是由:
($\varepsilon_t$)(部分成功、异步、分页等)
($h(\cdot)$)(观测不完备)
共同决定的条件化信息获取过程。
4. 动作层:MCP 与 Code-as-MCP 的关键差异
在结构层固定之后,两种范式的差异主要体现在动作如何表示、如何验证。
4.1 MCP(Tool-based)
动作来自一个可枚举集合:
$a_t \in \mathcal{A}_{tool}$
每个动作通过 schema 明确约束参数,典型特征是:
- pre-exec 验证:参数不合法时在执行前失败
- 错误更结构化
- 单次动作开销较小
4.2 Code-as-MCP(代码执行)
动作被表示为“生成并执行程序”:
$\text{prog}t=\pi(O_t), \qquad (O{t+1}, S_{t+1})=\text{Exec}(\text{prog}_t, S_t)$
其特征是:
- 动作空间“生成式”,表达能力强(if/loop/search/聚合)
- runtime 暴露错误:很多错误在执行中才出现
- 单次动作可能更重(生成+执行+解析)
两者共享同一结构层闭环,但在动作表示与验证时机上做了不同取舍。
5. 成本层:把“慢、贵、易错”统一成可讨论的对象
在工程决策中,我们常关心三类代价:
- 延迟(用户体感、交互流畅性)
- token/上下文(规模与费用、上下文压力)
- 失败与重试(修复成本、用户可见性、稳定性)
一个最简成本模型可以写成:
$C=\sum_t\Big(\lambda_L L_t+\lambda_T Tok_t+\lambda_F Fail_t\Big)$
解释:
- ($L_t$):第 (t) 轮端到端延迟
- ($Tok_t$):第 (t) 轮 token 消耗(输入输出/上下文累积)
- ($Fail_t$):第 (t) 轮失败带来的代价(可取 0/1、重试次数、严重度等)
- ($\lambda$) 是权重:系统更看重什么,就给什么更高权重
5.1 结构参数:“交互强度、约束强度”?
它们决定轮数下界与失败分布,从而间接决定成本。
交互强度(最少需要多少轮反馈闭环)可表述为:
$t \ge I$
约束强度(schema 稳定与可静态验证程度)影响失败期望:
$\mathbb{E}[Fail_t]=f(K), \qquad \frac{d}{dK}\mathbb{E}[Fail_t]<0$
因此,在高交互强度 (I) 的系统中,多轮成本会被自然放大;在高约束强度 (K) 的系统中,pre-exec 验证通常更有价值。
6. 将两种范式放回 Digital Twin:结论与边界
在 digital twin 的“异常实体筛选 + 前端高亮”任务中,结构层常见特征是:
- (I) 偏高:需要多次获取反馈与 ack
- ($\varepsilon_t$) 明显:分页、部分成功、异步、并发等
- 观测 (O_t) 不完备:只能看到投影、不能直接得到全量状态
- 失败往往需要快速、结构化处理(体验与稳定性敏感)
在这一结构下:
- MCP(tool-based)的优势更多体现在:
- pre-exec 验证降低失败成本项
- 单次动作开销更小,适合高频交互
- Code-as-MCP 的优势更多体现在:
- 对大规模过滤/聚合表达力强
- 能把重计算外置,减少“把数据塞进上下文”的压力
两者并非互斥,而是在相同交互结构下,对“动作表达能力 vs 验证时机”的不同取舍。在高频交互与强约束场景中,工具化动作更有利于控制延迟与失败成本;
在重计算、低交互、输出可压缩(top-k/aggregate)的子任务上,代码执行更能发挥优势。
7. 可迁移条件:这套分析适用于哪里?
这套分层模型适用于所有具有以下特征的系统:
- 开放状态(外部变化不可控)
- 反馈闭环(行动依赖观测)
- 多轮交互不可消除
- 同时存在“动作表达能力”和“验证时机”两种设计取舍
当你把问题换成其他领域(例如数据分析、批处理、离线检索)时,只要结构层参数 (I, K, $\varepsilon$) 的形态发生变化,成本结论就可能翻转
8. 小结
本文用“结构层 + 动作层 + 成本层”的分层方式,将 MCP(tool-based)与 Code-as-MCP 置于同一抽象框架下对比。关键收获是:
- 多轮闭环往往来自结构约束,而非实现优劣
- 两种范式的核心差异在于“动作表示”与“验证时机”
- 成本函数负责累加代价,结构参数(如交互强度、约束强度)决定代价如何增长
- 在 digital twin 的典型交互任务中,应当将两者视为互补组件,而非单选题
在下篇中,我会继续记录我如何尝试一种折中架构,在不放弃 MCP-as-Code 优势的前提下,把延迟和失败成本重新拉回可接受区间。