本文引用的文件
清鉴 AI 调查工具由 ai-gateway(Spring Cloud Gateway) 和 ai-server(Spring Boot 3 + MyBatis-Plus + AgentScope) 两个后端服务组成。前端通过 /js 前缀访问,实际请求最终落到 ai-server 的 /js/a 上下文路径;开发环境前端代理到 http://127.0.0.1:8980。本文按业务域整理 REST 接口参考,并重点说明认证方式、SSE 连接、跨域、分页、上传下载及常见错误排查。
章节来源
ai-server 与 ai-gateway。com.zsjz.ai.App,默认端口 8980。com.zsjz.ai,业务模块固定取值:agent、call、dm、external、govern、graph、otg、person、plat、track、trans。所有业务 Controller 位于 module/<domain>/controller,统一返回 Result<T>。
graph TB
Client["浏览器或 Electron 前端"] --> Gateway["Spring Cloud Gateway<br/>粘性路由 + 管理端鉴权"]
Gateway --> ServerA["ai-server 节点 A<br/>/js/a 上下文"]
Gateway --> ServerB["ai-server 节点 B<br/>/js/a 上下文"]
ServerA --> DB["PostgreSQL / DuckDB / Redis / Neo4j"]
ServerB --> DB
图示来源
章节来源
| 项目 | 约定 |
|---|---|
| 网关对外前缀 | /js |
| 后端上下文路径 | /js/a |
| 开发环境代理目标 | http://127.0.0.1:8980 |
| 统一响应体 | Result<T>,字段包含 code、message、data |
| 成功状态码 | HTTP 200,Result.code=200 |
| 登录态令牌 | 请求头 x-token |
| 会话实现 | Sa-Token,基于 Redis 存储 token 和用户会话 |
POST /js/a/auth/login,携带用户名与密码 JSON。Result<LoginVO>,其中 data.token 是 Sa-Token 凭据。token 存入本地存储,后续请求在请求头中附加 x-token。body.code=401。网关层根据 x-token 解析 userId,并把用户绑定到某个 ai-server 节点,实现粘性路由。
sequenceDiagram
participant FE as "前端"
participant GW as "网关"
participant SV as "ai-server"
participant ST as "Sa-Token"
FE->>GW: POST /js/a/auth/login {username,password}
GW->>SV: 转发登录请求
SV->>ST: 校验账号
ST-->>SV: 登录成功
SV-->>GW: Result{code:200,data:{token,userId,username}}
GW->>GW: 记录用户与节点绑定
GW-->>FE: 返回登录结果
FE->>GW: 后续请求 + x-token
GW->>GW: 解析 userId → 选择绑定节点
GW->>SV: 转发业务请求
SV-->>GW: Result<T>
GW-->>FE: 透传响应
图示来源
章节来源
网关暴露的管理接口统一位于 /gateway/admin/**,不走普通业务鉴权,而是由网关自身过滤器处理。
| 项目 | 说明 |
|---|---|
| URL 模式 | /gateway/admin/** |
| 前置开关 | gateway.admin.enabled=false 时直接返回 404,接口“消失” |
| IP 白名单 | gateway.admin.ip-whitelist,支持单 IP 与 CIDR,空表示不限 |
| 认证方式 | 请求头 x-token,经 Sa-Token 共享 Redis 解析出 userId |
| 权限要求 | 用户需满足 sys_user.is_admin=1 且 status=1 |
| 响应格式 | 网关内部 JSON,结构同 ApiResult |
flowchart TD
Start["进入 /gateway/admin/**"] --> Enabled{"管理接口已启用?"}
Enabled -->|否| NotFound["返回 404"]
Enabled -->|是| IpCheck["校验来源 IP 白名单"]
IpCheck -->|不通过| Forbidden["返回 403"]
IpCheck -->|通过| TokenCheck["校验 x-token"]
TokenCheck -->|无效| Unauthorized["返回 401"]
TokenCheck -->|有效| AdminCheck["检查 is_admin=1 且 status=1"]
AdminCheck -->|不通过| Forbidden
AdminCheck -->|通过| Pass["放行并注入管理员 userId"]
图示来源
章节来源
| 方法 | URL | 请求体 | 响应 | 说明 |
|---|---|---|---|---|
| POST | /js/a/auth/login |
LoginDTO,包含用户名和密码 |
Result<LoginVO> |
登录成功后返回 token、userId、username |
| POST | /js/a/auth/logout |
无 | Result<Void> |
注销 token 并释放该用户占用的案件数据源 |
| GET | /js/a/auth/info |
无 | Result<UserVO> |
获取当前登录用户信息 |
| POST | /js/a/auth/changePwd |
ChangePwdDTO |
Result<Void> |
自助修改密码 |
| POST | /js/a/auth/verifyPwd |
VerifyPwdDTO,可选 password |
Result<Boolean> |
锁屏解锁等场景校验密码,失败返回 data=false |
Sa-Token 白名单中还开放以下路径,用于健康检查、授权校验、地图静态资源等:
/js/a/sys/health/js/a/sys/checkAuth/js/a/sys/info/js/a/sys/code/js/a/sys/noNet/js/a/sys/map/**这些接口无需登录即可访问。
章节来源
Agent 子系统围绕 module/agent 展开,核心能力包括:
| 模块 | 典型 URL 模式 | 用途 |
|---|---|---|
| 对话 | /js/a/agent/chat/** |
发起对话、查询会话消息、停止推理等 |
| 模型 | /js/a/agent/model/** |
模型与 Provider 的 CRUD |
| SQL 结果 | /js/a/agent/result/** |
execute_sql 结果集分页查询 |
| Python 文件 | /js/a/agent/py/files/** |
访问 Python 产出图片等资源 |
| 专家/能力/工具包 | /js/a/agent/expert/**、/js/a/agent/capability/**、/js/a/agent/tool-pack/** |
Agent 能力配置 |
| 洞察 | /js/a/agent/insight/** |
洞察分析相关接口 |
Agent 对话 Controller 采用 REST + SSE 混合方式:普通问答走 REST,流式输出走 SSE。SQL 结果分页由独立 Controller 提供,避免长连接阻塞。
章节来源
SSE 属于长连接,客户端需要:
fetch 或 WebSocket/SSE 客户端发起请求。x-token。Accept: text/event-stream。若前端使用浏览器 fetch,注意:
text/event-stream。Agent SSE 事件一般包含以下几类语义(具体事件名以各 Controller 实现为准):
| 事件类型 | 含义 |
|---|---|
| 开始事件 | 对话任务已创建并开始处理 |
| 文本增量 | 大模型返回的文本片段 |
| 工具调用 | 正在调用 execute_sql、render_chart、execute_python 等业务工具 |
| 工具结果 | 工具执行完成,附带结构化结果 |
| 图表配置 | render_chart 返回的 ECharts 配置 |
| 错误事件 | 业务异常、工具执行失败、模型调用失败 |
| 结束事件 | 对话完成,可清理本地状态 |
SSE 消息通常包含:
event:事件类型。data:JSON 或纯文本消息体。id:可选消息标识,便于断线续传。对于 Agent 对话,data 常见字段包括:
| 字段 | 类型 | 说明 |
|---|---|---|
| sessionId | 字符串 | 会话标识 |
| messageId | 字符串 | 消息标识 |
| type | 字符串 | 消息类型,如思考、工具调用、结果、错误 |
| content | 字符串 | 人类可读内容 |
| toolName | 字符串 | 工具名称,如 execute_sql |
| resultId | 字符串 | SQL 结果缓存 ID |
| error | 字符串 | 错误信息 |
SSE 保活建议遵循以下原则:
messageId,以便服务端补齐遗漏消息。sequenceDiagram
participant FE as "前端"
participant GW as "网关"
participant AC as "AgentChatController"
participant SVC as "AgentChatService"
participant TOOLS as "工具集"
participant STORE as "SQL 结果缓存"
FE->>GW: POST /js/a/agent/chat (x-token)
GW->>AC: 转发请求
AC->>SVC: 创建或查找会话
SVC->>TOOLS: 调用意图识别 / 工具
TOOLS->>STORE: execute_sql 写入结果
STORE-->>TOOLS: resultId + 列定义 + 分页信息
SVC-->>AC: 流式事件
AC-->>FE: SSE event/text/data
FE->>GW: 拉取 SQL 结果分页
GW->>AC: 转发分页请求
AC-->>FE: 返回结果页
图示来源
章节来源
AI 清洗模块位于 module/dm 与 module/aiclean,主要职责是把多源异构数据导入后清洗、映射、治理,并沉淀到 DuckDB 案情库。
| 模块 | URL 模式 | 功能 |
|---|---|---|
| 数据建模 | /js/a/dm/** |
表元数据、字段映射、导入模板、清洗任务 |
| AI 清洗 | /js/a/aiclean/** |
智能清洗、值转换、字段短名、同义词 |
| 清洗错误日志 | /js/a/dm/clean-error-log/** |
查看清洗过程中的错误记录 |
Result<T>,分页查询返回 MyBatis-Plus Page<T>。BigDecimal,避免浮点精度问题。章节来源
知识检索围绕 RAG 与知识库展开,涉及:
| 模块 | URL 模式 | 功能 |
|---|---|---|
| 知识库 | /js/a/knowledge/** |
知识库列表、新增、更新、删除、检索 |
| Embedding 调试 | /js/a/embedding/** |
向量模型调试 |
| Agent RAG 工具 | 通过 search_table_schema 工具间接暴露 |
基于 pgvector 的模板元数据语义检索 |
知识库下载接口返回裸文件流,不带 Result 包装,前端需使用带 x-token 的 fetch 获取 blob 并触发保存。
章节来源
| 典型 URL 模式 | 功能 |
|---|---|
/js/a/graph/** |
关系图查询、图谱节点与边数据 |
| 典型 URL 模式 | 功能 |
|---|---|
/js/a/person/person-basic-info/** |
人员基本信息 |
/js/a/person/person-group/** |
人员分组 |
/js/a/person/resident-population/** |
常住人口 |
/js/a/person/intimacy/** |
亲密度分析 |
/js/a/person/data-profile/** |
人物画像 |
| 典型 URL 模式 | 功能 |
|---|---|
/js/a/call/call-record/** |
通话原始明细 |
/js/a/call/call-night/** |
夜间通话统计 |
/js/a/call/call-continuous/** |
持续联系统计 |
/js/a/call/call-sensitive/** |
敏感日期联系统计 |
| 典型 URL 模式 | 功能 |
|---|---|
/js/a/trans/trans-record/** |
交易记录 |
/js/a/trans/trans-fund-flow/** |
资金流水、资金流向图、资金流向轨迹 |
/js/a/trans/trans-frequency/** |
高频交易统计 |
/js/a/trans/trans-continuous/** |
连续交易统计 |
/js/a/trans/trans-cash-flow/** |
现金流水 |
/js/a/trans/trans-card-hold/** |
共同持卡 |
/js/a/trans/trans-financial/** |
金融账户统计 |
/js/a/trans/trans-fixed-deposit/** |
定期存款 |
/js/a/trans/trans-fast-fund-flow/** |
快进快出 |
/js/a/trans/trans-big/** |
大额交易统计 |
/js/a/trans/trans-sensitive/** |
敏感交易统计 |
/js/a/trans/cash-key/**、financial-key/**、fixed-deposit-key/** |
交易关键参数配置 |
| 典型 URL 模式 | 功能 |
|---|---|
/js/a/track/track-cell-tower/** |
基站轨迹 |
/js/a/track/track-en-local/** |
本地轨迹 |
/js/a/track/track-meet/** |
轨迹相遇 |
/js/a/track/track-together-live/** |
同住轨迹 |
/js/a/track/track-together-travel/** |
同行轨迹 |
/js/a/track/express-info/** |
快递信息 |
| 典型 URL 模式 | 功能 |
|---|---|
/js/a/govern/** |
治理任务、治理树 |
/js/a/govern/govern-tree/** |
治理树与关联人/银行/通话操作人分页 |
| 典型 URL 模式 | 功能 |
|---|---|
/js/a/external/** |
外部表元数据、字段元数据 |
| 典型 URL 模式 | 功能 |
|---|---|
/js/a/dm/** |
数据建模、清洗、模板、错误日志 |
上述接口普遍遵循:
Page<T>。BigDecimal。章节来源
跨域由网关与后端共同控制:
| 层级 | 行为 |
|---|---|
| 后端 ai-server | 默认开启 CORS,允许任意 Origin,允许所有方法和请求头,开启 credentials=true,暴露 Content-Disposition,优先级最高 |
| 网关 ai-gateway | 默认关闭 CORS;仅在 gateway.cors.enabled=true 时启用,允许所有方法、所有请求头,不携带凭据,暴露 X-Gateway-Node、Content-Disposition、X-Request-Id |
关键点:
x-token 请求头,不属于 Cookie,所以不需要 Cookie 凭证。credentials: 'include' 的 fetch,因此后端必须允许凭据。Access-Control-Allow-Origin,否则浏览器会拒绝响应。章节来源
Page<T>。PaginationInnerInterceptor(DbType.DUCKDB)。execute_sql)会返回 resultId,再由分页接口拉取结果。Result 包装。Content-Disposition 传递文件名。Content-Disposition,使跨域前端能读取文件名。fetch 获取 blob,再触发浏览器保存。当前代码证据中未发现统一的限流控制器或全局限流拦截器。生产环境如需限流,应在网关或应用层增加独立限流组件。现有风险点主要体现在:
章节来源
后端统一返回 Result<T>:
| 字段 | 含义 |
|---|---|
| code | 业务状态码,成功通常为 200 |
| message | 人类可读消息 |
| data | 业务数据 |
网关错误处理器会根据异常类型返回明确 HTTP 状态码: | HTTP 状态 | 含义 | |---|---| | 404 | 无匹配路由或资源不存在 | | 401 | 未登录或 token 失效 | | 403 | 非管理员访问管理接口、IP 不在白名单 | | 502 | 后端节点连接失败或超时 | | 503 | 粘性路由不可用、绑定节点不可用、服务暂无可用节点 | | 500 | 网关内部错误 |
可能原因:
x-token。排查步骤:
x-token。/js/a/auth/login 拿到 token。可能原因:
/gateway/admin/** 但 IP 不在白名单。排查步骤:
gateway.admin.ip-whitelist。is_admin=1 且 status=1。可能原因:
排查步骤:
defaultNodeId 是否配置。可能原因:
排查步骤:
章节来源
登录:
curl -X POST http://localhost:8980/js/a/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"your-password"}'
携带 token 调用业务接口:
curl http://localhost:8980/js/a/auth/info \
-H "x-token: 从登录响应 data.token 获取"
下载文件(示例):
curl -o file.xlsx http://localhost:8980/js/a/knowledge/download/xxx \
-H "x-token: 从登录响应 data.token 获取"
使用带 x-token 的 fetch:
const res = await fetch('/js/a/auth/info', {
headers: { 'x-token': localStorage.getItem('token') }
});
const json = await res.json();
if (json.code === 401) {
// 跳转登录
} else if (json.code === 200) {
// 渲染用户信息
}
SSE 调用示例:
const res = await fetch('/js/a/agent/chat/sse', {
method: 'POST',
headers: {
'x-token': localStorage.getItem('token'),
'Accept': 'text/event-stream'
},
body: JSON.stringify({ message: '分析近期夜间通话异常' })
});
const reader = res.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value);
// 按 event/data 解析 SSE 事件
}
章节来源
清鉴 AI 调查工具的 API 以 /js/a 为后端入口,通过网关进行粘性路由与管理端准入控制。认证基于 Sa-Token,token 通过 x-token 请求头传递;所有业务接口默认受登录态保护。Agent 对话同时支持 REST 与 SSE,SSE 需要客户端自行处理连接保活与重连。跨域默认在后端开启,网关默认关闭以避免重复跨域头。分页统一使用 MyBatis-Plus Page<T>,下载接口返回裸文件流并依赖 Content-Disposition 响应头。常见错误 401、403、503 与 SSE 中断应优先从 token、IP 白名单、节点健康状态和连接生命周期排查。