青云
青云
发布于 2026-02-25 / 4 阅读
0
0

Spring AI Alibaba:智能Agent开发实战指南

一、pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.8</version>
        <relativePath/>
    </parent>

    <groupId>com.zhan.agent</groupId>
    <artifactId>agent-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>agent-demo</name>
    <description>agent demo</description>

    <properties>
        <java.version>17</java.version>
        <spring-ai-alibaba.version>1.1.0.0-M5</spring-ai-alibaba.version>
        <spring-ai.version>1.1.0-M4</spring-ai.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud.ai</groupId>
                <artifactId>spring-ai-alibaba-bom</artifactId>
                <version>${spring-ai-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- Spring Boot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Agent Framework -->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-agent-framework</artifactId>
        </dependency>
        <!-- Dash5cope(阿里云百炼) -->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
            <version>${spring-ai-alibaba.version}</version>
        </dependency>
        <!-- Graph Core -->
        <dependency>
            <groupId>com.alibaba.cloud.ai</groupId>
            <artifactId>spring-ai-alibaba-graph-core</artifactId>
        </dependency>

        <!-- Spring Boot Starter Test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

二、yml配置文件

spring:
  ai:
    dashscope:
      api-key: sk-09c7b571687b46d5a2e25a03fbddxxxx
  application:
    name: spring-ai-alibaba-demo
server:
  port: 8080
logging:
  level:
    com.alibaba.cloud.ai: DEBUG

三、agentConfig

package com.zhan.agent.config;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AgentConfig {
    @Bean
    public ChatClient chatBotAgent(ChatModel chatModel) {
        return ChatClient.builder(chatModel).defaultSystem("你是一个友好的AI助手,能够回答用户的问题。请用中文回答,保持回答简洁明了。").build();
    }

    @Bean
    public ChatClient calculatorAgent(ChatModel chatModel) {
        return ChatClient.builder(chatModel).defaultSystem("你是一个数学计算助手,能够处理各种数学计算问题。请用中文回答。").build();
    }

    @Bean
    public ChatClient creativeWriterAgent(ChatModel chatModel) {
        return ChatClient.builder(chatModel).defaultSystem("你是一个创意写作助手,擅长创作各种文体的内容。请用中文回答。").build();
    }
}

四、workflowController

package com.zhan.agent.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/workflow")
public class WorkflowController {

    @Autowired
    private ChatModel chatModel;

    @GetMapping("/execute")
    public String executeWorkflow(@RequestParam String input) {
        try {
            //模拟工作流:分类->处理->输出结果
            String classification = classifyInput(input);
            String result = processClassification(classification);
            return result;
        } catch (Exception e) {
            return "工作流执行错误:" + e.getMessage();
        }
    }

    private String classifyInput(String input) {
        String prompt = "请将以下文本分类为:积极、消极或中性。只返回分类结果,不要其他解释。\n\n文本:" + input;
        return ChatClient.builder(chatModel)
                .build()
                .prompt()
                .user(prompt)
                .call()
                .content();
    }

    private String processClassification(String classification) {
        String prompt = "根据分类结果生成相应的回复。分类:" + classification + "\n请生成一个简洁的回复。";
        return ChatClient.builder(chatModel)
                .build()
                .prompt()
                .user(prompt)
                .call()
                .content();
    }

    @GetMapping("/simple")
    public String simpleWorkflow(@RequestParam String input) {
        try {
            String result = ChatClient.builder(chatModel)
                    .build()
                    .prompt()
                    .user("请处理以下请求:" + input)
                    .call()
                    .content();
            return "工作流结果:" + result;
        } catch (Exception e) {
            return "工作流执行错误:" + e.getMessage();
        }
    }

    @GetMapping("/info")
    public String getWorkflowInfo() {
        return "简单工作流演示:输入文本->自动分类->处理结果";
    }
}

五、chatController

package com.zhan.agent.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

@RestController
@RequestMapping("/api")
public class ChatController {

    @Autowired
    @Qualifier("chatBotAgent")
    private ChatClient chatBotAgent;

    @Autowired
    @Qualifier("calculatorAgent")
    private ChatClient calculatorAgent;

    @Autowired
    @Qualifier("creativeWriterAgent")
    private ChatClient creativeWriterAgent;

    @Autowired
    private ChatModel chatModel;

    @GetMapping("/chat")
    public String chat(@RequestParam String query) {
        try {
            String response = chatBotAgent.prompt()
                    .user(query)
                    .call()
                    .content();
            return response;
        } catch (Exception e) {
            return "抱歉,处理请求时出现错误:" + e.getMessage();
        }
    }

    @GetMapping("/calculator")
    public String calculator(@RequestParam String query) {
        try {
            String response = calculatorAgent.prompt()
                    .user(query)
                    .call()
                    .content();
            return response;
        } catch (Exception e) {
            return "抱歉,计算出现错误:" + e.getMessage();
        }
    }

    @GetMapping("/creative")
    public String creative(@RequestParam String query) {
        try {
            String response = creativeWriterAgent.prompt()
                    .user(query)
                    .call()
                    .content();
            return response;
        } catch (Exception e) {
            return "抱歉,创作出现错误:" + e.getMessage();
        }
    }

    @GetMapping(value = "/stream", produces = "text/event-stream")
    public Flux<String> streamChat(@RequestParam String query) {
        return chatBotAgent.prompt()
                .user(query)
                .stream()
                .content()
                .onErrorReturn("抱歉,流式响应出现错误");
    }

    @GetMapping("/models")
    public String getModelInfo() {
        return "当前使用的模型:DashScope Qwen系列模型";
    }
}

六、index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>Spring AI Alibaba演示平台</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/daisyui/4.12.10/full.min.css" rel="stylesheet">
    <link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
</head>
<body class="bg-gray-50 min-h-screen">
    <!--导航栏-->
    <div class="navbar bg-gradient-to-r from-blue-600 to-purple-600 text-white shadow-lg">
        <div class="navbar-start">
            <div class="dropdown">
                <label tabindex="0" class="btn btn-ghost lg:hidden">
                    <i class="fas fa-bars text-xl"></i>
                </label>
                <ul tabindex="0" class="menu menu-compact dropdown-content mt-3 p-2 shadow bg-base-100 rounded-box w-52">
                    <li><a href="#chat" class="text-gray-800">智能对话</a></li>
                    <li><a href="#workflow" class="text-gray-800">工作流</a></li>
                    <li><a href="#features" class="text-gray-800">特性展示</a></li>
                </ul>
            </div>
            <a class="btn btn-ghost normal-case text-xl">
                <i class="fas fa-robot mr-2"></i>Spring AI Alibaba
            </a>
        </div>
        <div class="navbar-center hidden lg:flex">
            <ul class="menu menu-horizontal px-1">
                <li><a href="#chat" class="text-white hover:bg-white/20">智能对话</a></li>
                <li><a href="#workflow" class="text-white hover:bg-white/20">工作流</a></li>
                <li><a href="#features" class="text-white hover:bg-white/20">特性展示</a></li>
            </ul>
        </div>
        <div class="navbar-end">
            <button class="btn btn-ghost btn-circle">
                <i class="fas fa-cog text-xl"></i>
            </button>
        </div>
    </div>

    <!--主要内容区域-->
    <div class="container mx-auto px-4 py-8">
        <!--欢迎区域-->
        <div class="hero bg-gradient-to-r from-blue-50 to-purple-50 rounded-2xl mb-8">
            <div class="hero-content text-center py-12">
                <div class="max-w-2xl">
                    <h1 class="text-5xl font-bold text-gray-800 mb-4">
                        <i class="fas fa-brain text-blue-600 mr-3"></i>Spring AI Alibaba
                    </h1>
                    <p class="text-xl text-gray-600 mb-6">
                        基于ReactAgent设计理念,的智能Agent开发框架,支持多Agent编排、工作流管理和人在回路交互
                    </p>
                    <div class="flex justify-center space-x-4">
                        <div class="badge badge-primary badge-lg p-4">
                            <i class="fas fa-robot mr-2"></i>ReactAgent
                        </div>
                        <div class="badge badge-secondary badge-lg p-4">
                            <i class="fas fa-project-diagram mr-2"></i>Graph Core
                        </div>
                        <div class="badge badge-accent badge-lg p-4">
                            <i class="fas fa-users mr-2"></i>Agent
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!--功能区域-->
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
            <!--智能对话区域-->
            <div id="chat" class="card bg-white shadow-xl">
                <div class="card-body">
                    <h2 class="card-title text-2xl text-gray-800">
                        <i class="fas fa-comments text-blue-600 mr-2"></i>智能对话
                    </h2>
                    <p class="text-gray-60mb-4">体验基于ReactAgent的智能对话能力</p>
                    <div class="tabs tabs-boxed mb-4">
                        <a class="tab tab-active" onclick="switchChatMode('general')">通用对话</a>
                        <a class="tab" onclick="switchChatMode('calculator')">计算器</a>
                        <a class="tab" onclick="switchChatMode('writer')">创意写作</a>
                    </div>
                    <div class="form-control">
                        <label class="label">
                            <span class="label-text">输入您的问题</span>
                        </label>
                        <textarea id="chatInput" class="textarea textarea-bordered h-24"
                                  placeholder="请输入您想询问的问题.."></textarea>
                    </div>
                    <div class="card-actions justify-end mt-4">
                        <button onclick="streamChat()" class="btn btn-outline btn-primary">
                            <i class="fas fa-stream mr.-2"></i>流式对话
                        </button>
                        <button onclick="sendChat()" class="btn btn-primary">
                            <i class="fas fa-paper-plane mr-2"></i>发送
                        </button>
                    </div>
                </div>

                <div id="chatResponse" class="mt-4 p-4 bg-gray-50 rounded-lg hidden">
                    <div class="flex items-center mb-2">
                        <i class="fas fa-robot text-blue-600 mr-2"></i>
                        <span class="font-semibold">AI▣复:</span>
                    </div>
                    <div id="chatContent" class="text-gray-700"></div>
                </div>
            </div>

            <!--工作流演示区域-->
            <div id="workflow" class="card bg-white shadow-xl">
                <div class="card-body">
                    <h2 class="card-title text-2xl text-gray-800">
                        <i class="fas fa-project-diagram text-purple-600 mr-2"></i>工作流演示
                    </h2>
                    <p class="text-gray-600 mb-4">体验基于Graph Core的工作流编排</p>

                    <div class="form-control">
                        <label class="label">
                            <span class="label-text">输入文本进行分类</span>
                        </label>
                        <input id="workflowInput" type="text" class="input input-bordered" placeholder="请输入需要分类的文本..">
                    </div>

                    <div class="card-actions justify-end mt-4">
                        <button onclick="executeWorkflow()" class="btn btn-secondary">
                            <i class="fas fa-play mr-2"></i>执行工作流
                        </button>
                    </div>

                    <div id="workflowResult" class="mt-4 p-4 bg-purple-50 rounded-lg hidden">
                        <div class="flex items-center mb-2">
                            <i class="fas fa-chart-line text-purple-600 mr-2"></i>
                            <span class=-"font-semibold">工作流结果:</span>
                        </div>
                        <div id="workflowContent" class="text-gray-700 whitespace-pre-line"></div>
                    </div>
                </div>
            </div>
        </div>


        <!--特性展示区域-->
        <div id="features" class="mt-12">
            <h2 class="text-3xl font-bold text-center text-gray-800 mb-8">
                <i class="fas fa-star text-yellow-500 mr-3"></i>核心特性展示
            </h2>
            <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
                <div class="card bg-gradient-to-br from-blue-500 to-blue-600 text-white">
                    <div class="card-body text-center">
                        <i class="fas fa-brain text-4xl mb-4"></i>
                        <h3 class="card-title justify-center">ReactAgent</h3>
                        <p>基于ReAct范式的智能Agent,支持推理和行动能力</p>
                    </div>
                </div>
                <div class="card bg-gradient-to-br from-purple-500 to-purple-600 text-white">
                    <div class="card-body text-center">
                        <i class="fas fa-sitemap text-4xl mb-4"></i>
                        <h3 class="card-title justify-center'">多Agent编排</h3>
                        <p>支持Sequential、Parallel、Routing、Loop等多种编排模式</p>
                    </div>
                </div>
                <div class="card bg-gradient-to-br from-green-500 to-green-600 text-white">
                    <div class="card-body text-center">
                        <i class="fas fa-project-diagram text-4xl mb-4"></i>
                        <h3 class="card-title justify-center">Graph Core</h3>
                        <p>基于图的工作流运行时,支持条件路由和状态管理</p>
                    </div>
                </div>
                <div class="card bg-gradient-to-br from-orange-500 to-orange-600 text-white">
                    <div class="card-body text-center">
                        <i class="fas fa-user-check text-4xl mb-4"></i>
                        <h3 class="card-title justify-center">人在回路</h3>
                        <p>支持Human-in-the-loop交互,人工参与关键决策</p>
                    </div>
                </div>
            </div>
        </div>

        <!--架构图展示-->
        <div class="mt-12 card bg-white shadow-xl">
            <div class="card-body">
                <h2 class="card-title text-2xl text-gray-800 mb-6">
                    <i class="fas fa-layer-group text-indigo-600 mr-2"></i>架构层次
                </h2>
                <div class="space-y-4">
                    <div class="p-4 bg-gradient-to-r from-blue-100 to-blue-200 rounded-lg border-l-4 border-blue-500">
                        <h4 class="font-bold text-blue-800">Agent Framework(高级抽象层)</h4>
                        <p class="text-blue-700">ReactAgent,SequentialAgent,ParallelAgent,LlmRoutingAgent,LoopAgent</p>
                    </div>
                    <div class="text-center text-gray-400">
                        <i class="fas fa-arrow-down text-2xl"></i>
                    </div>
                    <div class="p-4 bg-gradient-to-r from-purple-100 to-purple-200 rounded-lg border-l-4 border-purple-500">
                        <h4 class="font-bold text-purple-800">Graph Core(工作流运行时)</h4>
                        <p class="text-purple-700">StateGraph,Node,Edge,OverAllState,CompiledGraph</p>
                    </div>
                    <div class="text-center text-gray-400">
                        <i class="fas fa-arrow-down text-2xl"></i>
                    </div>
                    <div class="p-4 bg-gradient-to-r from-green-100 to-green-200 rounded-lg border-l-4 border-green-500">
                        <h4 class="font-bold text-green-800">Spring AI(基础抽象层)</h4>
                        <p class="text-green-700">ChatModel,Tool,Message,MCP</p>
                    </div>
                </div>
            </div>
        </div>
    </div>

<!--页脚-->
<footer class="footer footer-center p-10 bg-gray-800 text-white mt-16">
    <div>
        <p class="text-lg">Spring AI Alibaba演示平台</p>
        <p class="text-sm opacity-7">基于ReactAgent设计理念,的智能Agent开发框架</p>
        <p class="text-xs opacity-50 mt-2">
            参考文档:<a href="https://blog.csdn.net/Traitsw/article/details/155613644" target="_blank"
                        class="link link-hover">CSDN-Spring AI Alibaba:智能Agent;开发实战指南</a>
        </p>
    </div>
</footer>

<script>
    let currentChatMode ='general';

    function switchChatMode(mode){
        currentChatMode = mode;
        document.querySelectorAll('.tab').forEach(tab => tab.classList.remove('tab-active'));
        event.target.classList.add('tab-active');

        const input = document.getElementById('chatInput');
        switch(mode){
            case 'general':
                input.placeholder='请输入您想询问的问题..';
                break;
            case 'calculator':
                input.placeholder='请输入数学计算问题,如:计算15+27*3';
                break;
            case 'writer':
                input.placeholder='请输入创作需求,如:写一篇关于春天的短文';
                break;
        }
    }

    async function sendChat() {
        const input = document.getElementById('chatInput').value.trim();
        if (!input) return;

        const responseDiv = document.getElementById('chatResponse');
        const contentDiv = document.getElementById('chatContent');

        responseDiv.classList.remove('hidden');
        contentDiv.innerHTML='<div class="loading loading-spinner loading-md"></div>正在处理..';
        try {
            let endpoint ='/api/chat';
            if (currentChatMode === 'calculator') endpoint = '/api/calculator';
            if (currentChatMode === 'writer') endpoint = '/api/creative';
            const response = await fetch(`${endpoint}?query=${encodeURIComponent(input)}`);
            const result = await response.text();

            contentDiv.innerHTML = result;
        } catch (error) {
            contentDiv.innerHTML='抱歉,请求失败:' + error.message;
        }
    }

    async function streamChat() {
        const input = document.getElementById('chatInput').value.trim();
        if (!input) return;

        const responseDiv = document.getElementById('chatResponse');
        const contentDiv = document.getElementById('chatContent');

        responseDiv.classList.remove('hidden');
        contentDiv.innerHTML='<div class="loading loading-spinner loading-md"></div>正在流式处理..';
        try {
            const response = await fetch(`/api/stream?query=${encodeURIComponent(input)}`);
            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let result ='';
            while (true) {
                const { done,value } = await reader.read();
                if (done) break;

                result += decoder.decode(value);
                contentDiv.innerHTML = result;
            }
        } catch (error){
            contentDiv.innerHTML='抱歉,流式请求失败:' + error.message;
        }
    }

    async function executeWorkflow(){
        const input = document.getElementById('workflowInput').value.trim();
        if (!input) return;

        const resultDiv = document.getElementById('workflowResult');
        const contentDiv = document.getElementById('workflowContent')

        resultDiv.classList.remove('hidden');
        contentDiv.innerHTML='<div class="loading loading-spinner loading-md"></div>正在执行工作流..';
        try {
            const response = await fetch(`/api/workflow/execute?input=${encodeURIComponent(input)}`);
            const result = await response.text();
            contentDiv.innerHTML = result;
        } catch (error){
            contentDiv.innerHTML='抱歉,工作流执行失败:' + error.message;
        }
    }

    //回车发送
    document.getElementById('chatInput').addEventListener('keypress',function(e){
        if (e.key === 'Enter' && !e.shiftKey){
            e.preventDefault();
            sendChat();
        }
    });

    document.getElementById('workflowInput').addEventListener('keypress',function(e){
        if (e.key === 'Enter'){
            e.preventDefault();
            executeWorkflow();
        }
    });
</script>
</body>
</html>

七、效果


评论