工作流引擎
概述
工作流模块提供可视化的 AI 流程编排能力。包含两部分核心功能:
- 前端设计器:基于 Vue Flow 的可视化编排组件
- 后端执行引擎:基于 langgraph4j 的 StateGraph 执行引擎
节点类型
| 节点类型 | type 枚举值 | 说明 |
|---|---|---|
| Start | Start | 工作流入口,定义输入参数 |
| End | End | 工作流结束,定义输出结果 |
| LLM | LLM | 调用大语言模型 |
| Knowledge | Knowledge | 知识库检索 |
| Tool | Tool | 调用工具 |
| Condition | Condition | 条件分支判断 |
| Aggregator | Aggregator | 变量聚合 |
| Batch | Batch | 批处理并行执行 |
前端设计器
组件定位
Workflow 组件位于 agent-plus-admin-front/src/components/AgentPlusFlow/workflow/,是一个纯 UI 编排组件,不直接调用 HTTP 接口,所有业务操作通过事件交由宿主页面实现。
最简使用
vue
<template>
<div class="aiflow-container">
<div class="design-header">
<span>{{ flowName }}</span>
<!-- Workflow 的发布控制区通过 Teleport 渲染到这里 -->
<div id="workflow-publish-controls"></div>
</div>
<div class="design-body">
<Workflow
ref="workflowRef"
v-if="ready"
v-model:workflow="workflowData"
:workflow-config="workflowConfig"
publish-controls-target="#workflow-publish-controls"
:type="flowType === 2 ? 'chatflow' : 'workflow'"
:flow-id="flowId"
:version-id="versionId"
@publish="handlePublish"
@save-draft="handleSaveDraft"
@save-env-vars="handleSaveEnvVars"
@run-test="handleRunTest"
@import="handleImport"
@export="handleExport"
@view-history="handleViewHistory"
/>
</div>
</div>
</template>
<script setup>
import Workflow from '@/components/AgentPlusFlow/workflow'
import { newWorkflow, newChatworkflow } from '@/components/AgentPlusFlow/workflow/mocks/workflowMockAPI.js'
import { ref, onMounted, nextTick } from 'vue'
// 路由参数:flowId=流程ID type=流程类型(1=工作流 2=对话流)
const flowId = ref(route.query.flowId);
const flowType = ref(route.query.type ? Number(route.query.type) : 1);
const flowName = ref('');
const workflowRef = ref(null);
const ready = ref(false); // 数据加载完成后再渲染
const versionId = ref(null); // 当前编辑的版本ID
// 按流程类型返回初始化模板
function getInitWorkflow() {
const template = flowType.value === 2 ? newChatworkflow : newWorkflow;
return JSON.parse(JSON.stringify(template));
}
const workflowData = ref(getInitWorkflow());
const workflowConfig = ref({});
onMounted(async () => {
await loadData();
});
async function loadData() {
ready.value = false;
// 加载流程详情...
await nextTick();
ready.value = true;
}
// 存草稿
const handleSaveDraft = async (data, resolve, reject) => {
try {
await api.saveWorkflow({
id: versionId.value,
flowId: flowId.value,
workflow: data
});
resolve();
} catch (e) {
reject(e);
}
}
// 保存环境变量
const handleSaveEnvVars = async (envVars, resolve, reject) => {
try {
await api.updateConfig({
id: versionId.value,
config: { envVars }
});
resolve();
} catch (e) {
reject(e);
}
}
// 试运行:mode=flow 运行整个流程;mode=node 单节点运行
const handleRunTest = async (params, resolve, reject) => {
try {
const res = params.mode === 'flow'
? await api.runFlow({ versionId, flowId, inputs: params.data })
: await api.runNode({ versionId, flowId, nodeId: params.nodeId, inputs: params.data });
resolve(res.data);
} catch (e) {
reject(e);
}
}
// 发布
const handlePublish = async (data, resolve, reject) => {
try {
await api.publish(versionId.value);
resolve();
} catch (e) {
reject(e);
}
}
// 导入
const handleImport = async (resolve) => {
// 选择文件并读取...
resolve();
}
// 导出
const handleExport = (data, resolve) => {
// 下载 JSON 文件...
resolve();
}
// 查看运行历史
const handleViewHistory = (resolve) => {
// 打开历史抽屉...
resolve();
}
</script>完整实现详见源码:
agent-plus-admin-front/src/views/aiflow/workflow/design.vue
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| workflow | Object | - | 工作流数据,支持 v-model |
| workflowConfig | Object | {} | 配置(modelList、knowledgeList、envVars 等) |
| type | String | 'workflow' | 流程类型:workflow/chatflow |
| flowId | String/Number | - | 流程ID |
| versionId | String/Number | - | 当前编辑的版本ID |
| saveDraftInterval | Number | 60 | 自动存草稿间隔(秒) |
| publishControlsTarget | String | null | 发布控制区 Teleport 目标 |
Methods
通过 ref 可以调用组件暴露的方法:
| 方法名 | 说明 |
|---|---|
| locateNode(nodeId) | 定位到指定的画布节点 |
Events
所有业务事件的监听函数签名统一为 (payload, resolve, reject) => void,必须调用 resolve 或 reject,否则内部 loading 状态无法复位。
| 事件 | 说明 |
|---|---|
| publish | 点击「发布」时触发 |
| save-draft | 点击「存草稿」或自动保存时触发 |
| save-env-vars | 环境变量保存时触发 |
| run-test | 点击「测试运行」时触发。params.mode 为 'flow' 时是运行整个流程,为 'node' 时是单节点运行 |
| import | 点击「导入」时触发 |
| export | 点击「导出」时触发 |
| view-history | 点击「运行历史」时触发 |
数据结构
javascript
{
nodes: [
{
id: 'start',
type: 'Start',
position: { x, y },
data: { ... }
}
],
edges: [
{
id: 'e-start-condition',
type: 'default',
source: 'start',
target: 'condition-1'
}
],
viewport: { x, y, zoom }
}相关文件
design.vue- 集成示例(宿主页面)workflow/index.vue- 组件主入口store/modules/workflow.js- Pinia 状态管理utils/workflowSchema.js- 节点默认数据与输出变量定义mocks/workflowMockAPI.js- Mock 数据,包含newWorkflow(工作流模板)和newChatworkflow(对话流模板)utils/workflowFileIO.js- 工作流文件导入导出工具
后端执行引擎
核心类
WorkflowEngine
执行引擎门面,Builder 模式构造:
java
WorkflowEngine engine = WorkflowEngine.builder()
.chatModelProvider(chatModelProvider)
.knowledgeRetriever(knowledgeRetriever)
.toolRegistry(toolRegistry)
.build();
WorkflowExecutionResult result = engine.execute(
WorkflowExecuteRequest.simple(workflow, config, inputs, "流程名称"));ExecutionContext
执行上下文,包含:
runId- 执行 ID(即 OTel traceId)globalInputs- 全局输入envVars- 环境变量nodeOutputs- 各节点输出nodeStatus- 各节点状态nodeTimings- 各节点执行时间
节点执行器
| 节点类型 | 执行器类 | 说明 |
|---|---|---|
| Start | StartNodeExecutor | 装配全局输入 |
| End | EndNodeExecutor | 收集输出结果 |
| LLM | LLMNodeExecutor | 调用 ChatModel,支持工具调用循环 |
| Knowledge | KnowledgeNodeExecutor | 调用 KnowledgeRetriever |
| Tool | ToolNodeExecutor | 调用 ToolRegistry |
| Condition | ConditionNodeExecutor | 条件判断,chosenBranch 用于分支路由 |
| Aggregator | AggregatorNodeExecutor | 变量聚合 |
| Batch | BatchNodeExecutor | 批处理,并行执行子图 |
参数解析
resolveInputs(List<InputParam>, ctx)- 结构化解析输入参数renderTemplate(String template, ctx)- 字符串模板渲染,支持{{nodeId.paramName}}占位
条件分支
支持的运算符:
| 运算符 | 说明 |
|---|---|
| == / eq | 等于 |
| != / ne | 不等于 |
| > / gt | 大于 |
| >= / gte | 大于等于 |
| < / lt | 小于 |
| <= / lte | 小于等于 |
| contains | 包含 |
| not_contains | 不包含 |
| len_gt | 长度大于 |
| len_gte | 长度大于等于 |
| len_lt | 长度小于 |
| len_lte | 长度小于等于 |
| is_empty | 为空 |
| not_empty | 不为空 |
使用说明
1. 创建工作流
进入 AI 工作流 → 工作流,点击「新增」:
- 填写工作流名称和描述
- 选择流程类型:workflow/chatflow
- 点击「确定」
2. 设计流程
点击「设计」进入编排界面:
- 从左侧节点库拖拽节点到画布
- 连接节点
- 点击节点在右侧面板配置参数
- 使用「自动布局」一键整理
- 点击「试运行」测试
- 点击「存草稿」或「发布」
3. 变量引用
在配置中引用其他节点的输出:
{{nodeId.paramName}}特殊变量:
{{env.varName}}- 环境变量{{inputs.paramName}}/{{start.paramName}}- 全局输入
核心表
| 表名 | 说明 |
|---|---|
| ai_flow | 工作流定义 |
| ai_flow_version | 工作流版本 |
| ai_flow_runtime | 工作流执行记录 |
| ai_flow_runtime_node | 工作流节点执行记录 |
自动装配
只要容器中存在 ChatModelProvider Bean,WorkflowEngine 会自动创建。可选注入:
KnowledgeRetriever- 知识库检索ToolRegistry+ToolQueryProvider- 工具注册与查询HistoryMessageProvider- 会话历史
扩展点
| 扩展点 | 说明 |
|---|---|
ChatModelProvider | 必须实现,对接模型元数据 |
KnowledgeRetriever | 使用 Knowledge 节点时实现 |
ToolRegistry | 使用 Tool 节点或 LLM 工具调用时实现 |
NodeExecutor | 需要新增节点类型时实现 |
SpanExporter | 需要 span 落库时 |