Java EE 项目的 Agent-Native 改造:一份纯理论架构设计
引子
上一篇《无头软件:软件正在丢掉它的”头”,而 agent 成了那颗通用的头》给出的判断是:软件正在从”以 UI 为人机接口”进化为”以能力契约为接口、以 agent 为可替换的通用头”。
那么问题来了——如果你手上正好有一个典型的 Java EE 项目(Servlet / SSM / Spring MVC + JSP/Vue + RBAC + 工作流 + 报表 + 大量 CRUD),它到底该怎么设计?
这篇只谈理论:不给代码,只给参考架构、元模型、法则、演进模式与判据。
思路按”先分析、再设计”两步走。
第一部分 · 先分析:Java EE 的”头”为什么是焊死的
1.1 典型结构解剖
一个 Java EE 类项目,几乎都能拆成这条纵向调用链:
浏览器页面(JSP/Vue)
↓ HTTP + Cookie/Session
Controller (Servlet / @Controller) ← 一个方法 ≈ 一个页面动作
↓
Service (业务逻辑,事务边界) ← 真正的业务资产在这里
↓
DAO / Mapper (MyBatis / JPA)
↓
DB / 中间件 / 工作流引擎(Flowable 等)
横向还挂着:权限(Realm/RBAC)、会话(HttpSession)、表单校验(Bean Validation)、视图渲染、报表导出、审批流。
1.2 关键判断:耦合点在哪里
这类系统”不能被 agent 直接用”,不是因为没接口,而是因为它有三处焊在”人—页面”上的耦合:
| 耦合 | 表现 | 为什么挡住 agent |
|---|---|---|
| 会话耦合 | 状态存在 HttpSession / Cookie 里 | agent 没有浏览器会话;状态必须显式化 |
| 权限耦合 | 权限绑在”登录用户 + 角色”上,粒度到菜单/页面 | agent 是代别人操作,需要”委托身份”,不是登录态 |
| 展示耦合 | Controller 方法 ≈ 页面按钮;返回值 ≈ 页面字段 | 粒度是”给人填表单”,不是”业务意图” |
1.3 一个反直觉的好消息
- Service 层是资产,不是负债。 它已经封装了业务规则和事务边界——这恰恰是 agent 最需要的东西。
- Strangler Fig(绞杀榕)模式已经成熟:遗留系统改造的通行做法是”在旁边长新枝、逐步替换”,不推倒重来。agent-native 改造可以完全复用这个思路。
- Java 生态已经就位:Spring AI MCP Server 已支持多种传输模式;Spring AI Alibaba / JManus 提供 PLAN-ACT 多智能体与企业级运行时。技术上不再是空白。
所以:设计的核心任务,是把这条 Service 骨架从”人—页面”的耦合里解出来、重新命名、重新治理——而不是重写业务逻辑。
第二部分 · 设计的第一性原理
从”页面即产品”转到”能力即产品”,有五条必须内化的原理:
P1 · 意图优先(Intent-First)
接口粒度 = 一个业务动作,而不是一个页面字段。create_order 是能力,setOrderField(3, x) 不是。
P2 · 契约即产品(Contract-as-Product) 能力的描述文本(tool description)就是它的”UI 文案”,是模型决定用不用的唯一依据。写不好文档 = 产品不可用。
P3 · 上下文显式化(Explicit Context) agent 没有隐式会话,所有状态必须显式放进参数或上下文对象——这是 Java EE 改造里最容易被低估的一条。
P4 · 可确认、可撤销(Confirmable & Reversible) 任何有副作用的操作,都要能”先给计划、再确认、再执行”;写操作要可回滚或可补偿。
P5 · 最小能力暴露(Least Capability) 工具越少越好。业界实践(如 Stripe Minions 单流程只开 15 个工具)表明:工具越多,agent 的选择困惑率越高。用组合解决复杂度,而不是用堆砌。
第三部分 · 目标参考架构:ANLRA
ANLRA = Agent-Native Layered Reference Architecture。
3.1 关键构件(理论定义)
| 构件 | 职责 | 理论要点 |
|---|---|---|
| 能力注册表 (Capability Registry) | 登记所有可被 agent 调用的能力 | 单一事实来源;UI 与 agent 共用同一份 |
| 能力卡片 (Capability Card) | 每个能力的元数据契约 | 见第四部分元模型 |
| 契约编译器 (Contract Compiler) | OpenAPI/注解 → MCP Tool 定义 | 双向一致,不手写两套 |
| 治理总线 (Trust Fabric) | 身份、授权、审批、幂等、审计 | 不可绕过;所有能力调用必经 |
| 上下文对象 (Invocation Context) | 承载显式状态 | 取代 HttpSession |
| 双模输出器 (Dual Renderer) | 同一结果给机器与人两种形态 | JSON + 摘要 |
3.2 与经典 Java EE 构件的映射
| Java EE 旧构件 | Agent-Native 新构件 | 关系 |
|---|---|---|
@Controller 页面动作 | 能力 (Capability) | 粒度从”页面”升到”业务意图” |
HttpSession | Invocation Context / Token | 从隐式变显式 |
| Realm / 角色菜单权限 | 权限引擎 (scope + 委托) | 从静态角色到上下文感知 |
| JSP/Vue 页面 | L4 可替换壳 | 保留必要专业页,其余可退场 |
| Service 方法 | 能力的实现体 | 基本原样保留,包装而非重写 |
| Bean Validation | 输入 schema 校验 | 复用,同时暴露给模型 |
| 工作流引擎节点 | 可编排能力 | 节点即能力,流程即编排 |
这张表是全文最重要的一页。它说明改造不是”重写系统”,而是”给已有 Service 资产加一层能力外壳 + 一层治理外壳”。
第四部分 · 能力建模理论
4.1 能力卡片元模型
理论定义:一个能力 = 一个业务意图 + 一组显式契约。
CapabilityCard {
// —— 标识 ——
name : 动词_名词 (如 refund_order)
description : 何时用 / 何时别用 / 前置条件 ← 模型选型的唯一依据
version : 语义化版本
// —— 契约 ——
inputSchema : JSON Schema(由 Bean Validation 推导)
outputSchema : 结构化;同时产出 humanSummary
errorSemantics: 可自我纠正的错误(含"允许范围/如何重试")
// —— 治理 ——
requiredScope : 最小权限(不是角色!)
sideEffect : none | reversible | irreversible
idempotent : 是否幂等 / 幂等键来源
confirmation : 是否需要计划→确认→执行
dataClass : 涉及的数据分级(PII/敏感)
// —— 运行 ——
rateLimit / budget / timeout
}
4.2 能力粒度法则
- 一个能力 = 一个业务语义动作(Business Semantic Action, BSA)。
- 判据:这个能力能否被一句话说清、被一个人批准?
- 能 → 粒度合适。
- 要解释三层才懂 → 太细(像 CRUD)。
- 一次包含多个可独立批准的决策 → 太粗(应拆分)。
- 查询能力可以”宽”,写能力必须”窄”。
4.3 组合优于堆砌
- 目标:暴露给单个 agent 的能力数量受控(经验值:单个工作流十几到几十个量级)。
- 超出时,用”委托/组合”而不是”全量暴露”:让一个能力内部完成多步,而不是让模型去串 10 个原子工具。
- 这与 Java EE 的”服务编排”传统完全一致——只是执行者从代码变成了模型。
第五部分 · 治理与信任理论(Trust Fabric)
这是 Java EE 项目最需要新建、最容易做错的一层。 三条业界血泪教训:
❌ 直接把管理员 API Key 配给 agent —— agent 权重里没有”谨慎使用权限”的约束,它会为了”整理季度数据”高高兴兴调用删除接口。 ❌ 权限基于静态 RBAC,不绑定任务与数据范围 —— 客服 agent 能查所有用户订单。 ❌ 审计断层 —— 出事之后分不清是模型幻觉还是人为指令。
5.1 身份模型:三方委托链
真实用户 (Principal)
↓ 授权(可撤销 / 可过期 / 限 scope)
Agent 身份 (Actor, 代表用户)
↓ 携带委托凭证,调用具体能力
能力 (Capability)
理论要求:永远不共享登录态,必须走”代表用户”的委托(on-behalf-of);委托可撤销、可过期、可限定数据范围;全程留痕。
5.2 权限引擎:从静态 RBAC 到上下文感知
| 维度 | 传统 RBAC | Agent-Native 需要 |
|---|---|---|
| 绑定对象 | 角色 | 角色 + 任务 + 数据范围 |
| 生效期 | 长期 | 运行时收敛 + 自动过期 |
| 粒度 | 菜单/页面 | 能力 + scope |
| 撤销 | 手工 | 自动回收,无持久后门 |
5.3 危险等级与审批环
| 等级 | 例子 | 策略 |
|---|---|---|
| L0 只读 | 查询订单、报表 | 可直接执行 |
| L1 可逆写 | 改状态、发草稿 | 可执行 + 留痕 |
| L2 不可逆写 | 付款、删除、对外发布 | 计划 → 确认 → 执行,逐步授权 |
5.4 幂等、事务与补偿
- agent 会重试、并发、重放,这是硬约束。
- 原则:一个能力 = 一个事务边界;跨能力的长流程用 Saga / 补偿。
- 所有写能力需要幂等键。
5.5 审计与防注入
- 不只记录”调了什么”,要记录**“为什么调”**:模型意图、上下文、工具结果——让操作可回放、可定责。
- 工具返回值是数据,不是指令。 系统返回内容里带”可执行指引”是注入重灾区。
- 数据分级 + 脱敏:PII 不进日志明文,跨能力传递做最小化。
第六部分 · 演进理论:三层迁移模型
不是实施计划,是结构分层分析。
模式 A · 能力网关(旁路封装)
- 改什么:只在系统外侧加一层网关 + 治理,内核零改动。
- 收益:最低风险、最快见效;本质是 Strangler Fig 的”agent 版新枝”。
- 风险:网关可能退化成”又一个集成层”;粒度沿用旧接口,可能偏细。
- 适用:绝大多数遗留系统先到这里就够用。
- 退出判据:当”每个新功能都要绕过旧接口”时,说明该进模式 B。
模式 B · 能力化重构(抽 Capability 层)
- 改什么:把 Controller 里的动作上提为独立能力层;UI 与 agent 共用这一层。
- 收益:消除”页面动作”与”能力”的割裂;一处定义、两处消费。
- 风险:要动 Controller 结构;要防”能力层又变成新的贫血壳”。
- 退出判据:当 UI 已不再是核心交付物、能力契约本身成为产品时,进模式 C。
模式 C · 原生(UI 降为可选视图)
- 改什么:产品定义 = 能力契约;UI 只是 L4 的一个可选实现。
- 收益:真正无头;能进入 agent 生态分发(连接器市场 / 智能体广场)。
- 风险:可发现性、信任、B 端合规。
重要:不是每个项目都要走到 C。 多数 Java EE 项目的合理终点是 A 或 B。强行冲 C 而不解决”可发现性 + 信任”,会得到一个”没人用也没有 agent 用”的系统。
第七部分 · Java EE 特有的硬问题
| # | 硬问题 | 理论解法 |
|---|---|---|
| 1 | HttpSession 隐式状态 | 显式 Invocation Context;会话状态外置 |
| 2 | 事务边界绑在 Service 方法 | 能力 = 事务;跨能力用 Saga + 补偿 |
| 3 | 表单校验与业务校验混在一起 | 拆成 schema 校验(暴露给模型)+ 领域校验(内核) |
| 4 | 贫血模型 / 事务脚本 | 能力层需要”语义”,倒逼领域模型清晰化 |
| 5 | 报表/导出是给人看的 | 双模输出:结构化数据 + 人类摘要 |
| 6 | 工作流引擎(Flowable 等) | 流程节点能力化,人审节点 = 审批环 |
| 7 | 权限散落在注解与菜单 | 收敛到治理总线的权限引擎 |
| 8 | 返回值含”操作指引”文本 | 数据/指令分离,防止注入 |
| 9 | 审计只有操作日志 | 升级为”决策轨迹”,可回放 |
| 10 | 老代码无契约 | 用契约编译器从注解/接口反向生成契约 |
第八部分 · 度量要换一套
| 旧指标(页面时代) | 新指标(能力时代) |
|---|---|
| 页面 PV / DAU | 任务成功率 |
| 按钮点击埋点 | 自主完成率 |
| 表单转化率 | 智效比(产出 ÷ 成本) |
| 接口 QPS | 每任务成本 / 步数 |
| 崩溃率 | 误操作率 / 撤销率 |
当”使用者”从人变成 agent,衡量软件价值的单位就从”访问”变成了”任务”。
第九部分 · 反模式清单(设计评审逐条自检)
- ❌ 把每个页面做成一个 tool(粒度错,模型无法组合)。
- ❌ 直接暴露 CRUD 原子操作(把复杂度推给模型)。
- ❌ 给 agent 超级 token / 管理员 Key。
- ❌ 无幂等(agent 重试 = 重复下单)。
- ❌ 工具返回值里带指令(注入通道)。
- ❌ 一次性暴露全部能力(该组合的没组合)。
- ❌ 忽略可发现性(agent 不知道你能干什么)。
- ❌ 审计只记操作不记决策(出事无法定责)。
- ❌ UI 与能力各写一套(必然漂移,契约失效)。
- ❌ 为”无头”而无头(该保留的专业前端被砍掉)。
第十部分 · 边界:什么不该做
- 专业前端不要砍:强可视化、高信任合规、多人实时协作、性能敏感场景。
- 不可逆的高危能力默认不自动执行:必须人工确认。
- 数据分级不清的能力不要暴露。
- 没有治理总线就不要开写能力——先建 Trust Fabric,再放权限。
- 别把”无头”当 KPI:目标是”任务能被完成”,不是”页面数量归零”。
结论:一句话设计哲学
Java EE 项目不需要”重写”,它已经有 Service 这条能力骨架。 设计要做的是:把骨架从”人—页面”的耦合里解出来,包一层能力契约(L1),再包一层治理总线(L2),让 UI 变成可替换的壳。 改造的难点不在技术,而在能力粒度与信任模型这两件事的取舍。
附录 · 理论与事实锚点
- 路线之争已见分晓的方向:豆包手机《屏幕自动化操作声明协议》(SAEP) 公示后,150+ 款 App 拒绝 GUI 屏幕自动化(腾讯系 65 款、阿里系几乎全量),而行业同时推 MCP / A2A / CLI 三条”接口化”路线——应用方明确选”接口”,不选”看屏点击”。
- Java 生态已就绪:Spring AI MCP Server、Spring AI Alibaba / JManus(PLAN-ACT、企业级运行时)。
- 遗留系统改造方法论:Strangler Fig(绞杀榕)渐进式替换,不自上而下的重写。
- Agent 治理实践共识:最小权限、上下文感知权限引擎、运行时收敛与自动过期、数据分级与脱敏、决策级审计。
- 工具数量克制:Stripe Minions 单流程仅 15 个工具。
说明:第一至十部分是理论设计,属于判断;附录为可查证事实。两者请分开信任。
延伸阅读
- 《无头软件:软件正在丢掉它的”头”,而 agent 成了那颗通用的头》——本文的上一环:为什么这轮趋势成立,以及哪些前端会消失、哪些不会。
📱 手机扫码阅读本文
