第四篇:AI 模块架构设计:多 Provider 切换、RAG 知识库与 Agent 编排

前言

本文是 SeaPack 项目技术系列的第四篇,聚焦 AI 模块的整体架构设计与功能全景。这篇文章的目标是介绍 AI 模块「做了什么」------有哪些核心能力、各部分如何协作、解决了哪些问题。具体的实现细节会拆分到后续每篇文章中逐一展开。

访问地址http://124.222.194.201/

前端代码github.com/seapack-hub...

后端代码github.com/seapack-hub...

一、为什么需要一个 AI 模块架构

在很多 AI 项目中,最常见的做法是「对着一个模型硬编码」------用 DeepSeek 就写死 DeepSeek 的调用,想换成通义千问就得改代码、改配置、重新部署。这在原型阶段没问题,但在生产环境会遇到几个致命问题:

痛点 硬编码一个模型的表现
模型切换成本高 换一个 Provider 就要改代码、改配置、重新部署
向量化和文本模型混用 文本对话用 A 厂商,向量化用 B 厂商,代码里到处 if-else
知识库数据散落 文档解析、分片、向量化、检索各写一套,没有统一流程
Agent 扩展困难 想给 Agent 加个技能,要改一堆硬编码逻辑
可观测性差 不知道每次调用花了多少 Token、耗时多久、走了哪条链路

SeaPack 的 AI 模块设计目标非常明确:

一套配置切换所有 Provider,一套流程管理知识库全生命周期,一个流水线编排 Agent 执行,一条 SSE 管道流式输出所有结果。

目前是后端动态设置切换AI模型,之后可以前后端联动,由前端动态设置使用哪个大模型。

二、整体架构:一张图看懂全貌

plain 复制代码
                        ┌─────────────────────────────────────────────┐
                        │            前端 SSE 通信层                   │
                        │  useChatExecution.ts → chatExecute.ts       │
                        │  统一 Composable,根据 session.mode 自动路由 │
                        └──────────────────┬──────────────────────────┘
                                           │ fetch + ReadableStream
                                           ▼
┌──────────────────────────────────────────────────────────────────────────────────────┐
│                          AiDialogService(统一对话调度)                              │
│                                                                                      │
│   mode: streaming_llm ──→ 直接调用 LLM(通用对话)                                    │
│   mode: agent_stream ──→ Agent 四步流水线                                            │
│   mode: orchestration ─→ LLM 智能路由 → 编排 / Agent / 通用 LLM                       │
└──────────────────────────────────────────────────────────────────────────────────────┘
                                           │
              ┌────────────────────────────┼────────────────────────────┐
              ▼                            ▼                            ▼
   ┌──────────────────┐       ┌──────────────────────┐      ┌──────────────────────┐
   │ 多 Provider 配置  │      │   Agent 四步流水线    │      │   编排执行引擎        │
   │                   │      │   1. 提示词组装      │      │                       │
   │ activeProvider    │      │   2. 知识库检索      │      │ sequential / parallel │
   │ embeddingProvider │      │   3. 技能调用        │      │ dynamic orchestration │
   │ providers{}       │      │   4. LLM 流式调用    │      │                       │
   └──────────────────┘       └──────────┬───────────┘      └──────────────────────┘
              │                           │
              ▼                           ▼
   ┌──────────────────┐       ┌──────────────────────────────────────┐
   │ LangChain4j      │       │          ChromaDB 向量数据库          │
   │ 模型实例化        │       │  文档解析 → 分片 → 向量化 → 语义检索   │
   └──────────────────┘       └──────────────────────────────────────┘

三层职责划分:

层级 核心组件 职责
调度层 AiDialogService 按 mode 分发对话请求,统一取消标志和 Token 额度校验
执行层 AgentTestChatService / OrchestrationExecuteService Agent 四步流水线 / 编排步骤执行
基础层 AIProperties / AiConfig / ChromaDbConfig 多 Provider 配置、模型实例化、向量存储

三、核心能力一:多 Provider 动态切换

3.1 设计目标

改一行配置,所有 AI 调用自动切换到新模型------零代码改动。

系统同时对接了三家大模型厂商(DeepSeek、阿里云通义千问、小米 MiMo),通过配置文件中的 ai.active-provider 字段决定当前使用哪个。更重要的是,文本对话模型和向量化模型可以来自不同厂商------文本追求推理能力用 MiMo,向量化追求语义表达用阿里云,两者独立配置互不干扰。

3.2 配置结构

properties 复制代码
# 当前激活的 Provider(文本对话用)
ai.active-provider=mimo

# 向量化服务使用的 Provider(可以和文本对话不同)
ai.embedding-provider=aliyun

# 各 Provider 的具体配置
ai.providers.deepseek.api-key=sk-xxx
ai.providers.deepseek.base-url=https://api.deepseek.com/v1
ai.providers.deepseek.chat-model=deepseek-chat
ai.providers.deepseek.embedding-model=text-embedding-ada-002

ai.providers.aliyun.api-key=sk-xxx
ai.providers.aliyun.base-url=https://dashscope.aliyuncs.com/compatible-mode/v1
ai.providers.aliyun.chat-model=qwen-plus
ai.providers.aliyun.embedding-model=text-embedding-v3

ai.providers.mimo.api-key=sk-xxx
ai.providers.mimo.base-url=https://api.xiaomi.com/v1
ai.providers.mimo.chat-model=mimo-v2.5

3.3 已实现的功能

功能 说明
Provider 动态切换 通过AIProperties + @ConfigurationProperties 自动映射配置,AiConfig 根据 activeProvider 动态创建 LangChain4j 模型 Bean
文本/向量模型分离 activeProvider 控制文本对话,embeddingProvider 控制向量化,各自独立
OpenAI 协议兼容 所有厂商都使用 OpenAI 兼容协议,LangChain4j 的OpenAiChatModel 一套代码通吃
Provider 身份注入 自动在消息头部注入模型身份提示词,避免模型「自报错误身份」

3.4 涉及的关键类

职责
AIProperties 配置属性类,映射ai.* 前缀,管理所有 Provider 配置
AiConfig Spring 配置类,根据activeProvider 创建 ChatLanguageModel / StreamingChatLanguageModel Bean
ChromaDbConfig ChromaDB 配置,创建EmbeddingModel Bean,按知识库 ID 提供 EmbeddingStore
AiProviderIdentities 各 Provider 的身份提示词常量

四、核心能力二:RAG 知识库

4.1 设计目标

上传文档,自动解析、分片、向量化、入库;对话时自动检索相关知识,让 Agent 拥有「领域记忆」。

RAG(Retrieval-Augmented Generation)是让大模型「知道你私有数据」的关键技术。SeaPack 实现了完整的 RAG 链路:从文档上传到语义检索,全流程异步处理,前端实时展示进度。

4.2 完整流程

plain 复制代码
用户上传文档
    │
    ▼
保存文件 → 创建文档记录 → 生成 taskToken → 触发异步向量化
                                                   │
    ┌────────────────────────────────────────────────┘
    │  异步线程 (@Async)
    │
    ├── 1. 解析文档 ──── FileParserUtil(支持 PDF / Word / TXT / Markdown)
    │
    ├── 2. 文档分片 ──── 按段落分片,可配置分片大小和重叠字符
    │
    ├── 3. 向量化 ────── 调用 EmbeddingModel 生成每个分片的向量
    │
    ├── 4. 向量入库 ──── 存入 ChromaDB(每个知识库独立 Collection)
    │                    同时写入 MySQL(记录 vectorId,支持回溯和删除)
    │
    └── 5. 更新统计 ──── 文档数、分片数、向量数等统计信息

4.3 已实现的功能

功能 说明
知识库 CRUD 创建、编辑、删除、复制、启停控制,支持分页查询
文档上传与解析 支持 PDF、Word、TXT、Markdown,通过FileParserUtil 统一解析
异步向量化 @Async 异步线程处理,不阻塞用户请求,前端实时展示进度
可配置分片 每个知识库可独立设置分片大小(chunkSize)和重叠字符(chunkOverlap)
ChromaDB 向量存储 每个知识库对应独立 Collectionknowledge_{id}),数据完全隔离
语义检索 基于向量相似度的 top-K 检索,返回最相关的分片内容
关键词降级 ChromaDB 不可用时自动降级到 MySQL 关键词匹配,保障可用性
进度追踪 taskToken + VectorProgressManager,前端实时展示解析→分片→向量化进度
文档重新处理 清理旧向量,重置状态,从磁盘重新读取并向量化
级联删除 删除知识库时自动清理文档、分片、向量数据和磁盘文件

4.4 涉及的关键类

职责
KnowledgeBaseService 知识库 CRUD、文档上传、语义检索入口
KnowledgeVectorService 异步向量化核心,文档解析→分片→向量化→入库
ChromaDbConfig EmbeddingModel 创建 + EmbeddingStore 动态获取
VectorProgressManager 向量化进度管理,通过 taskToken 推送实时进度
FileParserUtil 多格式文档解析工具(PDF / Word / TXT / Markdown)

五、核心能力三:Agent 四步编排流水线

5.1 设计目标

Agent 不是「带 System Prompt 的聊天机器人」,而是一个完整的任务执行流水线------自动组装提示词检索知识调用技能生成回答

每个 Agent 可以关联多个提示词模板、多个知识库、多个技能。对话时系统自动完成四个步骤的编排,每步执行前用户都可以取消。

5.2 四步流水线

plain 复制代码
用户消息: "帮我查一下最近一周的股票行情"
    │
    ▼
┌─────────────────────────────────────────────────────────────────┐
│                 Agent 四步编排流水线                             │
│                                                                 │
│  Step 1: 提示词组装 (prompt_assembly)                            │
│  ├── 加载 Agent 基础 system_prompt                               │
│  ├── LLM 动态选择相关模板(从 Agent 关联的模板池中)               │
│  └── 拼接: system_prompt + selected_templates                    │
│                                                                 │
│  Step 2: 知识库检索 (knowledge_retrieval)                        │
│  ├── 遍历 Agent 关联的知识库列表                                  │
│  ├── 对每个知识库执行 ChromaDB 向量检索 top-K                     │
│  └── 拼接: system_prompt + 【参考知识】                          │
│                                                                 │
│  Step 3: 技能调用 (skill_execution)                              │
│  ├── LLM 智能选择技能(从 Agent 关联的技能池中)                   │
│  ├── LLM 提取参数(根据 inputSchema + 用户消息)                  │
│  ├── HTTP 调用技能 endpoint                                      │
│  └── 拼接: system_prompt + 【技能执行结果】                       │
│                                                                 │
│  Step 4: LLM 流式调用 (llm_call)                                 │
│  ├── 组装完整 messages(system + history + user)                │
│  ├── 流式调用 LLM API                                            │
│  └── 逐 token 通过 SSE 推送给前端                                │
│                                                                 │
│  完成后: 组装 TraceSnapshot → 保存会话记录 → 统计 Token           │
└─────────────────────────────────────────────────────────────────┘

5.3 已实现的功能

功能 说明
LLM 动态选择模板 不是全部加载,而是让** LLM 根据用户意图从模板池中选择最相关的模板**
LLM 动态选择技能 LLM 从 Agent 关联的技能池中选择最匹配的技能,避免全部执行
LLM 智能参数提取 根据技能的 inputSchema,LLM 自动从用户消息中提取结构化参数
知识库检索集成 自动遍历 Agent 关联的所有知识库,向量检索后拼接到提示词中
技能策略模式 SkillHandler 接口 + Spring 自动注册,支持 LLM / HTTP / 文件生成等多种技能类型
Step 间取消检查 每个步骤执行前检查 cancelFlag,用户可随时终止
链路追踪(Trace Snapshot) 完整记录每步的输入、输出、耗时、Token 消耗,存入数据库
场景级配置覆盖 Agent 在不同场景下可覆盖模型、temperature、maxTokens 等参数
对话记忆 支持滑动窗口记忆,保留最近 N 轮对话上下文

5.4 涉及的关键类

职责
AgentTestChatService Agent 四步流水线编排核心,管理完整的对话执行链路
AgentSkillExecutor 技能执行引擎:LLM 选择技能 → LLM 提取参数 → HTTP 调用 endpoint
SkillHandler 技能执行器策略接口,各类型技能实现各自的 Handler
Agent Agent 实体,包含 system_prompt、模型参数、记忆配置等

六、核心能力四:编排模式与 LLM 智能路由

6.1 设计目标

不需要预先定义流程,让 LLM 根据用户消息实时决定------该用哪个 Agent、按什么顺序执行、甚至是否需要 Agent

编排模式是整个 AI 模块最灵活的能力。它把「编排决策」本身也交给了 LLM。

6.2 路由决策流程

plain 复制代码
用户消息: "帮我分析一下茅台的财务数据并生成报告"
    │
    ▼
┌─── 编排路由 ───────────────────────────────------┐
│                                             │
│  1. 收集候选 Agent                           │
│     └── 从场景关联的 Agent 列表中获取         │
│                                             │
│  2. 决策分支                                 │
│     ├── 有预定义编排步骤 → 按步骤执行         │
│     ├── 仅 1 个候选 Agent → 直接使用          │
│     ├── 多个候选 Agent → LLM 动态选择         │
│     │   ├── 选中 1 个 → Agent 对话            │
│     │   ├── 选中多个 → 动态编排(顺序/并行)   │
│     │   └── 选 0 个 → 降级到通用 LLM          │
│     └── 无候选 Agent → 降级到通用 LLM         │
│                                              │
│  每个分支都通过 SSE 事件向前端实时反馈路由结果  │
└─────────────────────────────────────────────------┘

6.3 已实现的功能

功能 说明
LLM Agent 选择 LLM 分析用户意图,从候选 Agent 中选择合适的,返回选择原因
sequential / parallel 策略 LLM 判断 Agent 之间是否有依赖,决定顺序执行还是并行执行
动态步骤构建 LLM 选中多个 Agent 时,动态编排步骤(上一步输出作为下一步输入)
多级降级 LLM 选择失败 → 默认 Agent → 通用 LLM,三级 fallback
SSE 路由事件 前端实时展示路由分析过程(routingroute_resultagent_select
预定义编排执行 支持预先配置好的编排步骤,按顺序逐步执行

6.4 涉及的关键类

职责
AiDialogService 统一对话调度,编排模式的路由决策核心
OrchestrationExecuteService 编排步骤执行引擎,支持顺序/并行/动态编排

七、核心能力五:SSE 流式通信

7.1 设计目标

后端逐 token 输出,前端实时渲染------用户看到的不是「等待 5 秒出一堆文字」,而是「像打字一样一个字一个字蹦出来」。

SSE(Server-Sent Events)是整套 AI 模块的通信基础。不仅用于最终的文本输出,还用于传递步骤进度、路由决策、Token 统计等结构化信息。

7.2 SSE 事件协议

所有对话模式共享统一的事件协议:

事件类型 用途 关键字段
routing 编排模式路由开始 message
route_result 路由结果 route, agents, strategy
agent_select Agent 选择结果 agents, strategy, fallback
step_start 步骤开始 stepIndex, stepType, stepName
step_progress 步骤进度 stepIndex, message
step_detail 步骤详情 stepIndex, detailType, + 各类详情
step_done 步骤完成 stepIndex, status, durationMs
content 流式文本输出 text
done 对话完成 tokens, durationMs, traceSnapshot
stop 用户终止 message, durationMs
error 错误 message

7.3 已实现的功能

功能 说明
后端 SseEmitter SpringSseEmitter 作为 SSE 发射器,LlmSseHelper 封装通用 LLM 流式调用
前端 readSseStream 基于fetch + ReadableStream 的通用 SSE 读取器,行缓冲处理不完整数据
useChatExecution 统一 Composable,根据 session.mode 自动选择 LLM/场景模式的 SSE 处理
步骤进度可视化 每个步骤实时推送step_startstep_progressstep_detailstep_done
取消机制 前端AbortController + 后端 AtomicBoolean cancelFlag,用户可随时终止
请求中断 新请求自动中断上一次进行中的 SSE 流

传送门:LLM 流式调用工具类 LlmSseHelper解析这篇文章深入剖析了 LlmSseHelper 类,一个专为大语言模 - 掘金 (juejin.cn)

八、核心能力六:Token 统计与额度管理

8.1 设计目标

每次 LLM 调用都可追踪------谁调的、用了什么模型、花了多少 Token、耗时多久、走了哪条链路。

8.2 已实现的功能

功能 说明
Token 消耗记录 每次 LLM 调用(包括模板选择、技能选择等辅助调用)都记录到token_usage_log
额度校验 每次对话前**检查用户剩余额度**,超限则拒绝并提示
多维度统计 按用户、模型、场景、业务类型等维度统计 Token 消耗
链路追踪快照 Agent 对话生成TraceSnapshot,完整记录每步输入输出和耗时
前端用量展示 对话完成后展示 Token 消耗,支持查看完整执行链路

九、模块全景:前端 AI 管理界面

AI 模块不仅有后端能力,还配套了完整的前端管理界面:

模块 功能
Agent 管理 Agent 的创建、编辑、配置(提示词、知识库、技能、记忆),支持详情查看与编辑双态模式
知识库管理 知识库的创建、文档上传、分片预览、向量化进度追踪、检索测试
技能管理 技能的创建、分类管理、参数 Schema 编辑、技能测试
提示词模板 模板的创建、编辑、预览,支持 Agent 关联
场景管理 场景创建、Agent 关联、编排步骤配置、部署管理
Token 统计 Token 消耗趋势图、模型分布饼图、用户排行、场景消耗
Token 额度 用户额度设置、用量进度条、超限告警
AI 对话 统一对话界面,支持 LLM 直聊和场景编排两种模式

十、设计总结

设计点 实现方式 解决的问题
多 Provider 切换 AIProperties + AiConfig + activeProvider 一行配置切换大模型,零代码改动
文本/向量模型分离 activeProvider + embeddingProvider 不同场景用不同模型
RAG 全链路 解析→分片→向量化→ChromaDB→检索+降级 完整的知识库生命周期管理
Collection 隔离 每个知识库独立 ChromaDB Collection 知识库数据互不干扰
LLM 智能路由 LLM 选择模板/技能/Agent 动态决策,避免硬编码
SSE 流式通信 统一事件协议 + 前端 Composable 逐 token 输出 + 步骤进度可视化
取消机制 前端 AbortController + 后端 AtomicBoolean 用户可随时终止对话
Token 统计 每次调用记录 + 额度校验 可观测、可控制
链路追踪 AgentTraceSnapshot 完整记录执行链路
多级降级 向量→关键词、POST→GET、LLM选择失败→默认Agent 系统鲁棒性保障

十一、写在最后

AI 模块的架构设计核心思想是配置驱动 + LLM 智能路由 + 降级保障

多 Provider 切换让模型选择变得灵活,RAG 知识库让 Agent 拥有了「领域知识」,四步编排流水线让 Agent 从「聊天机器人」升级为「可执行任务的智能体」,SSE 流式通信让用户能实时看到每一步的执行过程。

整套架构的一个重要原则是:LLM 能做的事让 LLM 做,LLM 做不了的事有降级方案。模板选择失败就加载全部,技能选择失败就全部执行,向量检索失败就关键词匹配,Agent 选择失败就用默认 Agent。

这种「智能 + 兜底」的设计让系统在各种异常场景下都能正常工作。

后续文章计划:本文只做架构总览,每个核心能力的实现细节(多 Provider 切换的具体配置方式、RAG 知识库的向量化实现、Agent 编排流水线的代码结构、SSE 流式通信的前后端对接)将在后续文章中逐一展开。

相关推荐
Gopher_HBo1 小时前
Cobra源码学习
后端
用户80806181436931 小时前
JavaScript 面向对象入门到精通
前端·javascript
Erishen1 小时前
tsm-hub:把 LLM、Tools、MCP、Skills 收进一个统一网关
架构·开源·agent
吠品1 小时前
STM32最小系统板引脚梳理与配置实操
前端·javascript·vue.js
曹一二1 小时前
前端性能优化场景题:图片懒加载 + 大数据渲染
前端
斯维赤1 小时前
Spring AI | 结构化输出 & 多模态 一篇讲透
java·后端
GISer_Jing1 小时前
Come on,工作总结
前端·ai·前端框架
程序员清风1 小时前
聊聊我的AI学习方法与思考!
java·后端·面试
Hilaku1 小时前
Sass 和 Less 在 2026 年彻底多余了吗?
前端·javascript·程序员