2026-06-21 16:10:42 +00:00

12 KiB

agentic 集成架构:控制面与管理面

🚧 设计中 · 控制面是 tier2 与现有 SAA 线共用的治理层;部分组件已有地基(D12、infra_config 热改通路),部分还是蓝图。

这是什么:让两条生成线(SAA 廉价线、tier2 自治富游戏)被配置、观测、审计、管起来的治理层设计 —— 配置驱动(改配置不发版)、可追踪、可审计。 给谁看:生成主线后端、做平台 / 中台的工程师、想"像 Dify 一样管 agent 平台"的产品与创始人。

为什么要这一层

让 agent 自治生成游戏,这件事本身不够。平台还得能配置它(改 prompt、换模型、调 skill 不用发版)、看见它(每次生成到底发生了什么)、审计它(谁改了哪条配置)、在入口拦住它(配额、并发、降级)。这是创始人最早提的"像 Dify 一样可视化、可追踪、可审计地管 agent 平台"。这一层就是控制面和管理面,它同时管两条生成线 —— SAA 廉价线和 tier2 自治富游戏。

flowchart TB
    subgraph G[控制面 / 管理面]
        R[配置注册表<br/>prompt · model · skill · tool · mcp]
        O[观测 / 审计仓<br/>运行轨迹 + 配置审计]
        D[D12 运行治理门<br/>配额 · 并发 · 背压 · 降级]
        UI[管理面 UI<br/>视图 + 编辑器]
    end
    SAA[SAA · Tier0/1 廉价线]
    T2[tier2 · 自治富游戏]
    R -->|读配置 id+版本| SAA
    R -->|读配置 id+版本| T2
    SAA -->|写轨迹| O
    T2 -->|写轨迹| O
    SAA --> D
    T2 -. 待接 .-> D
    UI --> R
    UI --> O

它的内核是:配置即数据,全链可观测。不是从零造一个 Dify。能复用现成件就复用,能用一道一致性门兜住的就不上重型框架 —— 同目录的对抗审查给过一个对症范例:某个运行时能力本来要四处人手同步,正确解法不是上重型注册表,而是加一道一致性测试逼你改齐(从实现反射真实签名、断言它和注册表相等、对不上就红)。

它从属于线A,只做净增量

仓里已经有一份《生成主线架构演进路线》(下称线A),它是配置外置那层地基的分期主计划:把 prompt 做成两端同源、解决 split-brain(同一份 prompt 被 Java 和 Python 各存一份会漂移),是它的阶段2;把模型名外置成 models.yaml 加跨语言一致性校验,是它的阶段3。配置外置那层地基,本设计不另立分期,只认领并引用线A。控制面真正的净增量收窄到几件:配置审计日志、管理面 UI、把两条线的轨迹收成一份统一契约、把配置注册表从 prompt 推广到 skill / tool / mcp、热加载机制选型。

四个组件

控制面四个组件对两条生成线暴露同一套契约:生成线只管"从注册表读配置、向观测仓写轨迹",不感知管理面长什么样。

配置注册表:配置的唯一事实源

配置注册表解决创始人那句"改 prompt、模型、skill、mcp 还要重新部署"。内核是:凡是现在"要改就得发版"的东西,都搬进一个版本化、可回滚的注册表。

prompt 和 models 这两层是线A的阶段2-3,本设计只引用、不重排,但给 models.yaml 补一句线A没细化的范围:它要覆盖"SAA 的逐角色路由加 tier2 的 agent 路由",并说清现有两个配置入口怎么并进去 —— AigcExecutorProperties.llmModel 是 worker 的单模型默认值,SaaGraphDispatcher.saaForceModel 是一个全局覆盖开关(创始人那次"只用 M3"加的,非空就把全部角色统一成那个模型)。models.yaml 落地时,前者降为 fallback,后者作为"全局强制覆盖"保留在配置里,逐角色那档从 Java 工厂迁进 yaml。

把注册表从 prompt 推广到 skill / tool / mcp,是净增量。但有一条硬纪律:别在裂的地基上盖更大的注册表。今天的 Prompt Registry 不是"现成可热加载"的地基 —— 它的加载器类注释写着,prompt 是构建期被 maven 插件复制进 classpath 的快照,改 prompt 等于改 contracts/ 原文件、升版本号、过四道闸,下次构建部署才带新版,是 Git 版本化加构建期注入,不是运行时热加载。它自身还有缺口:注册表里有的条目标着"STUB 占位",对应 prompt 文件通篇是占位提纲;加载器里硬编码了一批模板路径,未必都登记进注册表。所以推广前先补一道一致性 CI:注册表列的每条 prompt 都有对应文件、每个硬编码加载的 id 都在注册表登记、STUB 要么补正要么标为不可上线。地基自洽了,推广才有意义。

观测 / 审计仓:发生了什么的唯一事实源

这块回答两个独立问题,对应两条留痕线。

运行轨迹记的是每次生成发生了什么 —— 每步推理、每次工具调用、每次 LLM 输入输出、每道门裁决、每次成本。消灭 split-brain(轨迹分散在各条派发路上)的真口径是"每条派发路诚实镜像它真有的字段、没有的绝不编造",不是"强求两条线字段对齐" —— tier2 的 ReAct"想-做-看"和 SAA 16 个节点的阶段裁决本就不同构,强求对齐是错的。统一轨迹的目标是:同一张表,一个公共核心子集(traceId、step、cost、verdict、timestamp),各轨把独有的放进一个 JSON 扩展列(SAA 放阶段、修复轮次、门裁,tier2 放推理、动作、观察)。它要落成一份真契约,放 contracts/trace/,对齐契约组里已命名的轨迹位,additive 演进;内容含字段定义、schema 版本、脱敏规则、两条线 adapter 怎么映射,以及一条要选边的策略 —— 轨迹写不进去时阻塞生成还是 best-effort 丢弃告警(默认 best-effort 不阻塞主流程,但计入告警)。

配置审计日志记的是谁、什么时候、改了哪条配置、为什么。这条线现在完全没有,是新建的。它的最小数据模型至少含:谁改的、从哪改的(UI 还是直接改 Git / DB)、改了什么(前后 diff)、配置版本号、谁批的、何时生效、回滚到哪个版本、影响了哪些生成任务。这里有一个要选边、不能既要又要的决策:UI 改配置,直接写运行时(DB 直写)还是建 Git PR(GitOps)?

flowchart TD
    C[UI 改配置] --> Q{哪类配置?}
    Q -->|prompt · models<br/>版本化资产| GO[GitOps 建 PR<br/>审计天然 · 可回滚 · 有构建延迟]
    Q -->|运营开关<br/>降级 · 配额数值| DB[DB 直写 infra_config<br/>即时生效 · 审计自补]

分类处理:prompt、models 这类版本化资产走 GitOps(它们本就在 contracts/ 里、线A的 CI 也以 Git 为源),运营开关类(降级、配额数值)走 DB 直写、复用现有 infra_config 通路(它们本就该即时生效、且有现成通路)。

把两条线钉一起的价值是:任何一次生成都能反查"它当时用的哪几条配置的哪个版本",才能回答"那批游戏质量掉了,是不是上周改的那条 prompt 干的"。存储复用已部署的 MySQL 加对象存储,不新起重型可观测中间件(链路追踪那套是 future-state,等真有第一个消费者再上)。

D12 运行治理门:入口前的保护门,已有件复用

D12 是已经存在的件,本设计只复用、不改。它把配额、并发限制、背压保护、降级开关、记账骨架,焊在生成任务入口前 —— 代码里 SAA 的提交和重试两条路都过它,默认关闭、零行为变更进主干,开闸前创始人显式打开。它有两点边界:现在只覆盖 SAA,tier2 接进来的入口、预算扣减、并发释放、失败补偿还要补;它的记账是骨架不是真计费(只是门结构加配置键,不是成本核算)。

这接上引擎设计里那道"花到上限就拒绝执行"的预算闸 —— 它现在不是现成能力。现有计费只是 best-effort 取价、取不到也不阻断,那个金额阈值是观测台账口径、不是网关层强制拒绝。tier2 自治多轮 ReAct 的成本风险是真的(一次失控循环能烧掉数美元),要落三层强制:worker 本地的 token / 成本预测先闸、网关配额二闸、任务 deadline 三闸,并定义取价不可达时的策略(直接失败,还是降级到纯 token 上限)。这套强制预算建成前,tier2 不规模化跑、只在严格时间盒的实验里跑。

管理面 UI:注册表与观测仓的视图与编辑器

管理面 UI 是注册表和观测仓的视图与编辑器,不是真相本身。这是创始人最在意的那半边 —— "Dify 式可视化 agent 平台管理":改 prompt / 模型 / skill / tool / mcp 不发版、可视化、可追踪、可审计、不要死代码。

一个设计选择先定下来:从零造一个 Dify 式可视化建图器,还是让配置成为真相、UI 只做配置加轨迹的视图与编辑器?选后者,三个理由:前期平台调研已拍板"维持现有 SAA / AgentScope、不迁可视化平台";裸图的节点是 Java 代码、ReAct 的工具也是代码,真相在代码和配置里,靠 UI 拖拽生成代码是另一套不可靠的范式;还有那条别过度工程的纪律。但"配置是真相、UI 是视图"不等于"第一期什么都不做、把可视化全推远期"。管理面按三档落,而且诚实命名:

flowchart LR
    P1[phase-1 配置管理 + 运行可观测<br/>只读看得见 · 配置编辑落 Git] --> P2[phase-2 限定范围图编辑<br/>节点启停 · 参数 · 版本 diff · 回放]
    P2 --> P3[phase-3 完整可视化建图<br/>拖拽改拓扑 —— 远期不投]

phase-1 叫"配置管理加运行可观测",不叫"可视化编排"(这期还没有真的图编辑,叫编排名不副实)。它先含一个不依赖任何前置、纯只读的"看得见"切片:读现有轨迹和模型配置,呈现三件事 —— 看各角色当前用什么模型、回放任意一次生成的全轨迹、按 new-api 的 quota 口径对账成本。这件事现在就能做,不改配置、不画图、不依赖线A任何一步,是立刻能给创始人看见的最小兑现。其上再加配置编辑:在 UI 改 prompt 文本、换模型、调阈值,改的是注册表条目,改完落 Git 加审计日志,不是直接热生效。

phase-2 叫"配置编辑 UI 完整化加限定范围的图编辑"。把图编辑排进来:节点启停、边开关、节点的模型 / 工具绑定、配置版本 diff、按轨迹回放。"限定范围"指它编辑的是节点参数和启停,渲染的拓扑来自运行时自报,不是让用户拖拽新增节点改结构。

phase-3 叫"完整可视化建图",是远期。拖拽改拓扑、可视化编 agent flow、跨编排复用,要等真有多编排、多 agent 团队的需求,而且"拓扑配置化"那个深坑(运行时重建图)被填了才上。现在不投。

一条贯穿管理面的约束:管理面对拓扑只渲染框架运行时自报的结构(数据源是运行时轨迹实际走到哪个节点),绝不在管理面这侧另持一份拓扑模型。因为 SAA 是静态 StateGraph、tier2 的 ReAct 没有静态图,两套异构范式要用同一个管理面呈现,只能靠"渲染运行时自报"这个共同口径;将来换框架时,管理面里硬编码的拓扑模型反而会成为阻力。这也对应配置注册表那处推迟:phase-1 只把节点参数外置(用哪个 prompt、哪个模型、什么阈值),拓扑结构本身的配置化推迟 —— 把结构变成运行时配置就是运行时重建图,那是真正的平台工程深坑。

接口对称,内容不对称

控制面和两条生成线的接法,是接口层对称、内容层不对称 —— 这才是"一份管理面管两条异构线"能成立的条件。读配置:两条线的节点和 agent 都按"id 加版本"从注册表加载,接口一样,但 SAA 读 16 个节点的参数、tier2 读 ReAct 的工具集和轮数预算,内容不同。写轨迹:都按统一契约写,公共核心子集对称,扩展段各写各的。过治理门:都先过 D12,但 D12 现在只覆盖 SAA、tier2 要补。配置安全门尤其要分清:tier2 的 eval / 灰度门是 tier2 实验的产物、现在不存在,所以"配置改动要过 eval 门"对 tier2 现在是空头支票 —— 在 tier2 自己的 eval 门建成前,tier2 的配置改动只有"下次任务生效加轨迹留痕"两层保护,没有 eval 门拦截。这不是设计缺陷,是 tier2 成熟度的现实,但要写明,否则会让人以为 tier2 配置改动有它实际没有的安全网。