Skip to content

数据模型 ​

平台使用 MySQL 存交易与账户数据,MongoDB 存文档型与事件型数据,Redis 做缓存与跨实例广播。这一页给出全貌与边界。


存储分工 ​

存储适合什么使用模块
MySQL(TypeORM)强关系、事务、账户与订单task、account、wallet、order、appmodel
MongoDB(Mongoose)文档结构、事件日志、可演进 schemaworkflow、agent、agent-profile、state、fulfillment、escrow、dialog
Redis(ioredis)缓存、会话、Socket.IO 广播、队列全局

MySQL 核心表 ​

表作用模块
tasks任务实例、状态、摘要、执行信息task
appmodel模型/应用配置appmodel
account账户account
wallet / bankcard钱包与银行卡wallet
orders订单order
member / subscriber会员与订阅member / subscriber

平台主链路中,Task 是 MySQL 侧的核心。它同时承担计费与取证主键。


MongoDB 集合 ​

能力与供给 ​

集合作用
skillsSkill Catalog
agent_profilesAgent 档案
agents / agent_templates⚠️ 遗留,当前未使用

需求与编排 ​

集合作用
tasks任务实体(已从 MySQL 迁入 Mongo),内嵌 agentDeliveries[]、artifacts[]
translated_demands需求翻译结果
workflows工作流定义
workflow_executions工作流执行记录
workflow_templates工作流模板
offline_tasks外部 Agent 离线任务
runs / run_approvals / run_payment_orders执行期的 Run、审批、支付
agent_dialogues会话:kind=relation(人 × agent)/ kind=task(任务对话)
dialogue_messages对话消息(独立集合,会话内 seq 分页)

任务的过程数据 ​

集合作用
task_journal任务发展日志(仅追加,seq 单调,前端时间线)
task_input_facts用户确认过的字段值
task_materials上传文件的解析结果((taskId, fileId) 指纹幂等)

所有者面与变更授权(状态层) ​

owner 面的知识、经验与变更决策落在状态层(state_entries / state_events):

数据路径作用
知识 / 经验/agents/{agentId}/knowledge|lessons/{id}客户面只读 approved;scope.ownerId 控制 per-owner 隔离
变更提案/agents/{agentId}/changes/{changeId}提案与决策结果;决策后带 authorizationId
变更授权/agents/{agentId}/owners/{ownerId}/change-authorizations/{authorizationId}一次性 token 的 tokenHash、绑定字段、TTL、消费状态
变更验证码/agents/{agentId}/owners/{ownerId}/change-challenges/{challengeId}L3 邮箱 OTP 的 codeHash、尝试次数、TTL

scope.ownerId 缺省表示 agent 级;有值只对这位所有者的会话生效。 L3 的决策必须由 email_otp 强度的 token 消费;验证码不落库明文、不进对话消息。

信任层 ​

集合作用
verification_results输出验证结果
fulfillment_deliveries交付
fulfillment_acceptances验收
fulfillment_disputes争议
fulfillment_resolutions裁定
escrows托管(含结算指令)
policy_settings策略设置当前版本
policy_settings_changes策略变更审计(仅追加)
state_events状态事件(仅追加)
state_entries物化状态
state_subscriptions订阅
state_namespace_counters序列分配

关键关系 ​

Company (ownerId = userId + metadata.org)
  │
  ▼
AgentProfile (Mongo)  ← 一个业务一个 Agent
  │ agentId(平台托管自动生成 agent_<uuid>)
  │ skillIds[]
  ▼
Skill (Mongo)

Task (Mongo)
  │ workflowSnapshot.nodes[].agentId
  ▼
Workflow (Mongo)
  │ nodes[].agentId
  ▼
AgentProfile (Mongo)

Task (Mongo)
  ├─ agentDeliveries[]        (内嵌:每个 agent 的投递与费用)
  ├─ Delivery (Mongo) ── Acceptance (Mongo)
  │        └─ Dispute (Mongo) ── Resolution (Mongo)
  ├─ Run (Mongo) ── RunApproval / RunPaymentOrder
  ├─ TaskJournal[] (Mongo, taskId + seq)
  ├─ StateEvent[] (Mongo, path=/tasks/{taskId}/...)
  └─ DialogueSession (kind=task) ── DialogueMessage[]

AgentProfile (Mongo)
  └─ DialogueSession (kind=relation) ── DialogueMessage[]   (scope 缺失)

跨库关联都是软关联(存 ID,不做外键),这是当前架构的一个已知权衡。


一致性与事务 ​

场景保证
单 Mongo 集合写入单文档原子性
履约/托管 + 状态层同一 Mongo 事务(副本集必需)
同一 path 并发写withTransaction + WriteConflict 自动重试
显式版本冲突传 expectedVersion → 409
MySQL 与 Mongo 之间❌ 无分布式事务

MongoDB 必须以副本集运行(rs0),否则事务不可用。见 私有化部署。


会话的两类与消息拆表 ​

会话按用途分两类,键与生命周期都不同:

kind键装什么生命周期
relation(userId, agentId, audience)直聊、主动播报常驻,没有终态
task(taskId, agentId)该任务的全部消息随任务,删任务即删会话

两条纪律:owner 面永远是 relation(所有者维护 agent 没有任务上下文); 外部 A2A 对端不复用会话(复用会让两个并发任务看到彼此的上下文)。

消息独立成集合(dialogue_messages),不再内嵌在会话文档里。两个原因:

  • 内嵌数组会无限增长 —— 单文档 16MB 上限,触到之后该用户的对话永久写不进去;
  • findOne → push → save 是读-改-写 —— 用户发消息与系统主动播报并发时会互相覆盖, 表现为"用户的话凭空消失"。

写入变成一条 insertOne,读取按会话内 seq 分页,(sessionId, seq) 唯一索引兜底。

主动播报(metadata.proactive)只写 kind=relation 那条会话,按天幂等 (proactive:summary:<date>);没有卡住的任务就一个字都不说。

MySQL 的 task 表已停用(读源切 Mongo),迁移脚本见 scripts/migrate-tasks-to-mongo.ts。


Agent 展示页(showcase) ​

agent_profiles.showcase 是可选子文档,把"对外怎么介绍这个业务"与业务字段分开存:

字段说明
slides[]Markdown 说明片段(≤6 条,单条 ≤4000 字符),用于对话右栏与展示页卡片
site平台内生成的单文件静态站点(html ≤200KB,version 每次保存自增)
generatedBytemplate / ai / manual,标明内容来源
templateId / generatedAt模板版本与生成时间

为空时由标准模板从 profile 字段现算、不落库;站点 HTML 永不可执行。 详见 Agent 展示页与信任档案。


索引与约束 ​

集合唯一约束
tasksid;dialogId(partial)
agent_dialoguessessionId
dialogue_messagesmessageId;(sessionId, seq)
task_journaljournalId;(taskId, idempotencyKey)
state_entriespath
state_eventseventId;(namespace, seq)
state_namespace_countersnamespace
skillsskill_id
agent_profilesagentId(平台托管由后端生成 agent_<uuid>;外部注册沿用注册方标识)

金额字段统一为整数最小单位,不使用浮点。


数据保留 ​

数据策略
state_events仅追加,不删除(删除会破坏 replay)
对话消息dialogue_messages 独立集合;删会话不级联删消息(历史可审计),清理靠脚本
离线任务过期标记 expired
审计日志仅追加

下一步 ​

Released under the MIT License.