flow - 图的加载与文本转换(及例外)
2025年12月5日 上午9:43:47
1、编排格式支持
- yaml [推荐]
- json
或者其它自定义格式,最终能转换成 Graph 对象即可。
2、加载方式
通过 url 加载编排文件
Graph graph = Graph.parseByUri("classpath:flow/demo1.yml");
Graph graph = Graph.parseByUri("classpath:flow/demo1.json");
//flowEngine.load(graph); //加载到引擎
//flowEngine.eval(graph); //或者,直接执行
通过 text 加载编排配置(可以存入数据库,再加载出来)
String text = flowService.get("demo1");
Graph graph = Graph.parseByText(text); //会自动识别 yaml, json
//flowEngine.load(graph); //加载到引擎
//flowEngine.eval(graph); //或者,直接执行
3、文本与实体相互转换(方便持久化管理)
文本格式(yml、json)可以转换为 Graph。用代码动态构建的 Graph 对象,也可以转为 json 格式用于持久化。
//从文本加载
Graph graph = Graph.parseByText(txt);
//转为文本
String json = graph.toJson();
String yaml = graph.toYaml();
示例:
Graph graph = Graph.create("d2", decl -> {
decl.addStart("s").title("发起人").metaPut("role", "employee").metaPut("form", "form1").linkAdd("n1");
decl.addActivity("n1").title("主管批").metaPut("role", "tl").linkAdd("g1");
decl.addExclusive("g1")
.linkAdd("g2", l -> l.title("3天以下"))
.linkAdd("n2", l -> l.title("3天以上").condition("day>=3"));
decl.addActivity("n2").title("部门经理批").metaPut("role", "dm").linkAdd("g2");
decl.addExclusive("g2")
.linkAdd("e", l -> l.title("7天以下"))
.linkAdd("n3", l -> l.title("7天以上").condition("day>=7"));
decl.addActivity("n3").title("副总批").metaPut("role", "vp").linkAdd("e");
decl.addEnd("e");
});
//转为 json ,并持久化
String json = graph.toJson();
//攻取 json,并加载
Graph graph = Graph.parseByText(json);
4、全部硬编码的方式不支持转换(也不方便持久化管理)
什么是全部硬编码的方式?用 Java 原生构建图时,如果任务、条件都用 Java 组件(或 lambda 表达式),则无法转换为文本。
示例(task 用了 Java 组件,when 用了 lambda):
Graph graph = Graph.create("demo2", decl -> {
decl.addStart("start").linkAdd("agent");
decl.addActivity("agent").task(new AiNodeAgent(chatModel)).linkAdd("review");
decl.addExclusive("review").task(new AiNodeReview())
.linkAdd("final_approval", lc -> lc.when(fc -> "APPROVED".equals(fc.get("review_status"))))
.linkAdd("final_failure", lc -> lc.when(fc -> "REJECTED".equals(fc.get("review_status")) && fc.<AtomicInteger>getAs("revision_count").get() >= MAX_REVISIONS))
.linkAdd("agent", lc -> lc.when(fc -> "REJECTED".equals(fc.get("review_status")) && fc.<AtomicInteger>getAs("revision_count").get() < MAX_REVISIONS))
.linkAdd("review");
decl.addActivity("final_approval").task(new AiNodeFinalApproval()).linkAdd("end");
decl.addActivity("final_failure").task(new AiNodeFinalFailure()).linkAdd("end");
decl.addEnd("end");
});
全部硬编码的方式,不需要容器适配和脚本支持。比较适合一些特殊的需求。