状态:设计完成,待应用实现与集成验证。依据:需求规格、验收标准。
采用模块化应用,API、Agent worker、后台 worker 分别部署与扩容。模块通过应用服务调用,跨进程使用持久化任务及领域事件。数据库事务属于应用服务,HTTP handler 与 Agent 工具不直接修改业务表。
| 模块 | 所有权 | 对外服务 |
|---|---|---|
| identity | 租户、店铺、应用、员工授权、客户身份关联 | authenticate、authorize、resolve_subject |
| channels | 渠道绑定、Inbox、消息归一化、回调投递 | accept_message、deliver_event |
| conversations | 会话、消息、控制权、输入事件 | append_message、take_over、release_control |
| after_sales | 工单、方案、确认、审批、数量占用 | create_proposal、confirm、decide、prepare_operation |
| integrations | OMS 连接器、外部操作、结果查询 | submit_exchange、reconcile_operation |
| knowledge_memory | 文档发布、检索、客户记忆与删除状态 | retrieve、read_memory、update_memory、delete_memory |
| agent_runtime | run、等待、执行租约、图版本 | enqueue、resume、cancel、execute |
| model_governance | 路由、调用预算、实际用量 | reserve_budget、invoke、settle_usage |
| platform_governance | 发布清单、Outbox、审计、运行配置 | publish、audit、dispatch |
API 进程处理认证、参数验证、短事务及 SSE。模型和外部网络请求均设置截止时间;数据库事务内不等待这些请求。Agent worker 处理推理和图推进,后台 worker 处理文档导入、记忆提取、Outbox、回调、外部结果查询。长任务与交互任务使用独立并发额度。
MySQL 是业务状态、授权、执行权与操作记录的事实来源。Redis 分别提供缓存、持久检查点及记忆索引;Milvus 保存可重新生成的知识向量。外部订单投影只是查询加速数据。
主键使用应用生成的 UUID,MySQL 保存为 BINARY(16),API 输出标准 UUID 字符串。时间使用 UTC DATETIME(6),业务版本使用 BIGINT UNSIGNED,数量使用正整数;金额如需扩展使用最小货币单位整数并带 currency。业务状态使用 VARCHAR(32),在服务和数据库 CHECK 中限制合法值。
租户数据必含 tenant_id。关联对象使用 UNIQUE(tenant_id,id) 与复合外键 (tenant_id,parent_id),阻止跨租户关联。查询统一接收服务器建立的 AuthContext,禁止仅凭 id 查询租户对象。删除使用显式生命周期操作;审批和审计记录不覆盖历史。
通用可变实体包含 created_at、updated_at、version;业务更新带 expected_version 并验证受影响行数。列表采用 (created_at,id) 游标分页,默认 20、上限 100。JSON 用于不可变方案内容、引用和事件数据;授权字段、状态、版本及调度条件使用独立列。
| 表 | 关键字段 | 唯一约束与索引 |
|---|---|---|
| tenants | id、status、quota_policy_id | 主键 id |
| stores | tenant_id、id、name、status | tenant_id,id |
| client_apps | tenant_id、id、credential_ref、status | tenant_id,id;凭据引用保存在密钥系统 |
| app_store_grants | tenant_id、app_id、store_id、scope | tenant_id,app_id,store_id,scope |
| staff_grants | tenant_id、staff_id、store_id、permission、status | tenant_id,staff_id,store_id,permission |
| customer_subjects | tenant_id、id、status、memory_epoch、memory_revision、consent_version | tenant_id,id |
| channel_bindings | tenant_id、id、store_id、app_id、key_id、secret_ref、status | tenant_id,id |
| customer_identities | tenant_id、binding_id、external_user_id、subject_id、verification_id | tenant_id,binding_id,external_user_id |
| identity_verifications | tenant_id、id、subject_id、method、verified_at、expires_at、evidence_ref | tenant_id,id;证据脱敏与限制访问 |
| conversations | tenant_id、id、store_id、subject_id、binding_id、control_owner、control_version、active_run_id | tenant_id,subject_id,created_at,id |
| messages | tenant_id、id、conversation_id、sequence、role、content_ref、control_version | tenant_id,conversation_id,sequence |
| input_events | tenant_id、id、conversation_id、actor_id、event_type、payload、payload_hash、consumed_by | tenant_id,id |
| rule_versions | tenant_id、rule_id、version、status、effective_at、definition、document_version_id | tenant_id,rule_id,version |
| knowledge_versions | tenant_id、id、document_id、version、status、object_ref、content_hash | tenant_id,document_id,version |
| releases | tenant_id、id、graph_version、state_schema_version、prompt_version、tool_version、knowledge_manifest、rule_manifest、model_route_version | tenant_id,id |
渠道客户标识使用大小写敏感比较。身份关联只接受两端验证通过的证明,并在同一事务更新映射和审计。撤销身份关联立即影响新请求,已有业务记录保留原主体及授权审计。
| 表 | 关键字段 | 唯一约束与索引 |
|---|---|---|
| order_projections | tenant_id、connector_id、external_order_id、subject_id、source_version、observed_at、payload | tenant_id,connector_id,external_order_id |
| tickets | tenant_id、id、store_id、subject_id、conversation_id、status、current_proposal_id、version | tenant_id,subject_id,created_at,id;tenant_id,store_id,status,created_at,id |
| proposals | tenant_id、id、ticket_id、current_version、created_by | tenant_id,id |
| proposal_versions | tenant_id、proposal_id、version、order_id、item_id、quantity、reason、rule_manifest、order_version、content_hash | tenant_id,proposal_id,version |
| confirmations | tenant_id、proposal_id、proposal_version、subject_id、input_event_id、confirmed_at | tenant_id,proposal_id,proposal_version |
| approvals | tenant_id、id、proposal_id、proposal_version、submitted_by、status、decided_by、decision_reason、version | tenant_id,proposal_id,proposal_version;tenant_id,status,created_at,id |
| item_guards | tenant_id、connector_id、order_id、item_id、version | tenant_id,connector_id,order_id,item_id |
| reservations | tenant_id、id、operation_id、connector_id、order_id、item_id、quantity、status | tenant_id,operation_id;tenant_id,connector_id,order_id,item_id,status |
| external_operations | tenant_id、id、proposal_id、proposal_version、action_type、request_hash、status、external_id、lease_token、lease_until、next_check_at、last_error | tenant_id,proposal_id,proposal_version,action_type;status,next_check_at,id |
proposal_versions 的业务内容不可修改。只有 DRAFT 或 NEEDS_REVISION 允许创建修订;已确认且等待审批的方案需要显式撤回到修订流程,作废旧审批并清除其执行资格,然后生成新版本。已有外部操作时禁止修订。客户确认、主管审批、准备操作都检查 tickets.current_proposal_id 与 proposals.current_version。
item_guards 是每个订单明细的稳定加锁行,首次插入处理唯一键竞争后重新读取并加锁。reservations 状态为 HELD、CONSUMED、RELEASED:未知结果保持 HELD;外部受理后转 CONSUMED;外部确定失败且不会迟到执行时转 RELEASED。已受理数量由 OMS 当前可申请数量反映,计算本地可提交数量时只减尚未被 OMS 确认受理的 HELD,禁止重复扣减。
| 表 | 关键字段 | 唯一约束与索引 |
|---|---|---|
| agent_runs | tenant_id、id、conversation_id、status、release_id、version、lease_token、lease_until、checkpoint_ref、next_attempt_at、deadline_at | status,next_attempt_at,id;tenant_id,conversation_id,created_at,id |
| run_waits | tenant_id、run_id、interrupt_id、expected_type、proposal_id、proposal_version、run_version、status、input_event_id | tenant_id,run_id,interrupt_id |
| run_events | tenant_id、run_id、sequence、type、payload、created_at | tenant_id,run_id,sequence |
| api_idempotency | tenant_id、app_id、actor_id、route、key、request_hash、status、resource_id、response、expires_at | tenant_id,app_id,actor_id,route,key |
| channel_inbox | tenant_id、binding_id、external_message_id、payload_hash、payload、status、next_attempt_at | tenant_id,binding_id,external_message_id |
| outbox_events | event_id、tenant_id、aggregate_id、aggregate_version、event_type、schema_version、payload、status、next_attempt_at | event_id;status,next_attempt_at,event_id |
| consumer_receipts | consumer_name、event_id、processed_at | consumer_name,event_id |
| webhook_deliveries | tenant_id、id、subscription_id、event_id、status、attempt_count、next_attempt_at | tenant_id,subscription_id,event_id;status,next_attempt_at,id |
| memory_jobs | tenant_id、id、subject_id、epoch、revision、source_event_id、status | tenant_id,subject_id,epoch,source_event_id |
| model_attempts | tenant_id、id、run_id、provider_request_id、reserved_tokens、actual_tokens、status、pricing_version | tenant_id,id;provider_request_id 按供应商范围去重 |
| audit_records | tenant_id、id、actor_id、action、resource_type、resource_id、request_id、before_version、after_version、created_at | tenant_id,resource_id,created_at,id |
api_idempotency 增加 actor_id,防止同一 H5 应用中的不同客户复用 key 读取他人响应;这进一步限定需求中的应用级范围。过期 API 记录清理不影响外部操作的永久业务去重。输入正文包含敏感信息时加密存储并按照数据保留策略清理。
erDiagram
tenants ||--o{ stores : owns
stores ||--o{ channel_bindings : exposes
customer_subjects ||--o{ customer_identities : verifies
customer_subjects ||--o{ conversations : uses
conversations ||--o{ agent_runs : executes
conversations ||--o{ tickets : creates
tickets ||--o{ proposals : contains
proposals ||--|{ proposal_versions : versions
proposal_versions ||--o| confirmations : confirmed
proposal_versions ||--o| approvals : reviewed
proposal_versions ||--o{ external_operations : performs
external_operations ||--o| reservations : reserves
agent_runs ||--o{ run_waits : waits
agent_runs ||--o{ run_events : streams
统一加锁顺序:当前授权控制行 → conversation → run → ticket → proposal → approval → item_guard → operation。按需取用,多个同类资源按主键排序。短事务发生并发冲突时,由调用方使用同一幂等键进行有界重试;参数、权限、规则错误直接返回。
验签或验证登录身份后,事务插入 Inbox / 幂等记录,锁定 conversation,保存 input_event。无 active_run 时创建 QUEUED run 和 Outbox;存在等待 run 时只接受该等待类型的输入。接管会话只保存供人工处理的输入。提交事务后返回受理结果。RabbitMQ 只是唤醒信号,定时扫描 MySQL 的到期任务可补充遗漏的唤醒。
确认事务校验客户、当前方案版本、当前规则有效性,写 confirmation、审批记录、工单 WAITING_REVIEW、审计及 Outbox。审批事务核验主管权限、提交人分离、方案版本与客户确认,写不可重复决定、工单状态及 Outbox。事件驱动等待 run 恢复,调用端无需伪造恢复参数。
先在事务外读取 OMS 最新版本。事务内锁定上述相关记录,校验权限、会话控制权、审批、规则撤销状态及订单明细占用,建立 HELD reservation、PREPARED operation、PROCESSING 工单和 Outbox。提交后连接器携带 stable operation_id 与 expected_order_version 调用 OMS。外部条件更新处理读取和写入之间的订单变化。
权限撤销、规则撤销与操作准备使用相同的对应授权或规则行锁,确定提交顺序。准备操作事务是平台的业务授权提交点;提交后的操作作为已授权业务继续跟踪,接管与取消不得将其解释为尚未开始。对已提交操作提出终止要求需要 OMS 提供独立撤销流程。
OMS 返回明确受理后,锁定 operation 和关联 ticket,以当前版本更新外部标识、CONSUMED reservation、审计和 Outbox。响应超时转 UNKNOWN,工单 RESULT_UNKNOWN,保留占用并调度查询。收到履约完成回调可直接完成工单,即使此前处于 RESULT_UNKNOWN;检查外部版本,晚到受理响应不能覆盖已完成结果。
查询 NOT_FOUND 不足以证明原提交不会迟到。只有 OMS 对该 operation_id 记录了不可再执行的终止结果,才释放占用。重发始终使用同一 operation_id 和 request_hash;缺少持久幂等、条件更新或结果查询能力的连接器禁止自动执行写操作,转人工处理。
接管事务锁 conversation,增加 control_version、更新 owner,取消未完成 run 并记录事件。操作准备和 Agent 对客消息入库必须在同一 conversation 锁下核验版本。发布通道按会话串行处理控制事件和消息,对旧版本尚未发送的内容进行过滤。已交给网络的字节可能在接管后到达,H5 依据 control_version 丢弃旧版本内容;外部渠道只承诺接管后不再受理新的 Agent 发送动作。
取消工单与准备操作争用同一 ticket 锁;已有 operation 时返回 OPERATION_IN_PROGRESS。取消 run 只终止后续图执行,不撤销外部业务。人工释放控制权后,新客户输入创建新 run。
基础路径 /openapi/v1,员工配置与平台治理使用 /admin/v1。H5 使用安全登录会话并执行 CSRF 校验;服务调用使用限权访问令牌;外部回调使用签名。AuthContext 包含 tenant_id、app_id、actor_type、actor_id、subject_id、store_ids、scopes、request_id,由认证层创建,禁止模型或请求正文提供。
所有写接口要求 Idempotency-Key;变更已有对象同时要求 expected_version。JSON 禁止未知业务字段,数量为正整数。错误响应固定为 {code,message,request_id,details,retryable},details 不包含其他租户对象信息。查询越权对象与不存在对象统一返回 404。
| 方法与路径 | 主要输入 | 权限与响应 |
|---|---|---|
| POST /conversations | channel_binding_id | conversations:write;201 conversation_id、version |
| POST /conversations/{id}/runs | message、client_message_id | 客户本人;202 run_id、status、events_url |
| GET /orders | cursor、limit | 当前客户订单;员工需 orders:read 与店铺范围 |
| GET /orders/{id} | 无 | 返回当前订单、source_version、observed_at |
| POST /after-sales/proposals | conversation_id、order_id、item_id、quantity、reason | 售后创建权限;201 proposal_id、proposal_version、ticket_id、引用 |
| POST /after-sales/proposals/{id}/revisions | expected_version、业务字段 | 当前主体或授权客服;201 新版本,作废旧确认与审批资格 |
| POST /after-sales/proposals/{id}/confirm | proposal_version、expected_ticket_version | 当前客户确认;200 confirmation_id、approval_id、ticket_status |
| GET /approvals | status、cursor、limit | 审批权限与店铺过滤 |
| POST /approvals/{id}/decisions | expected_version、proposal_version、decision、reason | 当前主管且非提交人;200 决定结果 |
| GET /tickets/{id} | 无 | 本人或授权员工;当前状态、版本与可执行动作 |
| POST /tickets/{id}/cancel | expected_version、reason | 当前客户或授权客服;200 当前状态 |
| POST /conversations/{id}/takeover | expected_control_version | 授权客服;200 owner、control_version |
| POST /conversations/{id}/release | expected_control_version | 当前接管客服或主管;200 control_version |
| POST /conversations/{id}/messages | text、expected_control_version | 接管客服;201 message_id |
| GET /runs/{id} | 无 | 当前主体或授权员工;状态、等待类型与版本 |
| GET /runs/{id}/events | Last-Event-ID | SSE,按 run 内 sequence 续传 |
| POST /runs/{id}/inputs | interrupt_id、expected_run_version、answer | 当前客户;201 input_event_id,后台自动请求恢复 |
| POST /runs/{id}/resume | input_event_id、interrupt_id、expected_run_version | 内部恢复权限;202,同一事件幂等 |
| POST /runs/{id}/cancel | expected_version、reason | 当前客户或授权员工;200 状态 |
| GET /me/memories | cursor、limit | 本人;当前 epoch 的可读记忆 |
| PUT /me/memories/{id} | expected_revision、content | 本人;200 新 revision |
| DELETE /me/memories | expected_epoch | 本人;200 新 epoch,后台清理旧内容 |
| POST /webhooks/v1/channels/{binding_id}/messages | 签名消息 envelope | 202 receipt_id;路径独立于基础路径 |
规则发布使用 POST /admin/v1/rules/{id}/versions,激活使用 POST /admin/v1/releases,撤销使用 POST /admin/v1/rules/{id}/versions/{version}/revoke;均需商家配置权限、expected_version 与审计。知识导入通过受控对象上传后 POST /admin/v1/knowledge/imports 创建异步任务。配置发布必须引用已完成索引的知识版本。
Webhook 订阅通过 /admin/v1/webhook-subscriptions 管理,重投使用 POST /admin/v1/webhook-deliveries/{id}/retry。租户、应用、店铺与角色管理遵守 identity 的同一授权规则;平台配置权限不自动授予客户数据读取权限。
| HTTP | code | 调用方行为 |
|---|---|---|
| 401 / 403 | UNAUTHENTICATED / FORBIDDEN | 完成认证或申请相应授权 |
| 404 | RESOURCE_NOT_FOUND | 不重试相同查询 |
| 409 | IDEMPOTENCY_CONFLICT | 检查请求键和参数 |
| 409 | PROPOSAL_VERSION_CONFLICT / VERSION_CONFLICT | 重新读取资源再执行用户动作 |
| 409 | CONVERSATION_WAITING / HUMAN_CONTROLLED | 展示等待动作或人工状态 |
| 409 | OPERATION_IN_PROGRESS / QUANTITY_CONFLICT | 查询工单或调整申请 |
| 422 | RULE_NOT_SATISFIED / INVALID_INPUT_EVENT | 展示业务原因与修正字段 |
| 429 | TENANT_QUOTA_EXCEEDED | 遵守 Retry-After |
| 503 | DEPENDENCY_UNAVAILABLE | 保留幂等键,有界重试 |
EXTERNAL_RESULT_UNKNOWN 是已受理工单的业务状态提示,查询接口返回 200 并提供 operation_id 和下一次检查时间,客户端不得因此创建新申请。SSE 返回 event_id、event_type、sequence、control_version;过期游标在建立流之前返回 410 EVENT_CURSOR_EXPIRED,客户端查询当前快照。
渠道签名字符串为 timestamp + 换行 + nonce + 换行 + HTTP 方法 + 换行 + 原始路径 + 换行 + SHA256(raw_body)。使用 HMAC-SHA256,头部提供 X-Key-Id、X-Timestamp、X-Nonce、X-Signature。签名常量时间比较,时间允许窗口为 300 秒,nonce 在窗口内去重;绑定决定租户及应用。业务重投使用新 nonce 和同一 external_message_id。密钥轮换保留明确的双密钥有效期。
入站 envelope 包含 external_message_id、external_user_id、occurred_at、type、payload;type 为 message、proposal_confirmation 或 clarification。客户动作只在渠道确实提供已认证用户身份且本地映射有效时受理,普通聊天文本不转换为确认记录。
领域事件示例:
{
"event_id": "01951000-0000-7000-8000-000000000001",
"event_type": "after_sale.approved",
"schema_version": 1,
"tenant_id": "01951000-0000-7000-8000-000000000002",
"aggregate_type": "ticket",
"aggregate_id": "01951000-0000-7000-8000-000000000003",
"aggregate_version": 4,
"occurred_at": "2026-09-19T12:00:00Z",
"trace_id": "8c37a78437a84603a629b45ea6257f97",
"payload": {"proposal_id": "01951000-0000-7000-8000-000000000004", "proposal_version": 1}
}
| 事件 | 生产者 | 消费行为 |
|---|---|---|
| conversation.input_received | channels / conversations | 唤醒对应 run |
| after_sale.proposal_confirmed | after_sales | 恢复等待确认的 run,通知审批 |
| after_sale.approved / rejected | after_sales | 恢复等待审批的 run,或调度人工流程的执行 |
| after_sale.operation_prepared | after_sales | 提交指定 operation |
| after_sale.result_changed | integrations | 更新通知与工单查询投影 |
| conversation.taken_over | conversations | 终止后续 Agent 动作与旧版本输出 |
| memory.deleted | knowledge_memory | 清理旧 epoch 索引和内容 |
| knowledge.published | knowledge_memory | 更新可用发布版本 |
Outbox 发布采用至少一次投递,只有 broker 确认且路由有效才标记已发送。消费者在业务事务中插入 consumer_receipts 并更新业务,提交后 ACK。外部 I/O 使用独立 operation 或 delivery 状态机;收据不能在外部提交前使业务失去恢复入口。
回调复用相同签名规范,额外提供 delivery_id。自动重试采用带随机扰动的指数退避,最多 12 次且最长 24 小时,超过限制进入人工处理队列。接收方按 event_id 去重,按 aggregate_version 处理乱序。订阅地址限制 HTTPS,解析与连接时均阻止内网、环回及链路本地地址,禁止自动跟随重定向,凭据保存在密钥系统。
图状态字段:run_id、conversation_id、release_id、state_schema_version、intent、candidate_order_ids、selected_order_id、missing_fields、rule_refs、proposal_id、proposal_version、interrupt_id、input_event_id、operation_id、control_version、step_count、token_budget_remaining、last_error_code。身份从运行时重新建立的 AuthContext 注入;checkpoint 不作为权限证据。
| 节点 | 输入与产物 | 转移条件 |
|---|---|---|
| load_context | 读取当前身份、控制权、发布清单与授权记忆 | 无权限结束;人工控制时取消 |
| classify_intent | 结构化意图与必需字段 | 问答进入检索;换货进入查单;人工请求触发接管请求 |
| resolve_order | 权限内订单候选 | 不唯一或缺信息进入 await_input |
| await_input | 保存等待类型、interrupt_id 与 run_version | 有效输入事件恢复到 resolve_order |
| retrieve_policy | 当前商家、发布版本的文档引用 | 无依据时请求人工;有依据进入 evaluate_policy |
| evaluate_policy | 确定性业务校验结果 | 拒绝则答复;符合则 create_proposal |
| create_proposal | 调用共享服务,保存方案引用 | 进入 await_confirmation |
| await_confirmation | 客户指定版本确认事件 | 确认有效进入 await_approval |
| await_approval | 指定版本审批事件 | 拒绝答复;批准进入 prepare_operation |
| prepare_operation | 调用共享应用服务复核并创建唯一操作 | 变化请求修订;成功交由后台执行 |
| respond | 从业务事实生成答复并附引用 | 保存带控制版本的消息,完成 run |
interrupt 前保存 run_waits 与持久检查点。若 MySQL 等待记录已保存但检查点保存失败,run 标记恢复异常并暂停,恢复协调器检查两侧版本后继续;不能向客户端宣称可以恢复一个不存在的检查点。输入可能先于图进入等待到达,因此恢复协调器扫描未消费的有效事件,不依赖一次性通知。
恢复使用原 thread_id(服务器按 tenant_id/run_id 构造)和原 release_id。可能重复执行的节点只能执行查询或调用幂等应用服务。恢复前核验事件所属租户、主体、等待类型、方案版本、消费状态和当前 run_version;同一事件绑定一个等待记录并以 CAS 推进状态。运行取消与恢复争用同一 run 行锁,已取消任务拒绝恢复。
租约由 MySQL 发放,每次重新领取增加 lease_token。检查点写入使用每次执行独立 checkpoint namespace;失去租约的 worker 不能更新 MySQL 中已接受的 checkpoint_ref。接管、取消、业务写入和最终答复均校验 lease_token 与 control_version,过期 worker 产生的检查点不被恢复入口采用。
图默认最多 20 个节点步骤,单次活跃执行截止时间 120 秒,单次模型调用截止时间 30 秒;等待用户与审批的时间不计入活跃执行时长。超限保存 FAILED 与错误原因,工单保持实际业务状态。等待业务失效或超期通过业务服务关闭,不能凭模型决定释放未知外部操作。
| 工具 | 模型可提供的参数 | 服务端强制行为 |
|---|---|---|
| search_orders | 查询条件、分页游标 | 注入主体与店铺范围,限制返回条数 |
| get_order | order_id | 校验归属,返回来源版本 |
| retrieve_policy | question、product_type | 注入 tenant 与知识版本过滤,返回引用 |
| evaluate_exchange | order_id、item_id、quantity、reason | 确定性规则计算,返回拒绝码或依据 |
| create_exchange_proposal | 当前订单明细、数量、理由 | 应用服务校验,节点重放复用持久化命令标识 |
| get_ticket | ticket_id | 校验主体,返回实际进度 |
| request_human | reason | 登记接管请求,等待客服取得控制权 |
确认、审批、执行授权、身份关联和记忆删除不开放为模型自行决定的工具。prepare_operation 节点由图控制调用应用服务,并验证已保存的业务证据。工具返回不包含其他客户字段、密钥或可执行指令。工具参数 JSON schema 在工程中与 API 请求模型复用,约束由服务执行。
记忆写入按 customer_subject 串行处理,写前与提交后核验 epoch、revision、consent_version。更正或删除增加版本,使迟到提取任务失效。读取同时检查 MySQL 当前 epoch,持久 Redis 故障时不使用不确定版本的个性化内容。每条记忆保存来源、更新时间及授权依据。
知识导入采用对象存储原文 → 解析 → 分段 → Embedding → Milvus → 检索验证 → 发布的任务链,任务以 document_version_id 和阶段去重。检索过滤 tenant_id、store 范围、发布版本及文档权限;缓存键包含这些维度。删除或撤销立即改变可读状态,后台异步清理向量。
模型入口按供应商全局额度、租户额度、应用额度、客户额度执行准入;使用估算输入加最大输出预留 token,实际完成后按 model_attempt_id 结算。超时且用量未知的尝试保留待核对状态。每次真实重试创建独立 attempt,不能重复结算同一 attempt。
交互队列按租户轮转并限制各租户运行数量,全局供应商信号量控制外呼,检索与文档任务使用独立并发池。API 连接池总量以所有副本进程之和核算,保留 MySQL 运维连接。SSE 使用有界发送缓冲,慢客户端断开后通过事件游标恢复,禁止无限累计内存。
发布清单锁定图、状态 schema、Prompt、工具、规则、知识、模型路由及依赖版本。新 run 使用当前发布,等待 run 使用原发布;安全撤销与权限变化始终依据当前状态。数据库迁移采用兼容新增、数据迁移、切换读取、最后清理的顺序,运行中的旧版本退出前保留所需字段及执行制品。
运行环境分别管理密钥、数据库和 OMS 地址;审计访问需要单独权限。生产发布需要完成备份恢复演练、告警通知、密钥轮换、数据保留清理以及已确定 RTO / RPO 的验证。业务日志使用 trace 关联,不记录令牌、完整敏感正文和密钥。
| 设计领域 | 验收依据 | 必需证据 |
|---|---|---|
| 身份与共享服务 | AC-01~AC-08、AC-19、AC-32 | 授权结果、规则引用及业务记录 |
| 确认与审批 | AC-09~AC-13、AC-23~AC-24 | 不可变版本、确认与审批审计 |
| 事务与外部恢复 | AC-14~AC-17、AC-21~AC-22 | 并发事务结果、OMS 操作唯一性 |
| 接管与流式输出 | AC-18、AC-20 | 控制提交时间、消息版本与事件续传 |
| 记忆与消息可靠性 | AC-25~AC-28 | epoch、收据、投递及查询记录 |
| 资源与质量 | AC-29~AC-35 | 按租户指标、真实用量与分类评测 |
后续工程实现按身份与数据库 → 售后服务与 OMS → 可靠投递与人工 API → Agent 与知识记忆 → 全链路验收推进。数据库迁移、OpenAPI 文件与依赖锁定随应用实现生成并验证;本文不表示已经运行这些组件。