摸索AI(六)Spring AI获取思考过程(推理)

Spring Ai
placeholder image
admin 发布于:2026-03-15 19:16:30
阅读:loading

之前也是花了巨多的时间从Github上下载了一些AI摸索的实践项目,涉及到的有文生图、文生视频、图生图、语音克隆、数字人等,它们的实践对电脑配置的依赖有一定的要求,而且实践的过程复杂程度较高,属于摸索着玩玩而已。本次摸索AI的范围则是面向对擅长领域的代码接入实践。如果你对Java代码交互的AI大模型有一些兴趣,又或者是跟我一样不知从哪里入手,或许看看我这里分享的前后实践过程与实践的案例范围,也是不错的选择。

1.基本介绍

所以,本系列教程相关的实践是在本地部署大模型,并且使用Java代码与本地的大模型进行交互。除了本地部署的大模型以为,也是可以付费接入网络上的一些付费大模型,比如Deepseek、千问等等,但是对我个人来讲,私有化的本地大模型更加有意义,毕竟可以免费的集成到企业级应用实践当中。

  本次实践围绕使用Spring AI在花活应用中的科学实践,主要是在接口交互的过程中快速向用户反馈响应数据中的AI思考过程,AI的思考过程不是必须的,但若是呈现一个思考的过程则显得更加专业。所以,本期的实践则是使用Spring AI来获取大模型思考过程信息。前后也是花了许多的时间来摸索,尝试了Spring Open API中的多款框架均未摸索出来个结果,锲而不舍的一再尝试,最终在经历了spring-ai-openai、spring-ai-deepseek、spring-ai-ollama等等API后算是成功了。

前面的文章中使用Spring AI获取数据后,也有一些接口获取到了Reason的信息,但是未能成功的异步获取(再获取最终结果前优先获取到思考过程),所以在本篇特专门针对于获取思考过程的实现做个总结,(因为整个过程也是各种费劲,纯粹的闭门摸索,过程艰辛、程度复杂),非常有整理意义。特别值得说的一点是之前调用AI的本地大模型URL为“http://localhost:11434/v1/chat/completions”或“http://localhost:11434/v1/completions”,而本次实践的URL为“http://localhost:11434/api/chat”,这是最大的差异,并且相关API使用的是OllamaApi,其它的OpenAiApi、DeepSeekApi实践的未能成功。

2.单元测试示例

第一个示例演示是在单元测试中进行的,使用自带的API来消费接口的响应结果,参考代码和IDEA的控制台输出如下所示:

  @RunWith(JUnit4.class)
public class AiHelloThinkTest {

    @Test
    public void testHelloThink() throws Exception {
        final OllamaApi ollamaAiApi = OllamaApi.builder().baseUrl("http://localhost:11434").build();
        List<OllamaApi.Message> messages = new ArrayList<>();
        messages.add(OllamaApi.Message.builder(OllamaApi.Message.Role.SYSTEM).content("你是一个非常专业的问答专家,请使用中文回答问题。").build());
        messages.add(OllamaApi.Message.builder(OllamaApi.Message.Role.USER).content("1 + 1 = ?").build());
        OllamaApi.ChatRequest chatRequest = OllamaApi......build();
        final Flux<OllamaApi.ChatResponse> chatResponseFlux = ollamaAiApi.streamingChat(chatRequest);
        System.out.println(chatResponseFlux);
        AtomicBoolean thinkStart = new AtomicBoolean(false);
        AtomicBoolean thinkEnd = new AtomicBoolean(false);
        chatResponseFlux.subscribe(chatResponse -> {
            final OllamaApi.Message message = chatResponse.message();
            final String thinking = message.thinking();

            if (StringUtils.isNotEmpty(thinking)) {
                if (! thinkStart.get()) {
                    System.out.println("\n<think>");
                    thinkStart.set(true);
                }
                System.out.print(thinking);
            }
            final String content = message.content();
            if (StringUtils.isNotEmpty(content)) {
                if (! thinkEnd.get()) {
                    System.out.println("\n</think>");
                    thinkEnd.set(true);
                }
                System.out.print(content);
            }
        });

        chatResponseFlux.blockLast();
        System.out.println("over1");
        chatResponseFlux.onBackpressureLatest();
        System.out.println("over2");
        TimeUnit.MINUTES.sleep(5);

    }

}

思考过程-含水印.gif

3.浏览器示例

第二个示例演示是在浏览器中进行的,用户通过URL传递自定义的问题,可以非常丝滑的看到AI大模型的思考过程,参考代码和IDEA的控制台输出如下所示:

@ApiVersion("1")
@RequestMapping(value = "/ai" , produces = MediaType.APPLICATION_JSON_VALUE)
@RestController
@Tag(name = "Ai")
public class AiController {

    @GetMapping(consumes = MediaType.ALL_VALUE , produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    @Operation(summary = "Ai" , description = "Ai简单问答")
    @ApiOperationSupport(order = 10)
    public Flux<OllamaApi.ChatResponse> getUsers(@RequestParam("content") String content) {
        final OllamaApi ollamaAiApi = OllamaApi.builder().baseUrl("http://localhost:11434").build();
        List<OllamaApi.Message> messages = new ArrayList<>();
        messages.add(OllamaApi.Message.builder(OllamaApi.Message.Role.SYSTEM).content("你是一个非常专业的问答专家,请使用中文回答问题。").build());
        messages.add(OllamaApi.Message.builder(OllamaApi.Message.Role.USER).content(content).build());
        OllamaApi.ChatRequest chatRequest = OllamaApi......build()).messages(messages).build();
        final Flux<OllamaApi.ChatResponse> chatResponseFlux = ollamaAiApi.streamingChat(chatRequest);
        // 使用 Flux.create 创建流式响应
        return chatResponseFlux;
    }


}

浏览器思考过程-含水印.gif

(浏览器输出)

F12-全-含水印.gif

(F12查看网络请求)

4.其它说明

(1)本次实践的代码是使用Spring AI调用本地大模型并获取思考过程(推理)的实现;

(2)示例在执行过程中有一定的等待,有了思考过程的输出,实际上请求响应的结果并不是感觉很慢;

(3)示例中浏览器的输出结果包含了AI执行过程中的各个信息,JSON格式的对象值略有不同,参考JSON如下:

    "data": {
       
"model": "qwen3:8b",
       
"created_at": "2026-03-15T12:17:13.814799200Z",
       
"message": {
         
"role": "assistant",
         
"content": "",
         
"thinking": "好的"
       
},
       
"done": false
    },
    "data": {
        
"model": "qwen3:8b",
        
"created_at": "2026-03-15T12:18:05.451375600Z",
        
"message": {
         
"role": "assistant",
         
"content": "学习"
       
},
       
"done": false
    }

(4)给出两个案例实际执行的全过程预览效果图,上述的图片省流只摘选了一部分,完整的预览参考《示例参考.zip》,包含完整的示例请求和响应结果;

(5)许多案例给出的是结合Spring Boot后的配置注入方式,这种把大模型的服务URL、模型名称等等参数细节配置在application配置文件中的形式,我感觉不够灵活,后续相关的示例均使用硬编码的形式给出,面向底层代码更加便于新手水平理解掌握;


 点赞


 发表评论

当前回复:作者

 评论列表


留言区