Solon v3.8.0

multi - TeamAgent 自由模式

</> markdown
2026年1月5日 上午11:39:09

在默认情况下,TeamAgent 遵循预定义的团队协议(如 Leader 模式)。但在某些业务场景下,我们需要打破固定协议,自定义 Agent 之间的流转逻辑,例如 并行翻译、条件分支或复杂的网关聚合。

自由模式 的核心特征是:不使用固定协议,通过 graphAdjuster 完全自主定义执行图(Graph),并手动总结结果。

1、如何使用自由模式

不指守 ChatModel 基座,之后也就不使用团队协议了。

TeamAgent team = TeamAgent.of(null)

2、示例代码:多语种同步翻译系统

下面的示例展示了如何编排一个并行翻译团队:将一段文字同时分发给英语翻译专家和法语翻译专家,并在汇聚节点完成结果汇总。

import demo.ai.agent.LlmUtil;
import org.junit.jupiter.api.Test;
import org.noear.solon.ai.agent.Agent;
import org.noear.solon.ai.agent.team.TeamAgent;
import org.noear.solon.ai.agent.team.TeamTrace;
import org.noear.solon.ai.agent.react.ReActAgent;
import org.noear.solon.ai.chat.ChatModel;
import java.util.stream.Collectors;

/**
 * 并行协作测试:多语种同步翻译
 * 验证:并行分支的独立运行与结果在 Join 节点的结构化汇聚。
 */
public class TeamAgentParallelAgentTest {
    @Test
    public void testParallelAgents() throws Throwable {
        ChatModel chatModel = LlmUtil.getChatModel();
        String teamId = "parallel_translator";

        // 1. 定义翻译专家(ReAct 模式)
        Agent enTranslator = ReActAgent.of(chatModel)
                .name("en_translator")
                .title("英语翻译")
                .promptProvider(p -> "你是负责英语翻译的专家")
                .description("负责英语翻译的专家")
                .build();

        Agent frTranslator = ReActAgent.of(chatModel)
                .name("fr_translator")
                .title("法语翻译")
                .promptProvider(p -> "你是负责法语翻译的专家")
                .description("负责法语翻译的专家")
                .build();

        // 2. 自由定义图:实现分发与汇聚
        TeamAgent team = TeamAgent.of(null)
                .name(teamId)
                .graphAdjuster(spec -> {
                    spec.addStart(Agent.ID_START).linkAdd("dispatch_gate");

                    // 并行分发:同时激活英、法两个 Agent
                    spec.addParallel("dispatch_gate").title("并行")
                            .linkAdd(enTranslator.name())
                            .linkAdd(frTranslator.name());

                    spec.addActivity(enTranslator).linkAdd("aggregate_node");
                    spec.addActivity(frTranslator).linkAdd("aggregate_node");

                    // 汇聚节点:从协作轨迹中提取各分支产出
                    spec.addParallel("aggregate_node").title("汇聚").task((ctx, n) -> {
                        TeamTrace trace = ctx.getAs("__" + teamId);
                        String summary = trace.getSteps().stream()
                                .map(s -> String.format("[%s]: %s", s.getAgentName(), s.getContent()))
                                .collect(Collectors.joining("\n"));
                        trace.setFinalAnswer("多语言处理完成:\n" + summary);
                    }).linkAdd(Agent.ID_END);

                    spec.addEnd(Agent.ID_END);
                })
                .build();
    }
}

3、轨迹提取 (TeamTrace)

在自由模式下,引擎会自动将执行过程存入 TeamTrace 对象。我们需要手动使用它:

  • Key 的规则:"__" + teamId
  • 用途:通过 trace.getSteps() 遍历每个 Agent 的执行快照,获取 content(回复内容)。
  • 设置最后的结果:trace.setFinalAnswer(...)