multi - 示例4 - 协作协议
2026年1月4日 下午10:46:36
示例代码
import demo.ai.agent.LlmUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.noear.solon.ai.agent.Agent;
import org.noear.solon.ai.agent.react.ReActAgent;
import org.noear.solon.ai.agent.team.TeamAgent;
import org.noear.solon.ai.agent.team.TeamProtocols;
import org.noear.solon.ai.agent.team.TeamTrace;
import org.noear.solon.ai.chat.ChatModel;
import org.noear.solon.flow.FlowContext;
/**
* Blackboard 策略测试:基于共享状态的补位协作
*/
public class TeamAgentBlackboardTest {
@Test
public void testBlackboardLogic() throws Throwable {
ChatModel chatModel = LlmUtil.getChatModel();
// 1. 定义互补的 Agent
Agent databaseDesigner = ReActAgent.of(chatModel)
.name("db_designer")
.promptProvider(c -> "你只负责数据库表结构设计,输出 SQL 代码。这只是个测试,有2张表就好了")
.description("负责数据库表结构设计,输出 SQL 代码。")
.build();
Agent apiDesigner = ReActAgent.of(chatModel)
.name("api_designer")
.promptProvider(c -> "你只负责 RESTful API 接口协议设计。这只是个测试,争对表做2个接口设计就好了。")
.description("负责 RESTful API 接口协议设计。")
.build();
// 2. 使用 BLACKBOARD 策略
TeamAgent team = TeamAgent.of(chatModel)
.name("blackboard_team")
.protocol(TeamProtocols.BLACKBOARD)
.addAgent(databaseDesigner)
.addAgent(apiDesigner)
.build();
String yaml = team.getGraph().toYaml();
System.out.println("------------------\n\n");
System.out.println(yaml);
System.out.println("\n\n------------------");
FlowContext context = FlowContext.of("test_blackboard");
// 任务涵盖两个领域,观察 Mediator 如何依次分派
String result = team.call(context, "请为我的电商系统设计用户模块的数据库和配套接口。");
System.out.println("=== Blackboard 策略测试 ===");
System.out.println("任务: 为电商系统设计用户模块的数据库和配套接口");
System.out.println("执行结果: " + result);
TeamTrace trace = team.getTrace(context);
Assertions.assertNotNull(trace, "应该有轨迹记录");
// 放松断言:验证任务完成,有轨迹记录
Assertions.assertNotNull(result, "任务应该有结果");
Assertions.assertFalse(result.trim().isEmpty(), "结果不应该为空");
Assertions.assertTrue(trace.getStepCount() > 0, "至少应该执行一步");
// 输出调试信息,但不做严格断言
System.out.println("实际步数: " + trace.getStepCount());
System.out.println("调用Agent数: " + trace.getSteps().stream()
.map(step -> step.getAgentName())
.distinct()
.count());
// 打印详细历史
System.out.println("协作轨迹:\n" + trace.getFormattedHistory());
System.out.println("=== 测试结束 ===\n");
}
@Test
public void testBlackboardWithExplicitRequest() throws Throwable {
ChatModel chatModel = LlmUtil.getChatModel();
// 创建互补的 Agent
Agent databaseDesigner = ReActAgent.of(chatModel)
.name("db_designer")
.description("负责数据库表结构设计,输出 SQL 代码。")
.build();
Agent apiDesigner = ReActAgent.of(chatModel)
.name("api_designer")
.description("负责 RESTful API 接口协议设计。")
.build();
TeamAgent team = TeamAgent.of(chatModel)
.name("blackboard_explicit_team")
.protocol(TeamProtocols.BLACKBOARD)
.addAgent(databaseDesigner)
.addAgent(apiDesigner)
.build();
FlowContext context = FlowContext.of("test_blackboard_explicit");
// 使用更明确的任务,要求两个部分
String result = team.call(context,
"请分两部分完成:\n" +
"1. 设计用户模块的数据库表结构,需要包含用户表、地址表、订单表\n" +
"2. 设计对应的 RESTful API 接口,包括用户注册、登录、信息查询");
System.out.println("=== Blackboard 策略测试(明确任务) ===");
System.out.println("任务: 分两部分设计数据库和API");
System.out.println("执行结果: " + result);
TeamTrace trace = team.getTrace(context);
Assertions.assertNotNull(trace, "应该有轨迹记录");
// 基本验证
Assertions.assertNotNull(result, "任务应该有结果");
Assertions.assertTrue(trace.getStepCount() > 0, "至少应该执行一步");
// 输出调试信息
System.out.println("实际步数: " + trace.getStepCount());
// 检查是否两个Agent都参与了(理想情况)
long uniqueAgents = trace.getSteps().stream()
.map(step -> step.getAgentName())
.distinct()
.count();
System.out.println("实际参与Agent数: " + uniqueAgents + " (期望: 2)");
System.out.println("协作轨迹:\n" + trace.getFormattedHistory());
System.out.println("=== 测试结束 ===\n");
}
}