---
title: "Solon AI Agent Graph 开发"
---

本系列是 **Solon AI Agent 与 Solon Flow Graph 的交叉进阶系列**。它不定义新的 Agent 类型，也不重复讲通用 Graph API，而是说明如何把 `SimpleAgent`、`ReActAgent`、`TeamAgent` 与确定性业务节点组织成可控制、可测试、可恢复的执行图。

```text
Agent：理解、推理、调用工具并生成结果
Graph：定义顺序、分支、汇聚、循环和子图
FlowContext：传递 Graph 业务数据并保存 FlowTrace
AgentSession：定义会话边界，保存消息历史并持有 FlowContext
FlowEngine：执行 Graph
```

核心原则：让 Agent 处理不确定的认知任务，让 Graph 处理确定的业务约束。

### 1、前置阅读

建议先了解：

- [Solon AI Agent（ReActAgent）开发](https://solon.noear.org/article/learn-solon-ai-agent)
- [agent - 认识 Solon AI Agent 接口](https://solon.noear.org/article/1314)
- [team - TeamAgent 自由模式（NONE 协议）](https://solon.noear.org/article/1299)
- [Solon Flow Graph 开发](https://solon.noear.org/article/learn-solon-flow-graph)

本系列不会重复介绍 ChatModel、各类 Agent 的完整配置，也不会重复 Graph Fluent API、网关和 DSL 的通用参考；这里只讲 **Graph 与 Agent 结合后新增的数据、状态和治理问题**。

### 2、为什么需要 Agent Graph？

当系统出现以下要求时，不宜让一个大 Agent 自由决定全部步骤：

- 必须先审核再发布；
- 按金额、风险等级或问题类型选择 Agent；
- 让多个专家分析，再统一汇聚；
- 在敏感工具或业务阶段前等待人工批准；
- 将复杂系统拆成团队和子图；
- 保存执行位置，并在另一进程恢复。

典型结构：

```text
Start
  -> 需求分析 Agent
  -> Parallel
       ├─ 技术 Agent ─┐
       ├─ 成本 Agent ─┼─> 汇聚 -> 决策 Agent
       └─ 风险 Agent ─┘
  -> 人工审核
  -> End
```

### 3、两种结合方式

#### 3.1 TeamAgent 内部 Graph

`TeamAgent` 内部使用 Graph。`TeamProtocols.NONE` 不预建拓扑，用户通过 `graphAdjuster` 完整定义结构：

```java
TeamAgent team = TeamAgent.of(null)
        .name("content_team")
        .protocol(TeamProtocols.NONE)
        .agentAdd(analyst, writer)
        .graphAdjuster(spec -> {
            spec.addStart(Agent.ID_START).linkAdd(analyst.name());
            spec.addActivity(analyst).linkAdd(writer.name());
            spec.addActivity(writer).linkAdd(Agent.ID_END);
            spec.addEnd(Agent.ID_END);
        })
        .build();
```

这种方式具备 TeamAgent 的 Prompt、TeamTrace、AgentEvent 和结果收敛语义。**当系统主体是多个 Agent 的协作时**，它是本系列优先讲解的主线方式；如果系统主体是通用业务流程，Agent 只是少量节点，则应选择后面的独立业务 Graph。

> `NONE` 是本系列用于讲解“显式 Agent Graph”的默认选择，不是 TeamAgent 构建器的框架默认协议。未显式配置时，TeamAgent 仍使用 `HIERARCHICAL`。`NONE` 也不提供自动协作：它不创建节点、不传递成员结果、不汇总并行结论，只保留 TeamAgent 运行时并把 Graph 定义权交给用户。

#### 3.2 独立业务 Graph 显式调用 Agent

业务 Graph 只在部分节点需要 AI 时，应显式完成 `FlowContext -> Prompt -> Agent -> FlowContext` 映射：

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

    spec.addActivity("summary")
            .task((ctx, node) -> {
                AgentSession session = ctx.getAs(Agent.KEY_SESSION);
                String input = ctx.getAs("input.document");

                String result = summarizer.prompt(input)
                        .session(session)
                        .call()
                        .getContent();

                ctx.put("summary.result", result);
            })
            .linkAdd("end");

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

FlowContext context = FlowContext.of("summary-job-001");
context.put("input.document", "需要摘要的正文");
InMemoryAgentSession.of(context);

FlowEngine.newInstance().eval(graph, context);
```

`InMemoryAgentSession.of(context)` 会让 Session 与 Graph 共用同一个 Context。

### 4、Agent 为什么可以成为节点？

`Agent` 继承 `NamedTaskComponent`，因此在 TeamAgent Graph 中可以直接使用：

```java
spec.addActivity(agent);
```

节点 ID 来自 `agent.name()`；未覆盖 `title()` 时，标题也默认使用名称；任务入口是 `Agent.run(FlowContext, Node)`。

但不要由此推断普通独立 Graph 会自动把 `context.get("input")` 转换成 Prompt。外层不存在 TeamTrace 时，没有团队协议替 Agent 准备本次 Prompt；而且不应依赖 `Agent.run` 自动创建的临时 Session，它持有独立 Context。独立 Graph 应使用显式适配节点，并预先执行：

```java
InMemoryAgentSession.of(context);
```

### 5、三个容易混淆的边界

#### Agent Graph 不是第四种 Agent

`SimpleAgent`、`ReActAgent`、`TeamAgent` 是执行单元；Agent Graph 是组织这些执行单元的结构。

#### Agent Graph 不是另一套 Graph 引擎

底层仍是 Solon Flow 的 `Graph`、`FlowContext` 和 `FlowEngine`。

#### Graph 拓扑不等于数据自动传递

```java
spec.addActivity(analyst).linkAdd(writer.name());
```

只表示执行顺序。前一个 Agent 的 `outputKey` 不会自动进入后一个 Agent 的 Prompt，后续文章会专门定义输入输出契约。
