# Python 智能体开发平台数据库设计(多服务 / 可横向扩展版) ## 1. 设计目标 本设计面向一套基于 Python 的智能体开发平台,要求支持: - 多应用、多租户、多环境 - 多智能体、团队协作、复杂工作流 - 会话、运行态、上下文、记忆、技能、工具、插件 - 多服务部署与水平扩展 - 高并发写入、长链路执行、可观测与审计 数据库设计的目标不是只满足 `V0.1`,而是保证从早期共库部署到后期多服务独立演进都能平滑过渡。 ## 2. 总体原则 ### 2.1 核心原则 - 配置数据和运行数据分离 - 热路径数据和冷路径数据分离 - 强事务数据优先放 PostgreSQL - 短期状态与幂等控制优先放 Redis - 语义记忆与知识检索使用 `pgvector` - 文件和产物不落数据库,统一进入对象存储 ### 2.2 分库分域原则 初期可以由一个 PostgreSQL 集群承载多个 schema,后期再按热点服务拆分成独立数据库。建议逻辑分域如下: - `auth_db` - `app_db` - `session_db` - `runtime_db` - `memory_db` - `tool_db` - `retrieval_db` - `trace_db` ### 2.3 横向扩展原则 - 所有运行态表必须支持按 `tenant_id`、`app_id`、`run_id` 定位 - 长链路表优先使用追加写,减少热点更新 - 高并发表尽量避免大事务和跨域 join - 跨服务关联尽量靠业务 ID,不依赖数据库外键 - 表设计默认支持归档和分区 ## 3. ID 与通用字段规范 ### 3.1 主键策略 建议统一使用 `UUID` 或 `ULID` 作为主键。 推荐: - 配置类对象:`UUID` - 高写入运行表:`ULID` 或时序友好的 UUID v7 好处: - 支持多服务独立生成 ID - 避免数据库序列成为全局瓶颈 - 便于未来跨库迁移 ### 3.2 通用字段 核心业务表建议统一带上以下字段: - `id` - `tenant_id` - `org_id` - `created_by` - `updated_by` - `created_time` - `updated_time` - `deleted_time` - `version` 说明: - `tenant_id`:多租户隔离关键字段 - `org_id`:组织维度隔离,可选 - `deleted_time`:软删除标记 - `version`:乐观锁或对象版本控制 时间字段规范: - 所有时间字段统一使用 `_time` 后缀 - 所有时间字段统一使用 `datetime` 类型 - 禁止混用 `_at`、`date`、`timestamp` 等命名风格 ### 3.3 枚举字段建议 不要使用数据库原生 enum 绑定太死,建议使用 `varchar + check` 或应用层常量控制,方便演进。 ## 4. 分域数据库设计 ## 4.1 Auth / Tenant 域 职责: - 用户、组织、租户、角色、权限 ### 表:`tenant` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | code | varchar(64) | 租户编码,唯一 | | name | varchar(128) | 租户名称 | | status | varchar(32) | `active` / `suspended` | | plan_code | varchar(64) | 套餐 | | settings_json | jsonb | 租户级配置 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | 索引: - `uk_tenant_code(code)` - `idx_tenant_status(status)` ### 表:`organization` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | parent_id | uuid | 上级组织 | | name | varchar(128) | 组织名 | | status | varchar(32) | 状态 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | 索引: - `idx_org_tenant(tenant_id)` - `idx_org_parent(parent_id)` ### 表:`user_account` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | org_id | uuid | 组织 ID | | username | varchar(64) | 用户名 | | email | varchar(128) | 邮箱 | | phone | varchar(32) | 手机号 | | display_name | varchar(128) | 显示名 | | status | varchar(32) | 状态 | | profile_json | jsonb | 扩展资料 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | 索引: - `uk_user_tenant_username(tenant_id, username)` - `uk_user_tenant_email(tenant_id, email)` - `idx_user_org(org_id)` ### 表:`role` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | code | varchar(64) | 角色编码 | | name | varchar(128) | 角色名 | | role_type | varchar(32) | 系统角色 / 自定义角色 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | ### 表:`permission` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | code | varchar(128) | 权限编码 | | name | varchar(128) | 权限名称 | | resource_type | varchar(64) | 资源类型 | | action | varchar(32) | 动作 | ### 表:`user_role` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | user_id | uuid | 用户 ID | | role_id | uuid | 角色 ID | | created_time | datetime | 创建时间 | 唯一索引: - `uk_user_role(tenant_id, user_id, role_id)` ### 表:`role_permission` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | role_id | uuid | 角色 ID | | permission_id | uuid | 权限 ID | | created_time | datetime | 创建时间 | 唯一索引: - `uk_role_permission(role_id, permission_id)` ## 4.2 App / Workflow 配置域 职责: - 应用定义 - 工作流定义 - 版本与环境配置 - Agent、Team、Skill 绑定 ### 表:`app_definition` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | code | varchar(64) | 应用编码 | | name | varchar(128) | 应用名称 | | description | text | 描述 | | app_type | varchar(32) | chat / workflow / hybrid | | status | varchar(32) | draft / active / archived | | owner_user_id | uuid | 负责人 | | settings_json | jsonb | UI、默认模型等配置 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | 索引: - `uk_app_tenant_code(tenant_id, code)` - `idx_app_owner(owner_user_id)` - `idx_app_status(tenant_id, status)` ### 表:`app_environment` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | env_name | varchar(32) | dev / test / prod | | model_policy_json | jsonb | 环境模型策略 | | secret_ref_json | jsonb | 环境密钥引用 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | 唯一索引: - `uk_app_env(app_id, env_name)` ### 表:`app_version` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | version_no | integer | 版本号 | | status | varchar(32) | draft / published / rollback | | workflow_version_id | uuid | 当前工作流版本 | | published_time | datetime | 发布时间 | | published_by | uuid | 发布人 | | changelog | text | 发布说明 | | created_time | datetime | 创建时间 | 唯一索引: - `uk_app_version(app_id, version_no)` ### 表:`workflow_definition` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | code | varchar(64) | 流程编码 | | name | varchar(128) | 流程名称 | | workflow_type | varchar(32) | main / subflow / template | | latest_version_no | integer | 最新版本号 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | 唯一索引: - `uk_workflow_code(app_id, code)` ### 表:`workflow_version` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | workflow_id | uuid | 流程定义 ID | | version_no | integer | 版本号 | | dsl_json | jsonb | 内部 DSL | | compiled_plan_json | jsonb | 编译后的执行计划 | | schema_version | varchar(32) | DSL 版本 | | checksum | varchar(128) | 内容摘要 | | status | varchar(32) | draft / validated / published | | created_by | uuid | 创建人 | | created_time | datetime | 创建时间 | 索引: - `uk_workflow_version(workflow_id, version_no)` - `idx_workflow_version_status(workflow_id, status)` ### 表:`workflow_import_record` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | source_type | varchar(32) | dify / custom_yaml / json | | source_uri | varchar(512) | 原始来源 | | raw_content_ref | varchar(512) | 原始文件对象存储地址 | | converted_workflow_version_id | uuid | 转换后的流程版本 | | import_status | varchar(32) | success / failed | | error_message | text | 错误原因 | | created_by | uuid | 导入人 | | created_time | datetime | 创建时间 | ### 表:`agent_definition` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | code | varchar(64) | Agent 编码 | | name | varchar(128) | Agent 名称 | | role_type | varchar(32) | planner / worker / judge / custom | | description | text | 描述 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | 唯一索引: - `uk_agent_code(app_id, code)` ### 表:`agent_version` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | agent_id | uuid | Agent 定义 ID | | version_no | integer | 版本号 | | system_prompt | text | 系统提示词 | | model_policy_json | jsonb | 模型策略 | | tool_policy_json | jsonb | 工具策略 | | output_schema_json | jsonb | 输出结构约束 | | created_by | uuid | 创建人 | | created_time | datetime | 创建时间 | 唯一索引: - `uk_agent_version(agent_id, version_no)` ### 表:`team_definition` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | code | varchar(64) | Team 编码 | | name | varchar(128) | Team 名称 | | team_mode | varchar(32) | leader_worker / debate / pipeline | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | ### 表:`team_version` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | team_id | uuid | Team 定义 ID | | version_no | integer | 版本号 | | config_json | jsonb | 团队策略 | | created_by | uuid | 创建人 | | created_time | datetime | 创建时间 | ### 表:`team_member_binding` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | team_version_id | uuid | Team 版本 ID | | agent_version_id | uuid | Agent 版本 ID | | member_role | varchar(32) | planner / reviewer / researcher | | sort_order | integer | 顺序 | | config_json | jsonb | 角色级配置 | 索引: - `idx_team_member_team(team_version_id)` ### 表:`skill_definition` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | code | varchar(64) | 技能编码 | | name | varchar(128) | 技能名称 | | skill_type | varchar(32) | prompt / workflow / decision / retrieval | | owner_scope | varchar(32) | system / tenant / app | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | ### 表:`skill_version` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | skill_id | uuid | 技能定义 ID | | version_no | integer | 版本号 | | content_json | jsonb | 技能定义内容 | | created_by | uuid | 创建人 | | created_time | datetime | 创建时间 | ### 表:`app_binding` 统一保存应用对 Agent / Team / Skill / Tool / Plugin 的绑定关系。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | bind_type | varchar(32) | agent / team / skill / tool / plugin | | target_id | uuid | 绑定对象 ID | | target_version_id | uuid | 绑定版本 ID | | binding_scope | varchar(32) | app / env / workflow / node | | config_json | jsonb | 绑定配置 | | created_time | datetime | 创建时间 | 索引: - `idx_app_binding_app(app_id, bind_type)` ## 4.3 Session 域 职责: - 用户会话 - 对话消息 - 请求入口 - 应答记录 ### 表:`session` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | user_id | uuid | 用户 ID | | channel_type | varchar(32) | web / api / webhook / sdk | | session_status | varchar(32) | active / closed | | title | varchar(256) | 会话标题 | | started_time | datetime | 开始时间 | | last_active_time | datetime | 最后活跃时间 | | closed_time | datetime | 结束时间 | 索引: - `idx_session_user(user_id, last_active_time desc)` - `idx_session_app(app_id, last_active_time desc)` ### 表:`conversation_turn` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | session_id | uuid | 会话 ID | | turn_no | integer | 轮次 | | input_message_id | uuid | 用户消息 ID | | output_message_id | uuid | 最终回答消息 ID | | run_id | uuid | 对应运行 ID | | created_time | datetime | 创建时间 | 唯一索引: - `uk_turn_session_no(session_id, turn_no)` ### 表:`message` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | session_id | uuid | 会话 ID | | turn_id | uuid | 对话轮次 ID | | role | varchar(32) | user / assistant / system / tool | | content_type | varchar(32) | text / json / file / stream | | content_text | text | 文本内容 | | content_json | jsonb | 结构化消息 | | token_count | integer | token 数 | | created_time | datetime | 创建时间 | 索引: - `idx_message_session(session_id, created_time)` - `idx_message_turn(turn_id)` ### 表:`run_request` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | session_id | uuid | 会话 ID | | app_version_id | uuid | 应用版本 ID | | workflow_version_id | uuid | 流程版本 ID | | trigger_type | varchar(32) | chat / api / schedule / webhook | | request_payload_json | jsonb | 原始请求 | | request_status | varchar(32) | accepted / rejected / started | | created_time | datetime | 创建时间 | 索引: - `idx_run_request_session(session_id, created_time desc)` ## 4.4 Runtime 域 职责: - 流程运行 - 节点执行 - 状态迁移 - 快照与恢复 - 异步事件 这是平台最高频的核心域之一。 ### 表:`workflow_run` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | app_version_id | uuid | 应用版本 ID | | workflow_id | uuid | 流程定义 ID | | workflow_version_id | uuid | 流程版本 ID | | session_id | uuid | 会话 ID,可空 | | parent_run_id | uuid | 父运行 ID,子流程时使用 | | root_run_id | uuid | 根运行 ID | | run_type | varchar(32) | main / subflow / scheduled / batch | | status | varchar(32) | pending / running / completed / failed / cancelled / paused | | trigger_type | varchar(32) | user / api / event / timer | | priority | integer | 优先级 | | current_node_count | integer | 已执行节点数 | | started_time | datetime | 开始时间 | | finished_time | datetime | 结束时间 | | error_code | varchar(64) | 错误码 | | error_message | text | 错误信息 | | created_time | datetime | 创建时间 | 索引: - `idx_run_root(root_run_id)` - `idx_run_session(session_id, created_time desc)` - `idx_run_status(status, created_time desc)` - `idx_run_app(app_id, created_time desc)` ### 表:`node_run` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | run_id | uuid | 运行 ID | | parent_node_run_id | uuid | 父节点运行 ID | | node_id | varchar(128) | DSL 节点 ID | | node_type | varchar(32) | llm / tool / code / team 等 | | attempt_no | integer | 第几次尝试 | | status | varchar(32) | pending / queued / running / completed / failed / skipped | | worker_key | varchar(128) | 执行 worker 标识 | | lease_expire_time | datetime | 执行 lease 到期时间 | | queued_time | datetime | 入队时间 | | started_time | datetime | 开始时间 | | finished_time | datetime | 结束时间 | | error_code | varchar(64) | 错误码 | | error_message | text | 错误信息 | | created_time | datetime | 创建时间 | 唯一索引建议: - `uk_node_run_attempt(run_id, node_id, attempt_no)` 普通索引: - `idx_node_run_status(status, queued_time)` - `idx_node_run_run(run_id, started_time)` - `idx_node_run_worker(worker_key, status)` ### 表:`node_io_snapshot` 用于存储节点输入输出快照,便于回放和问题定位。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | node_run_id | uuid | 节点运行 ID | | snapshot_type | varchar(32) | input / output / intermediate | | payload_json | jsonb | 快照内容 | | payload_ref | varchar(512) | 大对象外置引用 | | created_time | datetime | 创建时间 | 索引: - `idx_node_snapshot_node(node_run_id, snapshot_type)` ### 表:`run_state_snapshot` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | run_id | uuid | 运行 ID | | snapshot_no | integer | 快照号 | | state_json | jsonb | 当前运行态 | | context_hash | varchar(128) | 状态摘要 | | created_time | datetime | 创建时间 | 唯一索引: - `uk_run_snapshot(run_id, snapshot_no)` ### 表:`run_event` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint | 主键 | | tenant_id | uuid | 租户 ID | | run_id | uuid | 运行 ID | | node_run_id | uuid | 节点运行 ID,可空 | | event_type | varchar(64) | 事件类型 | | event_time | datetime | 事件时间 | | payload_json | jsonb | 事件内容 | 索引: - `idx_run_event_run(run_id, id)` - `idx_run_event_type(event_type, event_time desc)` 建议: - `run_event` 可按月分区 ### 表:`run_queue_task` 适合在没有独立 MQ 可视化追踪时保留调度状态。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | run_id | uuid | 运行 ID | | node_run_id | uuid | 节点运行 ID | | task_type | varchar(32) | schedule / retry / timeout / resume | | execute_after_time | datetime | 可执行时间 | | task_status | varchar(32) | pending / taken / done / dead_letter | | retry_count | integer | 重试次数 | | payload_json | jsonb | 任务内容 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | 索引: - `idx_queue_ready(task_status, execute_after_time)` ## 4.5 Memory / Context 域 职责: - 会话上下文 - 任务上下文 - 长期记忆 - 领域隔离记忆 - 召回记录 ### 表:`context_namespace` 表示不同作用域下的上下文命名空间。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | namespace_type | varchar(32) | session / run / user / domain / team | | namespace_key | varchar(256) | 如 `session:{id}` 或 `domain:policy` | | owner_ref | varchar(256) | 归属对象 | | created_time | datetime | 创建时间 | 唯一索引: - `uk_context_namespace(tenant_id, namespace_type, namespace_key)` ### 表:`context_kv` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | namespace_id | uuid | 命名空间 ID | | key | varchar(128) | 键 | | value_type | varchar(32) | string / number / bool / json | | value_json | jsonb | 值 | | revision | integer | 修订号 | | updated_time | datetime | 更新时间 | | updated_by_run_id | uuid | 最后修改运行 | 唯一索引: - `uk_context_kv(namespace_id, key)` ### 表:`context_change_log` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint | 主键 | | tenant_id | uuid | 租户 ID | | namespace_id | uuid | 命名空间 ID | | key | varchar(128) | 键 | | before_json | jsonb | 修改前 | | after_json | jsonb | 修改后 | | change_source | varchar(32) | node / tool / system | | run_id | uuid | 来源运行 | | node_run_id | uuid | 来源节点 | | created_time | datetime | 创建时间 | 索引: - `idx_context_change_namespace(namespace_id, id desc)` ### 表:`memory_record` 统一长期记忆记录。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | user_id | uuid | 用户 ID,可空 | | session_id | uuid | 会话 ID,可空 | | run_id | uuid | 运行 ID,可空 | | namespace | varchar(128) | `user` / `app` / `domain:order` | | memory_type | varchar(32) | fact / preference / summary / episode | | importance_score | numeric(5,2) | 重要性 | | freshness_score | numeric(5,2) | 新鲜度 | | content_text | text | 内容 | | content_json | jsonb | 结构化内容 | | source_type | varchar(32) | conversation / tool / import / rule | | status | varchar(32) | active / archived / deleted | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | 索引: - `idx_memory_namespace(namespace, created_time desc)` - `idx_memory_user(user_id, created_time desc)` - `idx_memory_app(app_id, created_time desc)` - `idx_memory_type(memory_type, status)` ### 表:`memory_embedding` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | memory_id | uuid | 记忆记录 ID | | embedding_model | varchar(64) | Embedding 模型 | | embedding | vector | 向量 | | token_count | integer | token 数 | | created_time | datetime | 创建时间 | 索引: - 向量索引:`ivfflat` 或 `hnsw(embedding)` - `idx_memory_embedding_memory(memory_id)` ### 表:`memory_recall_log` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint | 主键 | | tenant_id | uuid | 租户 ID | | run_id | uuid | 运行 ID | | node_run_id | uuid | 节点运行 ID | | query_text | text | 召回查询 | | namespace | varchar(128) | 召回命名空间 | | top_k | integer | 返回条数 | | result_ids_json | jsonb | 命中记录 ID 列表 | | created_time | datetime | 创建时间 | 索引: - `idx_memory_recall_run(run_id, created_time desc)` ## 4.6 Tool / Plugin 域 职责: - 工具、插件、凭据、调用记录 ### 表:`plugin_definition` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID,可空表示系统插件 | | code | varchar(64) | 插件编码 | | name | varchar(128) | 插件名称 | | provider | varchar(128) | 提供方 | | source_type | varchar(32) | marketplace / local / git | | manifest_json | jsonb | 插件清单 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | ### 表:`plugin_version` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | plugin_id | uuid | 插件 ID | | version | varchar(64) | 版本号 | | package_ref | varchar(512) | 包引用 | | checksum | varchar(128) | 校验值 | | status | varchar(32) | active / disabled | | created_time | datetime | 创建时间 | 唯一索引: - `uk_plugin_version(plugin_id, version)` ### 表:`tool_definition` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID,可空表示系统工具 | | plugin_id | uuid | 所属插件 | | code | varchar(64) | 工具编码 | | name | varchar(128) | 工具名称 | | tool_type | varchar(32) | function / http / mcp / db | | description | text | 描述 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | 唯一索引: - `uk_tool_code(tenant_id, code)` ### 表:`tool_version` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tool_id | uuid | 工具定义 ID | | version_no | integer | 版本号 | | input_schema_json | jsonb | 输入 schema | | output_schema_json | jsonb | 输出 schema | | invoke_config_json | jsonb | 调用配置 | | timeout_ms | integer | 超时 | | retry_policy_json | jsonb | 重试策略 | | created_time | datetime | 创建时间 | 唯一索引: - `uk_tool_version(tool_id, version_no)` ### 表:`tool_credential` 不要直接存明文密钥,建议只存密文或外部 Secret 引用。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | credential_name | varchar(128) | 名称 | | secret_type | varchar(32) | api_key / oauth / service_account | | secret_ref | varchar(512) | Secret Manager 引用 | | encrypted_payload | bytea | 可选密文 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | ### 表:`tool_binding` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | tool_version_id | uuid | 工具版本 ID | | credential_id | uuid | 凭据 ID | | binding_scope | varchar(32) | app / env / workflow / node | | enabled | boolean | 是否启用 | | config_json | jsonb | 绑定配置 | | created_time | datetime | 创建时间 | 索引: - `idx_tool_binding_app(app_id, binding_scope)` ### 表:`tool_invocation_log` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | run_id | uuid | 运行 ID | | node_run_id | uuid | 节点运行 ID | | tool_id | uuid | 工具 ID | | tool_version_id | uuid | 工具版本 ID | | request_json | jsonb | 请求参数 | | response_json | jsonb | 响应结果 | | response_ref | varchar(512) | 大对象引用 | | status | varchar(32) | success / failed / timeout | | latency_ms | integer | 调用耗时 | | error_message | text | 错误信息 | | invoked_time | datetime | 调用时间 | 索引: - `idx_tool_invocation_run(run_id, invoked_time desc)` - `idx_tool_invocation_tool(tool_id, invoked_time desc)` - `idx_tool_invocation_status(status, invoked_time desc)` ## 4.7 Retrieval / Knowledge 域 职责: - 知识库 - 文档与分片 - 向量索引 - 检索审计 ### 表:`knowledge_base` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | code | varchar(64) | 知识库编码 | | name | varchar(128) | 名称 | | retrieval_strategy | varchar(32) | vector / hybrid / keyword | | status | varchar(32) | active / disabled | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | ### 表:`document` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | kb_id | uuid | 知识库 ID | | source_type | varchar(32) | file / url / api / manual | | source_uri | varchar(512) | 来源 | | title | varchar(256) | 标题 | | mime_type | varchar(128) | 文件类型 | | object_ref | varchar(512) | 文件存储引用 | | parse_status | varchar(32) | pending / parsed / failed | | metadata_json | jsonb | 元数据 | | created_time | datetime | 创建时间 | | updated_time | datetime | 更新时间 | 索引: - `idx_document_kb(kb_id, created_time desc)` ### 表:`document_chunk` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | document_id | uuid | 文档 ID | | chunk_no | integer | 分片序号 | | content_text | text | 分片内容 | | metadata_json | jsonb | 分片元数据 | | created_time | datetime | 创建时间 | 唯一索引: - `uk_document_chunk(document_id, chunk_no)` ### 表:`chunk_embedding` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | chunk_id | uuid | 分片 ID | | embedding_model | varchar(64) | Embedding 模型 | | embedding | vector | 向量 | | created_time | datetime | 创建时间 | 索引: - 向量索引:`ivfflat` 或 `hnsw(embedding)` - `idx_chunk_embedding_chunk(chunk_id)` ### 表:`retrieval_log` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint | 主键 | | tenant_id | uuid | 租户 ID | | run_id | uuid | 运行 ID | | node_run_id | uuid | 节点运行 ID | | kb_id | uuid | 知识库 ID | | query_text | text | 查询语句 | | strategy | varchar(32) | vector / hybrid | | top_k | integer | 命中数 | | result_json | jsonb | 命中详情 | | latency_ms | integer | 耗时 | | created_time | datetime | 创建时间 | 索引: - `idx_retrieval_run(run_id, created_time desc)` - `idx_retrieval_kb(kb_id, created_time desc)` ## 4.8 Model / LLM 域 如果 `model-gateway` 需要单独统计模型调用和成本,建议独立表。 ### 表:`model_provider` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | code | varchar(64) | openai / azure_openai / anthropic | | name | varchar(128) | 名称 | | provider_type | varchar(32) | hosted / self_hosted | | config_json | jsonb | 默认配置 | | created_time | datetime | 创建时间 | ### 表:`model_definition` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | provider_id | uuid | Provider ID | | model_code | varchar(128) | 模型编码 | | model_kind | varchar(32) | chat / embedding / rerank | | capability_json | jsonb | 能力描述 | | pricing_json | jsonb | 价格配置 | | status | varchar(32) | active / deprecated | | created_time | datetime | 创建时间 | 唯一索引: - `uk_model_provider_code(provider_id, model_code)` ### 表:`model_invocation_log` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | run_id | uuid | 运行 ID | | node_run_id | uuid | 节点运行 ID | | provider_id | uuid | Provider ID | | model_id | uuid | 模型 ID | | request_json | jsonb | 请求摘要 | | response_json | jsonb | 响应摘要 | | prompt_tokens | integer | 输入 token | | completion_tokens | integer | 输出 token | | total_tokens | integer | 总 token | | estimated_cost | numeric(18,6) | 预估成本 | | latency_ms | integer | 耗时 | | status | varchar(32) | success / failed / timeout | | invoked_time | datetime | 调用时间 | 索引: - `idx_model_invocation_run(run_id, invoked_time desc)` - `idx_model_invocation_model(model_id, invoked_time desc)` ## 4.9 Trace / Eval 域 职责: - 链路追踪 - 回放 - 评测与基线 ### 表:`trace_span` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | trace_id | uuid | Trace ID | | parent_span_id | uuid | 父 Span | | span_type | varchar(32) | run / node / tool / model / memory | | ref_id | varchar(128) | 关联业务 ID | | name | varchar(128) | Span 名称 | | status | varchar(32) | ok / error | | started_time | datetime | 开始时间 | | finished_time | datetime | 结束时间 | | attributes_json | jsonb | 属性 | 索引: - `idx_trace_trace(trace_id, started_time)` - `idx_trace_ref(span_type, ref_id)` ### 表:`trace_event` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint | 主键 | | tenant_id | uuid | 租户 ID | | trace_id | uuid | Trace ID | | span_id | uuid | Span ID | | event_name | varchar(128) | 事件名 | | payload_json | jsonb | 事件内容 | | event_time | datetime | 事件时间 | 索引: - `idx_trace_event_trace(trace_id, id)` ### 表:`eval_suite` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | app_id | uuid | 应用 ID | | name | varchar(128) | 评测集名称 | | description | text | 描述 | | created_by | uuid | 创建人 | | created_time | datetime | 创建时间 | ### 表:`eval_case` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | suite_id | uuid | 评测集 ID | | input_json | jsonb | 输入 | | expected_json | jsonb | 预期输出 | | tags_json | jsonb | 标签 | | created_time | datetime | 创建时间 | ### 表:`eval_run` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | tenant_id | uuid | 租户 ID | | suite_id | uuid | 评测集 ID | | app_version_id | uuid | 评测应用版本 | | status | varchar(32) | pending / running / completed | | started_time | datetime | 开始时间 | | finished_time | datetime | 结束时间 | | created_time | datetime | 创建时间 | ### 表:`eval_result` | 字段 | 类型 | 说明 | | --- | --- | --- | | id | uuid | 主键 | | eval_run_id | uuid | 评测运行 ID | | eval_case_id | uuid | 评测用例 ID | | run_id | uuid | 实际运行 ID | | score | numeric(5,2) | 得分 | | verdict | varchar(32) | pass / fail | | detail_json | jsonb | 评测详情 | | created_time | datetime | 创建时间 | 索引: - `idx_eval_result_run(eval_run_id)` ## 5. 关键关系说明 核心关系可以理解为: - 一个 `tenant` 下有多个 `app_definition` - 一个 `app_definition` 下有多个 `app_version` - 一个 `app_definition` 下有多个 `workflow_definition` - 一个 `workflow_definition` 下有多个 `workflow_version` - 一个 `app` 可以绑定多个 `agent`、`team`、`skill`、`tool` - 一个 `session` 会产生多轮 `conversation_turn` - 一次输入通常对应一个 `run_request` 和一个 `workflow_run` - 一个 `workflow_run` 下会有多个 `node_run` - 一个 `node_run` 会产生快照、工具调用、模型调用、trace 和 memory recall - `memory_record` 与 `context_namespace` 共同组成“长期记忆 + 运行状态”的双层体系 ## 6. 索引与分区建议 ### 6.1 必须优先建索引的表 - `workflow_run` - `node_run` - `run_event` - `message` - `memory_record` - `tool_invocation_log` - `model_invocation_log` - `retrieval_log` - `trace_event` ### 6.2 建议分区的表 当数据量上来后,以下表建议按时间分区: - `run_event` - `tool_invocation_log` - `model_invocation_log` - `retrieval_log` - `trace_event` - `context_change_log` 优先方案: - PostgreSQL 按月 range partition ### 6.3 JSONB 使用建议 适合放 `jsonb` 的字段: - DSL 内容 - 节点快照 - 模型能力描述 - 工具输入输出 schema - 配置策略 不要把核心检索条件全部塞进 `jsonb`,例如状态、版本、归属、时间等必须单独成列。 ## 7. Redis 设计建议 Redis 不替代主数据库,主要承载以下内容: - `session:{id}:recent_messages` - `run:{id}:state_cache` - `run:{id}:node_lock:{node_id}` - `idempotency:{key}` - `queue:ready` - `model_rate_limit:{provider}:{model}` 建议: - 所有 Redis Key 带租户前缀 - 运行态缓存必须可从数据库重建 - 分布式锁必须带 TTL ## 8. 对象存储设计建议 对象存储主要保存: - 原始导入 YAML/JSON - 大体积节点快照 - 工具大响应结果 - 文件上传 - 回放原始材料 - 检索文档原文 建议存储路径规范: - `tenant/{tenant_id}/app/{app_id}/imports/...` - `tenant/{tenant_id}/run/{run_id}/snapshots/...` - `tenant/{tenant_id}/trace/{trace_id}/...` - `tenant/{tenant_id}/kb/{kb_id}/documents/...` ## 9. 分阶段建表建议 ### V0.1 必需表 - `tenant` - `user_account` - `app_definition` - `app_version` - `workflow_definition` - `workflow_version` - `session` - `message` - `run_request` - `workflow_run` - `node_run` - `node_io_snapshot` - `tool_definition` - `tool_version` - `tool_binding` - `tool_invocation_log` - `model_provider` - `model_definition` - `model_invocation_log` 目标: - 跑通“应用配置 + 工作流执行 + 工具调用 + 基础日志” ### V0.2 新增表 - `agent_definition` - `agent_version` - `skill_definition` - `skill_version` - `app_binding` - `context_namespace` - `context_kv` - `memory_record` - `memory_embedding` - `memory_recall_log` 目标: - 跑通“Agent + 技能 + 记忆” ### V0.3 新增表 - `team_definition` - `team_version` - `team_member_binding` - `run_state_snapshot` - `run_queue_task` - `context_change_log` - `knowledge_base` - `document` - `document_chunk` - `chunk_embedding` - `retrieval_log` 目标: - 跑通“多智能体 + 子流程 + 检索 + 恢复” ### V0.4 新增表 - `organization` - `role` - `permission` - `user_role` - `role_permission` - `plugin_definition` - `plugin_version` - `trace_span` - `trace_event` - `eval_suite` - `eval_case` - `eval_run` - `eval_result` 目标: - 跑通“治理、可观测、评测、插件化” ## 10. 跨服务数据边界建议 为避免后续服务拆分时数据库耦合过深,建议遵循以下约束: - `auth-service` 只直接管理 `auth_db` - `workflow-service` 只直接写 `app_db` - `runtime-service` 只直接写 `runtime_db` - `memory-service` 只直接写 `memory_db` - `tool-service` 只直接写 `tool_db` - `retrieval-service` 只直接写 `retrieval_db` - `trace-service` 只直接写 `trace_db` 其他服务如果需要这些数据: - 通过 API 读 - 或通过事件异步复制只读视图 不要在应用层做跨库强事务。 ## 11. 迁移与演进建议 ### 11.1 迁移工具 - `Alembic` 统一管理迁移 - 每个服务单独 migration 目录 - 共用库只提供模型定义,不直接统一迁移所有库 ### 11.2 演进策略 - 先 schema 兼容,再代码切换 - 大字段新增优先 nullable - 热表结构变更优先分阶段 rollout - 分区表和归档表尽量提前规划 ### 11.3 审计策略 以下操作建议强制审计: - 应用发布 - 工作流导入 - 工具绑定变更 - 记忆写入策略变更 - 权限变更 - 人工审批结果 ## 12. 推荐下一步 如果进入工程实施,最顺的下一步是: 1. 先把 `V0.1` 的 SQLAlchemy 模型定义出来 2. 建 Monorepo 下的多服务目录和共享 `libs` 3. 先跑通 `app_db + session_db + runtime_db + tool_db` 4. 后续再补 `memory_db` 和 `trace_db` ## 13. 结论 这套数据库设计的核心思想是: - 用 PostgreSQL 承载配置、运行、治理主数据 - 用 Redis 承载高频短期状态和幂等控制 - 用 pgvector 承载语义记忆与知识检索 - 用对象存储承载大对象和原始产物 - 用分域设计保证未来多服务拆分和水平扩展不需要推翻重来 如果你下一步继续让我执行,我建议直接进入: 1. `V0.1 SQLAlchemy 模型骨架` 2. `Alembic 初始建表脚本`