跳到主要内容

前端画布与后端 Runtime 对接

这一页讲的不是“如何再写一个前端编辑器”,而是:

  • 前端画布如何把工作流 schema 交给后端;
  • 后端 runtime 如何执行任务;
  • 两边的数据协议在哪里被适配。

AI4J 当前已经给出两端参考:

  • 后端:ai4j-flowgram-spring-boot-starter
  • 前端:ai4j-flowgram-webapp-demo

1. 整体对接结构

Flowgram 前端画布
-> runtime plugin
-> server client
-> /flowgram/tasks/*
-> FlowGramTaskController
-> FlowGramRuntimeFacade
-> FlowGramRuntimeService
-> node executors / LLM runner

如果你要做自己的 Agentic 工作流平台,这就是当前最重要的一条主链路。


2. 前端不是直接硬调五个接口

ai4j-flowgram-webapp-demo 里,前端运行时是通过 runtime plugin 接进去的。

关键文件:

  • src/plugins/runtime-plugin/create-runtime-plugin.ts
  • src/plugins/runtime-plugin/runtime-service/index.ts
  • src/plugins/runtime-plugin/client/server-client/index.ts

当前 runtime plugin 支持两种模式:

  • browser
  • server

如果你要对接 AI4J 后端 runtime,应使用 server 模式。

在这个模式下:

  • 前端会绑定 WorkflowRuntimeServerClient
  • 通过它调用 /flowgram/tasks/run
  • /flowgram/tasks/validate
  • /flowgram/tasks/{taskId}/report
  • /flowgram/tasks/{taskId}/result
  • /flowgram/tasks/{taskId}/cancel

3. 前端发给后端前会做一次 schema 归一化

这一步很关键。

关键文件:

  • ai4j-flowgram-webapp-demo/src/utils/backend-workflow.ts

它当前做了几件事:

  • 去掉只用于画布展示的节点类型,例如 CommentGroupBlockStartBlockEnd
  • 把前端节点类型映射成后端 runtime 识别的类型
  • 清理无效边
  • 处理 loop 节点的输入补齐

当前可以直接确认的类型映射包括:

  • start -> START
  • end -> END
  • llm -> LLM
  • http -> HTTP
  • code -> CODE
  • condition -> CONDITION
  • loop -> LOOP
  • variable -> VARIABLE
  • tool -> TOOL
  • knowledge -> KNOWLEDGE

这意味着:

  • 前端节点 type 不一定等于后端最终执行 type
  • 你加自定义节点时,前后端都要同步考虑

4. 后端执行链路怎么接

后端入口主要是三层:

4.1 Controller

  • FlowGramTaskController

负责暴露 REST API。

4.2 Facade

  • FlowGramRuntimeFacade

负责:

  • 请求转运行输入
  • caller 解析
  • 权限检查
  • task store 写入
  • 结果与报告输出

4.3 Runtime

  • FlowGramRuntimeService

负责:

  • 校验任务
  • 执行节点图
  • 聚合任务结果
  • 返回 report / result

5. 前端测试运行的真实调用方式

WorkflowRuntimeService 里,前端当前流程是:

  1. 先做本地表单校验
  2. /tasks/validate
  3. /tasks/run
  4. 按固定轮询间隔拉 /tasks/{taskId}/report
  5. 最后拉 /tasks/{taskId}/result

这说明当前平台形态是:

  • 异步任务执行
  • 前端轮询 report / result
  • 不是单次同步返回全部结果

如果你后面要接企业平台,这个轮询模型需要在产品层面先接受。


6. 前端现在应该消费哪一层 trace

当前后端已经不只是返回 workflow/nodes/result 这些静态结构。

ai4j.flowgram.trace-enabled=true 时:

  • /tasks/{taskId}/report
  • /tasks/{taskId}/result

都会带一个 trace 字段。

这层数据来自:

  • FlowGramRuntimeEvent
  • FlowGramRuntimeTraceCollector
  • FlowGramTraceView

它的定位是:

  • 给前端调试面板
  • 给节点时间线
  • 给任务详情页

也就是“前端直接渲染”的后端 projection。

6.1 trace 字段的结构

{
"taskId": "task-123",
"status": "success",
"startedAt": 1710000000000,
"endedAt": 1710000005231,
"summary": {
"durationMillis": 5231,
"eventCount": 4,
"nodeCount": 1,
"completedNodeCount": 1,
"failedNodeCount": 0,
"metrics": {
"promptTokens": 159,
"completionTokens": 236,
"totalTokens": 395
}
},
"events": [
{ "type": "TASK_STARTED", "timestamp": 1710000000000, "status": "processing" },
{ "type": "NODE_STARTED", "timestamp": 1710000000100, "nodeId": "llm_0", "status": "processing" },
{ "type": "NODE_FINISHED", "timestamp": 1710000004200, "nodeId": "llm_0", "status": "success" },
{ "type": "TASK_FINISHED", "timestamp": 1710000005231, "status": "success" }
],
"nodes": {
"llm_0": {
"nodeId": "llm_0",
"status": "success",
"terminated": true,
"startedAt": 1710000000100,
"endedAt": 1710000004200,
"durationMillis": 4100,
"eventCount": 2,
"metrics": {
"promptTokens": 159,
"completionTokens": 236,
"totalTokens": 395
}
}
}
}

前端一般可以这样消费:

  • 顶部任务状态
    • trace.status/startedAt/endedAt
  • 顶部总指标
    • trace.summary.metrics
  • 节点执行高亮
    • trace.nodes[nodeId].status
  • 时间线面板
    • 直接渲染 trace.events
  • 节点失败详情
    • trace.nodes[nodeId].error
  • 节点级 token / 成本
    • trace.nodes[nodeId].metrics
  • 节点原始输出区
    • 如果你还要展示 report 里的节点输出,可直接读 workflow.nodes[nodeId].outputs.metrics

6.2 为什么不直接读 OpenTelemetry

因为两层目标不一样:

  • OTel 面向后端 observability 平台
  • FlowGramTraceView 面向前端画布运行时

推荐模式是:

  • 后端可以继续往 OTel 导出
  • 前端只消费 trace projection

这样前后端的职责边界最清晰。

还要注意一件事:

  • 新版后端会在 report/result 返回前自动把 rawResponse.usage 归一化成 outputs.metrics
  • 同时补齐 trace.summary.metricstrace.nodes[nodeId].metrics

所以前端不应该再把“自己解析 provider 原始 usage”当成默认路径。只有在你明确兼容旧后端时,才需要做 client-side fallback。


7. 如何配置后端地址

WorkflowRuntimeServerClient 会把请求发到:

  • 当前页面相对路径,或
  • protocol + domain + port

也就是说,前端可以:

  • 同域部署,直接走相对路径
  • 前后端分离部署,显式指定 domain / port

如果你做正式平台,建议把:

  • API host
  • 协议
  • 端口
  • 反向代理规则

做成独立环境配置,而不是写死在 demo 里。


8. 安全与任务归属怎么接

后端 starter 当前已经预留了几层平台化接口:

  • FlowGramCallerResolver
  • FlowGramAccessChecker
  • FlowGramTaskOwnershipStrategy
  • FlowGramTaskStore

默认行为是:

  • caller 可匿名
  • access checker 默认全部放行
  • task store 默认内存版

这说明:

  • demo 可以直接跑
  • 真正的平台接入必须替换这几层

尤其是:

  • 多租户
  • 任务归属
  • 权限控制
  • 持久化任务查询

不要直接拿默认实现上线。


9. 推荐接入顺序

  1. 先用 ai4j-flowgram-demo 跑通后端 API
  2. 再用 ai4j-flowgram-webapp-demo 跑通 server 模式
  3. 确认 schema 归一化后的节点类型与后端一致
  4. 先把 trace 面板接上,确认节点时间线与状态可信
  5. 再补 caller、auth、task store、权限
  6. 最后再加你的自定义节点与业务面板

10. 继续阅读

  1. 前端自定义节点开发
  2. 前端工作流如何在后端执行
  3. Flowgram API 与运行时
  4. 自定义节点扩展
  5. Agent、Tool、知识库与 MCP 接入