Files

11 KiB
Raw Permalink Blame History

reviewStatus, reviewedAt, replacedBy
reviewStatus reviewedAt replacedBy
pending null null

第一阶段工程基线数据库设计

1. 设计边界

本文档定义第一阶段用户资料和 Agent 运行审计数据的逻辑结构、约束、索引、迁移与回滚策略。开发和自动化测试使用 SQLite,集成与生产使用 PostgreSQL。

项目尚未确认 PostgreSQL 精确版本,因此本文档不采用版本专属字段、索引方法、表达式索引或方言 SQL。实现以 Django 6.0.8 ORM 和迁移能力表达;版本专属优化须在 PostgreSQL 版本确认后另行评审。

关联设计:

2. 设计原则

  • 用户私有数据必须具有明确的用户归属。
  • 状态转换由服务层执行,数据库约束负责守住唯一性和基础合法性。
  • 运行事件采用追加模式,保留审计轨迹。
  • JSON 字段只保存经过脱敏和大小限制的摘要。
  • 时间统一存储为支持时区的 Django 时间值,显示时转换到用户时区。
  • 金额、token 和耗时使用确定类型,避免浮点误差。
  • 表名、约束名和索引名在迁移中显式稳定,避免不同数据库自动命名差异影响排查。

3. 实体关系

erDiagram
    AUTH_USER ||--o| USER_PROFILE : has
    AUTH_USER ||--o{ AGENT_RUN : owns
    AUTH_USER ||--o{ MODEL_PROVIDER_CONFIG : owns
    AGENT_RUN ||--o{ AGENT_RUN_EVENT : contains
    AGENT_RUN ||--o{ TOOL_CALL : contains
    AGENT_RUN ||--o{ HUMAN_APPROVAL : requests
    AUTH_USER ||--o{ HUMAN_APPROVAL : resolves

4. 表结构草案

4.1 accounts_user_profile

字段 Django 类型建议 空值 约束与说明
id BigAutoField 否 主键
user_id OneToOneField 否 唯一,关联 Django 用户
display_name CharField 是 空字符串表示未设置,长度上限实现时确认
timezone CharField 否 默认 Asia/Shanghai,必须来自受控候选
created_at DateTimeField 否 创建时写入
updated_at DateTimeField 否 修改时更新

删除策略:用户尚无审计数据时资料可随用户删除;用户存在 Agent Run 时由运行记录的保护关系阻止用户物理删除。

4.2 agent_runtime_agent_run

字段组 字段 类型建议 说明
标识 id UUIDField 主键,避免在页面暴露连续编号
归属 owner_id ForeignKey(PROTECT) 用户私有归属
展示 title CharField 简短标题
状态 status CharField 使用代码枚举和数据库检查约束
并发 lock_version PositiveBigIntegerField 每次状态写入递增
摘要 input_summary JSONField 脱敏、限长输入摘要
摘要 output_summary JSONField 可空,脱敏输出摘要
版本 agent_name CharField Agent 稳定标识
版本 agent_version CharField 可空
版本 instruction_version CharField 可空
版本 toolset_version CharField 可空
模型 model_name CharField 第一阶段允许为空
追踪 trace_id CharField 可空,非秘密标识
时间 started_at DateTimeField 可空
时间 finished_at DateTimeField 可空
耗时 duration_ms PositiveBigIntegerField 可空
用量 input_tokens PositiveBigIntegerField 可空
用量 output_tokens PositiveBigIntegerField 可空
费用 estimated_cost DecimalField 可空,精度实现前确认
失败 error_code CharField 可空、稳定机器码
失败 error_summary TextField 可空、脱敏且限长
审计 created_at DateTimeField 否
审计 updated_at DateTimeField 否

检查约束至少保证:

  • status 属于已定义枚举。
  • lock_version >= 0。
  • token、耗时和费用非负。

4.2.1 agent_runtime_model_provider_config

字段 类型建议 说明
owner_id ForeignKey(PROTECT) 用户私有归属
provider_code CharField 对应代码中的服务商稳定编码
encrypted_api_key TextField Fernet 密文,禁止通过页面或 Admin 展示
key_hint CharField 仅保存末四位提示
status、enabled、is_default 状态字段 连接状态和当前默认选择
default_model_id CharField 用户选择或预设推荐模型
available_models JSONField 最近一次验证取得的模型标识快照
last_verified_at、last_error_code 审计字段 验证时间和稳定错误码

唯一约束为 (owner_id, provider_code)。API Key 加密主密钥只从部署环境读取,不进入数据库;主密钥轮换必须先完成密文重加密,不能直接替换后重启。

跨字段状态不变量仍由服务层验证,因为 SQLite 与 PostgreSQL 对复杂检查约束和时间语义的行为需要保持一致。

4.3 agent_runtime_agent_run_event

字段 类型建议 说明
id BigAutoField 主键
run_id ForeignKey(PROTECT) 关联 Run,审计事件不可级联丢失
sequence PositiveBigIntegerField Run 内递增序号
event_type CharField 事件枚举
summary CharField 短摘要
payload_summary JSONField 脱敏事件数据
occurred_at DateTimeField 业务发生时间
created_at DateTimeField 数据库记录时间

唯一约束:(run_id, sequence)。

索引:(run_id, sequence) 唯一索引已覆盖详情页时间线读取,无需重复创建同前缀普通索引。

4.4 agent_runtime_tool_call

字段组 字段 类型建议 说明
标识 id BigAutoField 主键
归属 run_id ForeignKey(PROTECT) 关联 Run
调用 call_id CharField Run 内调用标识
工具 tool_name CharField 工具稳定名称
工具 tool_version CharField 可空
幂等 idempotency_key CharField 可空,作用域见约束
状态 status CharField started/succeeded/failed
摘要 arguments_summary JSONField 脱敏、限长
摘要 result_summary JSONField 可空、脱敏、限长
失败 error_code CharField 可空
失败 error_summary TextField 可空、限长
时间 started_at DateTimeField 否
时间 finished_at DateTimeField 可空
耗时 duration_ms PositiveBigIntegerField 可空
审计 created_at、updated_at DateTimeField 否

唯一约束:

  • (run_id, call_id) 唯一。
  • 非空幂等键的作用域在真实工具模型确定前采用 (run_id, idempotency_key),后续如需跨 Run 幂等必须重新设计业务作用域。

4.5 agent_runtime_human_approval

字段 类型建议 说明
id UUIDField 主键
run_id ForeignKey(PROTECT) 关联 Run
request_key CharField Run 内稳定请求键
approval_type CharField 确认类型枚举
status CharField 确认状态枚举
request_summary JSONField 脱敏请求摘要
decision_summary JSONField 可空、脱敏处理摘要
requested_at DateTimeField 请求时间
resolved_at DateTimeField 可空
resolved_by_id ForeignKey(PROTECT) 可空,处理人
created_at、updated_at DateTimeField 审计时间

唯一约束:(run_id, request_key)。

索引:(status, requested_at),支持 Admin 查询待处理确认。

5. 主要访问模式与索引

访问模式 过滤与排序 索引建议
当前用户 Run 列表 owner_id,created_at DESC (owner_id, created_at)
当前用户按状态查询 owner_id、status、created_at DESC 第一阶段无筛选需求,暂不新增
Run 事件时间线 run_id、sequence ASC 唯一索引 (run_id, sequence)
Run 工具调用列表 run_id、started_at ASC (run_id, started_at)
待处理人工确认 status、requested_at ASC (status, requested_at)
trace 定位运行 trace_id 有真实查询需求后再决定唯一性和索引

索引以第一阶段真实页面和 Admin 查询为依据,不为未来假设查询提前增加索引。

6. 事务与并发

  • Run 状态变更、状态事件和关联确认记录在同一事务内完成。
  • 更新 Run 前锁定目标记录,并校验 lock_version。
  • 事件序号在锁定 Run 后读取最大值并递增。
  • 唯一约束捕获遗漏的并发冲突,并转换为领域冲突错误。
  • 工具外部调用不持有数据库事务;开始和结束分别使用短事务。
  • SQLite 不提供等价的行锁验证,PostgreSQL 集成测试必须覆盖双并发更新。

7. 数据生命周期

  • 用户资料可修改,保留最新值即可。
  • Agent Run、事件、工具调用和人工确认属于审计数据,第一阶段不提供删除入口。
  • 用户存在运行记录时不得物理删除,改为停用账户。
  • 第一阶段不自动清理日志或审计记录。
  • 后续建立保留周期时必须区分运行摘要、完整原始证据和应用日志,不能使用同一删除策略。

8. 迁移顺序

  1. 创建 common 基础抽象代码,不生成抽象表。
  2. 创建 accounts 与 UserProfile 迁移。
  3. 创建 agent_runtime 核心表和基础约束。
  4. 单独迁移补充经验证的组合索引和检查约束。
  5. 在空 SQLite 数据库执行完整迁移。
  6. 确认 PostgreSQL 精确版本和隔离环境。
  7. 在空 PostgreSQL 数据库执行完整迁移和核心约束测试。

迁移发布后不得直接修改历史迁移;修正通过新迁移完成。

9. 回滚策略

  • 第一阶段没有存量业务数据转换,回滚以撤销未发布迁移为主。
  • 已发布环境回滚前必须确认表内是否已产生审计数据。
  • 存在数据时禁止直接反向删除表,应先停止写入、导出验证数据并制定显式迁移。
  • 应用代码回滚必须与数据库迁移兼容,不能先删除旧代码仍会读取的字段。

10. 验证清单

  • Django 迁移无遗漏。
  • 空 SQLite 数据库全量迁移和反向迁移测试。
  • 空 PostgreSQL 数据库全量迁移。
  • 用户一对一资料唯一约束。
  • Run 状态、非负数值和用户保护约束。
  • 事件序号唯一约束。
  • 工具调用编号和幂等键冲突。
  • 人工确认请求键唯一约束。
  • 两个并发状态更新只有一个成功。
  • 主要列表查询使用预期索引;数据量不足时不声称完成性能验收。

11. 待确认项

  • PostgreSQL 精确版本、部署方式和连接池策略。
  • 摘要字段的最大序列化字节数。
  • 字符字段长度、费用精度和稳定约束名称。
  • trace 标识是否需要全局唯一。
  • PostgreSQL 版本确认后是否需要部分索引或其他专属优化。