跳到正文

定义态、运行态与支撑服务 ​

一句话:把“能做什么”和“怎么跑”拆成物理隔离的两层,再用一组无状态支撑服务连接,是平台能安全演进的前提;代价是多一层网络跳转和一套跨层契约。

为什么需要 ​

平台早期最常见的错误,是把编排界面、Skill 定义和 Agent 执行放在同一个服务里。演示时很方便:点一下“运行”,同一个进程直接调模型、读文件、执行代码。上线后问题集中爆发:

  • 定义态的配置错误会直接拖垮执行进程,改一个提示词要重启整个平台;执行环境又需要 GPU、网络隔离和临时文件系统,和 Web 服务的资源模型完全不同,混在一起无法独立扩缩容。
  • 审计说不清一次执行用了哪个版本的 Skill、哪份知识、哪个工具,因为定义和执行共享内存,版本在运行中被覆盖;执行代码的进程还同时持有配置库和管理接口的凭证,安全边界失效。

根因是把“元信息”和“执行”当成同一类负载。它们的变更频率、资源模型、信任边界和故障影响都不同,必须拆开。

核心机制 ​

三层分离 ​

看这张图只抓三件事。第一,中间一列是唯一的执行主链:会话管理 → 任务分发 → 队列 → Pod,实线带标签的就是这条链上的动作;第二,右下六个支撑服务全由 Pod 调用,Pod 自己不留状态,所以它随时可以被杀掉重建;第三,所有跨到定义态的线都是虚线且方向只有一个——运行态读定义,定义态永远不碰运行态。

定义态只写元信息,不执行任何代码;运行态只读配置、不修改定义;支撑服务被运行态调用,自身无状态。三层的依赖是单向的:定义态可以独立发布,运行态可以独立扩缩容,支撑服务可以独立升级。反过来,如果运行态能回写定义态,一次故障就可能污染配置;如果支撑服务持有会话状态,Pod 回收后会话就断了。三层的依赖是单向的:定义态可以独立发布,运行态可以独立扩缩容,支撑服务可以独立升级。反过来,如果运行态能回写定义态,一次故障就可能污染配置;如果支撑服务持有会话状态,Pod 回收后会话就断了。

定义态:四个 Hub 各自管什么 ​

组件管什么不该管什么
Skill HubSKILL.md、版本、审核、依赖声明不执行 Skill,不持有工具凭证
MCP HubServer 注册、健康检查、工具目录不代理调用,不做业务鉴权
编排界面图定义、节点参数、发布版本不保存运行中间结果
知识库管理摄入、分块、索引、权限标记不直接向模型注入内容
模型路由配置路由规则、限流、降级链不承载具体请求

定义态的核心产物是可版本化的配置:工作流 JSON、SKILL.md、MCP 注册信息、知识索引和路由规则。它们应该像代码一样评审、diff、回滚,而不是在数据库里被随手改掉。

运行态:五个服务与一条任务链 ​

服务职责关键设计
会话管理会话创建、粘性路由、上下文装载会话与 Pod 解耦,Pod 回收不丢会话
任务分发依赖检查、任务分配、结果回收按任务类型选池,按依赖解锁下游
Pod 池管理冷 / 暖 / 热池、回收、扩容池化复用,不按用户独占
任务队列优先级、重试、死信至少一次投递 + 幂等消费
自动扩缩按队列深度与 GPU 指标扩容预热副本,避免冷启动打穿 SLA

运行态不保存业务定义,只保存“这次执行到哪了”。所有中间结果写入支撑服务,Pod 可以随时被杀掉重建。

一次任务的九个步骤 ​

  1. 用户消息经网关鉴权、限流后进入会话管理。
  2. 会话管理查找活跃会话;没有则创建 session_id 并分配管理 Pod。
  3. 任务分发从池中取 Pod,优先热池,其次冷池;池满则排队并触发扩容。
  4. 管理 Pod 拉取工作流、会话历史和用户上下文,组装本轮输入。
  5. 模型输出任务分解:子任务、依赖、执行类型。
  6. 分发器按类型分配执行 Pod,依赖未满足的任务留在队列。
  7. 执行 Pod 加载 Skill、连接 MCP、读取上下文,按步骤执行并做输出校验。
  8. 每个子任务完成后写回结果,解锁下游;全部分完成后管理 Pod 聚合。
  9. 结果推送给用户,Pod 进入空闲,超时后回收;会话记忆保留在支撑服务。

这条链路里,任何一个 Pod 都是可替换的:管理 Pod 挂了,会话从支撑服务恢复;执行 Pod 挂了,任务按检查点重试。真正不能丢的是 session_id、任务状态和已提交的结果,它们必须在 Pod 之外。

故障域与隔离 ​

故障影响范围隔离手段
执行 / 管理 Pod 崩溃单个子任务或会话检查点重试 + 幂等键;会话粘性重建 + 历史回放
模型网关 / 向量库不可用调用该模型的会话、依赖检索的 Skill熔断降级;无检索时标注置信度
定义态发布错误新版本会话版本固定 + 灰度 + 快速回滚
审计写入失败合规风险,不影响执行本地缓冲 + 告警 + 拒绝高风险操作

隔离的设计原则是:故障不能跨层传播。定义态的错误不应该让运行态整体不可用;运行态的过载不应该拖慢定义态的发布。

实战场景 ​

场景一:一行提示词直接打进全量在线会话 ​

现象:一名开发者在编排界面把客服 Skill 的提示词“微调一行”,没走审核直接保存;运行态当时每次执行都实时拉定义库,改动在几分钟内命中全部在途会话。此后两小时客服任务成功率从 96% 跌到 78%,31 个会话中断转人工、投诉二十余单(损失数字为经验值,需校准)。复盘会第一个问题就答不上来:“线上正在跑的到底是哪个版本?”

排查:按一次任务的九个步骤逐层排:网关鉴权正常、会话管理正常、任务分发正常;查到执行 Pod 加载 Skill 这一步,Skill Loader 每次取的是“最新版”,请求里没有版本参数。审计环节跟着暴露——执行记录关联不到任何 Skill 版本,因为定义与执行共享内存,版本在运行中被覆盖。根因两条:会话启动时没有固定 Skill、知识库与模型路由版本;定义态的“保存”直接等于生效,两层之间缺少“发布才生效”的契约。

对症:版本固定加发布流水线。会话创建时把本次要用的版本写进会话上下文,运行期间不变;界面保存不等于生效,改动必须走草稿 → 审核 → 灰度 → 全量:

yaml
session_runtime:
  pinned_versions:
    skill: skill-cs@1.4.1     # 会话创建时固定,每次执行随结果落审计
    knowledge: kb-cs@2026.09
    routing: rt-default@3
  rollout:
    canary_percent: 10        # 经验值,需校准
    auto_rollback_on: [error_rate>5%]

复盘:故障域表把“定义态发布错误”的影响范围定为“新版本会话”,而不是“全部在线会话”——圈住这个范围的手段就是版本固定加灰度,缺一样,表就只是纸。发布顺序同样按契约执行:先发布支撑服务,再发布运行态,最后切定义态版本;回滚按相反顺序。

场景二:运行态回写定义库,谁都能改提示词 ​

现象:一个月内,同一个 Skill 的提示词被 4 个人改过 9 次,没人说得清哪次改动对应哪段线上行为;月底更严重的一次:执行 Pod 故障重试,补偿逻辑把半截工作流 JSON 回写进定义库,污染了 3 个已发布编排,平台组周末抢修(频次与影响为经验值,需校准)。起因是平台早期把编排界面、Skill 定义和执行放在同一个服务、同一个数据库里,“方便”了两头,失信了中间。

排查:第一个问题查变更通道——界面和数据库都能直达同一个对象,绕库那条路没有审核记录;审计说不清用了哪个版本,正是定义与执行共享内存的后果。第二个问题查信任边界——执行代码的进程同时持有配置库和管理接口的凭证,“运行态只读配置”只写在文档里,网络策略没挡写连接。两条都指向依赖方向失守:运行态能回写定义态,一次故障就污染了配置。

对症:凭证与通道各收一道,主体权限一张表收敛:

主体对定义库的权限变更通道
业务开发者无直连权限编排界面提交,走草稿 → 审核 → 灰度 → 全量
定义态服务读写只经版本化定义态 API,禁止共享表
运行态与执行 Pod只读回写请求在网关直接拒绝,落审计并告警
yaml
data_plane:
  definition_access:
    mode: read_only
    write_back: reject_and_audit   # 运行态回写定义态即配置污染

复盘:三层分离的验收不看目录结构,看三条:Pod 被杀后会话还在不在;定义态发布是否影响在跑的会话;一次执行能否按 trace 还原用了哪个版本。任何一条答不上,就不是“已经拆了”,只是“代码分开放了”。

场景三:接入第三个业务方,才发现支撑服务欠了三本账 ​

现象:第三个业务方(强合规场景)的接入冻结了一个月:对方安全评审直接退回,因为接入清单上的三条硬要求——凭证不长期持有、每次执行可按 trace 还原、成本按租户归集——平台一条都答不利索;上游排队的另外三个团队跟着一起等(时长为经验值,需校准)。前两个业务方靠“各自配一下”跑了大半年,没人觉得这三条是缺口。

排查:按“定义态管元信息、运行态管执行、支撑服务被运行态调用且自身无状态”逐层核对:定义态四个 Hub 齐了,运行态五个服务能跑任务,缺项全部集中在支撑服务层——它长期被当成“以后再说”。MCP Proxy 缺位,鉴权逻辑每个工具适配各写一遍,凭证只能沉在各仓库配置文件里;LLM Gateway 只做了转发没做计量,成本归集没有数据源;审计与追踪没做成独立服务,执行 Pod 顺手写本地日志,冷热回收把日志连同证据一起回收掉了。

对症:支撑服务清单按欠账补齐,每项的无状态约束随接口一起定:

支撑服务补什么关键约束
MCP Proxy统一鉴权、限流、短期凭证自身不持会话状态,Pod 回收不断调用链
LLM Gateway路由、熔断、计量、按租户归集计量随 trace 上报,不落执行 Pod 本地
审计与追踪追加式审计:输入摘要、工具调用、权限判定、输出校验、终止原因写失败走本地缓冲 + 告警 + 拒绝高风险操作,不阻塞执行主链路

复盘:支撑服务的账,总在第三个接入方到来那天结算。无状态不是架构洁癖——会话粘性、检查点重试、Pod 池冷热回收,全部以记忆、结果、审计外置在这些服务里为前提;支撑服务缺一层,运行态的“Pod 可以随时杀掉重建”就只是口号。

最小上手 ​

先做一条最小链路,不要求多 Agent:网关 → 会话服务 → 单个执行 Pod → Skill Loader → LLM Gateway → 审计。用一份 SKILL.md 和一个只读工具跑通“输入 → 执行 → 结果 → 审计”四段。验收看四件事:Pod 重启后会话还在;Skill 改版本后旧会话仍按旧版本执行;工具超时能返回可读错误;每次执行能按 trace 查到用了哪份配置。

生产动作 ​

  • 契约先行:定义态与运行态只通过版本化 API 通信,禁止共享表;会话启动时固定 Skill、知识库和模型路由版本,运行中不跟随定义态变化。
  • 只读配置:运行态对定义态只有读权限;执行环境不持有配置库写凭证。
  • 超时与预算:每层调用都设超时,跨层传递剩余预算,避免下游无限重试;trace 贯穿网关、会话、Pod、工具和模型调用。
  • 发布顺序:先发布支撑服务,再发布运行态,最后切定义态版本;回滚按相反顺序。

边界 ​

  • 三层分离会增加延迟:多一次网络跳转和序列化,极低延迟场景要评估是否值得;小团队低并发时可以同进程,等出现独立扩缩容需求再拆。
  • 物理隔离不等于安全,无状态也不等于无瓶颈:同一集群仍共享网络与内核,强隔离要独立节点池;连接池、限流和向量库容量仍要独立规划。
  • 定义态不是越集中越好:所有团队共用一个发布通道会形成瓶颈,需要按业务域划分命名空间与审批流。

讲清楚 ​

平台的可演进性来自三层分离:定义态只保存可版本化的元信息,运行态只负责执行和状态推进,支撑服务提供无状态的加载、代理、记忆与审计。分离的收益是独立发布、独立扩缩容和清晰的故障域;代价是跨层契约、额外延迟和更复杂的排障。判断拆分是否做对,可以看三条:Pod 被杀后会话是否还在,定义态发布是否影响正在运行的会话,一次执行能否按 trace 还原用了哪个版本。三条都成立,三层才算真正分开。

适用:2026 年企业级 Agent 平台运行态设计 | 初稿 2026-10

把 AI 工程讲到既懂也会用