Insight 工作区与 Workspace Catalog.md 33 KB

Insight 工作区与 Workspace Catalog

本文引用的文件

  • AgentInsightSession.java
  • AgentInsightMessage.java
  • InsightAgentFactory.java
  • InsightServiceImpl.java
  • InsightController.java
  • InsightPromptBuilder.java
  • InsightContextBuilder.java
  • WorkspaceSchemaCatalog.java
  • WorkspaceManagerFactory.java
  • useInsightStream.ts
  • api.ts
  • types.ts
  • insight_agent_tables.sql
  • continuous-insight-plan.md

目录

  1. 引言
  2. 项目结构定位
  3. 核心数据模型
  4. 架构总览
  5. 关键组件分析
  6. 依赖关系分析
  7. 性能与可靠性特征
  8. 常见问题排查
  9. 操作示例
  10. 结论

引言

本文件聚焦 Insight 工作区与 Workspace Catalog,目标是解释以下问题:

  • AgentInsightSession 与 AgentInsightMessage 的数据模型、持久化边界与安全隔离。
  • InsightAgentFactory 如何启动分析型 Agent,以及与通用 Agent 的区别。
  • 前端 useInsightStream 如何通过 SSE 消费 Insight 流式输出。
  • Workspace Catalog(WorkspaceSchemaCatalog)与案件数据源、用户会话的关系。
  • Insight 与普通 Agent 对话在持久化、图谱分析结果、API 联动上的差异。
  • 创建 Insight 会话、关联图谱或外部数据、查看消息流、清理工作区的操作流程。
  • 常见故障:会话丢失、消息未落库、工作区跨节点不一致、SSE 被网关切断等。

项目结构定位

Insight 能力位于后端 ai-server/module/agent/insight 和前端 ai-electron/frontend/src/graph/insight 两个区域:

  • 后端负责:会话/消息表、动态提示词、Agent 实例池、SSE 流、案件访问守卫。
  • 前端负责:抽屉 UI、状态机、分页消息加载、结构化产物渲染、SSE 事件处理。
  • 数据库 DDL 独立存放于 sql/insight_agent_tables.sql,不复用通用对话表。
  • 设计意图由 docs/design/continuous-insight-plan.md 明确说明。

    graph TB
    subgraph "前端"
        FE_UI["Insight 抽屉 UI"]
        FE_HOOK["useInsightStream.ts"]
        FE_API["graph/insight/api.ts"]
    end
    
    subgraph "后端"
        CTRL["InsightController"]
        SVC["InsightServiceImpl"]
        ENTITY_S["AgentInsightSession"]
        ENTITY_M["AgentInsightMessage"]
        FACTORY["InsightAgentFactory"]
        PROMPT["InsightPromptBuilder"]
        CTX["InsightContextBuilder"]
        CATALOG["WorkspaceSchemaCatalog"]
        DB[("PostgreSQL<br/>agent_insight_session / agent_insight_message")]
    end
    
    FE_UI --> FE_HOOK
    FE_HOOK --> FE_API
    FE_API --> CTRL
    CTRL --> SVC
    SVC --> ENTITY_S
    SVC --> ENTITY_M
    SVC --> FACTORY
    SVC --> PROMPT
    SVC --> CTX
    FACTORY --> CATALOG
    ENTITY_S --> DB
    ENTITY_M --> DB
    

图表来源

  • InsightController.java:1-127
  • InsightServiceImpl.java:1-200
  • AgentInsightSession.java:1-90
  • AgentInsightMessage.java:1-85
  • InsightAgentFactory.java:1-200
  • InsightPromptBuilder.java:1-145
  • InsightContextBuilder.java:1-200
  • WorkspaceSchemaCatalog.java:1-200
  • useInsightStream.ts:1-200
  • api.ts:1-81

章节来源

  • continuous-insight-plan.md:1-200
  • insight_agent_tables.sql:1-107

核心数据模型

Insight 使用两张独立表,与通用对话表物理隔离:

  • agent_insight_session:会话元数据、上下文快照、系统提示词、消息水位、统计字段。
  • agent_insight_message:用户提问、助手回答、首轮自动分析结果、工具调用明细、结构化产物。

会话实体 AgentInsightSession

关键字段职责如下:

  • id:主键,应用侧生成,非单调。
  • caseId:案件级硬隔离边界,所有查询强制携带。
  • bizType:研判场景维度,当前固定为图谱关系。
  • scope:分析范围,本期主要为整批结果集。
  • agentRowId、modelId:使用的 Agent 配置行与默认模型。
  • title:会话标题,包含时间信息。
  • context:查询条件加图谱快照的 JSONB,是动态系统提示词的数据源。
  • contextHash:对 context 做 SHA-256,用于同条件复用和去重提示。
  • sysPrompt:会话内实际使用的完整系统提示词,不可变且不下发接口。
  • messageCount、lastSeq、totalTokens、lastMessageAt:列表展示与排序辅助。
  • pinned:是否置顶。
  • status:ACTIVE、STREAMING、ARCHIVED,STREAMING 用于并发抢占。
  • createAt、updateAt:创建与更新时间。

该实体的注释明确指出:隔离通过“独立表 + case_id 强制过滤 + session_id 与 case_id 双条件”建立;本实体只承载会话元数据,查询条件与结果快照落在 context,完整提示词落在 sys_prompt。

章节来源

  • AgentInsightSession.java:1-90
  • insight_agent_tables.sql:20-63

消息实体 AgentInsightMessage

关键字段职责如下:

  • id:主键,应用侧生成。
  • sessionId、caseId:归属到具体 Insight 会话,并冗余案件 ID 以强化越权防护。
  • seq:会话内单调递增序号,是稳定排序列。
  • role:user、assistant、system。
  • content:正文文本。
  • contentType:text 或 insight。
  • messageType:chat、first_round、followup。
  • metadata:轻量 JSONB,如思考过程、中断标记、耗时。
  • toolEvents:工具调用明细,单条可达数百 KB,列表查询不 select。
  • outputJson:首轮 assistant 消息的结构化产物 JSONB。
  • tokenCount:Token 用量。
  • replyToMessageId:追问指向的首轮消息,供 UI 分组。
  • starred:收藏标记。
  • status:DONE 或 INTERRUPTED。
  • createAt:创建时间。

DDL 中定义了 (session_id, seq) 唯一约束和外键级联删除,并说明:不能用 id 或 create_at 排序,必须用 seq;并发分配 seq 应通过原子更新会话水位而非 SELECT MAX。

章节来源

  • AgentInsightMessage.java:1-85
  • insight_agent_tables.sql:65-107

前端类型契约

前端 types.ts 把后端 VO 映射为 TypeScript 类型,并强调:ID 一律按字符串处理,避免 Long 精度丢失。主要类型包括:

  • InsightCreateParams:创建会话入参,包含案件、业务类型、分析范围、过滤条件、图谱快照、topN。
  • InsightSessionVO:会话返回体,含 status、context、messageCount 等。
  • InsightMessageVO:消息返回体,不含 toolEvents。
  • InsightMessagePage:MyBatis-Plus Page 形状。
  • InsightStreamParams:流式入参,首轮 message 留空。
  • InsightPayloadWithSource:结构化产物扩展类型。

章节来源

  • types.ts:1-199

架构总览

Insight 的整体流程可以分成三类路径:

  1. 创建会话:前端 POST /insight/sessions → 后端构建上下文与提示词 → 写入 agent_insight_session。
  2. 流式分析:前端 POST /insight/stream → 后端获取 Agent 实例 → 执行 AgentScope 事件流 → 写消息 → SSE 推送 token、工具调用、thinking、insight、done/error。
  3. 历史与追溯:GET /insight/sessions、/sessions/{id}、/sessions/{id}/messages、/messages/{messageId}/trace、/sessions/{id}/delete。

    sequenceDiagram
    participant FE as "前端 useInsightStream"
    participant API as "graph/insight/api.ts"
    participant CTRL as "InsightController"
    participant SVC as "InsightServiceImpl"
    participant CTX as "InsightContextBuilder"
    participant PROMPT as "InsightPromptBuilder"
    participant DB as "PostgreSQL"
    participant FACTORY as "InsightAgentFactory"
    participant AG as "HarnessAgent"
    
    FE->>API: createInsightSession(params)
    API->>CTRL: POST /insight/sessions
    CTRL->>SVC: createSession(dto)
    SVC->>CTX: build(caseId, caseName, dto)
    SVC->>PROMPT: build(context)
    SVC->>DB: INSERT agent_insight_session
    SVC-->>FE: InsightSessionVO
    
    FE->>API: streamInsight({sessionId, caseId})
    API->>CTRL: POST /insight/stream
    CTRL->>SVC: stream(dto)
    SVC->>FACTORY: getOrCreate(sessionId, modelId, sysPrompt)
    FACTORY->>AG: 构造 HarnessAgent
    loop 流式事件
        AG-->>SVC: token / thinking / tool_call / tool_result / insight / done
        SVC->>DB: 插入或更新 agent_insight_message
        SVC-->>FE: ServerSentEvent
    end
    

图表来源

  • InsightController.java:28-127
  • InsightServiceImpl.java:1-200
  • InsightContextBuilder.java:1-200
  • InsightPromptBuilder.java:1-145
  • InsightAgentFactory.java:1-200
  • api.ts:1-81

关键组件分析

数据模型类图

classDiagram
    class AgentInsightSession {
        +Long id
        +Long caseId
        +String bizType
        +String scope
        +Long agentRowId
        +Long modelId
        +String title
        +String context
        +String contextHash
        +String sysPrompt
        +Integer messageCount
        +Long lastSeq
        +Long totalTokens
        +LocalDateTime lastMessageAt
        +Boolean pinned
        +String status
        +LocalDateTime createAt
        +LocalDateTime updateAt
    }

    class AgentInsightMessage {
        +Long id
        +Long sessionId
        +Long caseId
        +Long seq
        +String role
        +String content
        +String contentType
        +String messageType
        +String metadata
        +String toolEvents
        +String outputJson
        +Integer tokenCount
        +Long replyToMessageId
        +Boolean starred
        +String status
        +LocalDateTime createAt
    }

    AgentInsightSession <|-- AgentInsightMessage : "一对多"

图表来源

  • AgentInsightSession.java:1-90
  • AgentInsightMessage.java:1-85

Insight 会话创建与提示词装配

创建 Insight 会话时,后端完成以下关键步骤:

  1. 通过 CaseAccessGuard 校验请求中的 caseId 属于当前用户打开的案件。
  2. 从 AgentModelService 获取默认模型,无默认模型直接拒绝。
  3. 通过 InsightContextBuilder.build 规整分析条件、图谱快照、topN,并裁剪图谱。
  4. 通过 InsightPromptBuilder.build 拼接静态人设、动态上下文块、结构化产物契约、RAG 指引。
  5. 将 context、contextHash、sysPrompt 写入会话表。
  6. 返回 InsightSessionVO,不包含完整的 sysPrompt。

InsightPromptBuilder 的注释强调:它不复用通用对话的渲染契约,因为 Insight 的 insight围栏结构与通用表格/ECharts/graph 载荷不同,混在一起会互相污染。首次自动分析的指令由firstRoundInstruction()` 提供,前端打开抽屉时不敲字,由服务端注入。

flowchart TD
    Start(["创建 Insight 会话"]) --> Guard["案件归属校验"]
    Guard --> ModelCheck{"是否存在默认模型"}
    ModelCheck -->|否| Error["返回错误:未配置默认模型"]
    ModelCheck -->|是| BuildCtx["InsightContextBuilder 构建上下文"]
    BuildCtx --> TrimGraph["裁剪图谱快照<br/>按度数保留 topN 节点与两端节点边"]
    TrimGraph --> BuildPrompt["InsightPromptBuilder 拼装系统提示词"]
    BuildPrompt --> Persist["写入 agent_insight_session"]
    Persist --> Return["返回 InsightSessionVO"]

图表来源

  • InsightServiceImpl.java:1-200
  • InsightContextBuilder.java:1-200
  • InsightPromptBuilder.java:1-145

章节来源

  • InsightServiceImpl.java:1-200
  • InsightPromptBuilder.java:1-145
  • InsightContextBuilder.java:1-200

InsightAgentFactory:分析型 Agent 启动与实例池

InsightAgentFactory 的核心职责是“取或建研判 Agent 实例”,并维护一个独立实例池。关键点如下:

  • 池 key 前缀为 insight-s,附加 sessionId,确保动态提示词不会在不同会话之间串台。
  • 通用 Agent 池 key 是 w{ws}-a{agent}-m{model},不含 sysPrompt 维度;复用会导致第二次分析拿到第一次的提示词。
  • LRU 上限为 64,空闲超过 30 分钟回收。
  • 记忆由 AgentStateStore 按 (userId, sessionId) 隔离;实例回收不影响会话记忆,只是下次重建 Agent 配置。
  • buildAgent 刻意为之的差异:

    • 不挂意图识别中间件;
    • 不挂 Followup 中间件;
    • 默认装备 graph 组而非 person 组,起点就是关系图谱数据。

      classDiagram
      class InsightAgentFactory {
      +String AGENT_NAME
      -Map~String, HarnessAgent~ agentPool
      -Map~String, Long~ lastAccessAt
      -ReentrantLock poolLock
      +getOrCreate(sessionId, modelId, sysPrompt) HarnessAgent
      +evict(sessionId) void
      -buildAgent(modelId, sysPrompt) HarnessAgent
      }
      
      class HarnessAgent {
      <<external>>
      }
      
      InsightAgentFactory --> HarnessAgent : "创建并缓存"
      

图表来源

  • InsightAgentFactory.java:1-200

章节来源

  • InsightAgentFactory.java:1-200

前端 useInsightStream:SSE 流式消费

useInsightStream 是一个独立的组合式 hook,专门管理 Insight 抽屉的状态机,而不是复用全局 chat store。其状态流转为:

  • idle → creating(创建会话)→ streaming(首轮或追问)→ done
  • 异常分支:error(模型未配置、网络失败、超限、409 进行中)

主要行为包括:

  • 使用本地临时负数 ID 表示尚未落库的前端消息。
  • 拉取第 N 页消息,服务端返回 seq DESC,前端 reverse 后升序展示。
  • 流式期间实时累积工具调用步骤和思考过程。
  • 从内容块中提取第一个合法的 insight 载荷作为结构化产物。
  • 历史消息通过 hydrate 解析富内容块,必要时按需拉取 trace。
  • 使用 AbortController 支持关闭抽屉时中止流。

    stateDiagram-v2
    [*] --> Idle
    Idle --> Creating : "创建会话"
    Creating --> Streaming : "开始流式"
    Streaming --> Done : "收到 done"
    Streaming --> Error : "模型未配置 / 网络 / 超限 / 409"
    Done --> Idle : "关闭或切换会话"
    Error --> Idle : "重试或关闭"
    

图表来源

  • useInsightStream.ts:1-200

章节来源

  • useInsightStream.ts:1-200
  • api.ts:1-81

Workspace Catalog 与 Workspace 文件系统

这里有两个容易混淆的概念需要区分:

  1. Workspace Schema Catalog:WorkspaceSchemaCatalog 是可查表目录,来源是模板库元数据,不是 DuckDB 运行时扫描。它聚合既有模板库 table_info/table_field 与 AI 智能清洗动态表 ai_clean_template/ai_clean_field,输出 Agent 可使用的表结构清单。它不读取 DuckDB 系统表,也不暴露内部表给模型。
  2. Agent 工作目录:WorkspaceManagerFactory 解析 Agent 运行时工作目录,路径形如 {cwd}/.agentscope/users/{userId}/workspaces/{workspaceId}/agents/{agentRowId}/,用于 skills、记忆、子 Agent、事件转录等文件系统隔离。

因此,Workspace Catalog 不等于 DuckDB 数据源目录;它是“模型知道有哪些表可以查”的元数据目录。而 Workspace 文件系统是 AgentScope 运行时的工作空间根。

graph TB
    WS_CAT["WorkspaceSchemaCatalog<br/>模板库元数据目录"]
    FILE_WS["WorkspaceManagerFactory<br/>Agent 工作目录"]
    TEMPLATE["table_info / table_field"]
    AICLEAN["ai_clean_template / ai_clean_field"]
    USER["用户"]
    WORKSPACE["业务工作空间"]
    AGENT["Agent 配置"]

    TEMPLATE --> WS_CAT
    AICLEAN --> WS_CAT
    USER --> FILE_WS
    WORKSPACE --> FILE_WS
    AGENT --> FILE_WS

图表来源

  • WorkspaceSchemaCatalog.java:1-200
  • WorkspaceManagerFactory.java:1-79

章节来源

  • WorkspaceSchemaCatalog.java:1-200
  • WorkspaceManagerFactory.java:1-79

依赖关系分析

Insight 模块的关键依赖链如下:

graph LR
    Controller["InsightController"] --> Service["InsightServiceImpl"]
    Service --> SessionEntity["AgentInsightSession"]
    Service --> MessageEntity["AgentInsightMessage"]
    Service --> ContextBuilder["InsightContextBuilder"]
    Service --> PromptBuilder["InsightPromptBuilder"]
    Service --> AgentFactory["InsightAgentFactory"]
    AgentFactory --> StateStore["AgentStateStore"]
    AgentFactory --> Catalog["WorkspaceSchemaCatalog"]
    Service --> CaseAccess["CaseAccessGuard"]
    Service --> ModelService["AgentModelService"]
    Service --> CaseInfo["CaseInfoMapper"]

图表来源

  • InsightController.java:1-127
  • InsightServiceImpl.java:1-200
  • InsightAgentFactory.java:1-200
  • WorkspaceSchemaCatalog.java:1-200

耦合与内聚

  • Insight 模块与通用对话模块解耦:独立表、独立 Mapper、独立 Service、独立 Agent 实例池。
  • 安全性内聚于 Service 层:案件归属校验、case_id 强制过滤、外键级联删除。
  • 提示词组装内聚于 PromptBuilder,避免污染通用渲染契约。
  • 前端状态机内聚于 useInsightStream,避免与全局 chat store 冲突。

潜在循环依赖

从现有结构看,没有明显的循环导入:Controller → Service → Entity/Mapper/Factory/Prompt/Context,Factory 依赖 Catalog 和 StateStore,Catalog 依赖模板库 Mapper,彼此单向。

章节来源

  • InsightController.java:1-127
  • InsightServiceImpl.java:1-200
  • InsightAgentFactory.java:1-200

性能与可靠性特征

持久化策略

  • Insight 会话与消息持久化入库,不复用 agent_chat_session / agent_message。
  • 消息列表接口不返回 tool_events 与 output_json,避免大字段拖慢列表。
  • 结构化产物 output_json 仅首轮 assistant 消息有值,前端也可从 SSE 的 insight 帧提前渲染。
  • 单条 trace 按需拉取,避免每次打开对话都加载全部工具调用明细。

并发控制

  • 会话级互斥闸门使用 Semaphore,因为抢占发生在订阅线程,释放发生在 Reactor 回调线程;ReentrantLock 跨线程 unlock 会抛异常。
  • 多实例并发抢占靠数据库 status 字段:ACTIVE、STREAMING、ARCHIVED。
  • 同一案件创建会话有进程内锁,防止重复创建。

排序与分页

  • 消息排序列是 seq,不是 id 或 create_at。
  • 前端第 1 页是最新 N 条,上滑加载更多更早消息。
  • 分页追加时前端用消息 id 去重兜底,防止持续追加导致同一条出现在两页。

Token 与迭代控制

  • Insight Agent 最大迭代轮数刻意压到 6,因为它是“读一批数据 → 给出结论”的任务,不适合长链路探索。
  • 图谱快照会被裁剪到 topN,避免一次性把过多节点和边塞进提示词。

章节来源

  • InsightServiceImpl.java:1-200
  • InsightAgentFactory.java:1-200
  • useInsightStream.ts:1-200
  • insight_agent_tables.sql:1-107

常见问题排查

Insight 会话丢失

可能原因:

  • 删除了 agent_insight_session,但消息随外键级联删除,因此消息也消失。
  • 前端重新打开页面后没有正确传入 sessionId,导致新会话替代旧会话。
  • 会话状态异常卡在 STREAMING,后续追问被拦截。

排查建议:

  • 检查 agent_insight_session.status 是否为 ACTIVE 或 ARCHIVED。
  • 确认前端 useInsightStream 的 sessionId 与 caseId 是否一致。
  • 若怀疑内存实例残留,检查 InsightAgentFactory 实例池是否已 evict。

章节来源

  • insight_agent_tables.sql:65-107
  • InsightAgentFactory.java:1-200
  • useInsightStream.ts:1-200

消息未落库

可能原因:

  • SSE 流被网关或代理切断,前端收不到 token/done。
  • 事务异常或数据库写入失败。
  • 前端只渲染流式状态,但未等待 done 后再触发刷新历史消息。

排查建议:

  • 检查后端日志中是否有 Agent 执行异常、工具调用异常。
  • 检查 agent_insight_message.content 是否为空。
  • 确认 SSE 事件协议是否包含 token、thinking、tool_call、tool_result、insight、done。

章节来源

  • api.ts:1-81
  • useInsightStream.ts:1-200
  • InsightController.java:28-127

工作区跨节点不一致

可能原因:

  • Agent 工作目录基于本地文件系统,多节点部署时每个节点有自己的 .agentscope 目录。
  • Skills、记忆、子 Agent 状态如果依赖本地文件,跨节点无法共享。
  • 真正需要共享的状态应放在 PostgreSQL:会话、消息、上下文快照、提示词。

排查建议:

  • 若需要跨节点共享 Agent 状态,应迁移到分布式存储或使用统一文件服务器。
  • 对于 Insight 主流程,优先依赖数据库持久化;本地文件只作运行期临时状态。
  • 注意 WorkspaceManagerFactory 生成的路径是本地绝对路径,不是共享卷路径。

章节来源

  • WorkspaceManagerFactory.java:1-79
  • insight_agent_tables.sql:1-107

SSE 流被网关切断

可能原因:

  • 网关超时时间短于 Insight 流式输出时长。
  • 网关未正确透传 text/event-stream。
  • 前端网络重试策略不正确,导致断流后状态不一致。

排查建议:

  • 调整网关 SSE 超时和缓冲大小。
  • 检查响应头是否包含 Content-Type: text/event-stream。
  • 前端应在 error 分支显示可重试提示,并保留当前会话状态。

章节来源

  • api.ts:1-81
  • useInsightStream.ts:1-200
  • InsightController.java:56-68

操作示例

创建 Insight 会话

  1. 前端准备 InsightCreateParams:包含 caseId、可选 bizType、scope、filters、graph、topN。
  2. 调用 createInsightSession,即 POST /insight/sessions。
  3. 后端校验案件归属、获取默认模型、构建上下文、拼装提示词、写入会话表。
  4. 前端获得 InsightSessionVO,随后立即发起首轮流式分析。

参考实现位置:

  • 前端 API:api.ts:25-33
  • 前端类型:types.ts:59-86
  • 后端控制器:InsightController.java:38-48
  • 后端服务:InsightServiceImpl.java:1-200

章节来源

  • api.ts:25-33
  • types.ts:59-86
  • InsightController.java:38-48
  • InsightServiceImpl.java:1-200

关联图谱或外部数据

Insight 的图谱关联方式是“快照”:

  • 前端把画布中的节点和边序列化为 InsightGraphSnapshot,随创建会话请求发送。
  • 后端 InsightContextBuilder.trimGraph 按度数裁剪,只保留 topN 节点及其两端都在的边。
  • 外部数据通过 WorkspaceSchemaCatalog 暴露的模板库元数据间接影响 Agent:Agent 可通过 RAG 工具检索表结构,再写 SQL 查询。

参考实现位置:

  • 前端快照类型:types.ts:22-58
  • 后端上下文裁剪:InsightContextBuilder.java:1-200
  • 可查表目录:WorkspaceSchemaCatalog.java:1-200

章节来源

  • types.ts:22-58
  • InsightContextBuilder.java:1-200
  • WorkspaceSchemaCatalog.java:1-200

查看 Insight 消息流

  1. 创建会话成功后,前端调用 streamInsight,连接 /insight/stream。
  2. 流式事件与通用聊天流同构,新增 insight 帧用于结构化产物。
  3. 前端 useInsightStream 根据消息类型区分首轮分析与追问。
  4. 列表消息通过分页接口加载,滚动向上加载更多。

参考实现位置:

  • 前端流式入口:api.ts:73-81
  • 前端流式状态机:useInsightStream.ts:1-200
  • 后端流式接口:InsightController.java:56-68

章节来源

  • api.ts:73-81
  • useInsightStream.ts:1-200
  • InsightController.java:56-68

清理工作区

Insight 的“清理”有两种层次:

  1. 清理 Insight 会话:调用 DELETE /insight/sessions/{id}/delete,消息随外键级联删除。
  2. 清理 Agent 工作目录:WorkspaceManagerFactory 提供路径解析,但不直接提供删除方法;删除应由运维或上层生命周期管理,注意多节点部署下本地文件不一致风险。

参考实现位置:

  • 前端删除接口:api.ts:65-71
  • 后端删除接口:InsightController.java:118-127
  • 外键级联:insight_agent_tables.sql:90-107
  • 工作目录解析:WorkspaceManagerFactory.java:15-79

章节来源

  • api.ts:65-71
  • InsightController.java:118-127
  • insight_agent_tables.sql:90-107
  • WorkspaceManagerFactory.java:15-79

结论

Insight 工作区的设计核心是“独立、安全、可追溯”:

  • 独立:会话、消息、Agent 实例池、提示词装配都与通用对话解耦。
  • 安全:case_id 冗余、外键级联、案件访问守卫、SQL 层越权防护。
  • 可追溯:消息按 seq 稳定排序,trace 按需拉取,结构化产物持久化。

Workspace Catalog 负责告诉 Agent “有哪些模板表可以查”,Workspace 文件系统负责隔离 Agent 运行态文件;两者共同支撑 Insight 的外部数据能力,但不应与 Insight 自身的持久化数据混淆。普通 Agent 对话侧重通用交互,Insight 侧重图谱关系研判、结构化线索产出与 SSE 流式体验。