01.Spring AI Alibaba 智能体开发基础示例

一灰灰blogSpringAISpringSpringAI约 3926 字大约 13 分钟

Spring AI Alibaba 智能体开发实战:L01-Simple-Demo 教程

一、概述

L01-Simple-Demo 是基于 Spring AI Alibaba 框架开发的智能体(Agent)示例工程,展示了如何快速构建具备工具调用能力的 AI 应用。本项目面向希望入门大模型应用开发的程序员,通过两个典型的使用场景帮助读者理解 Spring AI Alibaba 的核心概念和开发模式。

核心特性

  • OpenAI 接口风格接入:通过 SiliconFlow API 兼容接入多种大模型
  • ReAct Agent:基于阿里巴巴 Graph 架构的推理代理
  • 工具调用:支持自定义工具扩展 AI 能力边界
  • 流式响应:实时返回处理进度,优化用户体验
  • 状态管理:支持多线程会话与上下文传递

二、环境准备

2.1 基础要求

组件版本要求说明
JDK17+Spring Boot 3.x 要求
Maven3.6+项目构建工具
网络可访问 SiliconFlow API国内可直接访问

2.2 API Key 申请

本项目使用 SiliconFlowopen in new window 提供的兼容 OpenAI API 的模型服务。访问其官网注册账号后,在控制台获取 API Key。

推荐模型:Qwen2.5-7B-Instruct(支持工具调用,性价比高)

获取 API Key 后,有两种配置方式:

方式一:环境变量(推荐)

export silicon-api-key=your-api-key-here

方式二:修改配置文件

编辑 src/main/resources/application.yml

spring:
  ai:
    openai:
      api-key: your-api-key-here

⚠️ 安全提示:生产环境务必使用环境变量或外部配置管理,切勿将 API Key 提交到代码仓库。


三、核心概念

3.1 Spring AI Alibaba

Spring AI Alibaba 是阿里巴巴开源的 AI 应用开发框架,基于 Spring AI 标准接口,深度集成阿里云大模型服务。核心优势包括:

  1. 统一抽象:提供与模型无关的编程接口,切换模型只需配置变更
  2. 工具生态:内置丰富的工具支持,减少重复开发
  3. Graph 架构:基于状态图的 Agent 实现,支持复杂业务流程编排

ReAct Agent

ReAct(Reasoning + Acting)是一种融合推理与执行的大模型应用范式。其核心思想是:

思考 → 行动 → 观察 → 思考 → ...

模型不再一次性生成完整答案,而是:

  1. 推理:分析当前问题,决定下一步行动
  2. 行动:调用工具或继续对话
  3. 观察:获取行动结果
  4. 迭代:基于观察结果继续推理

这种模式使 AI 能够处理需要外部知识的复杂任务。

3.2 流式响应

传统 HTTP 请求需要等待模型生成完整回答才能返回,体验较差。流式响应(Server-Sent Events)允许模型边生成边返回,用户无需等待完整结果即可看到AI的思考过程。


四、项目结构

L01-simple-demo/
├── pom.xml                          # Maven 依赖配置
├── src/main/
│   ├── java/com/git/hui/springai/ali/
│   │   ├── L01Application.java      # Spring Boot 启动类
│   │   └── mvc/
│   │       └── DemoController.java  # 核心控制器(两个 Demo)
│   └── resources/
│       └── application.yml          # 应用配置

关键依赖

<!-- Spring AI OpenAI 适配器 -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

<!-- Spring AI Alibaba Agent 框架 -->
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-agent-framework</artifactId>
    <version>1.1.2.0</version>
</dependency>

<!-- Web 启动器 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

五、代码详解

Demo 1:指令驱动的顾问 Agent

instructionUsage 方法展示了最简单的 Agent 使用方式——通过系统指令定义 AI 的角色和能力。

public Flux instructionUsage(String msg) throws GraphRunnerException {
    // 1. 定义系统指令
    String instruction = """
        你是一个经验丰富的软件架构师。
                    
        在回答问题时,请:
        1. 首先理解用户的核心需求
        2. 分析可能的技术方案
        3. 提供清晰的建议和理由
        4. 如果需要更多信息,主动询问
                    
        保持专业、友好的语气。
        """;

    // 2. 构建 Agent
    ReactAgent agent = ReactAgent.builder()
            .name("architect_agent")
            .model(chatModel)
            .instruction(instruction)
            .build();

    // 3. 同步调用
    Optional<OverAllState> result = agent.invoke(msg);
    
    // 4. 提取回答
    StringBuilder ans = new StringBuilder();
    if (result.isPresent()) {
        List<Message> messages = (List<Message>) result.get().value("messages").orElse(List.of());
        for (Message message : messages) {
            if (message instanceof AssistantMessage) {
                ans.append(message.getText());
            }
        }
    }
    return Flux.just(Map.of("content", ans.toString()));
}

关键点解析

步骤方法说明
定义角色.instruction()设置系统提示词,定义 Agent 行为
构建 AgentReactAgent.builder()创建 Agent 实例
同步执行.invoke()阻塞等待完整结果
获取结果OverAllState.value("messages")从状态中提取对话历史

调用示例

curl "http://localhost:8080/ask?type=instruction&msg=我想做个电商系统,请给点建议"

Demo 2:工具调用的天气助手

toolUsage 方法展示了 Agent 的核心能力——自主调用外部工具完成复杂任务。

1. 定义工具

// 天气查询工具
public static class WeatherTool implements BiFunction<Map<String, Object>, ToolContext, String> {
    @Override
    public String apply(@ToolParam(description = "城市名,如:武汉") Map<String, Object> params,
                        ToolContext toolContext) {
        String city = (String) params.get("city");
        if (city == null || city.isEmpty()) {
            return "错误:未提供城市名称";
        }
        return "It's always sunny in " + city + "!";
    }
}

// 用户位置工具 - 展示如何获取上下文
public class UserLocationTool implements BiFunction<Map, ToolContext, String> {
    @Override
    public String apply(@ToolParam(description = "用户查询") Map query,
                        ToolContext toolContext) {
        // 从上下文中获取用户信息
        RunnableConfig runnableConfig = (RunnableConfig) toolContext.getContext()
                .get(AGENT_CONFIG_CONTEXT_KEY);
        Optional<Object> userIdObjOptional = runnableConfig.metadata("user_id");
        String userId = userIdObjOptional.map(Object::toString).orElse("1");
        
        return "1".equals(userId) ? "武汉" : "上海";
    }
}

工具定义要点

  • 使用 @ToolParam 描述参数用途,AI 会据此决定如何填充参数
  • ToolContext 提供执行上下文,可获取用户信息、会话状态等
  • 返回值必须是 String,AI 会将结果融入回答

2. 注册工具

// 注册天气工具
ToolCallback weatherTool = FunctionToolCallback.builder("get_weather", new WeatherTool())
        .description("根据你传入的城市,返回对应的天气")
        .inputType(Map.class)
        .build();

// 注册用户位置工具
ToolCallback userLocationTool = FunctionToolCallback
        .builder("get_user_location", new UserLocationTool())
        .description("根据用户id查询用户所处的城市名")
        .inputType(Map.class)
        .build();

3. 构建 Agent 并配置上下文

// 创建 Agent,注入工具和系统提示
ReactAgent agent = ReactAgent.builder()
        .name("weather_agent")
        .model(chatModel)
        .tools(weatherTool, userLocationTool)
        .systemPrompt("""
            你现在是一个智能天气助手。当用户询问天气或提到城市时,请调用 get_weather 工具查询天气。
            如果你不知道具体的城市信息,请首先调用 get_user_location 工具查询用户所在的城市,然后再查询对应的天气信息返回
            注意:没有具体城市时,直接调用工具获取城市,不需要二次确认
            """)
        .saver(new MemorySaver())  // 启用状态持久化
        .build();

// 配置上下文(用户ID、线程ID)
String threadId = "1";
RunnableConfig runnableConfig = RunnableConfig.builder()
        .threadId(threadId)
        .addMetadata("user_id", "1")
        .build();

4. 流式执行

// 流式调用 Agent
Flux<NodeOutput> response = agent.stream(msg, runnableConfig);

// 处理不同类型的输出
return response.map(nodeOutput -> {
    if (nodeOutput instanceof StreamingOutput streamingOutput) {
        OutputType outputType = streamingOutput.getOutputType();
        
        switch (outputType) {
            case AGENT_MODEL_STREAMING:
                // 增量输出(打字机效果)
                return Map.of("content", nodeOutput.node() + "#delta:" + streamingOutput.message().getText());
                
            case AGENT_MODEL_FINISHED:
                // 完整回答生成完毕
                return Map.of("content", nodeOutput.node() + "#complete:" + streamingOutput.message().getText());
                
            case AGENT_TOOL_FINISHED:
                // 工具执行结果
                ToolResponseMessage toolMsg = (ToolResponseMessage) ((StreamingOutput<?>) nodeOutput).message();
                StringBuilder toolRes = new StringBuilder();
                for (ToolResponseMessage.ToolResponse rp : toolMsg.getResponses()) {
                    toolRes.append("Tool:").append(rp.name())
                           .append(" ==rsp=> ").append(rp.responseData());
                }
                return Map.of("content", nodeOutput.node() + "#tool_result:" + toolRes);
        }
    }
    return Map.of("content", "No response");
});

输出类型说明

类型说明典型场景
AGENT_MODEL_STREAMING模型正在生成实时显示回答
AGENT_MODEL_FINISHED模型生成完成回答结束标志
AGENT_TOOL_FINISHED工具执行完成显示工具返回结果

调用示例

curl -N "http://localhost:8080/ask?type=weather&msg=今天天气怎么样"

六、运行指南

6.1 启动应用

# 方式一:直接运行
cd L01-simple-demo
mvn spring-boot:run

# 方式二:打包后运行
mvn clean package
java -jar target/L01-simple-demo-0.0.1-SNAPSHOT.jar

6.2 测试接口

测试指令模式

curl -X POST "http://localhost:8080/ask" -d 'type=instruction&msg=如何设计一个高并发系统'

返回如下

data:{"content":"设计一个高并发系统是一个复杂但非常重要的任务,它涉及到多个方面的考量和设计决策。下面我将按照理解用户需求、分析可能的技术方案、提供清晰的建议和理由的步骤来回答。\n\n### 1. 理解用户需求\n\n首先,我们需要明确几个关键点:\n- **系统需要支持的最大并发用户数**:比如同时在线用户数、每秒处理请求数等。\n- **系统的业务特性**:比如是电商系统、社交应用、还是游戏服务等。\n- **系统的性能要求**:比如响应时间、吞吐量、可用性要求等。\n- **系统的扩展性要求**:是否需要随着用户量增长而扩展,如果需要的话,是水平扩展还是垂直扩展。\n- **系统的安全性要求**:是否需要特别的认证、授权机制等。\n\n### 2. 分析可能的技术方案\n\n基于上述需求,我们可以考虑以下几个方面的技术方案:\n\n#### 2.1 网络和服务器层\n\n- **负载均衡器**:如Nginx、LVS等,用于分散请求,避免单点故障。\n- **服务器集群**:通过增加服务器数量来提升整体处理能力。\n- **缓存**:使用Redis、Memcached等缓存服务来减少数据库的访问压力。\n\n#### 2.2 数据库层\n\n- **分布式数据库**:如MySQL集群、分布式数据库系统如TiDB、CockroachDB等,以支持高并发和大规模数据处理。\n- **读写分离**:数据库层采用读写分离的方式,提升数据库的读写性能。\n- **分布式事务**:使用TCC、Saga等协议来处理分布式事务。\n- **数据库缓存**:如Redis的缓存,减少数据库的直接访问。\n\n#### 2.3 编程语言和框架\n\n- **选择合适的编程语言**:如Java、Go、Python等,这些语言在并发处理上都有较好的支持。\n- **微服务架构**:将系统拆分为多个服务,每个服务独立部署,通过API进行通信。\n- **异步处理**:使用消息队列(如RabbitMQ、Kafka)和异步框架来处理请求,减少系统阻塞。\n\n#### 2.4 其他优化\n\n- **系统监控**:使用Prometheus、Grafana等工具监控系统性能,及时发现并解决问题。\n- **代码优化**:包括减少数据库查询、使用高效的算法和数据结构等。\n- **硬件优化**:选择高性能的服务器硬件,如使用SSD硬盘提高I/O性能等。\n\n### 3. 提供清晰的建议和理由\n\n根据上述分析,建议采用以下架构方案:\n\n- **多层架构设计**:包括前端、应用层、服务层、数据库层,确保系统的模块化和解耦。\n- **使用负载均衡技术**:在服务器层使用Nginx等负载均衡器,确保请求的均匀分布。\n- **数据库层面的优化**:采用读写分离、分布式数据库、数据库缓存等技术,减少数据库的压力。\n- **微服务架构**:将复杂应用拆分为多个小型服务,增强系统的可维护性和扩展性。\n- **异步处理**:利用消息队列进行异步处理,提高系统的响应速度和处理能力。\n- **持续监控和优化**:定期使用监控工具检查系统性能,并进行相应的优化调整。\n\n### 4. 如果需要更多信息,主动询问\n\n如需进一步讨论某个方面的细节或具体实现方法,请告知我。例如,您是否对某个特定技术有更深入的兴趣?或者,您是否有特定的业务场景需要特别考虑?"}

测试工具调用

curl -X POST 'http://localhost:8080/ask' -d 'type=weather&msg=今天天气怎么样'

6.3 预期输出

工具调用场景的流式输出类似:

data:{"content":"START"}
data:{"content":"_AGENT_MODEL_#delta:"}
data:{"content":"_AGENT_MODEL_#delta:"}
data:{"content":"_AGENT_MODEL_#complete:"}
data:{"content":"_AGENT_TOOL_#tool_result:Tool:get_user_location ==rsp=> \"武汉\""}
data:{"content":"_AGENT_MODEL_#delta:"}
data:{"content":"_AGENT_MODEL_#complete:"}
data:{"content":"_AGENT_MODEL_#delta:"}
data:{"content":"_AGENT_TOOL_#tool_result:Tool:get_weather ==rsp=> \"It's always sunny in 武汉!\""}
data:{"content":"_AGENT_MODEL_#delta:"}
data:{"content":"_AGENT_MODEL_#delta:今天"}
data:{"content":"_AGENT_MODEL_#delta:武汉"}
data:{"content":"_AGENT_MODEL_#delta:的"}
data:{"content":"_AGENT_MODEL_#delta:天气"}
data:{"content":"_AGENT_MODEL_#delta:总是"}
data:{"content":"_AGENT_MODEL_#delta:阳光"}
data:{"content":"_AGENT_MODEL_#delta:明媚"}
data:{"content":"_AGENT_MODEL_#delta:!"}
data:{"content":"_AGENT_MODEL_#delta:不过"}
data:{"content":"_AGENT_MODEL_#delta:实际情况"}
data:{"content":"_AGENT_MODEL_#delta:可能会"}
data:{"content":"_AGENT_MODEL_#delta:有所不同"}
data:{"content":"_AGENT_MODEL_#delta:,"}
data:{"content":"_AGENT_MODEL_#delta:可以"}
data:{"content":"_AGENT_MODEL_#delta:查看"}
data:{"content":"_AGENT_MODEL_#delta:天气"}
data:{"content":"_AGENT_MODEL_#delta:预报"}
data:{"content":"_AGENT_MODEL_#delta:获取"}
data:{"content":"_AGENT_MODEL_#delta:最新"}
data:{"content":"_AGENT_MODEL_#delta:信息"}
data:{"content":"_AGENT_MODEL_#delta:。"}
data:{"content":"_AGENT_MODEL_#delta:null"}
data:{"content":"_AGENT_MODEL_#complete:今天武汉的天气总是阳光明媚!不过实际情况可能会有所不同,可以查看天气预报获取最新信息。"}
data:{"content":"END"}

七、配置详解

application.yml 完整配置

spring:
  ai:
    openai:
      # API 地址(SiliconFlow 国内可直接访问)
      base-url: https://api.siliconflow.cn
      
      # API Key(建议通过环境变量注入)
      api-key: ${silicon-api-key}
      
      chat:
        options:
          # 支持的工具调用模型
          # - Qwen/Qwen2.5-7B-Instruct ✅ 推荐
          # - Qwen/Qwen3-8B ✅
          # - THUDM/GLM-Z1-9B-0414 ✅
          # - DeepSeek-R1 系列 ❌ 不支持工具调用
          model: Qwen/Qwen2.5-7B-Instruct

可选配置项

配置项说明默认值
spring.ai.openai.base-urlAPI 端点地址api.openai.comopen in new window
spring.ai.openai.api-key认证密钥-
spring.ai.openai.chat.options.temperature生成随机性0.7
spring.ai.openai.chat.options.maxTokens最大生成 token 数-
spring.ai.openai.chat.options.model指定模型-

八、扩展实践

8.1 添加更多工具

参考 WeatherTool 实现,可以添加:

  • 数据库查询工具:查询业务数据
  • API 调用工具:调用外部服务
  • 计算工具:执行复杂计算
  • 文件操作工具:读写文件

8.2 多 Agent 协作

Spring AI Alibaba Graph 架构支持构建多 Agent 工作流:

// 伪代码示例
Graph graph = Graph.builder()
    .start()
    .branch(agent1, condition1, agent2)
    .end();

8.3 持久化会话

当前示例使用 MemorySaver,生产环境可替换为:

  • 数据库存储:保存到 MySQL/PostgreSQL
  • Redis 缓存:高性能会话管理
  • 文件系统:简单场景使用

8.4 接入阿里云模型

如需使用阿里云闭源模型:

首先调整pom.xml依赖,直接引用 DashScope

  <!-- DashScope ChatModel 支持(如果使用其他模型,请跳转 Spring AI 文档选择对应的 starter) -->
  <dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
    <version>1.1.2.0</version>
  </dependency>

然后配置 API Key

推荐通过环境变量设置:

export AI_DASHSCOPE_API_KEY=your_api_key_here

当然也可以在应用配置文件中进行设置

# application.yml
spring:
  ai:
    dashscope:
      api-key: ${AI_DASHSCOPE_API_KEY}

九、常见问题

Q1: 模型不支持工具调用?

确保使用的模型支持 Function Calling。推荐使用:

  • Qwen2.5 系列
  • GLM-4 系列

以下模型不支持工具调用:

  • DeepSeek-R1(纯推理模型) -glm-4-9b-chat

Q2: 工具调用失败?

  1. 检查工具定义是否正确,特别是 @ToolParam 描述
  2. 确认模型输出格式是否符合工具输入要求
  3. 查看日志中的具体错误信息

Q3: 流式输出乱码?

确保请求头正确设置:

curl -N -H "Accept: text/event-stream; charset=utf-8" \
  "http://localhost:8080/ask?type=weather&msg=天气如何"

Q4: 如何调试 Agent?

在代码中添加详细日志:

System.out.println("NodeOutput: " + nodeOutput);

观察 OutputTypenodeOutput.node() 的变化,理解 Agent 执行流程。


十、总结

本教程通过两个典型场景,展示了 Spring AI Alibaba 的核心使用方式:

  1. 指令模式:通过系统提示定义 AI 角色,适合问答、辅导类场景
  2. 工具模式:赋予 AI 行动能力,适合需要访问外部数据的复杂任务

这两个模式的组合,可以构建出功能强大的智能应用。后续教程将深入探讨多 Agent 协作、向量数据库集成、Guardrails 安全防护等高级主题。

参考资料

作者: 一灰
日期: 2026-03-09
标签: #SpringAI #Alibaba #Agent #ReAct #LLM

Loading...