首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >UIAgent · 流程 + 表单的Agent改造

UIAgent · 流程 + 表单的Agent改造

原创
作者头像
OneCode
发布于 2026-10-10 21:34:15
发布于 2026-10-10 21:34:15
910
举报
文章被收录于专栏:ooderAgentooderAgent

把"流程 + 表单"改造成 UIAgent(财务实战)

表面看是"表单换个地方填",背后是让智能体完整读懂企业的组织关系与内部规则;AI 的聪明从数据与知识中长出——一句话生成流程,一句话转换表单。直接可用的背后,是强大的数据支撑与完整的 agent 平台技术体系。

本文以财务报销单为样本,讲清一件事:传统 IT 里"流程引擎 + 表单"这套资产,怎样被改造成一个UIAgent——既能对话式地生成流程、转换表单,又能对接设计系统全套 UI/UE 组件、读懂组织机构、把组织变成 BPM 审批流、在知识库里完成字段的业务语义设置。前面看到的那一半只是"表单换了地方填";真正的重活在企业组织关系、内部规则与数据知识的沉淀,本文都用本机实测的路径、字段数、探针结果作为证据。

一、先讲业务:这一单要交付什么

需求很朴素:员工在协同办公平台或第三方财务系统里填报销单,数据要进我们的财务系统,按我们的规则审批、付款、归档;报销单里还带着费用明细 / 开票明细,不能丢。

拆成四件可验收的事:

业务诉求

验收口径

本文落点

单据能收

第三方字段 → 自有字段,一一对应且可回写

§3 字段对齐表

页面能填

生成可编辑表单(含明细子表),字段与第三方同源

§4 流水线 · §5 明细

流程能走

提交 → 审批 → 付款 → 归档,节点可编排

§5 审批流程

代码能跑

后端 Schema / Payload 生成并通过编译;产物落库可回读

§4 · §6

真正的麻烦不在"生成",而在两家口径不同:同一个"报销总金额",第三方财务系统叫 submitAmount,协同办公平台的表单里可能写作「报销金额 / 总报销金额 / 申请报销 / 合计 / 金额」,落到我们的页面又是另一个组件。手工对齐一次容易,每换一家重来一次不可接受。这就是整条链路要先解决的头号问题。

二、为什么要用 agent 重做"流程 + 表单"

传统"流程引擎 + 表单"这套资产,在企业里已经跑了十几年。把它们原样搬进新平台,技术上不难;难的是——原样搬,等于把当年的痛点也一起搬了进来。用 UIAgent 重做一遍,不是为了追新,而是传统做法始终没解决两件事,而智能化改造正好补上。

2.1 数据微循环要转起来,打通最后一公里

传统模式下,流程"走完了"不等于数据"通了":报销单在组织系统、发票在影像系统、科目在财务系统、台账在另一套库里,靠人工导出、Excel 对账、邮件催办把数据从一段搬到下一段。流程的"微循环"断在最后一公里——单子批了,但数据没真正汇到一处、没自动核对、没沉淀成可复用的资产。

UIAgent 的做法是把组织关系、内部规则、字段语义先读进统一的数据底座,流程每推进一步,数据就自动归集、自动校验、跨系统对账。数据在流程内部闭环,不再靠人肉接棒,最后一公里由系统自己走完。

2.2 表单要智能起来:一句话填表,发票自动识别,进度自动跟踪

传统表单是"静态格子"——人填、人传、人追进度,填表体验是"人去适配系统"。

UIAgent 让表单能对话:用一句话描述诉求,表单自动生成并预填;发票上传或拍照,字段自动识别并回填;报销走到哪一步、卡在谁手里,系统自动跟踪并提醒。填表从"人适配系统"变成"系统适配人",流程从"人追着跑"变成"系统推着走"。

这两点合起来,就是 UIAgent 相对传统流程 + 表单的本质增量:把"流程跑通"升级为数据自闭环 + 交互智能化。后面几节讲清这套能力在平台里是怎么一步步落地的。

三、字段入知识库:业务语义自动对齐(UIAgent 能力:字段语义对齐)

与其在每个生成器里各写一份映射,不如把它抽成唯一的对齐真相源:

  • 字段对齐表 v1.3.0(2026-10-02 建立,落 knowledge/finance/;实际文件名带第三方标识,此处匿名)
  • knowledge/finance/semantic/ExpenseClaim.naming-map.json(158 行语义命名映射,含角色 / 中文语义 / 第三方路径 / 组件)

表里每一条字段,同时记录三个视角:第三方财务系统的 API 路径、协同办公平台的别名与组件类型、OODUI 组件与键名,并给出对齐状态。

3.1 真实片段(取自生成的 .cls 绑定区,厂商标识已匿名)

代码语言:javascript
复制
role=amount       语义=报销总金额
  财务系统 path : submitAmount
  协同办公 别名 : ["报销金额","总报销金额","申请报销","合计","金额"]  组件 MoneyField
  OODUI         : ood.UI.Input(字段类型 amount,必填)       status=aligned

role=applicant    语义=报销人 / 申请人
  财务系统 path : applicant.name / applicant.userId
  协同办公 别名 : ["报销人","申请人","填报人","报销人员"]      组件 DDContact / InnerContactField
  OODUI         : ood.UI.Input(只读)                       status=aligned

role=expenseType  语义=费用类型
  财务系统 path : feeComponentList[].feeType
  协同办公 别名 : ["费用类型","费用类别","报销类别"]          组件 DDSelect
  OODUI         : ood.UI.Select                            status=aligned_with_gap

注意最后一条的 aligned_with_gap:两家都有,但口径不完全一致(财务系统是费用明细数组里的 feeType,协同办公是单选)。对齐表把这种"能对齐但有缝"的情况显式标注,而不是假装完全一致——后面生成时可以据此决定是否需要人工确认。

图 1 字段对齐:一个 role 同时绑定财务系统路径、协同办公别名与 OODUI 组件

四、表单转 componentTree,由 uiSkills 驱动交互(UIAgent 能力)

改造后的"流程 + 表单"被拆成两条可独立演进的驱动:流程侧由 skillflow(流程定义与编排)驱动,UI 侧由 uiSkills 基于 componentTree(UI 组件树)驱动。本节讲 UI 侧——表单不再手写 HTML,而是转译为一份 componentTree。

componentTree 描述"有哪些字段、什么类型、如何布局"的树:叶子是 Form 的字段组件(输入框、下拉、日期、金额),明细区是 TreeGrid 节点。uiSkills 基于这棵树完成传统表单的全部交互职责,而不依赖静态 HTML:渲染、取字段(extractFieldsFromComponentTree)、自动填(fillFieldsFromComponentTree)、校验(auditComponentTree)。componentTree 替代表单结构承载了用户交互;"填表单"从"人适配静态页面"变成"uiSkills 读组件树、按流程节点动态裁剪可见字段并回填"。

这份组件树有两个入口,收敛到同一份 componentTree:

4.1 入口一:对齐表确定性生成

对齐表确定后,剩下的工作应该是确定性生成,而不是每次靠模型即兴发挥。这条链路已拆成四个可独立跑、可单独验收的工具(_tools/ 下,Node 实现):

环节

工具

产物

实测结果

对齐表 → 可视化表单

formalign2ouc.mjs

ExpenseClaim.ouc.json(11 字段 / 2 分组:基础信息、收款信息)

555 行,bindings 11 条

表单 → 页面描述

ouc2cls.mjs

ooder-domain-finance/src/main/resources/view/ExpenseClaim.cls

绑定随页面走(moduleVar.bindings)

产物落库

vfs-publish.mjs

VFS 落库 + 回读校验

9/9 全绿,产物 7368 → 读回 8277 字符,字段命中 3/3

对齐表 → 后端代码

formalign2java.mjs

ExpenseClaimFormSchema.java+ExpenseClaimPayloadBuilder.java

110 / 63 行,javac编译通过

图 2 表单生成流水线:对齐表一次投入,页面与后端同时产出

生成的 .cls 不是"死页面":字段的第三方绑定写进组件树的 source / bindings,随页面一起流转——页面在哪,映射关系就在哪,不必再去别处查对齐表;source 还记了生成器与对齐表版本,半年后追问"这页面按哪版映射生成"答案就在文件里。

4.2 入口二:现有 HTML 单据经 html2cls 逆向为 componentTree

对齐表路线适合"字段已知、结构标准"的场景。现实中还有另一类需求:业务方手上已经有一份 HTML 单据(或设计师先出 HTML 稿)。这时不必手工建模,走平台的 html2cls:把 HTML 逆向成平台可加载的页面描述 .cls。

按业务各做一张(真实文件,位于 ooder-pro/src/main/resources/static/finance-reimburse/):

业务单据

页面 / 类名

核心字段与明细

员工日常报销单

expense-claim→ExpenseClaim

申请人 / 部门 / 费用类型 / 报销金额 / 事由 / 单据日期;明细:开票明细(开票抬头、含税金额);收款信息 + 附件

差旅报销单

travel-expense→TravelExpense

出差人 / 事由 / 起止日期 / 同行人员;明细:行程明细(日期、出发地、目的地、交通方式、金额);交通/住宿/补贴汇总

采购付款申请单

purchase-payment→PurchasePayment

供应商 / 合同号 / 发票号 / 发票类型;明细:采购明细(物料、数量、单价、金额);付款方式与收款信息

借款申请单

loan-request→LoanRequest

借款人 / 借款金额 / 类型 / 用途 / 预计归还日期 / 还款方式;收款信息与逾期提示

HTML 原版(浏览器直接打开):员工日常报销单 —— 基础信息、开票明细表、收款信息、附件与提交动作。

(图注取自该页面实际渲染文本)

同套做法的另一张业务单据:差旅报销单 —— 行程明细为多行表格,费用分区汇总。

(图注取自该页面实际渲染文本)

转换复用平台既有流程,两步即可接入:

  1. 注册 H5 包:在 Html2ClsPackageRegistry 中按官方扩展点注册 finance-reimburse(区块前缀 fr-,四个页面),页面源码按约定放在 js/pages.js(单 return 字符串,与 guide-training 同风格正则提取);
  2. 运行时注册落库:调既有端点,转换与落盘一次完成。
代码语言:javascript
复制
POST /api/html2cls/runtime/register
     {"projectName":"finance","packageId":"finance-reimburse"}

→ {"success":true,"projectName":"finance","packageId":"finance-reimburse",
    "ok":4,"fail":0,
    "pages":[{"page":"expense-claim","clsName":"ExpenseClaim","status":"OK"},
             {"page":"travel-expense","clsName":"TravelExpense","status":"OK"},
             {"page":"purchase-payment","clsName":"PurchasePayment","status":"OK"},
             {"page":"loan-request","clsName":"LoanRequest","status":"OK"}]}

产物落到工程 FS 真源 workspace/finance/src/main/resources/view/:ExpenseClaim.cls 5.8KB、TravelExpense.cls 5.5KB、PurchasePayment.cls 5.7KB、LoanRequest.cls 5.0KB。

CLS 运行时环境:左为 HTML 原版、右为 .cls 渲染结果,用于核对还原度。截图时页面下拉已能选到本次新增的四个业务单据,渲染日志为

✅ view.ExpenseClaim 渲染完成(链路:.cls JSON → cls.ftl 风格 JS → ood.Class → showModule 入 #gtContent)。

(图注取自该页面实际渲染文本;截图前先断言"渲染完成且页面是本次的报销单",避免又截到演示包)

展示型页面沉淀的,表单控件语义不在其现有覆盖内。下一步:把fr-field / fr-detail

这类表单结构补进外观目录与组件映射,即可把还原度从区块级推到字段级;字段级产物再与 §3 的对齐表对接,两条入口(对齐表 / HTML)就收敛到同一份.cls。

4.3 还原度审计:不靠肉眼,程序化断言

在 CLS 运行时并排渲染(左 HTML 原版、右 .cls 渲染)做断言式审计,程序化读取两侧 DOM:左侧断言文档是否真含报销单文本,右侧断言渲染区是否含业务字段。审计揪出两个真实缺陷并迭代修复——左侧缺 index.html 被兜底成错误页、右侧样式失效与 430px 移动视口错配。

修复后整体断言(落盘判据):rendered=true · isMine=true · leftHasForm=true · rightFields=true

—— 四项全过才允许覆盖截图(12-cls-runtime-render.png),两侧视觉基准一致。

五、读懂组织,转成 BPM 流程(UIAgent 能力:组织 → 流程)

5.1 审批流程

报销单不是静态表单,它要能被审批。平台里这条流程是 expense-approval-flow,在流程工作台里按泳道组织:

图 3 报销审批流程:提交申请 → 审批 → 出纳付款 → 归档

5.2 明细子表:用 1:N 关系承载,而不是塞进一个大字段

「开票明细」这类多行数据,最省事的做法是压成一个文本/JSON 大字段——然后查询、校验、统计全部失效。正确做法是把明细建模成子实体 + 一对多关系:

图 4 明细走 1:N 子实体:表单上是可增删的网格,数据层是真正的子表

落到 OODUI 就是 @Ref(ref = RefType.O2M, view = ViewType.GRID):表单上表现为可增删的明细网格,数据层是真正的子表。明细列名也不是拍脑袋——是从第三方表单样本里真实提取的列(如「开票抬头」「含税金额」),金额类按列名语义判为 DECIMAL(18,2)。

状态说明:主子表在生成链上的两处闸门——①View 层 1:N 模板变量(o2mRefs)此前全仓库无生产者,导致@Ref(O2M)静默不产出;②持久层展开只转主实体一张表,子表整体丢失。这两处已修复并接入(子实体随主表展开为tables=2、relations=1),现有证据为单测级(本机 25 个用例全绿),待一次真实生成流程复核。

六、操作与后台对接:编译·部署·验证(UIAgent 能力:操作 + 数据落库)

生成不是终点,产物要在真实工程里跑起来。这一环在 codeAgent 工作台完成:绑定工程(VFS 根 + FS 工程根,后者是编译/打包必需)后,可以编译当前文件、部署到沙箱、运行、看日志,并直接检测沙箱 harness 状态。

codeAgent 工作台(finance 工程):中栏「工程」页签绑定VFS 根 + FS 工程根(已绑定finance | FS根 ooder-biz-finance),可执行编译 / 部署到沙箱 / 晋级 / 运行 / 查看日志;右栏沙箱页签逐项检测——沙箱基址127.0.0.1:8081可达、令牌有(来源:file:.sandbox-token)、工程绑定是、可部署是、harness 就绪:可编译 / 打包 / 部署 / 运行。

面板是运行时状态而非静态声明:令牌没配时它直接报「未就绪」并给出补齐提示,配好后才变

切到「源码」页签:中栏是已绑定工程的真实源码树(工程根studio\ooder-biz-finace,条目 4:src / main / test / pom.xml),右栏沙箱页签同步显示令牌 有 · 工程绑定 是 · 可部署 是 · harness 就绪 是。这张图同时说明两件事:工程是真工程、真路径(不是演示数据),且"能不能编译/部署/运行"是可查询的运行时事实。(图注取自该页面实际渲染文本)实测判据(上游 G48–G50):设计器探针16/16 全绿;落库通道9/9 全绿,产物 7368 字符写库、引擎读回 8277 字符、字段命中 3/3;后端ExpenseClaimFormSchema.java与ExpenseClaimPayloadBuilder.java经javac编译通过。

七、融入平台:业务架构总览

图 5 业务架构:第三方差异封在 C 层,领域能力在 B 层,平台能力在 A 层复用

八、技术底座:让变化可管控

8.1 A/B/C 分层:把"变化"关进笼子里

层

职责

变化来源与频率

换第三方时改什么

A平台基座

工作台、代码生成、沙箱、VFS、流程引擎、知识库

平台演进(低频)

不改

B领域能力

报销、发票、流水、账龄、税负等业务语义与规则

业务规则调整(中频)

基本不改

C第三方适配

开放接口客户端、表单 Schema 拉取、字段别名归位

第三方接口/表单变更(高频)

只改这一层 + 对齐表

实际效果可以验证:本文的报销单链路里,"协同办公叫报销金额、财务系统叫 submitAmount"这件事只出现在对齐表和 C 层,B 层的报销规则、A 层的生成器都不知道第三方叫什么。再接一家,工作量是"补一列别名 + 一个适配方法",而不是重做页面与代码。

8.2 对话驱动 + 确定性流程:让自然语言需求落在可复现的工程链路上

用自然语言提需求最容易踩的坑是:一句话进去,一团不可复现的东西出来。这里的做法是让对话负责决策,让流程负责执行:

图 6 对话 + 确定性流程:对话决策 → 流程编排 → 生成器产出 → 探针验收

  • 对话面:用自然语言提需求、改字段、增删流程节点——负责"要什么";
  • 流程面:平台把常见做法固化成可复用编排(流程工作台左栏已按类提供:快速构建 5 / 场景编排 6 / 构建流程 2 / CRUD 编排 6 / BPM 流程 2 / 技能编排 1 / 闭环验证 1),设计器选流程、填参数,而不是从零生成;
  • 生成面:落到确定性的生成器(对齐表 → 表单 → 页面 → 代码),产物可复现、可回读校验。

一句话概括:对话负责决策,流程负责编排,生成器负责产出,探针负责验收。这样自然语言交互的随机性被关在决策环节,产出与验收环节仍然是确定性的、可回归的。

8.3 知识库:让字段业务设置成为可复用资产

字段对齐表、语义命名映射不是"一次性配置",而是可版本化的知识资产——它们已经落在知识库目录里:

  • knowledge/finance/semantic/ExpenseClaim.naming-map.json:158 行语义命名映射(role / 中文语义 / 第三方路径 / 组件类型)
  • knowledge/finance/semantic/ExpenseClaim.ouc.json:对齐后的表单知识表示,供后续场景复用

好处是:下一个报销类场景不需要从零对齐——直接命中已有语义映射,只处理差异项(对齐表里 aligned_with_gap / aligned_no_role 的条目就是需要人工拍板的部分)。平台已具备 kb_get 检索能力,知识库从"文档仓库"变成"生成链路的输入"。

九、方法论:可复用的四件事

  1. 先对齐,再生成。把"两家口径不一"这件事集中到一张可评审的表里,后面的工序才可能确定性。
  2. 绑定随产物走。映射关系写进 .cls 的 bindings 并记录对齐表版本,产物自解释、可追溯。
  3. 判据要语义化。"逐字一致"这种判据在真实链路里不可能成立(引擎会转写),应改为字段命中/结构完整等语义判据——否则不是假绿就是假红。
  4. 明细建关系,不塞大字段。1:N 子实体让查询、校验、统计都还能做;代价是生成链路要多打通两处装配,这笔投入值得。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 把"流程 + 表单"改造成 UIAgent(财务实战)
  • 一、先讲业务:这一单要交付什么
  • 二、为什么要用 agent 重做"流程 + 表单"
  • 2.1 数据微循环要转起来,打通最后一公里
  • 2.2 表单要智能起来:一句话填表,发票自动识别,进度自动跟踪
  • 三、字段入知识库:业务语义自动对齐(UIAgent 能力:字段语义对齐)
  • 3.1 真实片段(取自生成的 .cls 绑定区,厂商标识已匿名)
  • 四、表单转 componentTree,由 uiSkills 驱动交互(UIAgent 能力)
  • 4.1 入口一:对齐表确定性生成
  • 4.2 入口二:现有 HTML 单据经 html2cls 逆向为 componentTree
  • 4.3 还原度审计:不靠肉眼,程序化断言
  • 五、读懂组织,转成 BPM 流程(UIAgent 能力:组织 → 流程)
  • 5.1 审批流程
  • 5.2 明细子表:用 1:N 关系承载,而不是塞进一个大字段
  • 六、操作与后台对接:编译·部署·验证(UIAgent 能力:操作 + 数据落库)
  • 七、融入平台:业务架构总览
  • 八、技术底座:让变化可管控
  • 8.1 A/B/C 分层:把"变化"关进笼子里
  • 8.2 对话驱动 + 确定性流程:让自然语言需求落在可复现的工程链路上
  • 8.3 知识库:让字段业务设置成为可复用资产
  • 九、方法论:可复用的四件事
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档