Spring AI Alibaba 企业级系统架构完整方案 + 实操
基于 Spring‑AI‑AlibabaDashScope 通义面向业务 AI 应用聊天对话、RAG 知识库、FunctionCall 工具调用、流式 SSE 输出、权限、链路追踪、向量库、文档解析、接口层。 技术基线JDK17SpringBoot 3.2.xspring‑ai‑alibaba:1.0.0‑M6.1向量库PGVector生产/ InMemory测试Mysql业务元数据Redis会话缓存OpenTelemetry 链路追踪能力对话、知识库 RAG、工具调用、文档上传解析、SSE 流式输出、多模型切换整体架构分为五层接入层 → 应用服务层 → AI 能力层 → 存储层 → 外部大模型服务。一、整体系统架构设计架构分层接入层前端 Web / 小程序网关 Spring Cloud Gateway鉴权、限流、SSE 长连接透传接口统一封装不直接暴露 AI 原生接口。应用服务层业务层会话管理服务用户对话历史管理、会话隔离、上下文窗口裁剪知识库 RAG 服务文档上传、解析PDF/MD/TXT、文本切分、向量化入库、检索召回Agent 服务FunctionCall 工具调用编排、多轮工具循环调用AI 对话服务普通对话、流式对话、多模态图文模型管理多模型动态切换qwen‑turbo/qwen‑plus/qwen‑max、模型参数动态配置AI 能力层Spring AI Alibaba 核心封装 Spring AI 标准 API底层对接 DashScope 通义ChatClient / DashScopeChatModel大模型聊天DashScopeEmbeddingModel文本向量化DocumentReader文档解析器VectorStore向量存储PromptTemplate提示词模板FunctionCallback函数调用注册存储层MySQL会话元数据、知识库元数据、文档元数据、用户权限PGVector向量数据库生产环境替代内存向量库Redis会话缓存、SSE 会话标记、限流、热点 Prompt 缓存文件存储MinIO存储原始上传文档 PDF 等外部依赖阿里云百炼 DashScope API 服务可扩展本地部署 Qwen 模型 (Ollama)业务流程RAG 问答完整链路用户提问 → Gateway鉴权限流 → AI服务 → 1.问题向量化 → 2.PGVector检索相似文档片段 → 3.组装Prompt系统提示词检索上下文用户问题 → 4.调用DashScope大模型 → 5.流式SSE返回结果同时保存对话会话入库 → 前端渲染打字机效果Agent FunctionCall 流程用户提问 → 判断是否需要调用工具 → 大模型输出工具调用参数 → 本地执行Java工具函数 → 将工具返回结果再次塞回上下文 → 再次交给大模型整合输出答案非功能设计超时控制大模型调用超时、SSE 超时熔断降级大模型接口不可用时熔断返回友好提示可观测token 消耗统计、调用耗时、异常日志、otel 链路追踪密钥安全API‑key 配置环境变量禁止配置文件硬编码支持多密钥轮询二、工程模块划分Maven 多模块ai‑alibaba‑parent 父工程 ├── ai‑alibaba‑common 公共模块常量、工具、异常、DTO、配置、链路追踪 ├── ai‑alibaba‑gateway SpringCloud Gateway网关鉴权限流SSE透传 ├── ai‑alibaba‑service AI核心业务服务主服务 │ └── src/main/java │ ├── config AI配置类ChatClient、向量库、Embedding、FunctionCall注册 │ ├── controller 对外接口聊天、流式、知识库、文档上传 │ ├── service │ │ ├── chat 对话会话服务 │ │ ├── rag RAG知识库服务文档解析、切片、向量入库、检索 │ │ ├── agent Agent工具调用服务 │ │ └── session 会话管理服务 │ ├── repository Mysql、PGVector操作 │ └── dto 请求响应对象 └── ai‑alibaba‑api 对外API定义feign DTO三、完整 pom 关键依赖父 service 模块父 pom.xml?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.2.5/version relativePath/ /parent groupIdcom.ai/groupId artifactIdai‑alibaba‑parent/artifactId version1.0.0‑SNAPSHOT/version packagingpom/packaging modules moduleai‑alibaba‑common/module moduleai‑alibaba‑service/module /modules properties java.version17/java.version spring.cloud.version2023.0.1/spring.cloud.version spring‑ai‑alibaba.version1.0.0‑M6.1/spring‑ai‑alibaba.version pgvector.version0.8.0/pgvector.version /properties dependencyManagement dependencies !-- Spring AI Alibaba 版本管理 -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring‑ai‑alibaba‑dependencies/artifactId version${spring‑ai‑alibaba.version}/version typepom/type scopeimport/scope /dependency !-- Spring Cloud -- dependency groupIdorg.springframework.cloud/groupId artifactIdspring‑cloud‑dependencies/artifactId version${spring.cloud.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement /projectai‑alibaba‑service pom.xmldependencies dependency groupIdcom.ai/groupId artifactIdai‑alibaba‑common/artifactId version${project.version}/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency !-- Spring AI Alibaba starter -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring‑ai‑alibaba‑spring‑boot‑starter/artifactId /dependency !-- PGVector向量库 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring‑ai‑pgvector‑store/artifactId /dependency !-- pdf文档解析 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring‑ai‑pdf‑reader/artifactId /dependency !-- postgresql驱动 -- dependency groupIdorg.postgresql/groupId artifactIdpostgresql/artifactId scoperuntime/scope /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies四、application.yml 完整配置生产向server: port: 8080 spring: application: name: ai‑alibaba‑service # mysql业务库 datasource: url: jdbc:mysql://127.0.0.1:3306/ai_biz?useUnicodetruecharacterEncodingutf8 username: root password: 123456 # pgvector向量库 ai: alibaba: api-key: ${SPRING_AI_ALIBABA_API_KEY:} base-url: https://dashscope.aliyuncs.com/api/v1 chat: options: model: qwen‑plus temperature: 0.7 max‑tokens: 2048 # pgvector向量存储配置 vectorstore: pgvector: index-type: HNSW distance-type: COSINE_DISTANCE table‑name: ai_vector_store # redis data: redis: host: 127.0.0.1 port: 6379 # 自定义业务参数 ai: rag: # 文档切分大小 chunk‑size: 800 chunk‑overlap: 100 # RAG召回数量 top‑k: 4api‑key 优先使用环境变量生产不要写配置文件。PGVector 环境准备Postgres15安装 pgvector 扩展CREATE EXTENSION IF NOT EXISTS vector;启动项目后会自动创建ai_vector_store向量表。五、核心配置类实操代码1. AI 配置 AiConfig.javapackage com.ai.service.config; import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel; import com.alibaba.cloud.ai.dashscope.embedding.DashScopeEmbeddingModel; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.document.DocumentSplitter; import org.springframework.ai.document.TokenTextSplitter; import org.springframework.ai.vectorstore.PgVectorStore; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; Configuration public class AiConfig { /** * ChatClient 构建器SpringAI标准入口 */ Bean public ChatClient chatClient(ChatClient.Builder builder) { return builder.build(); } /** * 文本切片器RAG文档切分 */ Bean public DocumentSplitter documentSplitter(Value(${ai.rag.chunk-size}) int chunkSize, Value(${ai.rag.chunk-overlap}) int chunkOverlap) { return new TokenTextSplitter(chunkSize, chunkOverlap); } /** * PGVector向量存储 */ Bean public VectorStore vectorStore(JdbcTemplate jdbcTemplate, DashScopeEmbeddingModel embeddingModel) { return PgVectorStore.builder(jdbcTemplate, embeddingModel) .tableName(ai_vector_store) .dimensions(1536) .build(); } }2. FunctionCall 工具注册示例Agent 能力自定义工具类实现本地方法供大模型调用package com.ai.service.agent.tool; import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Component; Component public class WeatherTool { /** * 工具方法大模型会自动识别注解调用该函数 */ Tool(description 查询指定城市当前天气情况) public String getWeather(String city) { // 这里写实际业务调用http请求第三方天气接口 return city 当前天气晴26℃; } }使用时在 ChatClient 把工具注册进去即可开启 Agent 能力chatClient.prompt() .tools(weatherTool) .user(查询北京天气) .call() .content();六、核心业务服务实操代码1. RAG 知识库服务Service RequiredArgsConstructor public class RagService { private final VectorStore vectorStore; private final DocumentSplitter documentSplitter; private final PdfDocumentReader pdfDocumentReader; /** * 上传PDF文档入库解析→切片→向量化→存入PGVector */ public void uploadPdf(InputStream inputStream) { // 读取pdf ListDocument docs pdfDocumentReader.read(inputStream); // 文本切分 ListDocument chunks documentSplitter.split(docs); // 向量入库 vectorStore.add(chunks); } /** * 根据用户问题做向量检索获取上下文片段 */ public ListDocument searchContext(String query, int topK) { SearchRequest searchRequest SearchRequest.builder() .query(query) .topK(topK) .build(); return vectorStore.similaritySearch(searchRequest); } }2. 对话服务RAG 增强 PromptService RequiredArgsConstructor public class ChatAiService { private final ChatClient chatClient; private final RagService ragService; Value(${ai.rag.top-k}) private Integer topK; private static final String RAG_SYSTEM_PROMPT 你是知识库问答助手请基于下面检索到的上下文回答用户问题。 如果上下文中没有答案如实告知不知道不要编造内容。 上下文 {context} ; /** * RAG普通对话 */ public String chatWithRag(String userQuestion) { // 向量检索 ListDocument docs ragService.searchContext(userQuestion, topK); String contextStr docs.stream().map(Document::getText).collect(Collectors.joining(\n)); PromptTemplate promptTemplate new PromptTemplate(RAG_SYSTEM_PROMPT); promptTemplate.add(context, contextStr); promptTemplate.add(question, userQuestion); return chatClient.prompt(promptTemplate.create()) .call() .content(); } /** * RAG流式SSE输出 */ public FluxString streamChatWithRag(String userQuestion) { ListDocument docs ragService.searchContext(userQuestion, topK); String contextStr docs.stream().map(Document::getText).collect(Collectors.joining(\n)); PromptTemplate promptTemplate new PromptTemplate(RAG_SYSTEM_PROMPT); promptTemplate.add(context, contextStr); promptTemplate.add(question, userQuestion); return chatClient.prompt(promptTemplate.create()) .stream() .content(); } }3. Controller 对外接口RestController RequestMapping(/ai) RequiredArgsConstructor public class AiController { private final ChatAiService chatAiService; private final RagService ragService; /** * 普通RAG问答 */ PostMapping(/chat) public String chat(RequestBody ChatReq req) { return chatAiService.chatWithRag(req.getQuestion()); } /** * SSE流式输出 */ GetMapping(value /stream/chat, produces MediaType.TEXT_EVENT_STREAM_VALUE) public FluxString streamChat(RequestParam String question) { return chatAiService.streamChatWithRag(question); } /** * 上传PDF知识库文档 */ PostMapping(/rag/upload) public void uploadPdf(RequestPart(file) MultipartFile file) throws IOException { ragService.uploadPdf(file.getInputStream()); } }DTO 对象 ChatReq.javaData public class ChatReq { private String question; }七、会话管理实现关键点真实业务不能只靠大模型上下文需要自己做会话持久化数据库表保存会话 id、用户 id、消息角色 (user/assistant)、消息内容、创建时间每次对话把历史消息组装到 Prompt同时做窗口裁剪防止 token 超限Redis 缓存最近 N 条会话减少 DB 查询ChatClient 可以传入历史 Message 列表实现多轮对话示例组装历史消息ListMessage historyMessageList loadHistoryMessage(sessionId); Prompt prompt new Prompt(historyMessageList);八、生产环境重要优化点超时与熔断DashScope 调用是 http 接口设置 http 连接超时使用 Resilience4j 做熔断大模型不可用时降级。SSE 注意事项网关不能缓存 SSE 响应不要使用 ResponseBodyAdvice 统一包装 SSE 返回流式返回直接返回 Flux。Token 统计 监听 ChatResponse统计 input/output token做计费、日志埋点。提示词模板统一管理 放到数据库不要硬编码支持后台动态修改 system prompt。文档解析 PDF、Word、Markdown大文件异步解析MQ 异步处理避免接口超时。多模型动态选择 不写死 yml数据库维护模型配置运行时动态构建 DashScopeChatModel。九、部署方案开发环境本地 IDE 直接启动向量库可以切换为内存InMemoryVectorStore不需要 PG。# 测试环境使用内存向量库注释pgvector配置 #spring.ai.vectorstore.pgvector...生产部署Docker K8sPGVector 独立 Postgres 服务Redis、Mysql服务多实例API‑key 从 k8s secret 注入。十、常见坑JDK 版本必须 17SpringBoot3.2SpringAI Alibaba 版本对齐M6.1 不要和更高版本混用。SSE 被网关包装后前端拿不到流网关配置不要对 text/event‑stream 做 body 重写。PGVector 的 embedding 维度通义 embedding 输出 1536 维表维度要匹配。FunctionCall 工具方法必须 publicTool 注解正确否则无法识别工具。RAG 召回 chunk 不能过大否则 prompt 超长触发 max‑tokens 超限。Spring AI Alibaba Mysql 业务建表 SQL数据库ai_biz存储会话、知识库文档元数据向量数据由 PGVector 自行管理不在 Mysql。 字段设计会话多轮对话、知识库文档元信息、文档切片关联、软删除、时间戳。CREATE DATABASE IF NOT EXISTS ai_biz DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE ai_biz; -- 1. AI会话主表一个会话代表一次对话窗口 DROP TABLE IF EXISTS ai_chat_session; CREATE TABLE ai_chat_session ( id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 主键ID, session_id VARCHAR(64) NOT NULL COMMENT 会话唯一UUID前端传递, user_id VARCHAR(64) NOT NULL COMMENT 用户ID, title VARCHAR(256) DEFAULT COMMENT 会话标题AI自动生成, model_name VARCHAR(64) DEFAULT qwen-plus COMMENT 使用模型 qwen‑turbo/qwen‑plus/qwen‑max, status TINYINT DEFAULT 1 COMMENT 状态 1正常 0禁用, del_flag TINYINT DEFAULT 0 COMMENT 0未删除 1已删除, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_session_id (session_id), KEY idx_user_id (user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENTAI对话会话主表; -- 2. AI会话消息明细表保存每一轮 user / assistant 消息 DROP TABLE IF EXISTS ai_chat_message; CREATE TABLE ai_chat_message ( id BIGINT AUTO_INCREMENT PRIMARY KEY, session_id VARCHAR(64) NOT NULL COMMENT 关联会话ID, user_id VARCHAR(64) NOT NULL COMMENT 用户ID, role VARCHAR(32) NOT NULL COMMENT 消息角色user / assistant / system / tool, content TEXT NOT NULL COMMENT 消息内容, tool_call_json TEXT COMMENT FunctionCall工具调用原始JSON, input_tokens INT DEFAULT 0 COMMENT 输入token消耗, output_tokens INT DEFAULT 0 COMMENT 输出token消耗, del_flag TINYINT DEFAULT 0, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY idx_session_id (session_id), KEY idx_user_id (user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENTAI对话消息明细; -- 3. 知识库主表知识库分组支持多套知识库 DROP TABLE IF EXISTS ai_knowledge_base; CREATE TABLE ai_knowledge_base ( id BIGINT AUTO_INCREMENT PRIMARY KEY, kb_code VARCHAR(64) NOT NULL COMMENT 知识库编码业务唯一, kb_name VARCHAR(128) NOT NULL COMMENT 知识库名称, description VARCHAR(512) DEFAULT COMMENT 知识库描述, status TINYINT DEFAULT 1 COMMENT 1启用 0停用, del_flag TINYINT DEFAULT 0, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_kb_code (kb_code) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT知识库分组; -- 4. 上传文档元数据表记录上传的PDF/TXT等原始文档 DROP TABLE IF EXISTS ai_kb_document; CREATE TABLE ai_kb_document ( id BIGINT AUTO_INCREMENT PRIMARY KEY, kb_code VARCHAR(64) NOT NULL COMMENT 归属知识库编码, doc_name VARCHAR(256) NOT NULL COMMENT 文档原始文件名, doc_type VARCHAR(32) NOT NULL COMMENT 文档类型 pdf / txt / md / docx, file_key VARCHAR(256) DEFAULT COMMENT MinIO文件存储key, file_size BIGINT DEFAULT 0 COMMENT 文件大小字节, status TINYINT DEFAULT 0 COMMENT 0待解析 1解析成功 2解析失败, fail_msg TEXT COMMENT 解析失败原因, total_chunk INT DEFAULT 0 COMMENT 切分的chunk总数量, del_flag TINYINT DEFAULT 0, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY idx_kb_code (kb_code) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT知识库上传文档元数据; -- 5. Prompt模板配置表动态管理system提示词避免硬编码 DROP TABLE IF EXISTS ai_prompt_template; CREATE TABLE ai_prompt_template ( id BIGINT AUTO_INCREMENT PRIMARY KEY, template_code VARCHAR(64) NOT NULL COMMENT 模板编码如RAG_CHAT、AGENT_CHAT, template_name VARCHAR(128) NOT NULL COMMENT 模板名称, template_content TEXT NOT NULL COMMENT 提示词模板内容支持{xxx}占位符, description VARCHAR(512) DEFAULT , status TINYINT DEFAULT 1, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_template_code (template_code) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT动态Prompt模板表; -- 初始化一条RAG问答模板示例 INSERT INTO ai_prompt_template(template_code,template_name,template_content,description) VALUES ( RAG_CHAT, RAG知识库问答模板, 你是知识库问答助手请基于下面检索到的上下文回答用户问题。 如果上下文中没有答案如实告知不知道不要编造内容。 上下文 {context} 用户问题{question}, RAG场景system prompt模板 );配套实体简要说明JPAAiChatSession.javaData Entity Table(name ai_chat_session) public class AiChatSession { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String sessionId; private String userId; private String title; private String modelName; private Integer status; private Integer delFlag; private LocalDateTime createTime; private LocalDateTime updateTime; }AiChatMessage.javaData Entity Table(name ai_chat_message) public class AiChatMessage { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String sessionId; private String userId; private String role; Column(columnDefinition TEXT) private String content; Column(columnDefinition TEXT) private String toolCallJson; private Integer inputTokens; private Integer outputTokens; private Integer delFlag; private LocalDateTime createTime; private LocalDateTime updateTime; }
