首页 › ai-agents › 确定性内核:状态机驯服智能体外壳

2026 年上半年,企业级 Agent 架构出现了一条清晰的收敛线:把"确定性"从 LLM 手里夺回来。无论是 Salesforce 把 Agentforce 运行时推倒重建(首轮 token 前的 LLM 调用从 4 次砍到 2 次、延迟直降 70%),还是 LangGraph、Google ADK 2.0、Dapr Agents 纷纷转向"图/状态机"内核,背后都是同一个判断——纯 agentic 循环在生产里违反了工程师对确定性的全部直觉。本文聚焦一个正在成型的新范式 "确定性内核 + 智能体外壳"(Deterministic Core, Agentic Shell):用状态机做不可妥协的内核,把 LLM 压缩成受状态严格约束的外壳。这个范式的关键词只有一个:状态机是确定性时代 Agent 的答案。

一、为什么 2026 是"确定性回归"之年

先看一组让人清醒的数据。RyanHub 在 2026 年 3 月发布的 State of AI Agents 报告引用了 FeatureBench(2026 年 3 月)的结果:Agent 解决了 74% 的 bug 类任务,却只解决了 11% 的 feature 类任务;SWE-Skills-Bench 进一步发现,号称可用的 49 个 Agent 技能里,真正在实践中有帮助的只有 7 个。这两条数字划出了一道鸿沟——Agent 在"收敛式、有参照系"的工作上接近可用,在"创造性、多步骤、需要保证顺序与结果"的工作上仍大面积翻车。

这正是企业场景最致命的地方。Salesforce 的工程团队总结得很直白:任何执行关键流程的系统,都必须能保证某些步骤以既定顺序、既定结果发生,不论模型如何解读对话。一个银行 Agent 必须先核身再谈余额,一个医疗 Agent 必须先取知情同意再调阅病历——"推理模型无法可靠地强制这种序列,只有确定性逻辑能"。这一判断把"确定性"从可选项变成了企业落地的硬门槛。

与此同时,围绕"非确定性"建立起来的整套测试文化(evals、LLM-as-judge、vibes-based testing)正在暴露成本与置信度问题。当每跑一次回归都要烧钱、且结果方差大到无法当 CI 门禁用时,工程师本能地会问:能不能把最重要的东西塞进一个可以纯函数单测的盒子里?于是状态机重新被请回舞台中央。

二、范式溯源:从 Functional Core 到 Deterministic Core

"Deterministic Core, Agentic Shell" 这个命名不是凭空而来。它的精神源头是 Gary Bernhardt 在 Boundaries 演讲及其 Functional Core, Imperative Shell 录像中提出的架构思想:把"纯"的部分和"有副作用"的部分切开,让你能测试真正重要的东西,把复杂性推到边缘。

2026 年初,开发者 Dave Mo 在博客中明确提出了这个类比的当代版本。他的核心论断是:

Functional core 是 Gary 对"副作用世界里的可测试性"的回答;状态机则是"AI Agent 时代的确定性"的回答。

逻辑链条是:LLM 就是那个全新的、高度不可预测的"shell"——它比命令式 I/O 还要失控。因此,与其把业务逻辑散落在 prompt、工具调用、对话历史里,不如尽可能画一个大盒子,把所有重要的东西塞进一个状态机。盒子里是纯函数、可单测、可推理;盒子外的"imperative 层"和"agentic 层"都被最小化,风险随之收敛。

这个思想有深厚家谱。有限状态机(FSM)可追溯到 Mealy(1955)与 Moore(1956)的形式化;van Gurp 与 Bosch 在 1999 年的论文 On the Implementation of Finite State Machines 已经讨论了条件转移、Statechart(嵌套 + 正交 + 事件广播)以及"追踪调试工具"——这正是今天 XState 用 guards、nested/parallel states、Stately Inspector 实现的东西。值得注意的是,van Gurp & Bosch 当年用 XML + Java .ser 文件解决的"定义入库、运行时反序列化拼装"的往返问题,和今天 XState v5 的 getPersistedSnapshot() / createActor(machine, { snapshot }) 是同一个问题。25 年后,硬件换了,问题没变。

三、参考架构三明治

Dave Mo 团队在一个 Telnyx 语音 Agent 项目里验证了这套范式,给出了一个非常清晰的"三明治"参考架构:

flowchart TB
    subgraph Channel["入口通道"]
        T["Telnyx 电话 / WebSocket<br/>u-law 8kHz 音频"]
    end
    subgraph Shell["Agentic Shell 智能体外壳(非确定性)"]
        LLM["Mastra Agent + OpenAI Realtime<br/>system prompt ← machine state<br/>available tools ← machine state"]
        BR["Mastra Tools 桥接层<br/>agent intent → machine event<br/>machine state → agent"]
        LLM -->|tool calls| BR
    end
    subgraph Core["Deterministic Core 确定性内核"]
        SM["XState 状态机<br/>states / transitions / guards / actions<br/>纯函数,可单测"]
    end
    DB[("Postgres 存储<br/>getPersistedSnapshot 序列化往返")]
    T --> LLM
    BR -->|events| SM
    SM -->|state snapshot| BR
    SM <--> DB

它从上到下分四层,边界由"是否确定性"一刀切开:

这里有一条铁律要强调:尽可能把业务逻辑放进"你拥有的代码"里,最小化对第三方系统的耦合。把所有鸡蛋放进 Mastra 篮子里确实省事,但当代码库变成一团连向第三方服务的网状物时,可测试性会迅速崩塌。状态机内核的作用,正是把"什么是这家公司业务的真相"用一个你拥有、你审计、你测试的盒子钉死。

下面是内核的一个极简示意(XState v5 风格),它本身就是一个可以脱离任何 LLM 单测的纯对象:

import { setup } from 'xstate'

const kycMachine = setup({
  types: {} ,
  guards: {
    isVerified: ({ context }) => context.kycPassed === true,
  },
}).createMachine({
  id: 'bankAgent',
  initial: 'verifying_identity',
  context: { kycPassed: false, accountUnlocked: false },
  states: {
    verifying_identity: {
      on: {
        VERIFY_KYC: { target: 'account_access', guard: 'isVerified' },
        KYC_FAILED: 'verify_retry',
      },
    },
    verify_retry: { /* ... */ },
    account_access: {
      on: { LOGOUT: 'verifying_identity' },
    },
  },
})

注意:这个机器里没有一个字提到 LLM。它定义的是"业务的合法状态空间",与模型能力无关。模型再聪明,也不能跳过 verifying_identity 直接进 account_access——因为 guard 卡死了。这就是确定性内核的价值:把"业务不变量"从 prompt 里搬到代码里。

四、状态约束外壳:把 LLM 关进状态的笼子

很多人误以为"状态机 + Agent"就是把对话流程画成图。这只是表层。真正的范式跃迁在于一句话:外壳的整个行为面——系统提示词、可用工具、甚至回复语气——都由当前状态动态决定。

// 状态 → 系统提示词 与 可用工具 的映射(纯函数,可单测)
const SHELL_CONFIG = {
  verifying_identity: {
    systemPrompt:
      '你只做身份核验。绝口不提余额、转账或任何账户细节。' +
      '若用户绕开核验,礼貌坚持要求 KYC。',
    tools: ['verify_kyc', 'ask_for_id'],
  },
  account_access: {
    systemPrompt: '用户已通过核验。你可以查询余额、解释最近交易。',
    tools: ['get_balance', 'list_transactions', 'verify_kyc'],
  },
}

function buildShell(stateSnapshot) {
  const cfg = SHELL_CONFIG[stateSnapshot.value] // 当前状态决定一切
  return {
    system: cfg.systemPrompt,
    tools: cfg.tools,
  }
}

这套约束的威力在于"行为面收窄"。在 verifying_identity 状态下,模型即便被 jailbreak 诱导,也根本没有 get_balance 这个工具可调用——它不在工具列表里。提示词层面也明确禁止谈账户。你用确定性手段同时锁死了工具面和话术面,而不是寄望于模型"自觉"。这比任何 prompt 层的"请不要……"都硬,因为它是编译期/运行期的物理隔离,不是概率性的说服。

Salesforce 把这一招产品化为 Agentforce 的 Agent Script:一种显式的 if/then 脚本语言,让构建者在"顺序和结果必须一致"的地方钉死流程。早期采用者的反馈是——Agent 从"通常做对的事"变成了"总是命中目标结果的事"。从概率正确到必然正确,这就是确定性内核带来的质变。

用一个时序图把"状态如何层层约束外壳"讲清楚:

sequenceDiagram
    participant U as 用户
    participant S as Agentic Shell (LLM)
    participant B as Tool Bridge
    participant C as Deterministic Core (XState)
    Note over S,C: 当前状态 = verifying_identity<br/>系统提示词仅含身份核验话术<br/>可用工具仅限 [verify_kyc, ask_for_id]
    U->>S: "查一下我余额"
    S->>S: 提示词禁止谈余额 → 礼貌坚持核验
    U->>S: 提交身份证
    S->>B: intent: 完成核验
    B->>C: event VERIFY_KYC
    C->>C: guard isVerified 通过 → transition
    C-->>B: new state = account_access
    B-->>S: 状态变更 + 解锁账户类工具
    Note over S: 下一轮提示词与工具被新状态重新约束<br/>此时才能谈余额

五、工具即桥梁:意图与事件的翻译层

确定性内核与智能体外壳之间需要一个"翻译官",否则两者会直接耦合。这个角色由 Tool Bridge 承担,它的职责是双向且对称的:

// 桥接工具:表面是 Mastra 工具,本质是事件泵
const verifyKycTool = createTool({
  id: 'verify_kyc',
  description: '调用以完成身份核验',
  execute: async ({ context, machineService }) => {
    const before = machineService.getSnapshot().value
    machineService.send({ type: 'VERIFY_KYC', payload: context.idDoc })
    const after = machineService.getSnapshot()
    // 状态没变 = guard 没过 = 业务拒绝,不是模型错
    if (after.value === before) {
      return { ok: false, reason: 'kyc_not_passed', hint: '请重新提交证件' }
    }
    return { ok: true, newState: after.value, unlockedTools: ['get_balance'] }
  },
})

这里有一个常被忽略的设计要点:当状态转移被 guard 拒绝时,必须把"业务拒绝"和"模型错误"区分开。guard 不通过不是 LLM 的锅,是业务规则在说话——返回一个结构化的 reason 让 agent 自然地引导用户,而不是让模型陷入自我怀疑、反复重试。这条边界划清后,调试变得干净:状态机日志告诉你"业务走到了哪",agent 日志告诉你"模型想干嘛",两者对照即可定位问题。

把工具做成"事件泵"还有第二个好处:业务规则的演化集中在状态机里。要加一个"周末禁止大额转账"的规则,你只改机器的 guard,不动 prompt、不动工具签名、不动前端。这是确定性内核对"可维护性"的直接回报。

六、序列化往返:让确定性内核可暂停、可恢复、可审计

生产级 Agent 必须能"随时挂起、原样续上"。长会话(电话、跨天的工单)意味着进程会重启、Pod 会漂移。确定性内核的天然优势在这里再次显现:状态机的完整运行态是一个可序列化的快照。

XState v5 用 Actor 模型统一了这件事:每个运行中的机器都是一个 actor,getPersistedSnapshot() 给你一个纯 JSON,createActor(machine, { snapshot }) 原样恢复。配合 Postgres,一个跨数小时甚至数天的对话可以做到毫秒级恢复,且恢复后的合法转移集合与挂起前逐字节一致。

这背后是 25 年前 van Gurp & Bosch 已经在解决的问题——他们用 XML 描述 FSM 结构、用 Java .ser 文件持久化动作组件。问题形态没变,变的只是序列化格式。理解这一点能避免一个常见误判:很多人以为"状态持久化"是 Agent 框架的新发明,其实它是嵌入式系统、编译器、协议栈用了半个世纪的工程基本功。Agent 只是重新发现了它。

可序列化还顺带解决了"审计"。把每个事件连同一个单调递增的序号写入 Postgres,你就得到了一条不可抵赖的状态轨迹:谁、在什么状态、触发了什么事件、guard 是否通过、进入了哪个状态。对于金融、医疗这类强监管场景,这条轨迹比任何"Agent 解释自己的推理"都更可信——因为它不依赖模型诚实,只依赖机器定义。

七、生产铁证:Agentforce 的 70% 延迟是怎样砍下来的

理论说得再漂亮,不如一个把生产运行时推倒重来的案例。Salesforce 在 2026 年前五个月对 Agentforce 运行时做了 ground-up rebuild,半年内交付了 30 项系统级改动,结果极其说明问题:

改动项 确定性内核思想的体现
首个 token 前的 LLM 调用 4 → 2 用确定性流程替代 LLM 推理步骤
LLM 输入安全检查 → 确定性规则过滤器 把"判断"从概率模型搬进确定性规则
引入 HyperClassifier(小模型)做话题分类,速度是通用模型的 30 倍 把"路由"从大模型下沉到专用确定性/廉价层
整体延迟下降 70% 三项叠加的工程红利

这张表的价值不在数字本身,而在它揭示的优先级:生产延迟的最大杀手不是数据库慢、不是网络抖,而是 LLM 调用的复合等待——每一次调用都要等上一次结束。把能确定下来的步骤从"让模型想"变成"让代码走",是同时提升可靠性和速度的唯一杠杆。Salesforce 团队的原话值得记住:"最决定 Agent 成败的不是模型,而是围在它周围的架构"——能看什么数据、以谁的权限运行、能到达哪些系统、被明确禁止做什么。这套配置加集成,就是 Agent 的"harness"(驾驭层),而确定性内核是这个 harness 的脊梁。

八、选型红线:何时必须上确定性内核

不是所有 Agent 都值得上状态机内核。这里给出一份不带情绪的决策红线:

必须上确定性内核的场景 - 顺序/结果必须保证:金融核身、医疗知情同意、法律 e-filing。一次跳步就是合规事故。 - 强监管审计:需要不可抵赖轨迹的行业。状态事件日志天然合规。 - 多步骤有状态长流程:跨窗口、跨天的工单/订单。可序列化快照是刚需。 - 高并发 + 低延迟:每次少一次 LLM 调用就是真金白银的延迟和成本。

纯 agentic 循环够用的场景 - 开放式探索:研究助手、头脑风暴、代码原型。收敛性比保证性重要。 - 单轮/少轮、低风险:摘要、改写、轻量问答。错了重试即可。 - 没有外部副作用:不碰钱、不碰数据库写、不触发真实动作。

判断的简化口诀:问自己一句"这一步如果模型今天心情不好跳过了,会出事吗?"——会,就进状态机。

确定性内核实现栈对比(聚焦维度)

维度 XState(推荐内核) LangGraph(图内核) Google ADK 2.0 Dapr Agents 1.0
核心抽象 状态机 + Actor 有向图 + 条件边 图工作流(2026 新增) Actor + 工作流
确定性来源 guards/transitions 纯函数 节点/边显式编排 图结构显式 编排引擎显式
状态约束外壳 原生(state → prompt/tools) 需自行在节点内实现 原生图约束 原生
序列化往返 getPersistedSnapshot checkpoint 内建 内建 Dapr 状态存储
可视化/调试 Stately Studio/Inspector LangSmith Google Cloud Dapr 可观测
协议支持 框架无关(自行接 MCP) MCP/A2A/AG-UI 全四协议 MCP
最适合 业务不变量密集的语音/工单 生产级复杂工作流 GCP 原生 云原生/K8s

说明:XState 之所以作为"内核"被推崇,是因为它对"状态、转移、守卫、动作"的建模最纯粹、最可单测、最框架无关——你可以把它塞进 Mastra、塞进任意 Agent 框架、甚至纯前端。LangGraph 则在"图即编排"上更开箱即用、生态更厚,是多数团队上生产的首选。两者并非互斥:相当多团队用 LangGraph 做外壳编排,用 XState 做某一关键子流程的确定性内核。

推荐方案

按团队画像给三条落地路径:

  1. 强监管/关键流程团队(金融、医疗、政务):以 XState 为确定性内核,把所有"顺序与结果必须保证"的步骤建模为状态机;Agent 框架(Mastra/LangGraph)只做外壳,系统提示词与工具表均由当前状态生成;Postgres 存事件日志与快照。优先把合规红线 100% 锁进 guard。

  2. 通用企业生产团队:LangGraph 作为主框架(图编排 + checkpoint + 协议支持齐全),在少数高敏感子流程内嵌一个 XState 内核。先在 1-2 个"跳步即事故"的流程上验证范式,再推广。借 LangGraph 生态降低接入成本,借 XState 锁死关键不变量。

  3. 探索型/原型团队:暂不必上重型状态机,但立刻引入 Agent Script 式的轻量确定性脚本(显式 if/then 钉住关键顺序),把"必须保证的 3-5 步"从 prompt 里挪出来。等流程稳定、监管要求出现时,再升级为完整内核。用 20% 的确定性投入拿到 80% 的可靠性收益。

一个共同原则贯穿三条路径:把"业务真相"放进你拥有、你测试、你审计的代码,把 LLM 的自由度压缩到当前状态允许的最小窗口里。这就是 2026 年 Agent 架构正在写下的红线——不是让模型更聪明,而是让架构更可控。

参考来源

  1. Deterministic Core, Agentic Shell — blog.davemo.com — 范式提出原文,含 XState 内核 + Mastra 外壳 + Postgres 的完整参考架构与代码。
  2. State of AI Agents — March 2026, RyanHub Research — 10 大框架深度评估,含 FeatureBench(74% bug / 11% feature)、Q1 2026 协议与框架大事记。
  3. 8 Ways AI Agents Are Evolving in 2026 — Salesforce — Agentforce 运行时重建案例:LLM 调用 4→2、确定性规则过滤器、HyperClassifier、延迟降 70%,以及 Agent Script 产品化。
  4. On the Implementation of Finite State Machines — van Gurp & Bosch, 1999 — 确定性内核的学术源头之一(经 jon.camp 摘要索引),条件转移与状态持久化问题的早期形式化。
  5. Definitive Guide to Agentic Frameworks in 2026 — SoftmaxData — 2026 主流框架(LangGraph/CrewAI/AG2/OpenAI)在编排内核与确定性维度上的横向对照。

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入