本文引用的文件
本文档描述 ai-server 后端服务的整体架构。它基于 Spring Boot,面向“调查研判”场景,把平台管理、Agent 智能体、数据清洗、知识检索、图谱、通话、人员、传输、轨迹、治理、搜索、数据迁移、外部系统、嵌入向量等能力按模块组织;通过 MyBatis-Plus 与 Dynamic Datasource 同时连接 PostgreSQL/pgvector、Redis、DuckDB 等业务与临时数据源,并使用 Sa-Token 完成认证、SSE 实现长连接心跳保活,配合定时任务与工作空间清理保障多用户并发下的稳定性。
ai-server 采用 Spring Boot 模块化布局:
com.zsjz.ai.App 是应用入口,开启定时调度并负责工作空间初始化。com.zsjz.ai.module.* 按业务域划分模块:plat、agent、aiclean、knowledge、graph、person、call、trans、track、govern、search、dm、otg、external、embedding。src/main/resources 提供统一配置:通用配置在 application.yaml,开发环境在 application-dev.yaml,生产环境在 application-pro.yaml。pom.xml 声明 Spring Boot、Sa-Token、MyBatis-Plus、Dynamic Datasource、AgentScope、pgvector、DuckDB、ONNX Runtime 等依赖。
graph TB
App["应用入口<br/>App.java"] --> ModulePlat["平台模块<br/>module/plat"]
App --> ModuleAgent["智能体模块<br/>module/agent"]
App --> ModuleAiclean["AI 清洗模块<br/>module/aiclean"]
App --> ModuleKnowledge["知识库模块<br/>module/knowledge"]
App --> ModuleGraph["图谱模块<br/>module/graph"]
App --> ModulePerson["人员模块<br/>module/person"]
App --> ModuleCall["通话模块<br/>module/call"]
App --> ModuleTrans["传输模块<br/>module/trans"]
App --> ModuleTrack["轨迹模块<br/>module/track"]
App --> ModuleGovern["治理模块<br/>module/govern"]
App --> ModuleSearch["搜索模块<br/>module/search"]
App --> ModuleDm["数据迁移模块<br/>module/dm"]
App --> ModuleOtg["OTG 模块<br/>module/otg"]
App --> ModuleExternal["外部系统模块<br/>module/external"]
App --> ModuleEmbedding["嵌入向量模块<br/>module/embedding"]
图示来源
章节来源
App 类使用 @EnableScheduling 和 @SpringBootApplication,负责启动容器、注册定时任务,并在启动时检查或重建运行工作空间。module/* 包,通常包含 controller、service、mapper/entity、vo/dto、工具类等;模块之间通过共享的 common.model 实体、数据库和数据访问层协作,而不是直接互相调用 UI 或 HTTP 层。x-token 请求头传递令牌,默认单端登录,可切换为多端并发;登录态存储依赖 Redis。章节来源
ai-server 的整体职责可以理解为:对外暴露 REST/SSE 接口,对内协调平台元数据、Agent 推理、RAG 检索、向量索引、临时数据分析、外部数据接入以及图谱与治理结果输出。
graph TB
Client["前端或桌面客户端"] --> Api["REST/SSE 接口层"]
Api --> Plat["平台与认证<br/>plat"]
Api --> Agent["Agent 编排与工具<br/>agent"]
Api --> Clean["AI 清洗流程<br/>aiclean"]
Api --> Knowledge["知识文档解析与索引<br/>knowledge"]
Api --> Embedding["嵌入向量服务<br/>embedding"]
Api --> Graph["图谱构建与查询<br/>graph"]
Api --> Person["人员库<br/>person"]
Api --> Call["通话记录与分析<br/>call"]
Api --> Trans["数据传输<br/>trans"]
Api --> Track["轨迹数据<br/>track"]
Api --> Govern["治理规则与结果<br/>govern"]
Api --> Search["搜索与检索<br/>search"]
Api --> Dm["数据迁移<br/>dm"]
Api --> Otg["OTG 时序与特殊日期<br/>otg"]
Api --> External["外部系统对接<br/>external"]
Agent --> Knowledge
Agent --> Embedding
Agent --> Clean
Agent --> Graph
Agent --> Person
Agent --> Call
Agent --> Trans
Agent --> Track
Agent --> Govern
Agent --> Search
Agent --> External
该图展示了模块间的高层协作:Agent 是调查场景中的“中枢”,调用各业务模块能力,并结合 RAG、向量检索与 Python 执行器完成复杂分析。
App 类承担两个职责:
在启动时检查运行工作空间是否存在;若不存在或锁文件缺失,则从原始路径复制工作空间并创建锁文件,保证多进程或重启后的工作区一致性。
flowchart TD
Start["JVM 启动"] --> RunApp["SpringApplication.run(App.class)"]
RunApp --> EnableScheduling["启用 @EnableScheduling"]
EnableScheduling --> CheckWorkspace["检查工作空间"]
CheckWorkspace --> Exists{"工作空间存在?"}
Exists -->|否| CopyFromOriginal["从原始路径复制工作空间"]
Exists -->|是| HasLock{"存在锁文件?"}
HasLock -->|否| ForceOverride["强制覆盖模式:删除旧运行目录并重建"]
HasLock -->|是| Ready["就绪"]
CopyFromOriginal --> Ready
ForceOverride --> Ready
图示来源
章节来源
配置文件将三类数据源解耦:
DuckDB:按案件实例打开,用于临时分析、ETL 中间结果、AI 清洗中间表等。
graph TB
PGB["PostgreSQL<br/>pgvector"]
Redis["Redis"]
DuckDB["DuckDB<br/>案件临时库"]
Plat["plat 模块"] --> PGB
Plat --> Redis
Agent["agent 模块"] --> Redis
Aiclean["aiclean 模块"] --> PGB
Aiclean --> DuckDB
Knowledge["knowledge 模块"] --> PGB
Embedding["embedding 模块"] --> PGB
Graph["graph 模块"] --> PGB
Person["person 模块"] --> PGB
Call["call 模块"] --> PGB
Trans["trans 模块"] --> PGB
Track["track 模块"] --> PGB
Govern["govern 模块"] --> PGB
Search["search 模块"] --> PGB
Dm["dm 模块"] --> PGB
Otg["otg 模块"] --> PGB
External["external 模块"] --> PGB
图示来源
关键配置要点:
master,strict 模式避免误写 SQL 落到主库。zsjz.duckdb.* 配置控制最大同时打开数、内存比例、每实例线程数与兜底回收间隔。com.zsjz.ai.common.model.*.entity,所有模块实体集中放在 common 下,避免跨模块命名冲突。章节来源
Sa-Token 在本项目中仅做认证,不做细粒度权限控制;唯一管理员标识来自 sys_user.is_admin。令牌名固定为 x-token,有效期 30 天,关闭活跃超时,避免长时间研判中被登出;默认单端登录,后登录顶掉前登录。
sequenceDiagram
participant Frontend as "前端"
participant Server as "ai-server"
participant Stp as "Sa-Token"
participant Redis as "Redis"
Frontend->>Server: "携带 x-token 发起请求"
Server->>Stp: "校验令牌有效性"
Stp->>Redis: "读取会话信息"
Redis-->>Stp: "返回会话"
Stp-->>Server: "认证成功或失败"
Server-->>Frontend: "业务响应或 401"
Note over Frontend,Redis: "Redis 不可用时,所有 StpUtil 调用会抛异常"
图示来源
安全约束与建议:
x-token 请求头,否则无法携带登录态。章节来源
SSE 心跳由 Spring 调度任务驱动,默认每 5 秒遍历活跃连接并发送心跳,防止反向代理或浏览器因空闲超时断开连接。为避免批量任务阻塞心跳,调度线程池默认扩容到 4 个线程,使心跳、数据源回收、AI 清洗看门狗、附件孤儿清理相互隔离。
flowchart TD
Scheduler["Spring 调度器<br/>size=4"] --> Heartbeat["SSE 心跳任务"]
Scheduler --> Reaper["DuckDB 会话回收"]
Scheduler --> Cleaner["AI 清洗看门狗"]
Scheduler --> OrphanCleaner["附件孤儿清理"]
Heartbeat --> ActiveConnections["遍历活跃 SSE 连接"]
ActiveConnections --> SendPing["发送心跳事件"]
SendPing --> KeepAlive["保持连接存活"]
图示来源
注意事项:
章节来源
启动时的工作空间逻辑会判断运行目录与锁文件:
定时任务方面,除了 SSE 心跳,还包括:
维护 AI 清洗批次的 token 预算、超时与失败恢复。
flowchart TD
Startup["应用启动"] --> WorkspaceCheck["检查工作空间"]
WorkspaceCheck --> InitDone["工作空间就绪"]
InitDone --> ScheduleStart["启动定时任务"]
ScheduleStart --> HeartbeatTask["SSE 心跳"]
ScheduleStart --> DataSourceReaper["DuckDB 泄漏回收"]
ScheduleStart --> AiCleanWatchdog["AI 清洗看门狗"]
ScheduleStart --> AttachmentOrphanCleaner["附件孤儿清理"]
图示来源
章节来源
Agent 模块是调查场景中的智能编排层,主要职责包括:
与 knowledge、embedding、aiclean、graph、person、call、trans、track、govern、search、external 等模块协作,把多源数据整合成调查结论。
graph LR
Agent["agent 模块"] --> ToolRegistry["工具注册中心"]
ToolRegistry --> TableSchema["表结构语义检索"]
ToolRegistry --> PythonExec["Python 执行器"]
ToolRegistry --> AttachmentRAG["附件 RAG"]
ToolRegistry --> ExternalApi["外部系统接口"]
TableSchema --> Knowledge["knowledge 模块"]
AttachmentRAG --> Embedding["embedding 模块"]
Agent --> Aiclean["aiclean 模块"]
Agent --> Graph["graph 模块"]
Agent --> Person["person 模块"]
Agent --> Call["call 模块"]
Agent --> Trans["trans 模块"]
Agent --> Track["track 模块"]
Agent --> Govern["govern 模块"]
Agent --> Search["search 模块"]
Agent --> External["external 模块"]
图示来源
Agent 协作的关键点:
zsjz.embedding.enabled。章节来源
本项目支持两套向量模型路径:
在线 embedding 模型:当本地开关关闭且系统中存在 type=embedding 的活跃模型时使用。
flowchart TD
Config["zsjz.embedding.enabled"] --> Local{"是否启用本地模型?"}
Local -->|是| LoadOnnx["加载 ONNX 模型<br/>bge-m3"]
Local -->|否| UseOnline["使用在线 embedding 模型"]
LoadOnnx --> VectorIndex["向量索引"]
UseOnline --> VectorIndex
VectorIndex --> PgVector["pgvector 表"]
VectorIndex --> Redis["AgentScope Redis 扩展"]
图示来源
风险与建议:
章节来源
附件处理分为三条路径:
附件按 userId、caseId、sessionId 三层隔离,并具备 24 小时孤儿清理机制。Workspace Catalog 则与 Agent 工作空间、DuckDB 案件库、文件存储根目录共同构成调查工作区的数据边界。
flowchart TD
Upload["附件上传"] --> SizeCheck{"文件大小与类型"}
SizeCheck --> Small["小内容内联消息"]
SizeCheck --> Sheet["大表格<br/>路径传给 Agent"]
SizeCheck --> Doc["大文档<br/>分块向量化"]
Sheet --> PythonExec["Python 执行器"]
Doc --> Chunking["分块与重叠"]
Chunking --> EmbeddingSvc["向量嵌入"]
EmbeddingSvc --> Index["pgvector/RAG 索引"]
图示来源
章节来源
这些模块在调查场景中共同构成“数据接入 → 清洗 → 分析 → 治理 → 可视化”的完整链路。
章节来源
ai-server 的核心运行时依赖如下:
graph TB
SB["Spring Boot Web"] --> MP["MyBatis-Plus"]
MP --> DDS["Dynamic Datasource"]
DDS --> PG["PostgreSQL"]
DDS --> DuckDB
SB --> RedisClient["Spring Data Redis"]
SB --> SaToken["Sa-Token"]
SB --> AgentScope["AgentScope Harness"]
AgentScope --> DashScope["DashScope 模型扩展"]
AgentScope --> Ollama["Ollama 模型扩展"]
AgentScope --> OpenAI["OpenAI 模型扩展"]
AgentScope --> Mem0["Mem0 扩展"]
AgentScope --> RAGSimple["Simple RAG 扩展"]
AgentScope --> RedisExt["Redis 扩展"]
SB --> PgVector["pgvector Java SDK"]
SB --> DJL["DJL HuggingFace Tokenizers"]
SB --> ONNX["ONNX Runtime"]
图示来源
依赖耦合特点:
章节来源
/js/a 上下文路径,并处理 SSL、跨域与负载均衡。storage.local.root-path 控制,多节点应改用共享对象存储或挂载一致文件系统。[本节为通用性能与扩展建议,不直接分析具体代码文件]
x-token 请求头。sa-token.is-concurrent 是否符合预期。章节来源
章节来源
zsjz.duckdb.max-open-cases 是否过小或过大。memory-ratio 与 threads-per-instance 是否导致单实例占用过高。章节来源
zsjz.embedding.enabled 与 model-path 是否指向有效模型目录。章节来源
章节来源
章节来源
ai-server 是一个围绕调查研判场景构建的多模块 Spring Boot 服务。它以 App 为入口,通过模块化设计把平台、Agent、清洗、知识、图谱、通话、人员、传输、轨迹、治理、搜索、迁移、外部系统与嵌入向量能力解耦;通过 MyBatis-Plus 与 Dynamic Datasource 统一管理 PostgreSQL、Redis、DuckDB;通过 Sa-Token 提供轻量认证;通过 SSE 与定时任务保障长连接与资源回收;通过 AgentScope RAG、向量检索与 Python 执行器形成“数据—智能—结论”的调查闭环。
在生产部署中,应重点关注 Redis 与 PostgreSQL 的可用性、DuckDB 的资源预算、向量模型的加载成本、附件解析队列的背压控制,以及多节点间文件存储与模型权重的同步策略。