# 数据库建表设计 > 版本:v3.1 > 修订日期:2026-09-09 > 演进原则:只允许新增表和新增字段,不修改已有表名、已有字段名、字段类型及既有业务含义 ## 1. 文档目的 本文定义通用 Agent 平台、记忆系统和智能客服专项能力的数据库建设方案。数据库业务基线已固化为项目内的《00-新数据库基线设计.md》,本文只在该基线上补充字段、表、实施顺序和迁移规则。 ## 2. 数据库范围 - 数据库:MySQL 8.0。 - 默认字符集:`utf8mb4`。 - 默认排序规则:`utf8mb4_0900_ai_ci`。 - 基础业务表:33 张。 - 智能客服专项表:6 张。 - 平台底座增量表:12 张(原设计 10 张、outbox_delivery、api_request_receipt)。 - 建成后总表数:51 张(包含会话补表及公共 HTTP 写操作幂等回执)。 - Redis、Milvus 和 Neo4j 不计入 MySQL 表数量。 当前交易范围是场内基金模拟交易。数据库不建设充值、提现、银行流水匹配或场外基金申购赎回交易表。 ### 2.1 不可变基线规则 新版《00-新数据库基线设计.md》中的表名和已有字段是不可变基线。后续迁移只能创建新表、在已有表中增加新字段,或为新增字段增加索引和约束。禁止重命名表,禁止删除、重命名或复用已有字段,禁止改变已有字段的类型、可空性和既有业务含义。历史问题无法兼容解决时,新增语义明确的字段或新表,并由应用执行双读、回填和切换。 ## 3. 通用建表约定 数据库实体和迁移属于 MVC+S 的 Model 层。Controller 不访问 ORM;Service 通过 Repository 读写 Model。Alembic 迁移是表结构变更的唯一入口,运行时业务代码不执行 `CREATE TABLE` 或 `ALTER TABLE`。 | 项目 | 约定 | |---|---| | 主键 | `BIGINT UNSIGNED AUTO_INCREMENT` | | 业务编号 | 单独字段并建立唯一索引 | | 时间 | 使用 `DATETIME(6)`,统一以 `_at` 结尾 | | 金额 | `DECIMAL(18,2)` | | 价格 | `DECIMAL(18,6)` | | 数量 | `DECIMAL(18,4)` | | 置信度 | `DECIMAL(5,4)`,范围 0 至 1 | | JSON | 使用 MySQL 原生 `JSON`,禁止用逗号字符串代替数组 | | 删除 | 交易、预警、审计、对话和通知不物理删除 | | 审计 | 关键状态变化追加写入 `interaction_audit` | | 外键 | MySQL 核心实体使用外键;Milvus/Neo4j 关系由应用校验 | | 时间基准 | 应用和数据库统一使用 UTC,展示层转换时区 | ## 4. 51 张表总览 ### 4.1 基础业务表 | 域 | 表 | 主要职责 | Agent 访问边界 | |---|---|---|---| | 身份 | `sys_user` | 客户与员工统一身份 | 按字段策略读取 | | 权限 | `sys_role` | 角色定义 | 只读 | | 权限 | `sys_permission` | 资源、动作、数据范围 | 只读 | | 权限 | `sys_user_role` | 用户角色关系 | 只读 | | 权限 | `sys_role_permission` | 角色权限关系 | 只读 | | 归属 | `sys_customer_assignment` | 客户与投顾/运营归属 | 只读 | | 客户 | `fin_customer_profile` | 客户金融画像 | 只读 | | 客户 | `fin_risk_assessment` | 正式风险测评历史 | 只读、权威事实 | | 软事实 | `user_facts` | 现有代码兼容软事实 | 只读 | | 产品 | `fin_product` | 场内产品及适当性信息 | 只读 | | 行情 | `fin_market_price` | 场内日线行情 | 只读 | | 净值 | `fin_nav_history` | 基金净值兼容数据 | 只读 | | 账户 | `fin_sim_account` | 虚拟资金账户 | 只读 | | 资金 | `fin_cash_ledger` | 虚拟资金明细 | 只读 | | 资金 | `fin_capital_flow` | 风控兼容标准化流水 | 只读 | | 费用 | `fin_fee_rule` | 模拟交易费率 | 只读 | | 委托 | `fin_sim_order` | 场内模拟委托 | 交易服务写,Agent 只读 | | 成交 | `fin_transaction` | 模拟成交 | 交易服务写,Agent 只读 | | 持仓 | `fin_holding` | 当前持仓汇总 | 交易服务写,Agent 只读 | | 登录 | `sys_login_record` | 逐次登录结果 | 只读 | | 工单 | `biz_work_order` | 风险调查和处置工单 | 风控流程读写 | | 风控 | `fin_risk_alert` | 规则命中与人工处置 | 风控服务读写 | | 通知 | `fin_risk_notification` | 站内和邮件通知 | 风控服务读写 | | 会话 | `conversation_message` | 完整对话留存 | 公共基础层写 | | 知识 | `fin_knowledge_meta` | 知识元数据及正文镜像 | 知识服务写、Agent 只读 | | Episode | `episodes` | 会话片段摘要 | 记忆服务写 | | 记忆 | `memory_unit` | 中期记忆单元 | 记忆服务写 | | 证据 | `memory_evidence` | 记忆来源证据 | 记忆服务写 | | 冲突 | `memory_conflict` | 新旧记忆冲突 | 记忆服务写 | | 画像 | `profile_snapshots` | 长期画像版本投影 | 画像服务写 | | 同步 | `memory_sync_outbox` | Milvus/Neo4j 同步事件 | 记忆服务写、消费者更新状态 | | 审计 | `interaction_audit` | 全系统追加审计 | 公共基础层追加写 | | 内容 | `client_facing_content` | 对客内容审核发布 | 投顾流程读写 | ### 4.2 智能客服专项表 | 表 | 优先级 | 主要职责 | |---|---|---| | `agent_negative_word` | P0 | 禁止表达与变体规则配置 | | `svc_handover_ticket` | P0 | 客服转人工工单 | | `agent_faq_synonym` | P1 | FAQ 同义问法和口语表达 | | `conversation_feedback` | P1 | 用户对回复的反馈 | | `agent_reply_template` | Phase 2 | 兜底、拒答、免责声明等模板 | | `agent_intent_config` | Phase 2 | 意图、阈值、路由和工具配置 | ### 4.3 平台底座增量表 | 表 | 主要职责 | 写入方 | |---|---|---| | `svc_conversation_session` | 会话状态、澄清轮次和配置快照 | 会话服务 | | `outbox_delivery` | 已有 Outbox 消费幂等记录 | Outbox Worker | | `api_request_receipt` | 公共 HTTP 写操作幂等回执 | ApiTransactionService | api_request_receipt 是独立新增表,不复用只用于 Agent 运行的 request_idempotency。 其字段为 id BIGINT UNSIGNED 自增主键、user_id BIGINT UNSIGNED 非空、scope_hash CHAR(64) 非空、idempotency_key VARCHAR(128) 非空、request_hash CHAR(64) 非空、response_json JSON 可空、created_at DATETIME(6) 非空默认 CURRENT_TIMESTAMP(6),唯一键 (user_id, scope_hash, idempotency_key)。操作结果、业务状态和审计在同一事务完成;失败整体回滚。 迁移 20260909_api_receipt 仅 CREATE TABLE;既有 49 表字段指纹比对未变化,会话表保持 §8.1。 | `domain_event_outbox` | 通用领域事件可靠投递 | 事务内事件发布器 | | `request_idempotency` | 请求占位、结果定位和并发防重 | AgentService | | `agent_run` | 可恢复 Agent 运行状态、租约和结果定位 | AgentRunService/Worker | | `config_release` | 配置发布、审核、激活和回滚批次 | 配置中心 | | `platform_config_item` | 记忆、关系及运行参数的版本化配置项 | 配置中心 | | `model_endpoint_config` | 模型端点能力、限制和密钥引用 | 模型平台管理员 | | `model_routing_rule` | 按 Agent 和任务类型选择模型及备用链 | 模型路由服务 | | `model_routing_fallback` | 路由规则的有序备用端点及可重试错误 | 模型路由服务 | | `prompt_template_version` | 分类、生成、摘要和提取 Prompt 版本 | Prompt 管理服务 | ## 5. 核心关系 ```text sys_user 1 --- 1 fin_customer_profile sys_user 1 --- N fin_risk_assessment sys_user 1 --- N conversation_message sys_user 1 --- N svc_handover_ticket sys_user 1 --- N svc_conversation_session conversation_message N --- 1 session_id(逻辑会话) conversation_message 1 --- N conversation_feedback fin_knowledge_meta 1 --- N agent_faq_synonym fin_knowledge_meta -- 正文和向量镜像 --> Milvus 知识集合 episodes 1 --- N memory_unit memory_unit 1 --- N memory_evidence memory_unit N --- N memory_unit(通过 memory_conflict) memory_unit/profile_snapshots 1 --- N memory_sync_outbox svc_conversation_session 1 --- N conversation_message svc_conversation_session 1 --- N request_idempotency svc_conversation_session 1 --- N agent_run request_idempotency 1 --- 1 agent_run conversation_message 1 --- N agent_run(用户消息) conversation_message 1 --- N agent_run(助手结果) conversation_message/interaction_audit 1 --- N domain_event_outbox config_release 1 --- N platform_config_item config_release 1 --- N model_routing_rule config_release 1 --- N prompt_template_version model_endpoint_config 1 --- N model_routing_rule model_routing_rule 1 --- N model_routing_fallback model_endpoint_config 1 --- N model_routing_fallback fin_risk_alert 1 --- N biz_work_order fin_risk_alert 1 --- N fin_risk_notification svc_handover_ticket 与 biz_work_order 相互独立 ``` ## 6. 现有表字段增补 ### 6.1 conversation_message 新版基线已经包含 `tool_calls JSON`,保持其名称和定义不变。本次只新增以下三个字段: | 字段 | 类型 | 约束 | 用途 | |---|---|---|---| | `intent` | VARCHAR(32) | 可空、索引 | 助手消息的意图结果 | | `confidence` | DECIMAL(5,4) | 可空、索引、0 至 1 | 意图置信度 | | `source_references` | JSON | 可空 | RAG 来源集合与文档 ID | 用户原始消息的三个新增字段可以为空;助手最终消息记录实际采用的意图、置信度和来源。既有 `tool_calls` 字段继续保存脱敏后的工具调用;未使用知识或工具时对应 JSON 字段使用 `NULL`。 迁移示例: ```sql ALTER TABLE conversation_message ADD COLUMN intent VARCHAR(32) NULL COMMENT '识别的意图' AFTER trace_id, ADD COLUMN confidence DECIMAL(5,4) NULL COMMENT '意图置信度' AFTER intent, ADD COLUMN source_references JSON NULL COMMENT '检索来源' AFTER confidence, ADD CONSTRAINT chk_conversation_confidence CHECK (confidence IS NULL OR confidence BETWEEN 0 AND 1), ADD INDEX idx_conversation_intent (intent), ADD INDEX idx_conversation_confidence (confidence); ``` ### 6.2 fin_knowledge_meta 最终结构以新版表定义为准,必须包含 `content_text`、`tags`、`effective_date`、`expire_date`、`version`、`reviewer_id` 和 `review_status`。 实际迁移前使用 Alembic Inspector 检查现库。若 `version`、`effective_date`、`expire_date` 已存在,只新增以下四个缺失字段: ```sql ALTER TABLE fin_knowledge_meta ADD COLUMN content_text MEDIUMTEXT NULL COMMENT 'Milvus知识正文MySQL镜像,保持可空兼容旧数据', ADD COLUMN tags JSON NULL COMMENT '知识标签数组', ADD COLUMN reviewer_id BIGINT UNSIGNED NULL COMMENT '审校人ID', ADD COLUMN review_status VARCHAR(16) NOT NULL DEFAULT 'pending' COMMENT 'pending/approved/published/archived', ADD CONSTRAINT fk_knowledge_reviewer FOREIGN KEY (reviewer_id) REFERENCES sys_user(id), ADD INDEX idx_knowledge_review_status (review_status), ADD INDEX idx_knowledge_reviewer (reviewer_id); ``` `content_text` 保持新增时的可空定义,后续不得更改已有字段约束。应用通过发布校验保证 `published` 知识必须存在正文。 有效知识的统一过滤条件为: ```sql review_status = 'published' AND status = 'active' AND (effective_date IS NULL OR effective_date <= UTC_DATE()) AND (expire_date IS NULL OR expire_date > UTC_DATE()) ``` ## 7. 智能客服专项表 DDL 以下 DDL 面向全新数据库。若应用于已有数据库,必须通过 Alembic 生成版本迁移并在测试库演练。 ### 7.1 agent_negative_word 禁止表达不写死在业务 Agent 中。规则变更必须经过审核并保留版本。 ```sql CREATE TABLE agent_negative_word ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, rule_code VARCHAR(64) NOT NULL, word_pattern VARCHAR(256) NOT NULL, match_type VARCHAR(16) NOT NULL DEFAULT 'contains', category VARCHAR(32) NOT NULL, severity VARCHAR(16) NOT NULL DEFAULT 'block', applicable_agents JSON NULL, safe_reply_template_code VARCHAR(64) NULL, status VARCHAR(16) NOT NULL DEFAULT 'draft', version INT UNSIGNED NOT NULL DEFAULT 1, created_by BIGINT UNSIGNED NOT NULL, reviewer_id BIGINT UNSIGNED NULL, reviewed_at DATETIME(6) NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_negative_rule_code (rule_code), KEY idx_negative_status_category (status, category), KEY idx_negative_reviewer (reviewer_id), CONSTRAINT fk_negative_created_by FOREIGN KEY (created_by) REFERENCES sys_user(id), CONSTRAINT fk_negative_reviewer FOREIGN KEY (reviewer_id) REFERENCES sys_user(id), CONSTRAINT chk_negative_match_type CHECK (match_type IN ('exact', 'contains', 'regex')), CONSTRAINT chk_negative_severity CHECK (severity IN ('warn', 'regenerate', 'block')), CONSTRAINT chk_negative_status CHECK (status IN ('draft', 'active', 'disabled', 'archived')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Agent禁止表达配置'; ``` ### 7.2 svc_handover_ticket 本表只表示客服会话向人工坐席的转接,不替代风险预警处置工单 `biz_work_order`。 ```sql CREATE TABLE svc_handover_ticket ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, ticket_no VARCHAR(32) NOT NULL, session_id VARCHAR(64) NOT NULL, customer_id BIGINT UNSIGNED NULL, source_agent VARCHAR(32) NOT NULL DEFAULT 'customer_service', source_message_id BIGINT UNSIGNED NULL, intent VARCHAR(32) NULL, confidence DECIMAL(5,4) NULL, priority VARCHAR(8) NOT NULL DEFAULT 'P1', reason_code VARCHAR(64) NOT NULL, reason_detail VARCHAR(500) NULL, conversation_summary MEDIUMTEXT NULL, source_references JSON NULL, status VARCHAR(16) NOT NULL DEFAULT 'pending', assigned_to BIGINT UNSIGNED NULL, assigned_at DATETIME(6) NULL, accepted_at DATETIME(6) NULL, resolved_at DATETIME(6) NULL, closed_at DATETIME(6) NULL, resolution TEXT NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_handoff_ticket_no (ticket_no), KEY idx_handoff_session (session_id, created_at), KEY idx_handoff_customer (customer_id, created_at), KEY idx_handoff_queue (status, priority, created_at), KEY idx_handoff_assignee (assigned_to, status), CONSTRAINT fk_handoff_customer FOREIGN KEY (customer_id) REFERENCES sys_user(id), CONSTRAINT fk_handoff_source_message FOREIGN KEY (source_message_id) REFERENCES conversation_message(id), CONSTRAINT fk_handoff_assignee FOREIGN KEY (assigned_to) REFERENCES sys_user(id), CONSTRAINT chk_handoff_confidence CHECK (confidence IS NULL OR confidence BETWEEN 0 AND 1), CONSTRAINT chk_handoff_priority CHECK (priority IN ('P0', 'P1', 'P2')), CONSTRAINT chk_handoff_status CHECK (status IN ('pending', 'assigned', 'processing', 'resolved', 'closed', 'cancelled')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='客服转人工工单'; ``` 状态流转: ```text pending -> assigned -> processing -> resolved -> closed | | | `----------+-------------+-> cancelled ``` `cancelled` 只允许在未解决状态进入。每次分配、接单、解决、关闭或取消都要写入 `interaction_audit`。 ### 7.3 agent_faq_synonym ```sql CREATE TABLE agent_faq_synonym ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, knowledge_id BIGINT UNSIGNED NOT NULL, phrase VARCHAR(500) NOT NULL, normalized_phrase VARCHAR(500) NOT NULL, phrase_hash CHAR(64) NOT NULL, language_code VARCHAR(16) NOT NULL DEFAULT 'zh-CN', source_type VARCHAR(24) NOT NULL DEFAULT 'manual', hit_count BIGINT UNSIGNED NOT NULL DEFAULT 0, status VARCHAR(16) NOT NULL DEFAULT 'pending', created_by BIGINT UNSIGNED NOT NULL, reviewer_id BIGINT UNSIGNED NULL, reviewed_at DATETIME(6) NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_faq_synonym (knowledge_id, phrase_hash), KEY idx_faq_synonym_status (status), KEY idx_faq_synonym_normalized (normalized_phrase(191)), CONSTRAINT fk_synonym_knowledge FOREIGN KEY (knowledge_id) REFERENCES fin_knowledge_meta(id), CONSTRAINT fk_synonym_created_by FOREIGN KEY (created_by) REFERENCES sys_user(id), CONSTRAINT fk_synonym_reviewer FOREIGN KEY (reviewer_id) REFERENCES sys_user(id), CONSTRAINT chk_synonym_source CHECK (source_type IN ('manual', 'conversation', 'ticket', 'import')), CONSTRAINT chk_synonym_status CHECK (status IN ('pending', 'approved', 'disabled', 'archived')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='FAQ同义问法'; ``` 只有 `approved` 的同义问法参与意图识别和检索扩展。会话自动提取内容必须先进入 `pending`。 `phrase_hash` 由应用对完整 `normalized_phrase` 计算 SHA-256,防止仅使用索引前缀时不同长文本被误判为重复。 ### 7.4 conversation_feedback ```sql CREATE TABLE conversation_feedback ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, feedback_no VARCHAR(32) NOT NULL, session_id VARCHAR(64) NOT NULL, message_id BIGINT UNSIGNED NOT NULL, customer_id BIGINT UNSIGNED NULL, rating TINYINT NOT NULL, feedback_type VARCHAR(32) NULL, feedback_content VARCHAR(1000) NULL, status VARCHAR(16) NOT NULL DEFAULT 'open', handler_id BIGINT UNSIGNED NULL, handled_at DATETIME(6) NULL, handling_note VARCHAR(1000) NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_feedback_no (feedback_no), UNIQUE KEY uk_feedback_message_customer (message_id, customer_id), KEY idx_feedback_session (session_id, created_at), KEY idx_feedback_status_type (status, feedback_type), CONSTRAINT fk_feedback_message FOREIGN KEY (message_id) REFERENCES conversation_message(id), CONSTRAINT fk_feedback_customer FOREIGN KEY (customer_id) REFERENCES sys_user(id), CONSTRAINT fk_feedback_handler FOREIGN KEY (handler_id) REFERENCES sys_user(id), CONSTRAINT chk_feedback_rating CHECK (rating IN (-1, 1)), CONSTRAINT chk_feedback_status CHECK (status IN ('open', 'reviewed', 'resolved', 'ignored')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='对话回复反馈'; ``` 匿名或未登录反馈的 `customer_id` 可以为空,但必须由 API 限流并保存安全审计信息,防止重复刷票。 ### 7.5 agent_reply_template ```sql CREATE TABLE agent_reply_template ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, template_code VARCHAR(64) NOT NULL, scene VARCHAR(32) NOT NULL, title VARCHAR(128) NOT NULL, content_text MEDIUMTEXT NOT NULL, variables JSON NULL, locale VARCHAR(16) NOT NULL DEFAULT 'zh-CN', version INT UNSIGNED NOT NULL DEFAULT 1, status VARCHAR(16) NOT NULL DEFAULT 'draft', active_key VARCHAR(128) GENERATED ALWAYS AS (IF(status = 'active', CONCAT(template_code, ':', locale), NULL)) STORED, effective_at DATETIME(6) NULL, expire_at DATETIME(6) NULL, created_by BIGINT UNSIGNED NOT NULL, reviewer_id BIGINT UNSIGNED NULL, reviewed_at DATETIME(6) NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_reply_template_version (template_code, version), UNIQUE KEY uk_reply_template_active_one (active_key), KEY idx_reply_template_active (scene, status, effective_at, expire_at), CONSTRAINT fk_template_created_by FOREIGN KEY (created_by) REFERENCES sys_user(id), CONSTRAINT fk_template_reviewer FOREIGN KEY (reviewer_id) REFERENCES sys_user(id), CONSTRAINT chk_template_scene CHECK (scene IN ('disclaimer', 'low_confidence', 'compliance_block', 'transfer', 'model_failure', 'system_busy', 'clarification')), CONSTRAINT chk_template_status CHECK (status IN ('draft', 'approved', 'active', 'archived')), CONSTRAINT chk_template_window CHECK (expire_at IS NULL OR effective_at IS NULL OR expire_at > effective_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Agent回复模板'; ``` 相同 `template_code + locale` 可以有多个历史版本,但数据库通过 `active_key` 唯一索引保证同一组合最多一个 `active` 版本。发布服务仍须在事务中完成状态切换并写入审计记录。 ### 7.6 agent_intent_config ```sql CREATE TABLE agent_intent_config ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, agent_type VARCHAR(32) NOT NULL, intent_code VARCHAR(64) NOT NULL, intent_name VARCHAR(128) NOT NULL, description VARCHAR(500) NULL, examples JSON NOT NULL, classifier_instruction TEXT NULL, confidence_threshold DECIMAL(5,4) NOT NULL DEFAULT 0.6000, max_clarification_rounds TINYINT UNSIGNED NOT NULL DEFAULT 2, transfer_on_failure TINYINT(1) NOT NULL DEFAULT 1, collection_routes JSON NULL, allowed_tools JSON NULL, priority INT NOT NULL DEFAULT 100, version INT UNSIGNED NOT NULL DEFAULT 1, status VARCHAR(16) NOT NULL DEFAULT 'draft', active_key VARCHAR(128) GENERATED ALWAYS AS (IF(status = 'active', CONCAT(agent_type, ':', intent_code), NULL)) STORED, effective_at DATETIME(6) NULL, expire_at DATETIME(6) NULL, created_by BIGINT UNSIGNED NOT NULL, reviewer_id BIGINT UNSIGNED NULL, reviewed_at DATETIME(6) NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_intent_config_version (agent_type, intent_code, version), UNIQUE KEY uk_intent_config_active_one (active_key), KEY idx_intent_config_active (agent_type, status, priority), CONSTRAINT fk_intent_created_by FOREIGN KEY (created_by) REFERENCES sys_user(id), CONSTRAINT fk_intent_reviewer FOREIGN KEY (reviewer_id) REFERENCES sys_user(id), CONSTRAINT chk_intent_confidence CHECK (confidence_threshold BETWEEN 0 AND 1), CONSTRAINT chk_intent_status CHECK (status IN ('draft', 'approved', 'active', 'archived')), CONSTRAINT chk_intent_window CHECK (expire_at IS NULL OR effective_at IS NULL OR expire_at > effective_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Agent意图路由配置'; ``` 客服初始意图至少包含:`faq`、`product_inquiry`、`policy_explain`、`chitchat` 和 `transfer_human`。 ## 8. 平台底座增量表 DDL 本节所有对象均为新增表,不替换、不重命名原有表。 ### 8.1 svc_conversation_session ```sql CREATE TABLE svc_conversation_session ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, session_id VARCHAR(64) NOT NULL, user_id BIGINT UNSIGNED NOT NULL, portal VARCHAR(32) NOT NULL, agent_type VARCHAR(32) NULL, status VARCHAR(16) NOT NULL DEFAULT 'active', clarification_round TINYINT UNSIGNED NOT NULL DEFAULT 0, message_count INT UNSIGNED NOT NULL DEFAULT 0, last_intent VARCHAR(32) NULL, config_version VARCHAR(64) NULL, started_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), last_active_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), ended_at DATETIME(6) NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_session_id (session_id), KEY idx_session_user_active (user_id, last_active_at), KEY idx_session_status_active (status, last_active_at), CONSTRAINT fk_session_user FOREIGN KEY (user_id) REFERENCES sys_user(id), CONSTRAINT chk_session_status CHECK (status IN ('active', 'ended', 'transferred', 'expired')), CONSTRAINT chk_session_clarification CHECK (clarification_round <= 10) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Agent会话状态与澄清轮次'; ``` 澄清次数使用带旧值条件的原子更新;Redis 只缓存该记录,MySQL 是权威来源。会话结束、转人工和过期必须写明确状态。 ### 8.2 domain_event_outbox ```sql CREATE TABLE domain_event_outbox ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, event_id CHAR(36) NOT NULL, event_type VARCHAR(64) NOT NULL, aggregate_type VARCHAR(32) NOT NULL, aggregate_id VARCHAR(64) NOT NULL, trace_id VARCHAR(64) NOT NULL, payload JSON NOT NULL, status VARCHAR(16) NOT NULL DEFAULT 'pending', retry_count INT UNSIGNED NOT NULL DEFAULT 0, next_retry_at DATETIME(6) NULL, last_error VARCHAR(500) NULL, occurred_at DATETIME(6) NOT NULL, published_at DATETIME(6) NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_domain_event_id (event_id), KEY idx_domain_outbox_pending (status, next_retry_at, id), KEY idx_domain_outbox_aggregate (aggregate_type, aggregate_id), KEY idx_domain_outbox_trace (trace_id), CONSTRAINT chk_domain_outbox_status CHECK (status IN ('pending', 'published', 'failed', 'dead')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='通用领域事件Outbox'; ``` ### 8.3 request_idempotency ```sql CREATE TABLE request_idempotency ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, user_id BIGINT UNSIGNED NOT NULL, session_id VARCHAR(64) NOT NULL, agent_type VARCHAR(32) NOT NULL, idempotency_key VARCHAR(64) NOT NULL, request_hash CHAR(64) NOT NULL, trace_id VARCHAR(64) NOT NULL, status VARCHAR(16) NOT NULL DEFAULT 'processing', result_message_id BIGINT UNSIGNED NULL, error_code VARCHAR(64) NULL, locked_until DATETIME(6) NULL, expire_at DATETIME(6) NOT NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_idempotency_scope (user_id, agent_type, idempotency_key), KEY idx_idempotency_expire (expire_at), KEY idx_idempotency_trace (trace_id), KEY idx_idempotency_session (session_id, created_at), CONSTRAINT fk_idempotency_user FOREIGN KEY (user_id) REFERENCES sys_user(id), CONSTRAINT fk_idempotency_session FOREIGN KEY (session_id) REFERENCES svc_conversation_session(session_id), CONSTRAINT fk_idempotency_result FOREIGN KEY (result_message_id) REFERENCES conversation_message(id), CONSTRAINT chk_idempotency_status CHECK (status IN ('processing', 'completed', 'failed')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Agent请求幂等记录'; ``` 相同幂等键但 `request_hash` 不同必须返回冲突;`processing` 未过租约返回处理中,`completed` 返回原结果,只有租约超时后才能由新请求接管。 ### 8.4 agent_run ```sql CREATE TABLE agent_run ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, run_id CHAR(36) NOT NULL, idempotency_id BIGINT UNSIGNED NOT NULL, session_id VARCHAR(64) NOT NULL, user_id BIGINT UNSIGNED NOT NULL, agent_type VARCHAR(32) NOT NULL, trace_id VARCHAR(64) NOT NULL, request_message_id BIGINT UNSIGNED NOT NULL, result_message_id BIGINT UNSIGNED NULL, status VARCHAR(24) NOT NULL DEFAULT 'queued', attempt_count INT UNSIGNED NOT NULL DEFAULT 0, worker_id VARCHAR(128) NULL, locked_until DATETIME(6) NULL, result_version INT UNSIGNED NULL, error_code VARCHAR(64) NULL, cancel_requested_at DATETIME(6) NULL, started_at DATETIME(6) NULL, completed_at DATETIME(6) NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_agent_run_id (run_id), UNIQUE KEY uk_agent_run_idempotency (idempotency_id), UNIQUE KEY uk_agent_run_trace (trace_id), KEY idx_agent_run_session (session_id, created_at), KEY idx_agent_run_user (user_id, created_at), KEY idx_agent_run_worker_lease (status, locked_until), CONSTRAINT fk_agent_run_idempotency FOREIGN KEY (idempotency_id) REFERENCES request_idempotency(id), CONSTRAINT fk_agent_run_session FOREIGN KEY (session_id) REFERENCES svc_conversation_session(session_id), CONSTRAINT fk_agent_run_user FOREIGN KEY (user_id) REFERENCES sys_user(id), CONSTRAINT fk_agent_run_request_message FOREIGN KEY (request_message_id) REFERENCES conversation_message(id), CONSTRAINT fk_agent_run_result_message FOREIGN KEY (result_message_id) REFERENCES conversation_message(id), CONSTRAINT chk_agent_run_status CHECK (status IN ('queued', 'running', 'succeeded', 'failed', 'cancel_requested', 'cancelled')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='可恢复Agent运行状态'; ``` `run_id` 是对外运行主键,`trace_id` 只用于可观测性。Worker 通过 `locked_until` 租约接管过期运行;同一 `run_id` 安全重试,不承诺从模型中间 Token 续写。最终消息、审计、幂等完成状态和 Outbox 必须与运行成功状态同一事务提交。 ### 8.5 config_release ```sql CREATE TABLE config_release ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, release_no VARCHAR(64) NOT NULL, title VARCHAR(128) NOT NULL, change_summary VARCHAR(1000) NOT NULL, status VARCHAR(20) NOT NULL DEFAULT 'draft', created_by BIGINT UNSIGNED NOT NULL, reviewer_id BIGINT UNSIGNED NULL, reviewed_at DATETIME(6) NULL, activated_at DATETIME(6) NULL, supersedes_release_id BIGINT UNSIGNED NULL, rollback_of_release_id BIGINT UNSIGNED NULL, active_slot TINYINT GENERATED ALWAYS AS (IF(status = 'active', 1, NULL)) STORED, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_config_release_no (release_no), UNIQUE KEY uk_config_release_active_one (active_slot), KEY idx_config_release_status (status, created_at), CONSTRAINT fk_config_release_creator FOREIGN KEY (created_by) REFERENCES sys_user(id), CONSTRAINT fk_config_release_reviewer FOREIGN KEY (reviewer_id) REFERENCES sys_user(id), CONSTRAINT fk_config_release_supersedes FOREIGN KEY (supersedes_release_id) REFERENCES config_release(id), CONSTRAINT fk_config_release_rollback FOREIGN KEY (rollback_of_release_id) REFERENCES config_release(id), CONSTRAINT chk_config_release_status CHECK (status IN ('draft', 'validating', 'pending_review', 'approved', 'active', 'superseded', 'rejected', 'rolled_back')), CONSTRAINT chk_config_release_separation CHECK (reviewer_id IS NULL OR reviewer_id <> created_by) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='平台配置发布批次'; ``` ### 8.6 platform_config_item ```sql CREATE TABLE platform_config_item ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, release_id BIGINT UNSIGNED NOT NULL, namespace VARCHAR(64) NOT NULL, config_key VARCHAR(128) NOT NULL, value_json JSON NOT NULL, schema_version VARCHAR(32) NOT NULL, checksum CHAR(64) NOT NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_config_item_release (release_id, namespace, config_key), KEY idx_config_item_lookup (namespace, config_key, release_id), CONSTRAINT fk_config_item_release FOREIGN KEY (release_id) REFERENCES config_release(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='版本化平台配置项'; ``` `namespace` 首版限定为 `agent_runtime`、`memory_policy`、`relationship_view`、`compliance_policy` 和 `tool_policy`;`value_json` 必须先通过对应 Pydantic Schema 校验。 ### 8.7 model_endpoint_config ```sql CREATE TABLE model_endpoint_config ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, endpoint_code VARCHAR(64) NOT NULL, provider VARCHAR(32) NOT NULL, model_name VARCHAR(128) NOT NULL, base_url VARCHAR(500) NOT NULL, secret_ref VARCHAR(256) NOT NULL, capabilities JSON NOT NULL, allowed_data_levels JSON NOT NULL, context_window INT UNSIGNED NOT NULL, timeout_ms INT UNSIGNED NOT NULL DEFAULT 15000, cost_input_per_1k DECIMAL(12,6) NULL, cost_output_per_1k DECIMAL(12,6) NULL, status VARCHAR(16) NOT NULL DEFAULT 'disabled', created_by BIGINT UNSIGNED NOT NULL, reviewer_id BIGINT UNSIGNED NULL, reviewed_at DATETIME(6) NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_model_endpoint_code (endpoint_code), KEY idx_model_endpoint_status (status, provider), CONSTRAINT fk_model_endpoint_creator FOREIGN KEY (created_by) REFERENCES sys_user(id), CONSTRAINT fk_model_endpoint_reviewer FOREIGN KEY (reviewer_id) REFERENCES sys_user(id), CONSTRAINT chk_model_endpoint_status CHECK (status IN ('draft', 'approved', 'active', 'disabled', 'archived')) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='模型端点配置'; ``` `secret_ref` 只保存环境变量名或密钥服务路径,禁止保存明文密钥。 ### 8.8 model_routing_rule ```sql CREATE TABLE model_routing_rule ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, release_id BIGINT UNSIGNED NOT NULL, rule_code VARCHAR(64) NOT NULL, agent_type VARCHAR(32) NOT NULL, task_type VARCHAR(48) NOT NULL, model_policy VARCHAR(32) NOT NULL, primary_endpoint_id BIGINT UNSIGNED NOT NULL, fallback_endpoint_ids JSON NULL, condition_json JSON NULL, max_attempts TINYINT UNSIGNED NOT NULL DEFAULT 2, latency_budget_ms INT UNSIGNED NOT NULL DEFAULT 15000, cost_budget DECIMAL(12,6) NULL, priority INT NOT NULL DEFAULT 100, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_model_route_release (release_id, rule_code), KEY idx_model_route_match (release_id, agent_type, task_type, model_policy, priority), CONSTRAINT fk_model_route_release FOREIGN KEY (release_id) REFERENCES config_release(id), CONSTRAINT fk_model_route_primary FOREIGN KEY (primary_endpoint_id) REFERENCES model_endpoint_config(id), CONSTRAINT chk_model_route_attempts CHECK (max_attempts BETWEEN 1 AND 3) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='多模型路由规则'; ``` `fallback_endpoint_ids` 是为旧版读取方保留的兼容字段,可为空;它不再作为备用链权威来源。若迁移期继续填充该字段,其端点顺序必须与 `model_routing_fallback` 按 `fallback_order` 排序后的结果完全一致,发布服务在同一配置发布事务中校验。 ### 8.9 model_routing_fallback ```sql CREATE TABLE model_routing_fallback ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, routing_rule_id BIGINT UNSIGNED NOT NULL, endpoint_id BIGINT UNSIGNED NOT NULL, fallback_order TINYINT UNSIGNED NOT NULL, retryable_error_codes JSON NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_model_fallback_order (routing_rule_id, fallback_order), UNIQUE KEY uk_model_fallback_endpoint (routing_rule_id, endpoint_id), KEY idx_model_fallback_endpoint (endpoint_id), CONSTRAINT fk_model_fallback_rule FOREIGN KEY (routing_rule_id) REFERENCES model_routing_rule(id), CONSTRAINT fk_model_fallback_endpoint FOREIGN KEY (endpoint_id) REFERENCES model_endpoint_config(id), CONSTRAINT chk_model_fallback_order CHECK (fallback_order BETWEEN 1 AND 2) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='模型路由有序备用端点'; ``` `model_routing_fallback` 是备用链的权威关系表。发布服务必须校验主端点不出现在备用链中、每条路由的总端点数不超过 3,且 `retryable_error_codes` 只能包含平台登记的错误码。 ### 8.10 prompt_template_version ```sql CREATE TABLE prompt_template_version ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, release_id BIGINT UNSIGNED NOT NULL, prompt_code VARCHAR(64) NOT NULL, task_type VARCHAR(48) NOT NULL, agent_type VARCHAR(32) NULL, version INT UNSIGNED NOT NULL, system_prompt MEDIUMTEXT NOT NULL, user_prompt_template MEDIUMTEXT NOT NULL, input_schema JSON NULL, output_schema JSON NULL, checksum CHAR(64) NOT NULL, created_by BIGINT UNSIGNED NOT NULL, created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), PRIMARY KEY (id), UNIQUE KEY uk_prompt_version (prompt_code, version), KEY idx_prompt_release_task (release_id, task_type, agent_type), CONSTRAINT fk_prompt_release FOREIGN KEY (release_id) REFERENCES config_release(id), CONSTRAINT fk_prompt_creator FOREIGN KEY (created_by) REFERENCES sys_user(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Prompt不可变版本'; ``` ## 9. 创建与迁移顺序 ### 9.1 空库创建顺序 1. 创建数据库和 Alembic 版本表。 2. 创建 `sys_user`、角色、权限及用户角色关系。 3. 创建客户画像、风险测评和客户归属。 4. 创建产品、行情、账户、费用、委托、成交、资金和持仓。 5. 创建预警、通知、风险工单、内容和审计表。 6. 创建对话、知识、Episode 和记忆相关表。 7. 创建 `agent_negative_word` 和 `svc_handover_ticket`。 8. 创建 `agent_faq_synonym` 和 `conversation_feedback`。 9. 创建 `agent_reply_template` 和 `agent_intent_config`。 10. 创建会话、幂等、`agent_run` 和通用事件 Outbox 表。 11. 创建配置发布、平台配置、模型端点、模型路由、路由备用端点和 Prompt 表。 12. 写入初始角色、权限、意图、模板、模型路由和禁止表达。 13. 建立 Milvus 集合、Neo4j 约束和 Redis Key 规范。 ### 9.2 已有库升级 1. 备份结构和关键表数据。 2. 使用 Inspector 获取真实列、索引和外键。 3. 只增加缺失字段,不重建或覆盖现有业务表。 4. 新字段先允许兼容旧代码,再部署双版本兼容应用。 5. 回填知识正文、审核状态和对话分类信息。 6. 创建专项表和平台底座增量表。 7. 发布首个完整配置快照。 8. 部署新代码并验证双版本兼容读写。 `content_text` 在已有知识数据未回填前保持可空。即使回填完成,也不修改该已有字段定义;由应用校验和发布条件保证已发布知识正文非空。 ## 10. 初始数据 ### 10.1 内置角色 - `customer` - `advisor` - `operator` - `risk_operator` - `admin` - `super_admin` ### 10.2 客服初始禁止表达 至少录入:保本、稳赚、无风险、保证收益、预期收益率、年化收益率、安全,以及经合规确认的变体。初始状态必须经过审核后才可以设置为 `active`。 ### 10.3 客服初始模板 - 固定免责声明。 - AI 生成标识。 - 低置信兜底。 - 合规拒答。 - 转人工提示。 - 模型故障和系统繁忙提示。 ## 11. 事务和并发要求 - 模拟成交、账户余额、资金明细和持仓必须在一个事务内提交。 - 工单状态更新采用乐观锁或条件更新,禁止重复接单覆盖。 - 画像版本和 Outbox 事件在同一事务提交。 - 助手消息、执行审计和 `domain_event_outbox` 在同一短事务提交。 - 幂等记录通过唯一键抢占,完成状态与结果消息在同一事务更新。 - 配置发布批次和全部配置项校验通过后才能原子激活。 - 模板和意图新版本发布时,旧版本失效与新版本生效必须原子完成。 - 审计记录与受监管的业务状态变更应在同一事务写入。 - 外部模型、邮件、Milvus 和 Neo4j 调用不得放入 MySQL 长事务。 ## 12. 数据安全 - `password_hash` 不向 Agent、风控或 NL2SQL 开放。 - 身份证、手机号、银行卡号和精确账户余额不得写入 Milvus 或 Neo4j。 - `source_references` 只保存必要的来源标识,不复制整份文档。 - SQL 查询必须应用 `data_scope` 和客户归属过滤。 - `interaction_audit` 仅追加,不允许普通业务接口更新或删除。 - 生产备份、迁移导出和错误日志均执行敏感字段保护。 - 模型端点表只保存 `secret_ref`,不得保存 API 明文密钥。 ## 13. 验证清单 - 49 张表全部存在,原 39 张表的名称和已有字段定义保持不变。 - 主键、唯一键、外键和检查约束生效。 - `conversation_message` 三个 Agent 增量字段和既有 `tool_calls` 字段可正常读写。 - 知识检索只命中已发布且在有效期内的条目。 - Milvus 故障时 MySQL 正文降级检索可用。 - 客服转人工工单与风险工单完全独立。 - 同义问法只有审核通过后参与检索。 - 一个客户对同一回复不能重复反馈。 - 模板和意图配置可版本化发布和回滚。 - 每个模板或意图组合最多一个 `active` 版本,备用模型端点均受外键约束且顺序唯一。 - 越权客户查询被数据库访问层和服务层共同拒绝。 - Redis 丢失可以从 MySQL 恢复必要记忆。 - Milvus 或 Neo4j 单边失败不会丢失 Outbox 事件。 - 重复请求不会重复生成消息、工单或领域事件。 - 配置发布失败时旧版本继续有效,回滚不修改历史版本。 - 模型路由最多尝试三个已审核端点,并完整记录采用版本。 - 所有迁移在空库、旧版本库和回滚路径各执行一次。 ## 14. 已知实施前提 6 张专项表的字段由本文补全并作为建议实施结构。若团队已有《智能客服Agent新增表详细设计.md》,合并前必须逐字段比较;业务编号、状态枚举、审核流和外键语义不一致时,由数据库负责人组织评审,不允许两个定义同时进入迁移脚本。