### 1、编排格式支持

* yaml [推荐]
* json

或者其它自定义格式，最终能转换成 Graph 对象即可。

### 2、加载方式

通过 url 加载编排文件

```java
Graph graph = Graph.fromUri("classpath:flow/demo1.yml");
Graph graph = Graph.fromUri("classpath:flow/demo1.json");

//flowEngine.load(graph); //加载到引擎
//flowEngine.eval(graph); //或者，直接执行
```

通过 text 加载编排配置（可以存入数据库，再加载出来）

```java
String text = flowService.get("demo1");
Graph graph = Graph.fromText(text); //会自动识别 yaml, json

//flowEngine.load(graph); //加载到引擎
//flowEngine.eval(graph); //或者，直接执行
```


### 3、文本与实体相互转换（方便持久化管理）

文本格式（yml、json）可以转换为 Graph。用代码动态构建的 Graph 对象，也可以转为 json 格式用于持久化。

```java
//从文本加载
Graph graph =  Graph.fromText(txt); 

//转为文本
String json  = graph.toJson();
String yaml  = graph.toYaml();
```

示例：

```java
Graph graph = Graph.create("d2", spec -> {
    spec.addStart("s").title("发起人").metaPut("role", "employee").metaPut("form", "form1").linkAdd("n1");
    
    spec.addActivity("n1").title("主管批").metaPut("role", "tl").linkAdd("g1");
    
    spec.addExclusive("g1")
            .linkAdd("g2", l -> l.title("3天以下"))
            .linkAdd("n2", l -> l.title("3天以上").condition("day>=3"));

    spec.addActivity("n2").title("部门经理批").metaPut("role", "dm").linkAdd("g2");
    
    spec.addExclusive("g2")
            .linkAdd("e", l -> l.title("7天以下"))
            .linkAdd("n3", l -> l.title("7天以上").condition("day>=7"));

    spec.addActivity("n3").title("副总批").metaPut("role", "vp").linkAdd("e");
    
    spec.addEnd("e");
});
        
//转为 json ，并持久化
String json  = graph.toJson();


//攻取 json，并加载
Graph graph =  Graph.fromText(json); 
```


### 4、全部硬编码的方式不支持转换（也不方便持久化管理）

什么是全部硬编码的方式？

* 用 Java 原生构建图时，如果任务、条件用 Java 类（或 Lambda 表达式），则无法转换为文本。

示例（task 用了 Java 类，when 用了 Lambda 表达式）：

```java
Graph graph = Graph.create("demo2", spec -> {
    spec.addStart("start").linkAdd("agent");

    spec.addActivity("agent").task(new AiNodeAgent(chatModel)).linkAdd("review");
    
    spec.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");

    spec.addActivity("final_approval").task(new AiNodeFinalApproval()).linkAdd("end");
    
    spec.addActivity("final_failure").task(new AiNodeFinalFailure()).linkAdd("end");

    spec.addEnd("end");
});
```

全部硬编码的方式，不需要容器适配和脚本支持。比较适合一些特殊的需求。






