Agent 对话与 RAG 接口.md 30 KB

Agent 对话与 RAG 接口

本文引用的文件

  • AgentChatController.java
  • AgentModelController.java
  • AgentExpertController.java
  • AgentToolPackController.java
  • AgentCapabilityController.java
  • AgentArtifactController.java
  • AgentPythonFileController.java
  • InsightController.java
  • ChatRequestDTO.java
  • AgentChatServiceImpl.java
  • LlmService.java
  • RagSchemaService.java
  • PythonExecutor.java
  • Result.java
  • GlobalExceptionHandler.java
  • AuthController.java

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 接口规范
  6. SSE 对话流程详解
  7. 依赖关系分析
  8. 性能与限流特性
  9. 故障排查指南
  10. 结论

引言

本文档面向调用方和前端开发者,系统化说明后端 Agent 对话、RAG、模型管理、专家目录、工具包、能力清单、Artifacts、Python 文件服务以及 Insight 研判相关接口的 URL、方法、参数、响应格式、错误语义与排查方法。重点覆盖 /chat/stream SSE 接口:连接建立方式、x-token 认证、请求体字段、事件类型、增量数据、结束帧、心跳保活、中断重连策略,并给出 curl 与前端 fetch/SSE 示例。

项目结构

后端主要 API 集中在 ai-server 模块的 com.zsjz.ai.module.agent 包下,按控制器分层:

graph TB
    subgraph "Agent 控制器"
        Chat["AgentChatController<br/>/chat"]
        Model["AgentModelController<br/>/models"]
        Expert["AgentExpertController<br/>/agents"]
        ToolPack["AgentToolPackController<br/>/tool-packs"]
        Capability["AgentCapabilityController<br/>/capability"]
        Artifact["AgentArtifactController<br/>/agent/artifact"]
        PyFiles["AgentPythonFileController<br/>/py/files"]
        InsightCtrl["InsightController<br/>/insight"]
    end

    subgraph "核心服务"
        ChatSvc["AgentChatServiceImpl"]
        Llm["LlmService"]
        Rag["RagSchemaService"]
        Python["PythonExecutor"]
    end

    Chat --> ChatSvc
    InsightCtrl --> ChatSvc
    ChatSvc --> Llm
    ChatSvc --> Rag
    ChatSvc --> Python

图示来源

  • AgentChatController.java:24-170
  • InsightController.java:42-127
  • AgentChatServiceImpl.java:345-600

章节来源

  • AgentChatController.java:24-170
  • InsightController.java:42-127

核心组件

  • Agent 对话控制器:负责会话 CRUD、消息管理、附件上传、图谱复原、SSE 流式对话和索引重建。
  • 模型控制器:提供模型厂商列表、模型列表、模型增删改、默认模型设置、连通性测试。
  • 专家控制器:管理内置与自建专家,受登录用户隔离。
  • 工具包控制器:管理用户自定义工具组合,删除时自动清理方案绑定并驱逐实例池。
  • 能力控制器:暴露工具清单、技能列表、技能详情、技能安装/卸载/启停。
  • Artifacts 控制器:预览与下载 Agent 产出的 CSV。
  • Python 文件控制器:安全读取 Python 沙箱产出的图片。
  • Insight 控制器:对象关系研判场景的会话、历史、分页消息、执行明细与线索聚合。
  • LLM 服务:直连大模型的轻量文本调用层,不经过 Agent。
  • RAG Schema 服务:统一表结构向量索引查询门面。
  • Python 执行器:子进程沙箱执行 Python,生成快照数据库与图片输出。

章节来源

  • AgentChatController.java:24-170
  • AgentModelController.java:18-91
  • AgentExpertController.java:31-72
  • AgentToolPackController.java:33-73
  • AgentCapabilityController.java:33-135
  • AgentArtifactController.java:26-76
  • AgentPythonFileController.java:27-112
  • InsightController.java:42-127
  • LlmService.java:23-200
  • RagSchemaService.java:26-181
  • PythonExecutor.java:26-200

架构总览

Agent 对话链路以 AgentScope 的 HarnessAgent 为核心,结合工具、意图识别、Followup 中间件、RAG 与 Python 执行器完成多轮 ReAct 推理;LLM 服务则用于无需 Agent 链路的纯文本任务。

sequenceDiagram
    participant Client as "客户端"
    participant Controller as "AgentChatController"
    participant Service as "AgentChatServiceImpl"
    participant Agent as "HarnessAgent"
    participant Tools as "工具集合"
    participant LLM as "LLM Provider"
    participant DB as "持久层"

    Client->>Controller: POST /chat/stream
    Controller->>Service: stream(ChatRequestDTO)
    Service->>Service: 校验 sessionKey/案件/附件
    Service->>Agent: streamEvents([USER], RuntimeContext)
    Agent->>Tools: 工具调用
    Tools->>DB: 查库/SQL/图谱/RAG
    Tools-->>Agent: 工具结果
    Agent->>LLM: 生成回复
    LLM-->>Agent: token/思考/工具指令
    Agent-->>Service: event 流
    Service-->>Client: SSE: tool_call/token/thinking/done/error
    Service->>DB: 异步落库 assistant 消息

图示来源

  • AgentChatController.java:145-170
  • AgentChatServiceImpl.java:345-600
  • LlmService.java:23-200

接口规范

通用响应约定

  • 多数业务接口返回 Result<T>,包含 code、message、data。
  • /chat/** 与 /insight/** 采用裸响应(不走 Result<T>),便于前端复用原始流或对象。
  • 全局异常处理器将未处理异常统一封装为 Result,并映射 HTTP 状态码。

章节来源

  • Result.java:1-114
  • GlobalExceptionHandler.java:1-222
  • InsightController.java:53-65

认证与 Token

  • 登录接口位于 /auth/login,返回包含 token 的 LoginVO。
  • 鉴权通过 sa-token 拦截器实现,除白名单外均要求登录。
  • Token 通过请求头 x-token 传递。
  • 未登录、Token 失效、被顶下线时,全局异常处理器返回 HTTP 200 + body.code=401,由前端触发重新登录逻辑。
接口 方法 说明
/auth/login POST 用户名+密码登录,返回 token
/auth/logout POST 登出并释放数据源
/auth/info GET 当前用户信息
/auth/changePwd POST 修改密码
/auth/verifyPwd POST 验证密码

章节来源

  • AuthController.java:19-82
  • GlobalExceptionHandler.java:44-75

模型管理 /models

接口 方法 参数 响应 说明
/models/providers GET 无 Result<List<ModelProviderVO>> 模型厂商列表
/models GET 无 Result<List<ModelVO>> 启用模型列表
/models POST CreateModelDTO Result<ModelVO> 创建模型
/models/{id} PUT path:id, body:UpdateModelDTO Result<Void> 更新模型
/models/{id} GET path:id Result<Void> 删除模型
/models/{id}/default GET path:id Result<Void> 设置默认模型
/models/{id}/test GET path:id Result<ModelTestResultVO> 连通性测试,失败也返回 200 + success=false

章节来源

  • AgentModelController.java:18-91

专家目录 /agents

接口 方法 参数 响应 说明
/agents GET 无 Result<List<ExpertVO>> 内置 + 当前用户自建专家
/agents POST SaveExpertDTO Result<ExpertVO> 新建自建专家
/agents/{id} PUT path:id, body:SaveExpertDTO Result<ExpertVO> 编辑专家(内置拒绝)
/agents/{id} DELETE path:id Result<Void> 删除专家(内置拒绝)

章节来源

  • AgentExpertController.java:31-72

工具包 /tool-packs

接口 方法 参数 响应 说明
/tool-packs GET 无 Result<List<ToolPackVO>> 当前用户工具包列表
/tool-packs POST SaveToolPackDTO Result<ToolPackVO> 新建工具包
/tool-packs/{id} PUT path:id, body:SaveToolPackDTO Result<ToolPackVO> 编辑工具包
/tool-packs/{id} DELETE path:id Result<Void> 删除工具包,并移除方案绑定

章节来源

  • AgentToolPackController.java:33-73

能力与技能 /capability

接口 方法 参数 响应 说明
/capability/tools GET 无 Result<List<AgentToolVO>> 运行时工具清单
/capability/skills GET 可选 caseId Result<List<SkillVO>> 技能清单
/capability/skills/{name} GET path:name, 可选 caseId Result<SkillDetailVO> 技能详情
/capability/skills/{name}/file GET path:name, query:path, 可选 caseId Result<SkillFileContentVO> 技能内单个文件内容
/capability/skills POST SaveSkillDTO Result<SkillVO> 新建技能
/capability/skills/{name} PUT path:name, body:SaveSkillDTO Result<SkillVO> 修改技能
/capability/skills/install POST file:file, query:overwrite Result<SkillVO> 上传 zip 安装技能
/capability/skills/{name}/delete GET path:name Result<Void> 卸载技能
/capability/skills/{name}/toggle GET path:name, query:enabled Result<Void> 启停技能

章节来源

  • AgentCapabilityController.java:33-135

Artifacts 产物 /agent/artifact

接口 方法 参数 响应 说明
/agent/artifact/preview GET query:id, 可选 limit 裸对象 {columns, rows} 预览 CSV 前 N 行
/agent/artifact/download GET query:id 二进制 CSV 流 下载完整产物

注意事项:

  • 鉴权使用请求头 x-token,不进入 sa-token 白名单。
  • 路径归属由 CaseContextHolder 保证,跨案件访问返回 404/400。
  • 前端必须用 fetch 携带 x-token 后保存 blob,不能直接用 <a href>。

章节来源

  • AgentArtifactController.java:26-76

Python 文件 /py/files

接口 方法 参数 响应 说明
/py/files/{workspaceId}/{execId}/{filename} GET path:workspaceId,execId,filename 图片二进制流 读取 Python 沙箱产出图片

约束:

  • 仅允许 png、jpg、jpeg、gif、webp、svg、bmp。
  • workspaceId 必须等于当前打开案件 ID,否则返回 403。
  • 路径归一化后必须落在 workspace/{workspaceId}/py-out/,否则返回 400。
  • 响应带 1 小时公共缓存控制。

章节来源

  • AgentPythonFileController.java:27-112

Insight 研判 /insight

接口 方法 参数 响应 说明
/insight/sessions POST InsightCreateDTO InsightSessionVO 创建研判会话
/insight/stream POST InsightStreamDTO SSE 流 流式分析
/insight/sessions GET query:caseId, 可选 scope List<InsightSessionVO> 历史会话
/insight/sessions/{id} GET path:id, query:caseId InsightSessionVO 会话详情
/insight/sessions/{id}/messages GET path:id, query:caseId, 分页参数 IPage<InsightMessageVO> 分页消息
/insight/messages/{messageId}/trace GET path:messageId, query:caseId InsightMessageTraceVO 单条消息执行明细
/insight/sessions/{id}/delete GET path:id, query:caseId 裸空响应 删除会话
/insight/clues GET query:caseId, 可选 level,limit List<InsightClueVO> 线索聚合

注意:

  • 所有读接口强制 caseId 双条件校验。
  • 响应为裸对象,不走 Result<T>。

章节来源

  • InsightController.java:42-127

SSE 对话流程详解

端点与连接建立

  • 端点:POST /chat/stream
  • Content-Type:application/json
  • Accept:text/event-stream
  • 认证:请求头 x-token
  • 返回:Reactor Flux<ServerSentEvent<String>>,每个事件为一个 event: + data: JSON 帧

curl 示例:

curl -N -X POST http://host/chat/stream \
  -H "Content-Type: application/json" \
  -H "x-token: YOUR_TOKEN" \
  -d '{"message":"分析本案件资金流向","sessionKey":"SESSION_ID"}'

前端 fetch + ReadableStream 示例:

const res = await fetch("/chat/stream", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-token": token,
  },
  body: JSON.stringify({ message, sessionKey }),
});

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, { stream: true });
  // 按行解析 data: 和 event: 字段
}

章节来源

  • AgentChatController.java:145-170

请求体 ChatRequestDTO

字段 类型 必填 说明
message String 是 用户提问文本
sessionKey String 是 当前会话的业务标识,服务端解析为 sessionId
agentId Long 否 可覆盖会话绑定的专家,内部用于构建 Agent
modelId Long 否 动态切换模型;与会话绑定模型不同时回写会话
attachmentIds List<Long> 否 附件 ID,发送前通过 /chat/attachments 上传

章节来源

  • ChatRequestDTO.java:1-24

SSE 事件类型与增量字段

事件名 含义 关键字段 发生时机
tool_call 工具调用开始 type=tool_call、toolCallId、toolName AgentScope 发起工具调用
tool_input 工具输入累积完成 type=tool_input、toolCallId、toolInput 工具参数收集完毕
tool_result 工具结果累积完成 type=tool_result、toolCallId、toolName、toolResult 工具执行结束
token 文本增量 type=token、data 模型逐字输出
thinking 模型思考过程 type=thinking、phase=start/delta/end、data 开启、增量、结束
intent 意图识别结果 由中间件注入 意图识别完成
suggestions 下一步建议 由 Followup 中间件注入 对话结束后追加
graph_data 全量图谱数据 type=graph_data、toolCallId、graph 调用 get_case_graph 工具后补发
done 本轮对话结束 type=done、sessionKey Agent 结束事件
error 运行期错误 type=error、error 参数/会话/系统异常
heartbeat 心跳保活 type=heartbeat、ts 每 10 秒一次

增量字段说明:

  • token.data 是增量片段,不是完整文本,需要前端拼接。
  • tool_input.toolInput 和 tool_result.toolResult 在对应工具结束时一次性返回完整值。
  • thinking.data 同样增量拼接,phase=start 表示一段新思考开始,phase=end 表示该段结束。
  • done.sessionKey 可用于前端刷新后恢复会话上下文。

章节来源

  • AgentChatController.java:118-143
  • AgentChatServiceImpl.java:479-594

结束事件与错误事件

  • done:正常结束,附带 sessionKey。
  • error:参数为空、缺少 sessionKey、会话不存在、会话不属于当前案件、模型未配置等错误都会转为 error 帧。
  • 服务端会在错误情况下尝试把错误消息落库,使刷新会话后仍可见。

章节来源

  • AgentChatServiceImpl.java:345-370
  • AgentChatServiceImpl.java:742-776

心跳保活机制

服务端同时发射两条 Flux:

  1. 真实业务事件流。
  2. 每 10 秒一次的 heartbeat 事件。

心跳帧不参与正文、思考、工具结果累积,仅用于让前端区分“模型仍在处理”和“连接已断”。

章节来源

  • AgentChatServiceImpl.java:594-600

中断与重连策略

  • 同一会话同一时刻只允许一条 AI 流;重复发送会立即收到 error 帧:“该会话正在回复中,请等待当前回复完成后再发送”。
  • 用户主动中止 SSE 连接时,若 AgentResultEvent 尚未到达,服务端会把已输出的部分文本、工具事件和思考过程异步落库,标记为中断。
  • 重连建议:
    • 前端检测到连接断开或超时后,先判断是否收到 done。
    • 若未收到 done,可用相同 sessionKey 和上一次 message 重试;如果已经收到 done,不应重复发送同一条消息。
    • 对并发冲突错误,应提示用户等待或禁用发送按钮。

章节来源

  • AgentChatServiceImpl.java:379-400
  • AgentChatServiceImpl.java:576-594

SSE 流程图

flowchart TD
    Start(["POST /chat/stream"]) --> Validate["校验 message 与 sessionKey"]
    Validate --> Valid{"参数有效?"}
    Valid -->|否| ErrorFrame["发送 error 帧"]
    Valid -->|是| AcquireLock["获取会话级流锁"]
    AcquireLock --> Locked{"锁可用?"}
    Locked -->|否| BusyError["发送 '正在回复中' 错误帧"]
    Locked -->|是| BuildAgent["加载会话/模型/Agent/上下文"]
    BuildAgent --> StreamEvents["订阅 AgentScope 事件流"]
    StreamEvents --> ToolCall["tool_call/tool_input/tool_result"]
    StreamEvents --> Thinking["thinking start/delta/end"]
    StreamEvents --> Token["token 增量"]
    StreamEvents --> Done["done + sessionKey"]
    StreamEvents --> Heartbeat["每 10 秒 heartbeat"]
    Done --> End(["结束"])
    Heartbeat --> End
    ErrorFrame --> End
    BusyError --> End

图示来源

  • AgentChatServiceImpl.java:345-600

依赖关系分析

AgentScope、LLM Provider、RAG、Python 执行器的作用

组件 职责 在对话中的作用
AgentScope 多轮 Agent 编排、工具调度、记忆、技能过滤、Transcript 承载 ReAct 循环,驱动工具调用与模型交互
LLM Provider 实际大模型连接层 被 AgentScope 与 LlmService 调用,提供文本生成
RAG Schema 表结构元数据向量化检索 通过 search_table_schema 工具帮助模型理解数据库结构
Python 执行器 子进程执行 Python 代码 提供数据分析、绘图、DuckDB 查询能力,输出图片与结果
graph LR
    Chat["AgentChatController"] --> Svc["AgentChatServiceImpl"]
    Svc --> AgentScope["HarnessAgent"]
    AgentScope --> Tools["工具集合"]
    Tools --> Rag["RagSchemaService"]
    Tools --> Python["PythonExecutor"]
    AgentScope --> LLM["LLM Provider"]

图示来源

  • AgentChatServiceImpl.java:400-500
  • RagSchemaService.java:26-181
  • PythonExecutor.java:26-200

章节来源

  • LlmService.java:23-200
  • RagSchemaService.java:26-181
  • PythonExecutor.java:26-200

性能与限流特性

  • 会话级流互斥:同一会话并发流使用 Semaphore 非阻塞抢占,避免记忆污染。
  • 工具结果截断:根据工具名称限制最大字符数,防止超大 SSE 帧。
  • Python 执行超时:子进程按配置超时终止,输出有最大字符截断。
  • RAG 索引状态区分:SUCCESS 与 IDLE,空索引抛可操作错误而非静默空结果。
  • 心跳保活:10 秒间隔,避免长连接假死。

章节来源

  • AgentChatServiceImpl.java:65-90
  • AgentChatServiceImpl.java:514-535
  • PythonExecutor.java:140-200
  • RagSchemaService.java:85-181

故障排查指南

LLM 不可用

现象:

  • 创建会话或发送消息时报错。
  • /models/{id}/test 返回 success=false。
  • SSE 直接返回 error 帧。

排查步骤:

  1. 调用 /models 确认存在启用模型。
  2. 调用 /models/{id}/test 查看连通性失败原因。
  3. 检查是否设置了默认模型;若未指定且无默认模型,会返回 400。
  4. 查看 LlmService 日志中的模型名称与错误信息。

可能错误:

  • 未指定模型且无默认模型。
  • 模型配置无效、API Key 错误或网络不可达。
  • 模型调用超时(504)。

章节来源

  • AgentChatServiceImpl.java:420-445
  • AgentModelController.java:74-91
  • LlmService.java:120-200

RAG 无结果

现象:

  • 工具调用 search_table_schema 返回空。
  • 手动调用 RAG 相关接口报 409。

排查步骤:

  1. 确认 RAG 开关与嵌入模型可用。
  2. 调用 /chat/reindexWorkspace 重建索引。
  3. 检查索引状态是否为 SUCCESS。
  4. 若索引为空但能力可用,需先重建再检索。

可能错误:

  • 未配置嵌入模型。
  • 索引未构建。
  • 索引已构建但语义检索确实无命中。

章节来源

  • RagSchemaService.java:60-181
  • AgentChatController.java:165-170

SSE 断流

现象:

  • 前端长时间收不到事件。
  • 浏览器显示连接已关闭但未收到 done。

排查步骤:

  1. 观察是否收到 heartbeat;若无心跳,可能是连接层问题。
  2. 若收到 error,根据 error.error 字段定位。
  3. 若未收到 done,可视为中断,使用相同 sessionKey 重连重试。
  4. 若多次收到“会话正在回复中”,应等待当前流结束。

重连建议:

  • 监听 error、连接关闭、超时。
  • 未收到 done 时重试;收到 done 后不再重复发送。
  • 前端维护去重队列,避免双击发送导致并发冲突。

章节来源

  • AgentChatServiceImpl.java:379-400
  • AgentChatServiceImpl.java:576-600

Token 过期或被顶下线

现象:

  • 普通接口返回 HTTP 200 + body.code=401。
  • 前端跳转登录页。
  • /agent/artifact 下载失败。

排查步骤:

  1. 检查 x-token 是否携带。
  2. 调用 /auth/info 确认当前登录态。
  3. 若提示“账号已在其他客户端登录”,说明被顶下线。
  4. 登录后重新获取 token 并重试。

章节来源

  • AuthController.java:19-82
  • GlobalExceptionHandler.java:44-75
  • AgentArtifactController.java:33-43

Python 执行失败

现象:

  • 工具返回 Python 错误。
  • 图片无法显示。
  • 提示执行环境不可用或超时。

排查步骤:

  1. 确认 Python 执行环境已启用。
  2. 检查是否安装了 pandas、duckdb、matplotlib。
  3. 确认当前打开了案件。
  4. 检查工作空间数据库路径是否存在。
  5. 查看 Python 子进程 stdout/stderr。

章节来源

  • PythonExecutor.java:100-200
  • AgentPythonFileController.java:55-112

结论

Agent 对话接口以 /chat/stream 为核心,基于 AgentScope 的流式事件模型对外暴露 tool_call、token、thinking、done、error、heartbeat 等事件;配套提供模型、专家、工具包、能力、Artifacts、Python 文件与 Insight 研判接口。调用方应正确携带 x-token,按事件类型增量渲染,实现心跳检测、中断重连与错误降级,并在 LLM 不可用、RAG 无结果、SSE 断流、Token 过期等场景下依据本文排查路径快速定位问题。