要求JDK:17+
devil-ai
搭建
<dependency>
<groupId>org.springframework.aigroupId>
<artifactId>spring-ai-bomartifactId>
<version>${spring-ai.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>com.alibaba.cloud.aigroupId>
<artifactId>spring-ai-alibaba-starterartifactId>
<version>${spring-ai-alibaba.version}version>
dependency>
devil-mcp
服务端搭建MCP
服务端依赖 本文使用响应式方案
<dependency>
<groupId>org.springframework.aigroupId>
<artifactId>spring-ai-mcp-server-webflux-spring-boot-starterartifactId>
dependency>
Tools
工具开发 - 提供给客户端调用package com.devil.mcp.tools;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.devil.mcp.entity.ArticleInfo;
import com.devil.mcp.service.ArticleInfoService;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Devil
* @version 1.0
* @description 文章信息工具
* @date 2025/4/11 21:38
*/
@Service
public class ArticleInfoTools {
@Autowired
private ArticleInfoService articleInfoService;
@Tool(description = "获取文章信息")
String getArticleInfo(@ToolParam(description = "标题") String title) {
ArticleInfo articleInfo = articleInfoService.getOne(Wrappers.<ArticleInfo>query().lambda().eq(ArticleInfo::getTitle, title));
return articleInfo.toString();
}
}
ArticleInfoTools
添加到Spring
容器中package com.devil.mcp.config;
import com.devil.mcp.tools.ArticleInfoTools;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Devil
* @version 1.0
* @description 工具配置类
* @date 2025/4/11 22:53
*/
@Configuration
public class ToolsConfiguration {
/**
* 文章信息工具注册Bean
*
* 该配置方法将文章信息相关工具封装为Spring AI可识别的工具回调提供者,
* 使得AI智能体可以通过自然语言指令调用文章处理能力。
*
* 实现特性:
*
* - 基于方法级工具注册机制,自动暴露标注了@ToolMethod的端点
* - 支持动态工具发现,与Spring AI的Function Calling机制无缝集成
* - 工具方法支持参数自动类型转换(JSON Schema → Java Type)
*
*
* @param articleInfoTools 文章信息工具集合(需实现具体工具方法)
* @return ToolCallbackProvider Spring AI工具回调提供者实例
* @author Devil
* @version 1.0.0
* @see ArticleInfoTools 具体工具方法实现类
* @see MethodToolCallbackProvider 方法级工具注册器
* @since 2025/4/11
*/
@Bean
public ToolCallbackProvider articleInfoProvider(ArticleInfoTools articleInfoTools) {
return MethodToolCallbackProvider.builder()
.toolObjects(articleInfoTools) // 注入实现了@ToolMethod注解的工具类
.build();
}
}
application.yml
配置信息server:
port: 8088
spring:
application:
name: devil-mcp
ai:
mcp:
server:
name: devil-mcp
version: 1.0.0
devil-assistant
客户端搭建MCP
服务端依赖和阿里百炼<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloud.aigroupId>
<artifactId>spring-ai-alibaba-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.aigroupId>
<artifactId>spring-ai-mcp-client-webflux-spring-boot-starterartifactId>
dependency>
ChatClient
聊天客户端构造器/**
* 聊天客户端构造器(组件装配核心)
*
* 通过Spring AI的ChatClientBuilder构建具备以下能力的聊天引擎:
*
* - 系统角色定义:设定助手的性格特征和行为规范
* - 对话拦截链:
*
* - PromptChatMemoryAdvisor:上下文记忆管理
* - LoggingAdvisor:请求/响应日志追踪
*
*
* - 工具集成:
*
* - AssistantTools:本地预置工具集
* - mcpTools:MCP协议远程工具
*
*
*
*
* @param chatClientBuilder 聊天客户端构建器(Spring AI自动装配)
* @param vectorStore 向量存储组件(用于RAG检索)
* @param chatMemory 对话记忆管理组件
* @param assistantTools 本地工具集合(文章处理/数据分析等)
* @param mcpTools MCP协议工具提供者(动态工具发现)
*/
public AssistantController(ChatClient.Builder chatClientBuilder,
VectorStore vectorStore,
ChatMemory chatMemory,
AssistantTools assistantTools,
ToolCallbackProvider mcpTools) {
this.chatClient = chatClientBuilder
.defaultSystem("""
您是“Devil”的助手。请以友好、乐于助人且愉快的方式来回复。
您正在通过在线聊天系统与客户互动。
在获取文章信息之前,您必须始终从用户处获取以下信息:文章标题。
请讲中文。
""")
.defaultAdvisors(
new PromptChatMemoryAdvisor(chatMemory), // 上下文记忆管理
new LoggingAdvisor()) // 日志追踪
.defaultTools(assistantTools) // 本地工具注册
.defaultTools(mcpTools) // MCP协议工具
.build();
}
AssistantTools
/**
* @author Devil
* @version 1.0
* @description 本地助手工具
* @date 2025/4/11 21:45
*/
@Slf4j
@Service
public class AssistantTools {
@Tool(description = "我的开发者是谁")
String getDeveloper() {
return "Devil";
}
}
AiConfiguration
package com.devil.assistant.config;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.embedding.EmbeddingModel;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* AI核心组件配置中心
*
* 本配置类负责构建AI系统基础架构,包括对话记忆管理、向量存储等关键组件,
* 为上层业务功能提供基础设施支持。
*
* 配置功能清单:
*
* - 内存型对话记录存储(开发环境适用)
* - 简易向量存储组件(基于Embedding模型)
*
*
* @author yuanxu
* @version 1.0
* @see InMemoryChatMemory 基于内存的对话记忆实现
* @see SimpleVectorStore 轻量级向量存储方案
* @since 2025/4/12
*/
@Configuration
public class AiConfiguration {
/**
* 对话记忆存储Bean(内存实现)
*
* 特性说明:
*
* - 采用ConcurrentHashMap实现线程安全的对话存储
* - 默认保存最近20轮对话(可通过配置参数调整)
* - 重启服务后数据丢失,建议生产环境替换为持久化实现
*
*
* @return ChatMemory 对话记忆接口实例
*
* @apiNote 生产建议:替换为RedisChatMemory等持久化实现
*/
@Bean
public ChatMemory chatMemory() {
return new InMemoryChatMemory(); // 开发环境快速启动方案
}
/**
* 向量存储组件配置
*
* 构建流程:
*
* - 注入Embedding模型实现(如OpenAIEmbeddingModel)
* - 初始化向量存储构建器
* - 配置相似度计算阈值(默认0.75)
*
*
* @param embeddingModel 嵌入模型(自动装配)
* @return VectorStore 向量存储实例
*
* @see EmbeddingModel 向量嵌入模型接口
* @warning 需要额外配置向量持久化策略(默认内存存储)
*/
@Bean
public VectorStore vectorStore(EmbeddingModel embeddingModel) {
return SimpleVectorStore.builder(embeddingModel)
.build(); // 可追加.withIndexFolder()配置持久化路径
}
}
LoggingAdvisor
package com.devil.assistant.advisor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.ai.chat.client.advisor.api.AdvisedRequest;
import org.springframework.ai.chat.client.advisor.api.AdvisedResponse;
import org.springframework.ai.chat.client.advisor.api.StreamAroundAdvisor;
import org.springframework.ai.chat.client.advisor.api.StreamAroundAdvisorChain;
import reactor.core.publisher.Flux;
/**
* 流式处理日志增强切面顾问
*
* 实现流式处理全生命周期的日志跟踪能力,作为Spring Cloud Stream的增强组件,
* 在消息流的处理链中注入日志切面,提供可观测性支持。
*
* 核心职责:
*
* - 记录流式请求的元数据(入参、上下文等)
* - 透传处理链保证消息流连续性
* - 支持多切面执行顺序控制(通过getOrder()调节优先级)
*
*
* @see StreamAroundAdvisor 流式切面顾问标准接口
* @see AdvisedRequest 增强请求包装对象(包含消息头/体)
* @see StreamAroundAdvisorChain 处理链上下文(责任链模式实现)
* @author Devil
* @version 1.0
* @date 2025/4/11 21:48
*/
@Slf4j
public class LoggingAdvisor implements StreamAroundAdvisor {
/**
* 环绕式流处理增强(DEBUG级别日志记录)
*
* 在流处理链执行前后添加日志跟踪点,注意:
*
* - 采用Reactive模式,需确保日志记录操作符的正确位置
* - 通过chain.nextAroundStream()保持流处理连续性
* - DEBUG级别日志避免记录敏感数据或过大消息体
*
*
* @param advisedRequest 增强请求对象(包含消息上下文)
* @param chain 处理链执行器(触发下一个切面/最终处理器)
* @return 响应流(保持背压传递特性)
*/
@NotNull
@Override
public Flux<AdvisedResponse> aroundStream(@NotNull AdvisedRequest advisedRequest, StreamAroundAdvisorChain chain) {
log.debug("request: {}", advisedRequest); // 记录请求快照
return chain.nextAroundStream(advisedRequest); // 透传处理链
}
/**
* 切面执行顺序(默认最高优先级)
*
* 数值越小优先级越高,建议:
*
* - 日志切面通常设置为最早执行(最小数值)
* - 安全校验类切面可设置为更高优先级(更小数值)
*
*
* @return 执行顺序标识(Spring OrderUtils优先级规范)
*/
@Override
public int getOrder() {
return 0; // 最高优先级执行
}
/**
* 获取切面标识(默认使用类全限定名)
*
* 用于:
*
* - 监控系统显示切面名称
* - 动态配置排除特定切面
* - 异常堆栈定位问题切面
*
*
* @return 切面唯一标识符
*/
@NotNull
@Override
public String getName() {
return this.getClass().getName(); // 使用类名保证唯一性
}
}
/**
* 流式对话接口(SSE协议)
*
* 技术实现要点:
*
* - 采用响应式流(Flux)处理持续对话
* - 动态注入当前日期作为系统参数
* - 集成问答建议顾问(基于向量检索的RAG)
* - 响应流结尾追加[complete]作为结束标识
*
*
* @param message 用户输入消息(默认示例:"讲个笑话")
* @return SSE事件流(text/event-stream)
* @apiNote 示例请求:GET /assistant/chat?message=什么是Spring AI
*/
@GetMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> generateStreamAsString(
@RequestParam(value = "message", defaultValue = "讲个笑话") String message) {
return chatClient.prompt()
.system(spec -> spec.param("current_date", LocalDate.now().toString())) // 注入时间上下文
.advisors(spec -> spec.param(AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY, 100)) // 记忆检索窗口
.user(message) // 用户输入
.advisors(new QuestionAnswerAdvisor(vectorStore, // RAG增强
SearchRequest.builder().query(message).build()))
.stream()
.content()
.concatWith(Flux.just("[complete]")); // 流结束标识
}
}
application.yml
server:
port: 8080
servlet:
encoding:
charset: UTF-8
enabled: true
force: true
spring:
application:
name: devil-assistant
ai:
dashscope:
api-key: #你的ApiKey
chat:
options:
model: #模型
mcp:
client:
enabled: true
name: devil-assistant
version: 1.0.0
request-timeout: 30s
type: ASYNC # or SYNC
sse:
connections:
server1:
url: http://localhost:8088
Gitee访问
GitCode访问