Solon-AI聊天测试:对话功能测试案例

Solon-AI聊天测试:对话功能测试案例

【免费下载链接】solon-ai Java AI & MCP 应用开发框架(LLM,Function Call,RAG,Embedding,Reranking,Flow,MCP Server,Mcp Client,Mcp Proxy)。同时兼容 java8 ~ java24。也可嵌入到 SpringBoot2、jFinal、Vert.x 等框架中使用。 【免费下载链接】solon-ai 项目地址: https://gitcode.com/opensolon/solon-ai

引言

在AI应用开发中,聊天对话功能是最核心且常用的能力之一。Solon-AI作为Java AI应用开发框架,提供了强大而灵活的聊天模型(ChatModel)接口,支持多种LLM提供商和丰富的功能特性。本文将深入探讨Solon-AI的聊天测试实践,通过具体案例展示如何构建和测试对话功能。

核心接口概览

Solon-AI的聊天功能基于ChatModel接口构建,支持同步调用和流式响应两种模式:

// 基础聊天模型构建
ChatModel chatModel = ChatModel.of("http://127.0.0.1:11434/api/chat")
                .provider("ollama") // 指定供应商(方言)
                .model("qwen2.5:1.5b")
                .build();

// 同步调用
ChatResponse resp = chatModel.prompt("hello").call();

// 流式调用
chatModel.prompt("hello").stream(); // Publisher<ChatResponse>

测试架构设计

抽象测试基类

Solon-AI采用抽象测试基类AbsChatTest来统一管理各种LLM提供商的测试用例:

mermaid

基础对话功能测试

同步调用测试

@Test
public void case1_call() throws IOException {
    ChatModel chatModel = getChatModelBuilder().build();
    
    // 一次性返回
    ChatResponse resp = chatModel.prompt("hello").call();
    
    // 打印消息
    log.info("{}", resp.getMessage());
}

流式响应测试

@Test
public void case2_stream() throws Exception {
    ChatModel chatModel = getChatModelBuilder().build();
    
    // 流返回
    CountDownLatch doneLatch = new CountDownLatch(1);
    AtomicBoolean done = new AtomicBoolean(false);
    
    chatModel.prompt("hello").stream()
            .subscribe(new SimpleSubscriber<ChatResponse>()
                    .doOnNext(resp -> {
                        log.info("{} - {}", resp.isFinished(), resp.getMessage());
                        done.set(resp.isFinished());
                    }).doOnComplete(() -> {
                        log.debug("::完成!");
                        doneLatch.countDown();
                    }).doOnError(err -> {
                        doneLatch.countDown();
                        err.printStackTrace();
                    }));
    
    doneLatch.await();
    assert done.get();
}

工具调用功能测试

工具定义

Solon-AI支持Function Calling(工具调用)功能,可以定义各种工具函数:

@Component
public class Tools {
    @ToolMapping(description = "获取指定城市的天气情况")
    public String get_weather(@Param(name = "location", description = "根据用户提到的地点推测城市") String location) {
        if (location == null) {
            throw new IllegalStateException("arguments location is null (Assistant recognition failure)");
        }
        return "晴,24度";
    }

    @ToolMapping(description = "查询城市降雨量")
    public String get_rainfall(@Param(name = "location", description = "城市位置") String location) {
        if (location == null) {
            throw new IllegalStateException("arguments location is null (Assistant recognition failure)");
        }
        return "555毫米";
    }

    @ToolMapping(description = "用关键词搜索网络")
    public String search_www(@Param(name = "key", description = "根据用户内容提取关键词") String key) throws IOException {
        if (key == null) {
            throw new IllegalStateException("arguments key is null (Assistant recognition failure)");
        }
        return HttpUtils.http("https://solon.noear.org/article/about?format=md").get();
    }
}

工具调用测试案例

单工具调用测试
@Test
public void case3_wather_call() throws IOException {
    ChatModel chatModel = getChatModelBuilder()
            .defaultToolsAdd(new Tools())
            .build();

    ChatResponse resp = chatModel
            .prompt("今天杭州的天气情况?")
            .call();

    // 验证响应包含预期内容
    assert resp.getMessage() != null;
    assert resp.getMessage().getContent().contains("晴");
}
多工具组合调用测试
@Test
public void case3_wather_rainfall_call() throws IOException {
    ChatModel chatModel = getChatModelBuilder()
            .defaultToolsAdd(new Tools())
            .build();

    ChatResponse resp = chatModel
            .prompt("杭州天气和北京降雨量如何?")
            .call();

    // 验证多个工具调用结果
    assert resp.getMessage() != null;
    assert resp.getMessage().getContent().contains("晴");
    assert resp.getMessage().getContent().contains("555");
}

会话管理测试

聊天会话构建

@Test
public void case4_tool_stream() throws Throwable {
    ChatModel chatModel = getChatModelBuilder().build();
    
    // 创建聊天会话
    ChatSession chatSession = InMemoryChatSession.builder().build();
    chatSession.addMessage(ChatMessage.ofUser("今天杭州的天气情况?"));
    
    // 流式调用
    Publisher<ChatResponse> publisher = chatModel
            .prompt(chatSession)
            .options(o -> o.toolsAdd(new Tools()))
            .stream();
    
    // 订阅响应
    AtomicReference<AssistantMessage> msgHolder = new AtomicReference<>();
    CountDownLatch doneLatch = new CountDownLatch(1);
    
    publisher.subscribe(new SimpleSubscriber<ChatResponse>()
            .doOnNext(resp -> {
                msgHolder.set(resp.getAggregationMessage());
            }).doOnComplete(() -> {
                log.debug("::完成!");
                doneLatch.countDown();
            }).doOnError(err -> {
                err.printStackTrace();
                msgHolder.set(null);
                doneLatch.countDown();
            }));
    
    doneLatch.await();
    
    // 验证会话状态
    assert chatSession.getMessages().size() == 4;
    System.out.println(chatSession.toNdjson());
}

多轮对话测试

@Test
public void case5_tool_stream() throws Throwable {
    ChatModel chatModel = getChatModelBuilder().build();
    ChatSession chatSession = InMemoryChatSession.builder().build();
    
    // 第一轮对话
    chatSession.addMessage(ChatMessage.ofUser("今天杭州的天气情况?"));
    // ... 处理第一轮响应
    
    // 第二轮对话
    chatSession.addMessage(ChatMessage.ofUser("搜索网络:solon框架的作者是谁?"));
    // ... 处理第二轮响应
    
    // 验证多轮对话状态
    assert chatSession.getMessages().size() == 8;
}

高级功能测试

返回值工具测试

@Test
public void case6_wather_return_call() throws IOException {
    ChatModel chatModel = getChatModelBuilder()
            .defaultToolsAdd(new ReturnTools())
            .build();

    ChatResponse resp = chatModel
            .prompt("今天杭州的天气情况?")
            .call();

    // 验证精确返回值
    assert "晴,24度".equals(resp.getMessage().getContent());
}

复杂工具调用测试

@Test
public void case8_tool_stream() throws Exception {
    ChatModel chatModel = getChatModelBuilder()
            .defaultToolsAdd(new Case8Tools())
            .timeout(Duration.ofSeconds(600))
            .build();

    // 复杂查询场景
    Publisher<ChatResponse> publisher = chatModel
            .prompt(ChatMessage.ofUser("2025号3月20日,设备76-51的日用电量是多少"))
            .stream();
    
    // 处理复杂响应
    // ...
}

测试最佳实践

1. 测试环境配置

@SolonTest
public class OllamaTest extends AbsChatTest{
    private static final String apiUrl = "http://127.0.0.1:11434/api/chat";
    private static final String provider = "ollama";
    private static final String model = "qwen2.5:1.5b";

    protected ChatModel.Builder getChatModelBuilder() {
        return ChatModel.of(apiUrl)
                .provider(provider)
                .model(model);
    }
}

2. 断言策略

测试类型断言重点示例
同步调用响应内容完整性assert resp.getMessage() != null
流式调用完成状态验证assert done.get()
工具调用返回值验证assert resp.getMessage().getContent().contains("晴")
会话管理消息数量验证assert chatSession.getMessages().size() == 4

3. 异常处理

@Test
public void case3_wather_stream_finished() throws Exception {
    // ... 测试代码
    
    // 验证完成事件
    Assertions.assertEquals(1, atomicInteger.get(), "完成事件");
}

性能优化建议

超时配置

@Test
public void case8_tool_stream() throws Exception {
    ChatModel chatModel = getChatModelBuilder()
            .defaultToolsAdd(new Case8Tools())
            .timeout(Duration.ofSeconds(600)) // 设置超时时间
            .build();
    // ...
}

批量处理

// 在EmbeddingModel中支持批量处理
EmbeddingModel embeddingModel = EmbeddingModel.of(apiUrl)
        .apiKey(apiKey)
        .provider(provider)
        .model(model)
        .batchSize(10) // 批量大小
        .build();

总结

Solon-AI的聊天测试框架提供了全面的测试覆盖,从基础对话到复杂的工具调用场景。通过抽象测试基类和具体的提供商实现,可以轻松扩展支持各种LLM服务。关键优势包括:

  1. 统一的测试接口:通过AbsChatTest抽象基类实现测试标准化
  2. 全面的功能覆盖:支持同步/异步、工具调用、会话管理等
  3. 灵活的扩展性:易于添加新的LLM提供商测试
  4. 完善的断言机制:提供多种验证策略确保功能正确性

通过本文的测试案例,开发者可以快速掌握Solon-AI聊天功能的测试方法,构建稳定可靠的AI对话应用。

提示:在实际项目中,建议结合持续集成(CI)环境运行这些测试,确保AI功能的稳定性和可靠性。

【免费下载链接】solon-ai Java AI & MCP 应用开发框架(LLM,Function Call,RAG,Embedding,Reranking,Flow,MCP Server,Mcp Client,Mcp Proxy)。同时兼容 java8 ~ java24。也可嵌入到 SpringBoot2、jFinal、Vert.x 等框架中使用。 【免费下载链接】solon-ai 项目地址: https://gitcode.com/opensolon/solon-ai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值