Spring AI Alibaba 1.x 系列【70】思考模式

文章目录

  • [1. 前言](#1. 前言)
  • [2. ReactAgent](#2. ReactAgent)
    • [2.1 开启深度思考](#2.1 开启深度思考)
    • [2.2 AgentLlmNode 处理](#2.2 AgentLlmNode 处理)
    • [2.3 获取思考内容](#2.3 获取思考内容)
      • [2.3.1 同步调用](#2.3.1 同步调用)
      • [2.3.2 流式输出](#2.3.2 流式输出)
  • [3. Graph](#3. Graph)

1. 前言

思考模式下,模型先输出中间推理过程,再给出答案,在 Spring AI Alibaba 中如何实现深度思考输出思考内容呢?

2. ReactAgent

2.1 开启深度思考

Spring AI 中有两种方式:

  • application.yml 全局配置
  • 请求时通过构建 ChatOptions

DashScope 对应的配置参数为 enable_thinking ,默认为不开启:

配置示例:

yml 复制代码
spring:
  application:
    name: demo-ai
  ai:
    dashscope:
      # 替换为你的阿里云百炼 API Key
      api-key: sk-3d56ec506a8943d0b39f58f306
      chat:
        options:
          model: qwen-plus
          enable_thinking: true

DashScopeChatModel 中的参数:

2.2 AgentLlmNode 处理

Spring AI 中,思考内容从 AssistantMessage 中直接获取:

java 复制代码
ChatResponse chatResponse= zhiPuAiChatClient.prompt("你好").options(chatOptions).call().chatResponse();
ZhiPuAiAssistantMessage output = (ZhiPuAiAssistantMessage)chatResponse.getResult().getOutput();
String reasoningContent = output.getReasoningContent();

AgentLlmNode 中会将 ChatResponseAssistantMessage 封装为 ModelResponse

java 复制代码
// 构建并同步调用AI模型,获取完整的聊天响应
ChatResponse response = buildChatClientRequestSpec(request, config).call().chatResponse();

// 初始化默认的助手响应消息,防止模型无返回时出现空指针
AssistantMessage responseMessage = new AssistantMessage("Empty response from model for unknown reason");
// 校验模型响应非空,且存在有效结果
if (response != null && response.getResult() != null) {
    // 从模型响应结果中提取正式的助手消息
    responseMessage = response.getResult().getOutput();
}

// 如果开启了推理日志打印,则记录本轮Agent的思考返回信息
if (enableReasoningLog) {
    logger.info("[ThreadId {}] Agent {} reasoning round {} returned: {}.", 
            config.threadId().orElse(THREAD_ID_DEFAULT),  // 线程ID
            agentName,                                   // Agent名称
            iterations.get(),                            // 当前推理轮次
            responseMessage                              // 模型返回的消息
    );
}

// 封装助手消息与原始响应,返回给上层流程使用
return ModelResponse.of(responseMessage, response);

ModelResponse 中的 messages 属性中包含了思考内容:

最后又将其更新到 messages 状态中:

2.3 获取思考内容

2.3.1 同步调用

同步调用 call 方法直接从 AssistantMessage 中就能拿到思考内容:

java 复制代码
        AssistantMessage assistantMessages = chatAgent.call("你好");
        String content1 = assistantMessages.getMetadata().get("reasoningContent").toString();
        System.out.println(content1);
text 复制代码
好的,用户说"你好",我需要回应。首先看看有什么工具可以用。提供的工具都是获取时间、日期、星期几之类的。用户只是打招呼,可能不需要调用任何工具。不过可能需要确认是否需要提供当前时间或日期作为回应。但用户没有具体问题,可能只是测试。根据指示,如果不需要工具,就直接回复。所以应该不用调用任何函数,直接友好回应即可。

call 方法只返回最终回复,对于多次调用时,自然也是只输出最后一个思考内容

invokeinvokeAndGetOutput 同步方法可以返回全局状态 ,其中的 messages 包含了所有对话,自然也能拿到所有思考内容:

java 复制代码
        OverAllState overAllState = chatAgent.invoke("今天星期几?几点了").get();
        NodeOutput output = chatAgent.invokeAndGetOutput("今天星期几?几点了").get();

2.3.2 流式输出

流式输出获取思考内容示例:

java 复制代码
        // 1. 获取流式流
        Flux<NodeOutput> agentStream = chatAgent.stream("今天星期几?几点了");

        // 2. 直接订阅打印,不封装 SSE
        agentStream
                .filter(nodeOutput -> !(nodeOutput instanceof StreamingOutput<?> so
                        && so.getOutputType() == OutputType.AGENT_MODEL_FINISHED))
                .subscribe(nodeOutput -> {
                    try {
                        String node = nodeOutput.node();
                        Usage tokenUsage = nodeOutput.tokenUsage();
                        // 处理流式输出
                        if (nodeOutput instanceof StreamingOutput<?> streamingOutput) {
                            Message message = streamingOutput.message();
                            if (message == null) return;

                            if (message instanceof AssistantMessage assistantMessage) {
                                String reasoningContent = assistantMessage.getMetadata().get("reasoningContent").toString();
                                // ====================== 直接打印!======================
                                System.out.println("节点:" + node + " | 思考内容:" +reasoningContent);
                            }
                        }

                    } catch (Exception e) {
                        System.err.println("打印出错:" + e.getMessage());
                    }
                }, error -> {
                    System.err.println("执行错误:" + error.getMessage());
                });

打印结果:

text 复制代码
节点:_AGENT_MODEL_ | 思考内容:好的,用户
节点:_AGENT_MODEL_ | 思考内容:问今天星期
节点:_AGENT_MODEL_ | 思考内容:几和几点
节点:_AGENT_MODEL_ | 思考内容:了。我需要调
节点:_AGENT_MODEL_ | 思考内容:用两个工具来获取
节点:_AGENT_MODEL_ | 思考内容:这些信息。

3. Graph

思考模式 是大模型节点的输出,在 Graph 工作流中的 LLM 节点和 AgentLlmNode 一样返回即可,使用方式也和 ReactAgent 一样,就不赘述了!!!

相关推荐
smile-yan1 小时前
大厂故事之百度(3/4)AI商业化迷航——从技术强到落地难
人工智能·百度
vensli1 小时前
消息跨端架构演进:基于 C++ 的多端一致性研发框架实践
java·人工智能·软件工程·安卓
逸Y 仙X1 小时前
文章六:ElasticSearch 集群通信安全权限
java·大数据·服务器·elasticsearch·搜索引擎·全文检索
MediaTea1 小时前
人工智能通识课:大语言模型
人工智能·语言模型·自然语言处理
code 小楊1 小时前
AI Agent 核心范式 ReAct 深度详解:原理、流程、源码、实战与工程优化
人工智能·科技·开源
小脑斧1231 小时前
AI Skills 全链路自动化运营实践:抖音热点、小红书种草与文生图一体化方案
大数据·人工智能·小红书·skills·自动化运营
深度学习lover1 小时前
<数据集>yolo个人防护用品识别<目标检测>
人工智能·yolo·目标检测·安全帽识别·安全背心识别·安全手套识别·防护靴识别
IT_陈寒1 小时前
React的useEffect里设状态?我又踩雷了
前端·人工智能·后端
狮子座明仔1 小时前
DeCoRL:把推理链拆成“乐团合奏“——AAAI 2026 一篇把 RLHF 推到 32B 打 GPT-4o 的工作
人工智能·深度学习·算法