📖目录
- 前言
- [1. 什么是 Agent?为什么需要它?](#1. 什么是 Agent?为什么需要它?)
- [2. Agent 核心能力全景图](#2. Agent 核心能力全景图)
- [3. 核心功能详解(结合 AgentsExample.java)](#3. 核心功能详解(结合 AgentsExample.java))
-
- [3.1 基础配置:模型与 Prompt](#3.1 基础配置:模型与 Prompt)
- [3.2 工具集成:让 Agent "动手"](#3.2 工具集成:让 Agent “动手”)
- [3.3 动态 Prompt:上下文感知](#3.3 动态 Prompt:上下文感知)
- [3.4 对话记忆:支持多轮上下文](#3.4 对话记忆:支持多轮上下文)
- [3.5 流式响应:实时输出](#3.5 流式响应:实时输出)
- [3.6 结构化输出:强制 JSON/POJO](#3.6 结构化输出:强制 JSON/POJO)
- [4. 高级扩展:Hook 与 Interceptor](#4. 高级扩展:Hook 与 Interceptor)
-
- [4.1 Agent 生命周期钩子(Hook)](#4.1 Agent 生命周期钩子(Hook))
- [4.2 模型调用拦截器(Interceptor)](#4.2 模型调用拦截器(Interceptor))
- [5. 完整源码及执行结果](#5. 完整源码及执行结果)
-
- [5.1 完整源码](#5.1 完整源码)
- [5.2 执行结果](#5.2 执行结果)
- [5. 执行上下文分析(来自 AgentsExample_执行结果.txt)](#5. 执行上下文分析(来自 AgentsExample_执行结果.txt))
- [6. 生产建议](#6. 生产建议)
- [7. 结语](#7. 结语)
- [8. 福利资源](#8. 福利资源)
前言
📌 本文基于 Spring AI Alibaba 最新版本(2025 年 11 月,兼容 Spring Boot 3.5.7 / Spring Cloud Alibaba 2023.0.x)
✅ 适合中高级 Java 开发者、AI 应用架构师阅读
🔗 官方文档 :https://sca.aliyun.com/en/docs/ai/overview/
💡 参考代码说明 :本文所有示例均直接源自你提供的
AgentsExample.java文件(位于spring-ai-alibaba/examples/documentation/framework/tutorials/路径下),该文件是 Spring AI Alibaba 官方团队发布的 Agent 教程核心示例 。文中关键代码片段已做精简,完整逻辑请以该文件为准。运行依赖可通过AgentsExample_执行结果.txt中的 classpath 确认(如spring-ai-alibaba-graph-core-1.1.0.0-M5.jar等)。
在上一篇《【Spring AI Alibaba】① 技术内核全解析》中,我们系统剖析了框架的整体架构、核心组件(ChatClient、VectorStore、Function Calling)以及"模型无关"的扩展哲学------回答了 "Spring AI Alibaba 是什么、为何这样设计" 的问题。
而本文将聚焦一个更贴近业务落地的主题:如何用它构建真正能"思考+行动"的智能体(Agent)?
如果说第一篇讲的是"骨架",那么本篇就是"肌肉与神经"------我们将深入 ReactAgent 的完整能力体系,涵盖:
- 工具调用与错误兜底
- 对话记忆(Memory)
- 动态 Prompt 注入
- 流式响应(Streaming)
- 结构化输出(Structured Output)
- 全链路拦截与生命周期钩子(Interceptor & Hook)
所有内容均基于官方 AgentsExample.java 示例,带你从理论走向可运行、可调试、可扩展的生产级实践。
1. 什么是 Agent?为什么需要它?
Agent = LLM + 工具 + 记忆 + 规划能力。其核心价值在于:
让大模型不仅能"说",还能"做"。
典型场景:
- 自动化客服(查订单、退换货)
- 运维助手(查日志、重启服务)
- 数据分析师(查数据库、生成图表)
Spring AI Alibaba 的 ReactAgent 基于 ReAct(Reasoning + Acting) 范式,让模型在"思考"与"行动"间循环,直至达成目标。
2. Agent 核心能力全景图
根据 AgentsExample.java,Spring AI Alibaba Agent 支持以下能力模块(文本流程图):
┌───────────────────────┐
│ User Input │
└──────────┬────────────┘
▼
┌───────────────────────┐
│ Dynamic System │◄─── ModelInterceptor (动态Prompt)
│ Prompt / Instruction│
└──────────┬────────────┘
▼
┌───────────────────────┐
│ Tool Selection & │◄─── ToolCallback (工具定义)
│ Execution │◄─── ToolInterceptor (错误监控)
└──────────┬────────────┘
▼
┌───────────────────────┐
│ Memory Management │◄─── MemorySaver (对话记忆)
│ (Thread Context) │
└──────────┬────────────┘
▼
┌───────────────────────┐
│ Structured Output │◄─── outputType / outputSchema
│ (JSON / POJO) │
└──────────┬────────────┘
▼
┌───────────────────────┐
│ Response Streaming │◄─── Flux<NodeOutput>
│ or Blocking Call │
└──────────┬────────────┘
▼
┌───────────────────────┐
│ Agent Hooks │◄─── BEFORE_AGENT / AFTER_AGENT
│ (Logging, Metrics) │
└───────────────────────┘
💡 关键设计 :所有环节均可通过 Interceptor 或 Hook 插入自定义逻辑,实现非侵入式增强。
3. 核心功能详解(结合 AgentsExample.java)
3.1 基础配置:模型与 Prompt
java
// 示例1:基础模型配置
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
ReactAgent agent = ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.build();
支持高级参数(温度、Token 限制等):
java
// 示例2:高级模型配置
.defaultOptions(DashScopeChatOptions.builder()
.withTemperature(0.7)
.withMaxToken(2000)
.build())
3.2 工具集成:让 Agent "动手"
定义工具(实现 BiFunction):
java
// 示例3:工具定义
public static class SearchTool implements BiFunction<String, ToolContext, String> {
@Override
public String apply(@ToolParam(description = "搜索关键词") String query, ToolContext ctx) {
return "搜索结果:" + query;
}
}
注册工具并启用错误拦截:
java
// 示例4:工具错误处理(需自定义 ToolErrorInterceptor)
ReactAgent agent = ReactAgent.builder()
.tools(FunctionToolCallback.builder("search", new SearchTool()).build())
.interceptors(new ToolErrorInterceptor()) // 拦截工具异常
.build();
3.3 动态 Prompt:上下文感知
通过 ModelInterceptor 动态注入 Prompt:
java
// 示例7:动态 System Prompt
public static class DynamicPromptInterceptor extends ModelInterceptor {
@Override
public ModelResponse interceptModel(ModelRequest request, ModelCallHandler handler) {
String userRole = (String) request.getContext().getOrDefault("user_role", "default");
String dynamicPrompt = switch (userRole) {
case "expert" -> "你正在与技术专家对话...";
case "beginner" -> "你正在与初学者对话...";
default -> "你是一个专业的助手...";
};
// 增强 SystemMessage
SystemMessage enhanced = new SystemMessage(request.getSystemMessage().getText() + "\n\n" + dynamicPrompt);
return handler.call(ModelRequest.builder(request).systemMessage(enhanced).build());
}
}
3.4 对话记忆:支持多轮上下文
使用 MemorySaver 维护会话状态:
java
// 示例13:配置记忆
ReactAgent agent = ReactAgent.builder()
.saver(new MemorySaver()) // 内存存储(生产环境建议用 Redis)
.build();
RunnableConfig config = RunnableConfig.builder().threadId("user_123").build();
agent.call("我叫张三", config);
AssistantMessage resp = agent.call("我叫什么名字?", config); // 输出: "你叫张三"
3.5 流式响应:实时输出
支持 Reactive 流式处理:
java
// 示例10.1:基础流式调用
Flux<NodeOutput> stream = agent.stream("帮我写一首关于春天的诗");
stream.subscribe(output -> {
if (!output.isSTART() && !output.isEND()) {
System.out.println("Token: " + output.tokenUsage());
}
});
3.6 结构化输出:强制 JSON/POJO
两种方式:
- 类型安全 :
outputType(PoemOutput.class) - Schema 约束 :
outputSchema("{summary:..., keywords:...}")
java
// 示例11:outputType
ReactAgent agent = ReactAgent.builder()
.outputType(PoemOutput.class) // 自动校验并反序列化
.build();
4. 高级扩展:Hook 与 Interceptor
4.1 Agent 生命周期钩子(Hook)
java
// 示例14:日志 Hook
public static class LoggingHook extends AgentHook {
@Override
public HookPosition[] getHookPositions() {
return new HookPosition[]{HookPosition.BEFORE_AGENT, HookPosition.AFTER_AGENT};
}
@Override
public CompletableFuture<Map<String, Object>> beforeAgent(...) {
System.out.println("Agent 开始执行");
return CompletableFuture.completedFuture(Map.of());
}
}
4.2 模型调用拦截器(Interceptor)
用于内容安全、消息裁剪等:
java
// 示例15:消息裁剪 Hook(防 Token 超限)
public static class MessageTrimmingHook extends ModelHook {
private static final int MAX_MESSAGES = 10;
@Override
public CompletableFuture<Map<String, Object>> beforeModel(OverAllState state, ...) {
List<Message> messages = (List<Message>) state.value("messages").orElse(List.of());
if (messages.size() > MAX_MESSAGES) {
return CompletableFuture.completedFuture(
Map.of("messages", messages.subList(messages.size() - MAX_MESSAGES, messages.size()))
);
}
return CompletableFuture.completedFuture(Map.of());
}
}
5. 完整源码及执行结果
5.1 完整源码
- 选择你的 LLM 提供商并获取 API-KEY(如阿里云百炼的 DashScope),格式为:sk-xxx
- 需要设置系统全局变量:AI_DASHSCOPE_API_KEY = sk-xxxx
- 将语句【System.getenv("AI_DASHSCOPE_API_KEY") 】替换成具体的api-key
java
/*
* Copyright 2024-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.cloud.ai.examples.documentation.framework.tutorials;
import com.alibaba.cloud.ai.dashscope.api.DashScopeApi;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import com.alibaba.cloud.ai.graph.NodeOutput;
import com.alibaba.cloud.ai.graph.OverAllState;
import com.alibaba.cloud.ai.graph.RunnableConfig;
import com.alibaba.cloud.ai.graph.agent.ReactAgent;
import com.alibaba.cloud.ai.graph.agent.hook.AgentHook;
import com.alibaba.cloud.ai.graph.agent.hook.HookPosition;
import com.alibaba.cloud.ai.graph.agent.hook.ModelHook;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelCallHandler;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelInterceptor;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelRequest;
import com.alibaba.cloud.ai.graph.agent.interceptor.ModelResponse;
import com.alibaba.cloud.ai.graph.agent.interceptor.ToolCallHandler;
import com.alibaba.cloud.ai.graph.agent.interceptor.ToolCallRequest;
import com.alibaba.cloud.ai.graph.agent.interceptor.ToolCallResponse;
import com.alibaba.cloud.ai.graph.agent.interceptor.ToolInterceptor;
import com.alibaba.cloud.ai.graph.checkpoint.savers.MemorySaver;
import com.alibaba.cloud.ai.graph.exception.GraphRunnerException;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ToolContext;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.ai.tool.function.FunctionToolCallback;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import reactor.core.publisher.Flux;
/**
* Agents Tutorial - agents.md
*/
public class AgentsExample {
// ==================== 基础模型配置 ====================
/**
* 示例1:基础模型配置
*/
public static void basicModelConfiguration() {
// 创建 DashScope API 实例
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
// 创建 ChatModel
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
// 创建 Agent
ReactAgent agent = ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.build();
}
/**
* 示例2:高级模型配置
*/
public static void advancedModelConfiguration() {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.defaultOptions(DashScopeChatOptions.builder()
.withTemperature(0.7) // 控制随机性
.withMaxToken(2000) // 最大输出长度
.withTopP(0.9) // 核采样参数
.build())
.build();
}
// ==================== 工具定义 ====================
public static void toolUsage() {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
// 创建工具回调
ToolCallback searchTool = FunctionToolCallback
.builder("search", new SearchTool())
.description("搜索信息的工具")
.inputType(String.class)
.build();
// 使用多个工具
ReactAgent agent = ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.tools(searchTool)
.build();
}
/**
* 示例5:基础 System Prompt
*/
public static void basicSystemPrompt() {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
ReactAgent agent = ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.systemPrompt("你是一个专业的技术助手。请准确、简洁地回答问题。")
.build();
}
/**
* 示例6:使用 instruction
*/
public static void instructionUsage() {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
String instruction = """
你是一个经验丰富的软件架构师。
在回答问题时,请:
1. 首先理解用户的核心需求
2. 分析可能的技术方案
3. 提供清晰的建议和理由
4. 如果需要更多信息,主动询问
保持专业、友好的语气。
""";
ReactAgent agent = ReactAgent.builder()
.name("architect_agent")
.model(chatModel)
.instruction(instruction)
.build();
}
// ==================== System Prompt ====================
public static void dynamicSystemPrompt() {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
ReactAgent agent = ReactAgent.builder()
.name("adaptive_agent")
.model(chatModel)
.interceptors(new DynamicPromptInterceptor())
.build();
}
/**
* 示例8:基础调用
*/
public static void basicInvocation() throws GraphRunnerException {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
ReactAgent agent = ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.build();
// 字符串输入
AssistantMessage response = agent.call("杭州的天气怎么样?");
System.out.println(response.getText());
// UserMessage 输入
UserMessage userMessage = new UserMessage("帮我分析这个问题");
AssistantMessage response2 = agent.call(userMessage);
// 多个消息
List<Message> messages = List.of(
new UserMessage("我想了解 Java 多线程"),
new UserMessage("特别是线程池的使用")
);
AssistantMessage response3 = agent.call(messages);
}
/**
* 示例9:获取完整状态
*/
public static void getFullState() throws GraphRunnerException {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
ReactAgent agent = ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.build();
Optional<OverAllState> result = agent.invoke("帮我写一首诗");
if (result.isPresent()) {
OverAllState state = result.get();
// 访问消息历史
Optional<Object> messages = state.value("messages");
List<Message> messageList = (List<Message>) messages.get();
// 访问自定义状态
Optional<Object> customData = state.value("custom_key");
System.out.println("完整状态:" + state);
}
}
/**
* 示例10:使用配置
*/
public static void useConfiguration() throws GraphRunnerException {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
ReactAgent agent = ReactAgent.builder()
.name("my_agent")
.model(chatModel)
.build();
String threadId = "thread_123";
RunnableConfig runnableConfig = RunnableConfig.builder()
.threadId(threadId)
.addMetadata("key", "value")
.build();
AssistantMessage response = agent.call("你的问题", runnableConfig);
}
// ==================== 调用 Agent ====================
/**
* 示例10.1:流式调用 - 基础用法
*/
public static void basicStreamInvocation() throws GraphRunnerException {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
ReactAgent agent = ReactAgent.builder()
.name("streaming_agent")
.model(chatModel)
.build();
// 流式输出
Flux<NodeOutput> stream = agent.stream("帮我写一首关于春天的诗");
stream.subscribe(
output -> {
// 处理每个节点输出
System.out.println("节点: " + output.node());
System.out.println("Agent: " + output.agent());
if (output.tokenUsage() != null) {
System.out.println("Token使用: " + output.tokenUsage());
}
},
error -> System.err.println("错误: " + error.getMessage()),
() -> System.out.println("流式输出完成")
);
}
/**
* 示例10.2:流式调用 - 高级用法
*/
public static void advancedStreamInvocation() throws GraphRunnerException {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
ReactAgent agent = ReactAgent.builder()
.name("streaming_agent")
.model(chatModel)
.saver(new MemorySaver())
.build();
RunnableConfig config = RunnableConfig.builder()
.threadId("stream_thread_1")
.build();
// 使用配置的流式调用
Flux<NodeOutput> stream = agent.stream(new UserMessage("解释一下量子计算"), config);
// 使用 doOnNext 处理中间输出
stream.doOnNext(output -> {
if (!output.isSTART() && !output.isEND()) {
System.out.println("处理中...");
System.out.println("当前节点: " + output.node());
}
})
.doOnComplete(() -> System.out.println("所有节点处理完成"))
.doOnError(e -> System.err.println("流处理错误: " + e.getMessage()))
.blockLast(); // 阻塞等待完成
}
/**
* 示例10.3:流式调用 - 收集所有输出
*/
public static void collectStreamOutputs() throws GraphRunnerException {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
ReactAgent agent = ReactAgent.builder()
.name("streaming_agent")
.model(chatModel)
.build();
Flux<NodeOutput> stream = agent.stream("分析机器学习的应用场景");
// 收集所有输出
List<NodeOutput> outputs = stream.collectList().block();
if (outputs != null) {
System.out.println("总共收到 " + outputs.size() + " 个节点输出");
// 获取最终输出
NodeOutput lastOutput = outputs.get(outputs.size() - 1);
System.out.println("最终状态: " + lastOutput.state());
// 获取消息
Optional<Object> messages = lastOutput.state().value("messages");
if (messages.isPresent()) {
List<Message> messageList = (List<Message>) messages.get();
Message lastMessage = messageList.get(messageList.size() - 1);
if (lastMessage instanceof AssistantMessage assistantMsg) {
System.out.println("最终回复: " + assistantMsg.getText());
}
}
}
}
public static void structuredOutputWithType() throws GraphRunnerException {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
ReactAgent agent = ReactAgent.builder()
.name("poem_agent")
.model(chatModel)
.outputType(PoemOutput.class)
.saver(new MemorySaver())
.build();
AssistantMessage response = agent.call("写一首关于春天的诗");
// 输出会遵循 PoemOutput 的结构
System.out.println(response.getText());
}
/**
* 示例12:使用 outputSchema
*/
public static void structuredOutputWithSchema() throws GraphRunnerException {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
String customSchema = """
请严格按照以下JSON格式返回结果:
{
"summary": "内容摘要",
"keywords": ["关键词1", "关键词2", "关键词3"],
"sentiment": "情感倾向(正面/负面/中性)",
"confidence": 0.95
}
""";
ReactAgent agent = ReactAgent.builder()
.name("analysis_agent")
.model(chatModel)
.outputSchema(customSchema)
.saver(new MemorySaver())
.build();
AssistantMessage response = agent.call("分析这段文本:春天来了,万物复苏。");
}
/**
* 示例13:配置记忆
*/
public static void configureMemory() throws GraphRunnerException {
DashScopeApi dashScopeApi = DashScopeApi.builder()
.apiKey(System.getenv("AI_DASHSCOPE_API_KEY"))
.build();
ChatModel chatModel = DashScopeChatModel.builder()
.dashScopeApi(dashScopeApi)
.build();
// 配置内存存储
ReactAgent agent = ReactAgent.builder()
.name("chat_agent")
.model(chatModel)
.saver(new MemorySaver())
.build();
// 使用 thread_id 维护对话上下文
RunnableConfig config = RunnableConfig.builder()
.threadId("user_123")
.build();
agent.call("我叫张三", config);
agent.call("我叫什么名字?", config); // 输出: "你叫张三"
}
// ==================== 结构化输出 ====================
public static void main(String[] args) {
System.out.println("=== Agents Tutorial Examples ===");
System.out.println("注意:需要设置 AI_DASHSCOPE_API_KEY 环境变量\n");
try {
System.out.println("\n--- 示例1:基础模型配置 ---");
basicModelConfiguration();
System.out.println("\n--- 示例2:高级模型配置 ---");
advancedModelConfiguration();
System.out.println("\n--- 示例3:工具使用 ---");
toolUsage();
System.out.println("\n--- 示例5:基础 System Prompt ---");
basicSystemPrompt();
System.out.println("\n--- 示例6:使用 instruction ---");
instructionUsage();
System.out.println("\n--- 示例7:动态 System Prompt ---");
dynamicSystemPrompt();
System.out.println("\n--- 示例8:基础调用 ---");
basicInvocation();
System.out.println("\n--- 示例9:获取完整状态 ---");
getFullState();
System.out.println("\n--- 示例10:使用配置 ---");
useConfiguration();
System.out.println("\n--- 示例10.1:流式调用 - 基础用法 ---");
basicStreamInvocation();
System.out.println("\n--- 示例10.2:流式调用 - 高级用法 ---");
advancedStreamInvocation();
System.out.println("\n--- 示例10.3:流式调用 - 收集所有输出 ---");
collectStreamOutputs();
System.out.println("\n--- 示例11:使用 outputType ---");
structuredOutputWithType();
System.out.println("\n--- 示例12:使用 outputSchema ---");
structuredOutputWithSchema();
System.out.println("\n--- 示例13:配置记忆 ---");
configureMemory();
System.out.println("\n=== 所有示例执行完成 ===");
}
catch (GraphRunnerException e) {
System.err.println("执行示例时发生错误: " + e.getMessage());
e.printStackTrace();
}
catch (Exception e) {
System.err.println("发生未预期的错误: " + e.getMessage());
e.printStackTrace();
}
}
/**
* 示例3:定义和使用工具
*/
public static class SearchTool implements BiFunction<String, ToolContext, String> {
@Override
public String apply(
@ToolParam(description = "搜索关键词") String query,
ToolContext toolContext) {
return "搜索结果:" + query;
}
}
/**
* 示例4:工具错误处理
*/
public static class ToolErrorInterceptor extends ToolInterceptor {
@Override
public ToolCallResponse interceptToolCall(ToolCallRequest request, ToolCallHandler handler) {
try {
return handler.call(request);
}
catch (Exception e) {
return ToolCallResponse.of(request.getToolCallId(), request.getToolName(),
"Tool failed: " + e.getMessage());
}
}
@Override
public String getName() {
return "ToolErrorInterceptor";
}
}
// ==================== Memory ====================
/**
* 示例7:动态 System Prompt
*/
public static class DynamicPromptInterceptor extends ModelInterceptor {
@Override
public ModelResponse interceptModel(ModelRequest request, ModelCallHandler handler) {
// 基于上下文动态调整 system prompt
Map<String, Object> context = request.getContext();
// 根据上下文构建动态提示词
String dynamicPrompt = buildDynamicPrompt(context);
// 增强 system message
SystemMessage enhancedSystemMessage;
if (request.getSystemMessage() == null) {
enhancedSystemMessage = new SystemMessage(dynamicPrompt);
}
else {
enhancedSystemMessage = new SystemMessage(
request.getSystemMessage().getText() + "\n\n" + dynamicPrompt
);
}
// 创建增强的请求
ModelRequest modifiedRequest = ModelRequest.builder(request)
.systemMessage(enhancedSystemMessage)
.build();
return handler.call(modifiedRequest);
}
private String buildDynamicPrompt(Map<String, Object> context) {
// 示例:根据用户角色动态生成提示词
String userRole = (String) context.getOrDefault("user_role", "default");
return switch (userRole) {
case "expert" -> """
你正在与技术专家对话。
- 使用专业术语
- 深入技术细节
- 提供高级建议
""";
case "beginner" -> """
你正在与初学者对话。
- 使用简单易懂的语言
- 详细解释概念
- 提供入门级建议
""";
default -> """
你是一个专业的助手。
- 根据问题复杂度调整回答
- 保持友好和专业
""";
};
}
@Override
public String getName() {
return "DynamicPromptInterceptor";
}
}
// ==================== Hooks ====================
/**
* 示例11:使用 outputType
*/
public static class PoemOutput {
private String title;
private String content;
private String style;
// Getters and Setters
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getStyle() {
return style;
}
public void setStyle(String style) {
this.style = style;
}
}
/**
* 示例14:AgentHook - 在 Agent 开始/结束时执行
*/
public static class LoggingHook extends AgentHook {
@Override
public String getName() {
return "logging";
}
@Override
public HookPosition[] getHookPositions() {
return new HookPosition[] {
HookPosition.BEFORE_AGENT,
HookPosition.AFTER_AGENT
};
}
@Override
public CompletableFuture<Map<String, Object>> beforeAgent(OverAllState state, RunnableConfig config) {
System.out.println("Agent 开始执行");
return CompletableFuture.completedFuture(Map.of());
}
@Override
public CompletableFuture<Map<String, Object>> afterAgent(OverAllState state, RunnableConfig config) {
System.out.println("Agent 执行完成");
return CompletableFuture.completedFuture(Map.of());
}
}
// ==================== Interceptors ====================
/**
* 示例15:ModelHook - 在模型调用前后执行
*/
public static class MessageTrimmingHook extends ModelHook {
private static final int MAX_MESSAGES = 10;
@Override
public String getName() {
return "message_trimming";
}
@Override
public HookPosition[] getHookPositions() {
return new HookPosition[] {HookPosition.BEFORE_MODEL};
}
@Override
public CompletableFuture<Map<String, Object>> beforeModel(OverAllState state, RunnableConfig config) {
Optional<Object> messagesOpt = state.value("messages");
if (messagesOpt.isPresent()) {
List<Message> messages = (List<Message>) messagesOpt.get();
if (messages.size() > MAX_MESSAGES) {
return CompletableFuture.completedFuture(Map.of("messages",
messages.subList(messages.size() - MAX_MESSAGES, messages.size())));
}
}
return CompletableFuture.completedFuture(Map.of());
}
@Override
public CompletableFuture<Map<String, Object>> afterModel(OverAllState state, RunnableConfig config) {
return CompletableFuture.completedFuture(Map.of());
}
}
/**
* 示例16:ModelInterceptor - 内容安全检查
*/
public static class GuardrailInterceptor extends ModelInterceptor {
@Override
public ModelResponse interceptModel(ModelRequest request, ModelCallHandler handler) {
// 前置:检查输入
if (containsSensitiveContent(request.getMessages())) {
return ModelResponse.of(new AssistantMessage("检测到不适当的内容"));
}
// 执行调用
ModelResponse response = handler.call(request);
// 后置:检查输出
return sanitizeIfNeeded(response);
}
private boolean containsSensitiveContent(List<Message> messages) {
// 实现敏感内容检测逻辑
return false;
}
private ModelResponse sanitizeIfNeeded(ModelResponse response) {
// 实现响应清理逻辑
return response;
}
@Override
public String getName() {
return "GuardrailInterceptor";
}
}
// ==================== Main 方法 ====================
/**
* 示例17:ToolInterceptor - 监控和错误处理
*/
public static class ToolMonitoringInterceptor extends ToolInterceptor {
@Override
public ToolCallResponse interceptToolCall(ToolCallRequest request, ToolCallHandler handler) {
long startTime = System.currentTimeMillis();
try {
ToolCallResponse response = handler.call(request);
logSuccess(request, System.currentTimeMillis() - startTime);
return response;
}
catch (Exception e) {
logError(request, e, System.currentTimeMillis() - startTime);
return ToolCallResponse.of(request.getToolCallId(), request.getToolName(),
"工具执行遇到问题,请稍后重试");
}
}
private void logSuccess(ToolCallRequest request, long duration) {
System.out.println("Tool " + request.getToolName() + " succeeded in " + duration + "ms");
}
private void logError(ToolCallRequest request, Exception e, long duration) {
System.err.println("Tool " + request.getToolName() + " failed in " + duration + "ms: " + e.getMessage());
}
@Override
public String getName() {
return "ToolMonitoringInterceptor";
}
}
}
5.2 执行结果
=== Agents Tutorial Examples ===
注意:需要设置 AI_DASHSCOPE_API_KEY 环境变量
--- 示例1:基础模型配置 ---
--- 示例2:高级模型配置 ---
--- 示例3:工具使用 ---
--- 示例5:基础 System Prompt ---
--- 示例6:使用 instruction ---
--- 示例7:动态 System Prompt ---
--- 示例8:基础调用 ---
我目前无法获取实时天气信息。建议您通过可靠的天气预报网站或应用(如中国气象局、中央气象台、天气通、墨迹天气等)查询杭州当前的天气情况。通常这些平台会提供温度、湿度、风力、空气质量以及未来几天的天气趋势等详细信息。
如果您告诉我具体想了解的时间段(比如今天、明天或未来一周),我可以帮您分析一般情况下杭州那个时段的气候特点。
--- 示例9:获取完整状态 ---
完整状态:{"OverAllState":{"data":{"input":"帮我写一首诗","messages":[{"messageType":"USER","metadata":{"messageType":"USER"},"media":[],"text":"帮我写一首诗"},{"messageType":"ASSISTANT","metadata":{"search_info":"","role":"ASSISTANT","messageType":"ASSISTANT","finishReason":"STOP","id":"4fac813d-4144-4811-a0ff-9c3fc98478d9","reasoningContent":""},"toolCalls":[],"media":[],"text":"春风拂柳绿成行, \n细雨轻沾花自香。 \n燕语呢喃穿旧巷, \n蝶影翩跹过矮墙。 \n\n远山含黛云作裳, \n流水潺潺入梦长。 \n不问人间纷扰事, \n一壶清酒醉斜阳。"}]}}}
--- 示例10:使用配置 ---
--- 示例10.1:流式调用 - 基础用法 ---
节点: __START__
Agent: streaming_agent
--- 示例10.2:流式调用 - 高级用法 ---
处理中...
当前节点: model
处理中...
当前节点: model
节点: model
Agent: streaming_agent
Token使用: DefaultUsage{promptTokens=15, completionTokens=1, totalTokens=16}
处理中...
当前节点: model
节点: model
Agent: streaming_agent
Token使用: DefaultUsage{promptTokens=15, completionTokens=3, totalTokens=18}
(中间省略...)
节点: model
Agent: streaming_agent
Token使用: DefaultUsage{promptTokens=15, completionTokens=103, totalTokens=118}
节点: __END__
Agent: streaming_agent
流式输出完成
处理中...
当前节点: model
处理中...
(中间省略...)
当前节点: model
所有节点处理完成
--- 示例10.3:流式调用 - 收集所有输出 ---
总共收到 246 个节点输出
最终状态: {"OverAllState":{"data":{"input":"分析机器学习的应用场景","messages":[{"messageType":"USER","metadata":{"messageType":"USER"},"media":[],"text":"分析机器学习的应用场景"},{"messageType":"ASSISTANT","metadata":{"search_info":"","role":"ASSISTANT","messageType":"ASSISTANT","finishReason":"STOP","id":"54b1fea9-c981-4580-9bc2-5a9358d1f584","reasoningContent":""},"toolCalls":[],"media":[],"text":"机器学习(Machine Learning, ML)作为人工智能的核心技术之一,已在众多领域展现出强大的应用潜力。它通过从数据中自动学习模式和规律,实现预测、分类、聚类、推荐等功能。以下是机器学习的主要应用场景分析:\n\n---\n\n### 1. **互联网与电子商务**\n- **个性化推荐系统** \n 如电商网站(淘宝、京东)、视频平台(Netflix、YouTube)利用协同过滤、深度学习等算法为用户推荐商品或内容。\n- **搜索引擎优化** \n 通过自然语言处理(NLP)和排序学习(Learning to Rank)提升搜索结果的相关性。\n- **广告投放与点击率预测** \n 利用机器学习模型预测用户对广告的点击概率,实现精准营销。\n\n---\n\n### 2. **金融科技(FinTech)**\n- **信用评分与风控** \n 基于用户历史行为、交易记录等数据构建信用评估模型,判断贷款违约风险。\n- **欺诈检测** \n 使用异常检测算法识别信用卡盗刷、洗钱等异常交易行为。\n- **股票市场预测与量化交易** \n 利用时间序列分析、强化学习等方法辅助投资决策(需注意市场不确定性)。\n\n---\n\n### 3. **医疗健康**\n- **疾病诊断与辅助决策** \n 图像识别用于医学影像分析(如X光、CT、MRI),辅助医生诊断癌症、肺炎等疾病。\n- **基因组学与药物研发** \n 分析基因序列数据,发现致病基因;加速新药分子筛选过程。\n- **健康监测与预测** \n 可穿戴设备结合机器学习预测心律失常、糖尿病并发症等。\n\n---\n\n### 4. **智能制造与工业自动化**\n- **预测性维护(Predictive Maintenance)** \n 分析传感器数据预测设备故障,减少停机时间和维修成本。\n- **质量控制** \n 利用计算机视觉检测产品缺陷(如芯片、汽车零部件)。\n- **生产流程优化** \n 通过强化学习或回归模型优化参数配置,提高生产效率。\n\n---\n\n### 5. **交通运输与自动驾驶**\n- **智能交通管理** \n 预测交通流量、优化信号灯控制,缓解拥堵。\n- **自动驾驶** \n 感知(目标检测、语义分割)、决策(路径规划)、控制(动作执行)均依赖深度学习与强化学习。\n- **路径规划与物流优化** \n 快递配送路线优化、网约车调度等使用图神经网络或运筹学结合ML的方法。\n\n---\n\n### 6. **自然语言处理(NLP)**\n- **语音识别与合成** \n 如Siri、小爱同学等智能助手背后的语音转文字、文字转语音技术。\n- **机器翻译** \n Google Translate、DeepL 等基于Transformer架构实现高质量翻译。\n- **情感分析与舆情监控** \n 分析社交媒体评论、新闻文本中的情绪倾向,用于品牌管理或政策制定。\n\n---\n\n### 7. **教育科技(EdTech)**\n- **个性化学习路径推荐** \n 根据学生的学习行为和成绩推荐适合的学习资源。\n- **智能阅卷与作业批改** \n 自动批改选择题、填空题甚至作文(结合NLP)。\n- **学习效果预测** \n 预测学生是否可能挂科,提前干预。\n\n---\n\n### 8. **农业与环境科学**\n- **精准农业** \n 利用遥感图像和气象数据预测作物产量、病虫害风险。\n- **气候建模与灾害预警** \n 分析气候变化趋势,预测洪水、干旱等自然灾害。\n- **土壤与水质分析** \n 传感器数据结合模型评估土地适宜性或污染程度。\n\n---\n\n### 9. **安全与安防**\n- **人脸识别与身份验证** \n 广泛应用于门禁系统、支付验证、公共安全监控。\n- **网络安全威胁检测** \n 检测恶意软件、DDoS攻击、异常登录行为等。\n- **视频监控智能分析** \n 行为识别(如跌倒、打架)、人群密度监测等。\n\n---\n\n### 10. **娱乐与创意产业**\n- **内容生成(AIGC)** \n 文本生成(如ChatGPT)、图像生成(如Stable Diffusion)、音乐创作等。\n- **游戏AI** \n NPC智能行为设计、游戏平衡性调优、玩家行为预测。\n- **影视特效与后期制作** \n 深度伪造(Deepfake)、自动剪辑、画质增强等。\n\n---\n\n## 总结:机器学习应用的关键特点\n\n| 特点 | 说明 |\n|------|------|\n| **数据驱动** | 所有应用都依赖大量高质量数据 |\n| **自动化决策** | 减少人工干预,提升效率 |\n| **可扩展性强** | 模型一旦训练完成,可快速部署到多个场景 |\n| **持续优化** | 支持在线学习,随时间不断改进性能 |\n\n---\n\n## 挑战与注意事项\n- 数据隐私与伦理问题(如人脸识别滥用)\n- 模型可解释性不足("黑箱"问题)\n- 过拟合与泛化能力差\n- 对标注数据的依赖高\n- 计算资源消耗大\n\n---\n\n随着算法进步(如大模型、自监督学习)、算力提升和数据积累,机器学习的应用场景将持续拓展,逐步渗透到社会生活的方方面面,推动智能化转型。未来,跨学科融合(如生物+AI、法律+AI)将成为新的增长点。"}]}}}
最终回复: 机器学习(Machine Learning, ML)作为人工智能的核心技术之一,已在众多领域展现出强大的应用潜力。它通过从数据中自动学习模式和规律,实现预测、分类、聚类、推荐等功能。以下是机器学习的主要应用场景分析:
---
### 1. **互联网与电子商务**
- **个性化推荐系统**
如电商网站(淘宝、京东)、视频平台(Netflix、YouTube)利用协同过滤、深度学习等算法为用户推荐商品或内容。
- **搜索引擎优化**
通过自然语言处理(NLP)和排序学习(Learning to Rank)提升搜索结果的相关性。
- **广告投放与点击率预测**
利用机器学习模型预测用户对广告的点击概率,实现精准营销。
---
### 2. **金融科技(FinTech)**
- **信用评分与风控**
基于用户历史行为、交易记录等数据构建信用评估模型,判断贷款违约风险。
- **欺诈检测**
使用异常检测算法识别信用卡盗刷、洗钱等异常交易行为。
- **股票市场预测与量化交易**
利用时间序列分析、强化学习等方法辅助投资决策(需注意市场不确定性)。
---
### 3. **医疗健康**
- **疾病诊断与辅助决策**
图像识别用于医学影像分析(如X光、CT、MRI),辅助医生诊断癌症、肺炎等疾病。
- **基因组学与药物研发**
分析基因序列数据,发现致病基因;加速新药分子筛选过程。
- **健康监测与预测**
可穿戴设备结合机器学习预测心律失常、糖尿病并发症等。
---
### 4. **智能制造与工业自动化**
- **预测性维护(Predictive Maintenance)**
分析传感器数据预测设备故障,减少停机时间和维修成本。
- **质量控制**
利用计算机视觉检测产品缺陷(如芯片、汽车零部件)。
- **生产流程优化**
通过强化学习或回归模型优化参数配置,提高生产效率。
---
### 5. **交通运输与自动驾驶**
- **智能交通管理**
预测交通流量、优化信号灯控制,缓解拥堵。
- **自动驾驶**
感知(目标检测、语义分割)、决策(路径规划)、控制(动作执行)均依赖深度学习与强化学习。
- **路径规划与物流优化**
快递配送路线优化、网约车调度等使用图神经网络或运筹学结合ML的方法。
---
### 6. **自然语言处理(NLP)**
- **语音识别与合成**
如Siri、小爱同学等智能助手背后的语音转文字、文字转语音技术。
- **机器翻译**
Google Translate、DeepL 等基于Transformer架构实现高质量翻译。
- **情感分析与舆情监控**
分析社交媒体评论、新闻文本中的情绪倾向,用于品牌管理或政策制定。
---
### 7. **教育科技(EdTech)**
- **个性化学习路径推荐**
根据学生的学习行为和成绩推荐适合的学习资源。
- **智能阅卷与作业批改**
自动批改选择题、填空题甚至作文(结合NLP)。
- **学习效果预测**
预测学生是否可能挂科,提前干预。
---
### 8. **农业与环境科学**
- **精准农业**
利用遥感图像和气象数据预测作物产量、病虫害风险。
- **气候建模与灾害预警**
分析气候变化趋势,预测洪水、干旱等自然灾害。
- **土壤与水质分析**
传感器数据结合模型评估土地适宜性或污染程度。
---
### 9. **安全与安防**
- **人脸识别与身份验证**
广泛应用于门禁系统、支付验证、公共安全监控。
- **网络安全威胁检测**
检测恶意软件、DDoS攻击、异常登录行为等。
- **视频监控智能分析**
行为识别(如跌倒、打架)、人群密度监测等。
---
### 10. **娱乐与创意产业**
- **内容生成(AIGC)**
文本生成(如ChatGPT)、图像生成(如Stable Diffusion)、音乐创作等。
- **游戏AI**
NPC智能行为设计、游戏平衡性调优、玩家行为预测。
- **影视特效与后期制作**
深度伪造(Deepfake)、自动剪辑、画质增强等。
---
## 总结:机器学习应用的关键特点
| 特点 | 说明 |
|------|------|
| **数据驱动** | 所有应用都依赖大量高质量数据 |
| **自动化决策** | 减少人工干预,提升效率 |
| **可扩展性强** | 模型一旦训练完成,可快速部署到多个场景 |
| **持续优化** | 支持在线学习,随时间不断改进性能 |
---
## 挑战与注意事项
- 数据隐私与伦理问题(如人脸识别滥用)
- 模型可解释性不足("黑箱"问题)
- 过拟合与泛化能力差
- 对标注数据的依赖高
- 计算资源消耗大
---
随着算法进步(如大模型、自监督学习)、算力提升和数据积累,机器学习的应用场景将持续拓展,逐步渗透到社会生活的方方面面,推动智能化转型。未来,跨学科融合(如生物+AI、法律+AI)将成为新的增长点。
--- 示例11:使用 outputType ---
{
"content": "春风拂面柳轻摇,\n细雨润花影自娇。\n燕语呢喃穿翠幕,\n桃红李白满山腰。\n溪流欢唱冰初解,\n草色遥看近却寥。\n最是一年光好处,\n踏青何必远寻桥。",
"style": "五言律诗",
"title": "春日即景"
}
--- 示例12:使用 outputSchema ---
--- 示例13:配置记忆 ---
=== 所有示例执行完成 ===
5. 执行上下文分析(来自 AgentsExample_执行结果.txt)
从你提供的 classpath 可确认依赖版本:
spring-ai-alibaba-graph-core-1.1.0.0-M5.jarspring-ai-alibaba-starter-a2a-nacos-1.1.0.0-M5.jardashscope-api相关组件
这表明示例运行在 Spring AI Alibaba 1.1.0.0-M5 版本,与 Spring Boot 3.5.7 兼容,符合当前最新预发布版特性。
6. 生产建议
- 内存存储替换 :
MemorySaver仅用于演示,生产环境应接入 Redis 或数据库。 - 工具幂等性:确保工具函数可重试、无副作用。
- Token 监控 :通过
NodeOutput.tokenUsage()控制成本。 - 错误熔断 :在
ToolInterceptor中实现重试或降级策略。
7. 结语
Spring AI Alibaba 的 Agent 能力,将大模型从"聊天机器人"升级为"可编程智能体"。通过声明式 API 与丰富的扩展点,开发者可以快速构建复杂 AI 应用,而无需深陷 LLM 底层细节。
📝 动手建议:
- 运行
AgentsExample.java主方法,观察各示例输出- 尝试替换
SearchTool为真实 API(如天气查询)- 在
DynamicPromptInterceptor中加入用户画像逻辑
8. 福利资源
- 📦 完整示例代码及执行结果已上传至附件
- 📚 Spring-AI-Alibaba官方文档:https://java2ai.com/docs/quick-start
- 🎁 免费额度:阿里云百炼平台提供 Qwen API 免费调用额度。可在注册/登录后,开通大模型服务获取
📝 版权声明 :本文为原创,遵循 CC 4.0 BY-SA 协议。转载请附原文链接及本声明。
🔖 关键词:#SpringAI #AlibabaCloud #Agent #智能体 #ReAct #AI微服务 #JavaAI #Qwen