agent-data-model.md 5.4 KB

Agent 数据模型:工具 / 工具包 / 研判方案 的表关系

适用范围:ai-server 的 module/agent 域 + sql/agent_tool_pack.sql(含内置种子)。 结论先行:工具 ↔ 工具包 ↔ 研判方案 是两级多对多,都用 JSON 数组做松引用, 完整性由「保存时校验 + 删除时清理 + 装配时跳过」三道防线保证(见文末规则表)。

关系图

erDiagram
    agent_tool ||--o{ agent_tool_pack_item : "tool_names[] 按名引用"
    agent_tool_pack ||--o{ agent_tool_pack_item : "包内工具集合"
    agent_tool_pack ||--o{ agent_pack_bind : "被方案勾选"
    agent ||--o{ agent_pack_bind : "方案勾选的包"

    agent_tool {
        bigint id PK "雪花 ID"
        varchar tool_name UK "工具名(@Tool name)"
        varchar group_code "call/trans/track/graph/person/file/base"
        varchar status "ACTIVE | DELETED"
    }
    agent_tool_pack {
        bigint id PK "雪花 ID(内置包固定 1~6)"
        bigint user_id "创建者;内置包 = 1"
        varchar name "包名(user_id 内唯一)"
        text tool_names "JSON 数组:tool_name 列表"
        smallint is_builtin "1=内置(全局可见、不可改删)"
    }
    agent {
        bigint row_id PK "identity 自增"
        bigint user_id "创建者;内置方案 = 1"
        smallint is_builtin "1=内置(不可改删)"
        text tools_allow_json "JSON 数组:工具组编码白名单"
        text tool_packs_json "JSON 数组:工具包 id 白名单"
        text skills_allow_json "JSON 数组:技能名白名单"
    }

图中 agent_tool_pack_item / agent_pack_bind 是逻辑关系(多对多的语义实体), 物理上分别落在 agent_tool_pack.tool_names 与 agent.tool_packs_json 两个 JSON 数组列里, 不建物理中间表:数据量级为个位数包 × 十位数工具,JSON 松引用 + 服务层校验更贴合本域。

多对多怎么成立

关系 基数 存储 说明
工具 ↔ 工具包 一个工具可出现在多个包;一个包含多个工具 agent_tool_pack.tool_names[](工具名数组) 同一个 tool_name 可以出现在任意多个包的数组里,互不影响
工具包 ↔ 研判方案 一个包可被多个方案勾选;一个方案可勾多个包 agent.tool_packs_json[](包 id 数组) 同一个包 id 可以出现在任意多个方案的数组里;改包内容对所有引用它的方案即时生效(下次装配)
工具 ↔ 研判方案 传递多对多(经包)+ 直接的工具组白名单 agent.tools_allow_json[](组编码) 方案最终可见的业务工具 = 所选工具组的全部工具 ∪ 所选工具包的工具;全不勾 = 不限制

ID 约定

  • agent.row_id:PostgreSQL identity 自增(存量默认方案 = 1「数刃」);
  • agent_tool.id / agent_tool_pack.id:应用侧雪花 ID(MyBatis-Plus ASSIGN_ID); 内置工具包固定占用 1~6(雪花 ID 远大于此,不会碰撞),供脚本直接引用;
  • 前端传输一律字符串 ID(避免 JS 精度丢失);JSON 数组里也是字符串(["1","2"])。

完整性规则(三道防线)

时机 校验/清理 实现位置
保存工具包 工具名逐个对照 AgentToolRegistry.registeredToolNames()(业务工具;base 基础工具不进包),非法 400 ToolPackService.validateToolNames
保存研判方案 引用的包必须存在且「内置或属于当前用户」,否则 400/404 ToolPackService.requireBindable(由 AgentService.validateExpertConfig 调用)
删除工具包 内置拒绝;同时从所有方案的 tool_packs_json 摘掉该 id,并驱逐受影响的 agent 实例池 AgentToolPackController.deletePack → AgentService.removePackBinding
装配对话(buildAgent) 解析包 id:坏 id / 已删除的包跳过(双保险);组白名单 ∪ 包内工具 = 工具级白名单,白名单外业务工具 removeTool 真实注销 ToolPackService.resolveToolNames + AgentToolRegistry.registerBusinessToolsForWhitelist
改方案配置 保存后驱逐该方案的池化实例(否则旧工具面继续生效) AgentService.updateExpert → evictAgentPool

删除语义速查

删除对象 对工具包 对研判方案 对对话实例
工具(代码下线) 包里残留该名字 → 装配时自然无此工具(惰性失效),不报错 — —
工具包 — tool_packs_json 被摘掉该 id(不留悬空引用) 受影响方案实例池被驱逐
研判方案 不影响(包独立存在) — 该方案池清空;已建会话再对话报「智能体不存在」

内置 vs 自建

内置(is_builtin=1,user_id=1) 自建(is_builtin=0)
工具包 全局可见、不可编辑/删除(服务端双重拒绝);id 固定 1~6 仅创建者可见/改删
研判方案 全局可见、不可编辑/删除(如默认方案「数刃」) 仅创建者可见/改删
绑定 任何方案可勾选内置包 只能勾选自己的包(保存时校验)

默认方案(agent.row_id=1)绑定全部 6 个内置工具包(sql/agent_tool_pack.sql 维护; 内置方案 UI 不可编辑,其绑定关系只能由该脚本写入)。