Skip to content

Architecture interface design(draft)

hqy edited this page Jul 24, 2026 · 4 revisions

TimeFlow MVP 接口合并设计

2. 第一性原则

原则 设计要求
用户输入只有一个主入口 文本、图片、音频最终都进入同一条 HTTP 输入提交链路
母 AI 是业务核心 母 AI 负责理解、参数补全、上下文装配、子 Agent 调用和确认落盘编排
子 Agent 不直接读写数据库 子 Agent 只消费母 AI 已装配好的上下文,返回结构化候选或文本结果
写入必须用户确认 AI 对话写入与手动表单 CRUD 都必须先生成候选,再确认后落盘
数据模块只保存事实 全局数据模块只负责查询、校验、确认后写入,不做 AI 判断
前端只承载交互 前端负责输入、展示、候选选择和确认动作,不承载复杂业务判断
前端接口必须鉴权 除登录、注册外,所有暴露给前端的 HTTP / WS 接口都必须携带 JWT
系统审计模块暂不实现 MVP 暂不设计 agent_run_recordsaudit_events 相关接口和数据库表
消息级追踪,不引入 turn_id 使用 client_message_idreply_to_question_idsource_message_idtrace_id 完成幂等、反问关联和链路追踪

3. 统一模块边界

模块类型 标准模块名 本次接口合并处理
AI 编排模块 母 AI 编排模块 合并感知层和执行层,内部划分为“输入理解阶段”和“执行编排阶段”
AI 编排模块 反问机制 归入母 AI 编排模块内部函数,不单独作为独立服务
子 Agent 日程待办 Agent 提供事项 CRUD 候选生成,不直接落盘
子 Agent 反馈 Agent 提供反馈目标定位和反馈结构化候选,不直接落盘
子 Agent 重排 Agent 提供重排方案生成,不直接应用
子 Agent 复盘 Agent 提供文本复盘结果,默认不写数据库
子 Agent 长任务拆分 Agent 提供宏观规划文本和近期子任务候选,不直接创建正式子任务
公共基础模块 全局数据模块 提供事实查询、校验、确认后写入
公共基础模块 LLM 管理模块 提供结构化模型调用、提示词渲染和模型切换
公共基础模块 系统日志模块 MVP 暂不实现数据库和接口
公共基础模块 对象存储 提供图片、音频上传和 source_url
公共基础模块 OCR 识别模块 根据 source_url 输出 OCR 文本
公共基础模块 ASR 语音识别模块 根据 source_url 输出 ASR 文本
公共基础模块 用户账号模块 提供注册、登录、当前用户识别和业务用户 ID
公共基础模块 全局用户画像管理模块 提供全局画像查询和更新
公共基础模块 任务级画像管理模块 提供长任务维度画像查询和创建落盘
公共基础模块 弹窗确认机制 前端交互能力,后端只接收确认结果
公共基础模块 基础业务模块 提供今日事项、长目标、个人主页等基础页面数据
前端模块 消息推送模块 前端实现,不进入主 Agent 函数调用链
前端模块 前端交互与展示模块 调用 API、建立 WS、展示结果和确认卡片

4. 母 AI 编排模块合并结果

合并后,母 AI 编排模块只有一个模块,不再把“感知层”和“执行层”作为外部并列模块。

内部阶段如下:

阶段 职责 输入 输出 禁止行为
输入理解阶段 接收用户输入提交、归一化文本、读取最近 20 条对话、识别意图、解析参数、触发反问 ConversationInputRequest PerceptionDecisionClarificationRequest 不查询业务候选事项,不调用子 Agent,不写业务事实
执行编排阶段 校验结构化决策、查询必要事实、指代消解、调用目标子 Agent、处理返回、创建确认请求 ExecutionLayerInput MainAgentEvent 不重新识别意图,不重新补参,不绕过确认写业务事实

感知层和执行层的唯一交接对象是:

class ExecutionLayerInput(BaseModel):
    target_agent_name: AgentName
    target_function_name: str
    parsed_params: dict[str, Any]
    time_range: TimeRange
    raw_input: str
    source_message_id: UUID
    recent_messages: list[ConversationMessageDTO]
    trace_id: str | None = None

4.1 输入理解阶段规则

场景 处理规则 输出
普通任务参数完整 根据子 Agent 能力表识别 target_agent_nametarget_function_name,解析参数并抽取顶层 time_range ExecutionLayerInput
普通任务参数缺失 不进入执行编排阶段,先生成反问 dialogue.clarification
用户回答反问 通过 reply_to_question_id 恢复上一轮问题;如果回答无效,继续反问;如果无法关联,退化为新的普通输入 dialogue.decisiondialogue.clarification
长任务拆分 命中长任务拆分后先检查最近 20 条对话是否已有可复用问答;没有则一次性生成本次拆分所需问题 dialogue.clarification(mode=batch)ExecutionLayerInput

4.2 执行编排阶段规则

场景 处理规则 输出
创建类函数 不需要定位已有事项,可直接装配上下文并调用子 Agent AgentResponseEnvelope
更新 / 删除 / 反馈类函数 先按 time_range 和结构化参数粗筛数据库候选,再做范围内指代消解 single / range / ambiguous / not_found
候选唯一 直接装配子 Agent 入参 SubAgentInputBase
候选不唯一 通过 WS 返回候选选择,不调用子 Agent selection.required
母 AI 处理结果需写入 创建 write_requests,前端确认后再落盘 write.confirmation_required

5. 统一 WebSocket 协议

5.1 统一信封

所有 WS 消息统一使用同一信封,WS 仅承载结果推送、状态通知和少量交互控制消息。所有业务字段和关联字段全部放入 payload

class WsEnvelope(BaseModel):
    type: str
    timestamp: datetime
    payload: dict[str, Any]

字段说明:

字段 用途 生成方
type 消息类型,决定进入哪条流程 前端或后端
timestamp 消息产生时间 消息发送方
payload 当前消息的业务数据与关联字段 消息发送方

5.2 WS 连接身份绑定

WS 与 HTTP 统一输入接口使用同一套 JWT 鉴权。服务端通过 JWT 解析出 user_id,并用 user_id 作为 MVP 阶段的连接路由键。

环节 处理规则
WS 建立连接 前端在 WS 握手时携带 JWT;服务端校验成功后解析出 user_id
连接登记 WS 网关维护 active_connections[user_id] = websocket_connection
HTTP 输入提交 POST /api/v1/conversation/inputs 同样携带 JWT;服务端解析出同一个 user_id
结果推送 母 AI 处理完成后,WS 网关根据 user_id 找到当前连接,并推送携带 source_message_id 的处理结果
消息关联 前端使用 source_message_id 判断 WS 结果对应哪一次统一输入
无活跃连接 主要结果仍应写入可恢复的对话状态;前端重新连接后通过 conversation/snapshottransport.resume 恢复
多端登录 MVP 默认同一 user_id 只保留最近一个活跃连接;后续如支持多端,再扩展为 active_connections[user_id][client_instance_id]

因此,服务端识别客户端依赖两层绑定:

JWT -> user_id -> active websocket connection
source_message_id -> 本次用户输入及其处理结果

5.3 WS 推送 / 控制消息

类型 方向 所属阶段 说明
dialogue.clarification 后端 -> 前端 输入理解阶段 参数不足、答非所问或长任务拆分需要补充信息
dialogue.decision 后端 -> 前端 输入理解阶段 母 AI 已识别出目标子 Agent、函数和参数
execution.processing 后端 -> 前端 执行编排阶段 已进入执行编排,正在查询事实或调用子 Agent
selection.required 后端 -> 前端 执行编排阶段 多候选无法唯一定位,需要用户选择
selection.submit 前端 -> 后端 执行编排阶段 用户提交候选选择
selection.cancel 前端 -> 后端 执行编排阶段 用户取消候选选择
write.confirmation_required 后端 -> 前端 确认阶段 有写入候选,需要用户确认
write.decide 前端 -> 后端 确认阶段 用户确认或拒绝写入
write.applied 后端 -> 前端 确认阶段 确认写入已完成
execution.result 后端 -> 前端 执行编排阶段 查询、复盘等无需写入的展示结果
dialogue.error 后端 -> 前端 通用 输入理解失败
execution.error 后端 -> 前端 通用 执行编排失败
transport.ping / transport.pong 双向 传输层 心跳
transport.resume / transport.snapshot 双向 传输层 连接恢复与状态同步

5.4 统一输入提交 payload

InputModality = Literal["text", "image", "audio"]

class ConversationInputPayload(BaseModel):
    client_message_id: str
    modality: InputModality
    raw_content: str | None = None
    reply_to_question_id: str | None = None
    source_message_id: UUID | None = None
    trace_id: str | None = None

说明:POST /api/v1/conversation/inputs 使用统一输入提交语义。文本输入提交 raw_content;图片、音频通过 multipart/form-data 提交 file,后端写入对象存储后生成 source_url,再进入母 AI 编排流程。source_url 由服务端生成并写入消息记录,不作为客户端必填入参。

约束:

输入类型 raw_content source_url 处理方式
text 必填 必须为空 直接进入意图识别
image 为空 必填 后端先存对象存储,再调用 OCR
audio 为空 必填 后端先存对象存储,再调用 ASR

约束:

字段 约束
client_message_id 必填,用于客户端幂等
reply_to_question_id 仅在回答反问时可填
source_message_id 仅在恢复、继续或执行链路中可填
trace_id 可空,由后端链路注入

落库映射:

输入提交字段 conversation_messages.metadata 对应字段
client_message_id client_message_id
reply_to_question_id reply_to_question_id
trace_id trace_id
target_agent_name / target_function_name 同名字段
parsed_params / time_range 同名字段

说明:source_message_id 不进入 metadata;它只作为当前消息主键 conversation_messages.id 的结果引用,或者作为主流程链路中的外部引用字段单独消费,避免和追问状态重复表达。

6. 统一数据结构

InputModality = Literal["text", "image", "audio"]

AgentName = Literal[
    "schedule_todo_agent",
    "feedback_agent",
    "replan_agent",
    "review_agent",
    "long_task_split_agent",
]

AgentDisplayName = Literal[
    "日程待办 Agent",
    "反馈 Agent",
    "重排 Agent",
    "复盘 Agent",
    "长任务拆分 Agent",
]

说明程序内部统一使用 `AgentName` 作为分发和提示词映射键前端展示和文档说明可使用 `AgentDisplayName`class TimeRange(BaseModel):
    start_at: datetime
    end_at: datetime
    source: Literal["user_explicit", "agent_inferred", "system_default"]

class ConversationMessageDTO(BaseModel):
    id: UUID
    user_id: UUID
    message_index: int
    role: Literal["user", "assistant", "system", "tool"]
    modality: InputModality | None
    raw_content: str
    source_url: str | None
    metadata: "ConversationMessageMetadata"
    created_at: datetime

class ConversationInputAccepted(BaseModel):
    source_message_id: UUID
    client_message_id: str
    source_url: str | None = None
    status: Literal["accepted"]

class ConversationMessageMetadata(BaseModel):
    schema_version: int = 1
    message_kind: Literal[
        "input",
        "clarification_question",
        "clarification_answer",
        "decision",
        "execution_processing",
        "selection_required",
        "selection_submit",
        "selection_cancel",
        "execution_result",
        "confirmation_request",
        "confirmation_decision",
        "system_notice",
        "error",
    ]
    client_message_id: str | None = None
    trace_id: str | None = None
    question_id: UUID | None = None
    question_status: Literal["open", "answered", "expired"] | None = None
    question_type: Literal["normal", "long_task_split", "disambiguation", "confirmation"] | None = None
    expires_at: datetime | None = None
    reply_to_question_id: UUID | None = None
    target_agent_name: AgentName | None = None
    target_function_name: str | None = None
    missing_fields: list[str] = Field(default_factory=list)
    parsed_params: dict[str, Any] = Field(default_factory=dict)
    time_range: TimeRange | None = None
    write_request_id: UUID | None = None
    decision: Literal["confirmed", "rejected"] | None = None

class TaskItemDTO(BaseModel):
    id: UUID
    user_id: UUID
    long_goal_id: UUID | None = None
    item_type: Literal["schedule", "todo", "subtask"]
    title: str
    description: str | None = None
    start_at: datetime | None = None
    end_at: datetime | None = None
    due_at: datetime | None = None
    status: Literal["planned", "in_progress", "completed", "cancelled", "deferred"]
    version: int

class LongGoalDTO(BaseModel):
    id: UUID
    user_id: UUID
    title: str
    description: str | None = None
    plan_overview: str | None = None
    start_at: datetime | None = None
    deadline_at: datetime | None = None
    status: Literal["active", "completed", "cancelled"]
    version: int

class FeedbackDTO(BaseModel):
    id: UUID
    user_id: UUID
    task_item_id: UUID
    feedback_status: Literal["completed", "not_completed", "partially_completed", "deferred", "cancelled"]
    normalized_feedback: str
    duration_minutes: int | None = None
    occurred_at: datetime

class TaskProfileSnapshot(BaseModel):
    id: UUID
    user_id: UUID
    long_goal_id: UUID
    profile_summary: str
    source_message_id: UUID
    version: int

class GoalSplitCandidate(BaseModel):
    plan_overview: str
    task_profile_summary: str
    subtasks: list[dict[str, Any]] = Field(default_factory=list)

class WriteDecisionResult(BaseModel):
    write_request_id: UUID
    status: Literal["confirmed", "rejected", "applied", "expired"]
    applied_target_id: UUID | None = None
    message: str | None = None

class AgentFunctionDefinition(BaseModel):
    agent_name: AgentName
    function_name: str
    required_fields: list[str]
    optional_fields: list[str] = Field(default_factory=list)
    description: str

class ClarificationQuestion(BaseModel):
    question_id: str
    field_name: str
    question_text: str
    options: list[dict[str, str]] = Field(default_factory=list)

class ClarificationRequest(BaseModel):
    reason: Literal["missing_required_params", "invalid_answer", "long_task_split_questions", "ambiguous_reference"]
    mode: Literal["single", "batch"]
    questions: list[ClarificationQuestion]
    original_agent_name: AgentName | None
    original_function_name: str | None

class AgentResponseEnvelope(BaseModel):
    agent_name: AgentName
    function_name: str
    isNeedUser: bool
    isDisplayResult: bool
    isError: bool
    result: dict[str, Any] | str | list[Any]
    error_message: str | None = None

class PerceptionDecision(BaseModel):
    target_agent_name: AgentName
    target_function_name: str
    parsed_params: dict[str, Any]
    time_range: TimeRange
    missing_fields: list[str] = Field(default_factory=list)
    raw_input: str
    source_message_id: UUID
    recent_messages: list[ConversationMessageDTO]
    trace_id: str | None = None

class MainAgentEvent(BaseModel):
    event_type: Literal[
        "dialogue.decision",
        "dialogue.clarification",
        "execution.processing",
        "selection.required",
        "write.confirmation_required",
        "write.applied",
        "execution.result",
        "dialogue.error",
        "execution.error",
    ]
    source_message_id: UUID | None = None
    trace_id: str | None = None
    payload: dict[str, Any]

class SubAgentInputBase(BaseModel):
    user_id: UUID
    raw_input: str
    time_range: TimeRange
    recent_messages: list[ConversationMessageDTO]
    parsed_params: dict[str, Any]
    candidate_items: list[dict[str, Any]] = Field(default_factory=list)

class ScopeResolutionResult(BaseModel):
    decision: Literal["single", "range", "ambiguous", "not_found"]
    resolved_item_ids: list[UUID] = Field(default_factory=list)
    resolved_item_id: UUID | None = None
    question_text: str | None = None

7. 前后端交互级别 API

7.1 HTTP API

API 名称 方法与路径 调用方 承接模块 入参 出参 JWT 认证 是否写入 说明
注册用户 POST /api/v1/auth/register 前端交互与展示模块 用户账号模块 emailpassworddisplay_name user_idbusiness_user_idaccess_token 创建用户账号,不进入母 AI
登录用户 POST /api/v1/auth/login 前端交互与展示模块 用户账号模块 emailpassword user_idbusiness_user_idaccess_token 建立登录态
获取当前用户 GET /api/v1/auth/me 前端交互与展示模块 用户账号模块 登录凭证 user_idbusiness_user_iddisplay_name 页面初始化使用
提交统一输入 POST /api/v1/conversation/inputs 前端交互与展示模块 母 AI 编排模块 client_message_idmodality=text/image/audioraw_content?file?reply_to_question_id? source_message_idclient_message_idsource_url?status=accepted 条件写入对话消息 文本走 JSON,图片/音频走 multipart/form-datasource_url 进入消息表并回传,便于溯源;HTTP 接收后结束,处理结果通过 WS 推送
查询会话消息 GET /api/v1/conversation/messages 前端交互与展示模块 全局数据模块 user_idbefore_message_idlimit messages: list[ConversationMessageDTO]has_more 用于聊天页历史展示
恢复会话快照 GET /api/v1/conversation/snapshot 前端交互与展示模块 母 AI 编排模块 user_idlast_seen_message_id recent_messagespending_clarificationlast_event 页面初始化 / 刷新时的静态快照恢复;只负责首屏重建当前可见状态,不补发断线期间的流式事件
查询时间顺序事项 GET /api/v1/items/timeline 前端交互与展示模块 基础业务模块 user_idstart_atend_atitem_type? items: list[TaskItemDTO] 时间顺序 Tab 展示
查询长目标列表 GET /api/v1/long-goals 前端交互与展示模块 基础业务模块 user_idstatus? goals: list[LongGoalDTO] 长任务目标管理 Tab
查询长目标详情 GET /api/v1/long-goals/{goal_id} 前端交互与展示模块 基础业务模块 user_idgoal_id goalsubtaskstask_profile 长目标详情展示
查询全局用户画像 GET /api/v1/user/profile 前端交互与展示模块 全局用户画像管理模块 user_id UserProfileDTO 个人主页展示
创建手动写入请求 POST /api/v1/write-requests 前端交互与展示模块 全局数据模块 actiontarget_typetarget_id?payloadpreview_text write_request_idpayload_hashconfirmation_payload 是,写入请求 手动新增、修改、删除事项、长目标或画像时先创建确认门禁
提交手动确认决定 POST /api/v1/write-requests/{write_request_id}/decide 前端交互与展示模块 全局数据模块 decisionidempotency_key WriteDecisionResult 确认时写入 手动 CRUD 与 AI 写入走同一套确认和校验流程

7.2 WebSocket API

统一连接地址:

WebSocket /ws/v1/conversation

说明:WS 握手必须携带 JWT;前端建立连接时通过 Authorization: Bearer <token> 或等价握手认证方式完成鉴权,未登录或 token 失效时不允许进入对话链路。鉴权成功后,WS 网关必须将解析出的 user_id 绑定到当前连接;后续 HTTP 统一输入接口使用同一 JWT 得到同一个 user_id,母 AI 处理结果再通过该 user_id 路由到当前 WS 连接。

WS 事件 方向 payload 字段 JWT 认证 是否写入 说明
dialogue.clarification 后端 -> 前端 source_message_idquestionsreasonmode 返回反问问题或长任务拆分补充问题
dialogue.decision 后端 -> 前端 source_message_idtarget_agent_nametarget_function_nameparsed_paramstime_range 告知前端母 AI 已完成输入理解
execution.processing 后端 -> 前端 source_message_idstage 告知前端正在进入执行编排
selection.required 后端 -> 前端 interaction_idcandidate_itemsquestion_text 多候选无法唯一定位,需要用户选择
selection.submit 前端 -> 后端 interaction_idselected_candidate_ids 用户从候选对象中选择
selection.cancel 前端 -> 后端 interaction_id 取消中间选择
write.confirmation_required 后端 -> 前端 write_request_idconfirmation_payload 有写入候选,需要用户确认
write.decide 前端 -> 后端 write_request_iddecision=confirmed/rejectedidempotency_key 确认时写入 用户确认或拒绝写入
write.applied 后端 -> 前端 write_request_idstatusapplied_target_id? 确认写入已完成
execution.result 后端 -> 前端 source_message_idresult 返回无需写入的展示结果
dialogue.error 后端 -> 前端 source_message_id?error_codemessage 输入理解失败
execution.error 后端 -> 前端 source_message_id?error_codemessage 执行编排失败
transport.resume 前端 -> 后端 last_seen_message_id WS 重连握手;用于续接同一条长连接,并请求补发断线期间遗漏的流式事件
transport.snapshot 后端 -> 前端 recent_messagespending_clarificationlast_event WS 重连成功后返回当前连接态摘要,仅用于本次连接续接,不替代页面首屏快照

说明:client_message_idreply_to_question_idsource_message_idtrace_id 统一放在 payload 中,不再拆到顶层字段;初始文本和文件输入不通过 WS 发送,统一走 POST /api/v1/conversation/inputs

断开与重连约定:

场景 前端判断 系统处理
服务端主动关闭 ws.onclose 收到正常 close frame,code=1000 / 1001 等,通常 wasClean=true 前端可直接显示正常结束,不强制重连
鉴权失效关闭 code=1008reason 标记 token 失效或未授权 前端跳转登录或刷新 token,不进入普通重连
服务端异常关闭 code=1011 或无正常 close frame 前端进入重连流程,并携带 last_seen_message_id
网络中断 / 代理中断 通常表现为 code=1006wasClean=false 前端进入重连流程,并请求 transport.resume

恢复边界说明:

场景 使用接口 作用
页面首次打开 / 刷新后恢复界面 GET /api/v1/conversation/snapshot 拉取持久化静态快照,重建聊天页、反问卡片和待确认状态
已建立 WS 连接后发生断线并重连 transport.resume + transport.snapshot 续接长连接,补发断线期间遗漏的实时事件和当前连接态
只看历史消息列表 GET /api/v1/conversation/messages 仅分页加载消息,不恢复交互态

补充说明:conversation/snapshot 负责“页面状态恢复”,基于数据库中的持久化状态生成;transport.resume / transport.snapshot 负责“连接状态恢复”,只处理当前 WS 连接的续接与流式事件补发。前者不替代后者,后者也不承担首屏重建。

8. 模块之间函数级接口

8.1 母 AI 编排模块

函数名称 调用方 入参 出参 依赖模块 是否写入 说明
处理统一输入提交 HTTP 输入接口 ConversationInputPayloadfile? ConversationInputAccepted 对象存储、OCR 识别模块、ASR 语音识别模块、全局数据模块、LLM 管理模块 是,对话消息 统一接收文本、图片、音频和反问回复;归一化输入、保存消息、读取最近 20 条对话、识别意图、解析参数
生成反问请求 母 AI 编排模块 missing_fieldsraw_inputrecent_messagestarget_agent_nametarget_function_name ClarificationRequest LLM 管理模块 参数缺失或答非所问时返回追问
输出执行层输入 母 AI 编排模块 target_agent_nametarget_function_nameparsed_paramstime_rangeraw_inputsource_message_idrecent_messages ExecutionLayerInput 感知阶段到执行阶段的唯一交接对象
执行主编排流程 母 AI 编排模块 ExecutionLayerInput MainAgentEvent 全局数据模块、目标子 Agent、LLM 管理模块 条件写入 查询事实、指代消解、调用子 Agent、接收处理结果、创建确认请求、处理返回
执行范围内指代消解 母 AI 编排模块 raw_inputcandidate_itemstime_rangerecent_messages ScopeResolutionResult LLM 管理模块 只在候选事实范围内判断 singlerangeambiguousnot_found
调用目标子 Agent 母 AI 编排模块 target_agent_nametarget_function_nameSubAgentInputBase AgentResponseEnvelope 目标子 Agent 程序按注册表确定性分发;子 Agent 只做数据处理,不直接查库或写库
创建待确认写入请求 母 AI 编排模块 source_message_idactiontarget_typetarget_id?payloadpreview_text write_request_idconfirmation_payload 全局数据模块 是,写入请求 母 AI 执行层基于处理结果生成确认门禁
处理写入确认决定 WS 网关 write_request_iddecisionidempotency_key WriteDecisionResult 全局数据模块 确认时写入 用户确认后由数据模块事务落盘

8.2 子 Agent

模块 函数名称 调用方 入参 出参 是否写入 说明
日程待办 Agent 生成事项操作候选 母 AI 编排模块 user_idraw_inputtime_rangerecent_messagesaction=create/update/delete/querycandidate_items? AgentResponseEnvelope(result=item_operation_candidate) 基于母 AI 装配好的候选上下文生成日程、待办、子任务基础 CRUD 结果
反馈 Agent 生成执行反馈候选 母 AI 编排模块 user_idraw_inputtime_rangerecent_messagescandidate_items AgentResponseEnvelope(result=feedback_candidate) 基于母 AI 提供的候选事实定位目标事项并规范化反馈
重排 Agent 生成重排方案 母 AI 编排模块 user_idraw_inputtime_rangerecent_messagesfuture_itemsunfinished_feedbacksuser_profile?task_profile_snapshot? AgentResponseEnvelope(result=replan_candidate) 基于母 AI 提供的事实与画像生成方案,不直接应用
复盘 Agent 生成复盘报告 母 AI 编排模块 user_idraw_inputtime_rangerecent_messagesreview_factsreview_type AgentResponseEnvelope(result=review_text) 基于母 AI 提供的事实数据生成文本复盘
长任务拆分 Agent 生成长任务拆分候选 母 AI 编排模块 user_idraw_inputtime_rangerecent_messagesuser_profile? AgentResponseEnvelope(result=GoalSplitCandidate) 输出宏观规划文本、近期子任务候选和任务级画像总结;确认与落盘由母 AI 执行层完成

子 Agent 入参基线:

子 Agent 必填参数 条件参数 说明
日程待办 Agent user_idraw_inputtime_rangerecent_messagesparsed_params.action candidate_items create 不需要候选事项;update/delete/query 的候选范围由执行层预先装配
反馈 Agent user_idraw_inputtime_rangerecent_messagescandidate_items 反馈目标必须来自执行层提供的候选事实,子 Agent 不查库
重排 Agent user_idraw_inputtime_rangerecent_messagesfuture_itemsunfinished_feedbacks user_profiletask_profile_snapshot time_range 用于限定重排影响范围,未来事项由执行层查询并装配;任务级画像只读取已落盘快照
复盘 Agent user_idraw_inputtime_rangerecent_messagesreview_factsreview_type long_goal_id 复盘只基于执行层给定事实生成文本,不默认写库
长任务拆分 Agent user_idraw_inputtime_rangerecent_messagesuser_profile 输出 plan_overview、近期子任务候选和 task_profile_summary;长期宏观规划与任务级画像由执行层确认落盘

子 Agent 出参统一使用 AgentResponseEnvelope。长任务拆分 Agent 还必须额外返回 task_profile_summary,用于在创建长目标时与长目标数据一并落盘。子 Agent 不输出数据库动作,不负责创建 write_requests;若其结果会引发写入,是否进入确认门禁由母 AI 执行层判断。

8.3 公共基础模块

模块 函数名称 调用方 入参 出参 是否写入 说明
全局数据模块 保存对话消息 母 AI 编排模块 user_idrolemodalityraw_contentsource_urlmetadata ConversationMessageDTO 保存用户输入、系统追问和主要结果消息
全局数据模块 查询最近对话记录 母 AI 编排模块 user_idlimit=20before_message_id? list[ConversationMessageDTO] 给母 AI 和子 Agent 提供对话连续性
全局数据模块 查询事项列表 母 AI 编排模块、基础业务模块 user_idtime_rangeitem_type?status? list[TaskItemDTO] 用于候选定位、重排、复盘和页面展示
全局数据模块 查询长目标及子任务 母 AI 编排模块、基础业务模块 user_idlong_goal_id LongGoalDTOsubtasks 用于长任务拆分、重排和详情页
全局数据模块 查询反馈记录 母 AI 编排模块 user_idtime_rangetarget_item_ids? list[FeedbackDTO] 用于重排和复盘
全局数据模块 查询全局用户画像 母 AI 编排模块、全局用户画像管理模块 user_id UserProfileDTO 用于长任务拆分和重排
全局数据模块 查询任务级画像 母 AI 编排模块、任务级画像管理模块 user_idlong_goal_id TaskProfileSnapshot? 用于重排阶段读取已落盘快照
全局数据模块 创建写入请求 母 AI 编排模块 source_message_idactiontarget_typepayloadpreview_text write_request_idpayload_hash 写入确认门禁
全局数据模块 应用已确认写入 母 AI 编排模块 write_request_iddecisionidempotency_keyconfirmed_by WriteDecisionResult 校验确认后事务写入业务事实
LLM 管理模块 调用结构化模型 母 AI 编排模块、子 Agent prompt_namemessagesoutput_schemamodel_config? structured_outputtrace_id 所有模型调用统一入口
LLM 管理模块 渲染子 Agent 能力提示词 母 AI 编排模块 list[AgentFunctionDefinition] prompt_fragment 程序维护能力表,渲染注入系统提示词
对象存储 上传原始媒体文件 母 AI 编排模块 user_idfilefile_type=image/audio source_urlobject_key 是,对象存储 不做识别和业务理解
OCR 识别模块 识别图片文本 母 AI 编排模块 source_url recognized_textstatus 图片到文本
ASR 语音识别模块 识别语音文本 母 AI 编排模块 source_url recognized_textstatus 语音到文本
用户账号模块 获取当前用户 前端交互与展示模块、母 AI 编排模块 登录凭证 user_idbusiness_user_id 鉴权和用户归属
全局用户画像管理模块 更新全局用户画像 前端交互与展示模块 user_id、画像字段 UserProfileDTO 用户主动维护全局画像
任务级画像管理模块 查询任务级画像快照 母 AI 编排模块、重排 Agent user_idlong_goal_id TaskProfileSnapshot 任务级画像只在重排时使用,作为提示词输入
任务级画像管理模块 保存任务级画像快照 母 AI 编排模块 user_idlong_goal_idsource_message_idprofile_summaryversion TaskProfileSnapshot 长任务拆分确认落盘时,与长目标创建数据同步写入

9. 完整业务链路时序图

sequenceDiagram
    autonumber

    participant U as 用户
    participant FE as 前端交互与展示模块
    participant AUTH as 用户账号模块
    participant API as 统一输入提交接口
    participant OSS as 对象存储
    participant WS as WebSocket
    participant MA as 母AI编排模块
    participant ASR as ASR语音识别模块
    participant OCR as OCR识别模块
    participant DATA as 全局数据模块
    participant LLM as LLM管理模块
    participant SA as 目标子Agent

    FE->>WS: 建立 WS 连接(JWT)
    WS->>AUTH: 校验 JWT
    AUTH-->>WS: user_id
    WS->>WS: 登记 active_connections[user_id]
    WS-->>FE: 连接成功

    alt 文本输入
        U->>FE: 输入文本
        FE->>API: POST /api/v1/conversation/inputs(text, JWT)
    else 语音输入
        U->>FE: 输入语音
        FE->>API: POST /api/v1/conversation/inputs(audio, JWT)
    else 图片输入
        U->>FE: 上传图片
        FE->>API: POST /api/v1/conversation/inputs(image, JWT)
    end

    API->>AUTH: 校验 JWT
    AUTH-->>API: user_id
    API->>MA: 统一输入提交(user_id)

    alt modality=audio
        MA->>OSS: 上传音频
        OSS-->>MA: source_url
        MA->>ASR: 识别语音(source_url)
        ASR-->>MA: recognized_text
    else modality=image
        MA->>OSS: 上传图片
        OSS-->>MA: source_url
        MA->>OCR: 识别图片(source_url)
        OCR-->>MA: recognized_text
    else modality=text
        MA->>MA: raw_content 作为 normalized_text
    end

    MA->>DATA: 保存对话消息(normalized_text, source_url)
    DATA-->>MA: source_message_id
    API-->>FE: HTTP accepted(source_message_id)
    MA->>DATA: 查询最近20条对话(user_id)
    DATA-->>MA: recent_messages
    MA->>LLM: 意图识别 + 参数解析(能力表, normalized_text, recent_messages)
    LLM-->>MA: target_agent_name, target_function_name, parsed_params, time_range, missing_fields

    alt 长任务拆分且无可复用问答
        MA->>LLM: 生成长任务拆分问题
        LLM-->>MA: ClarificationRequest(mode=batch)
        MA-->>WS: dialogue.clarification(user_id, source_message_id)
        WS-->>FE: 一次性展示拆分问题
    else 参数缺失或回答无效
        MA->>LLM: 生成反问(missing_fields)
        LLM-->>MA: ClarificationRequest
        MA-->>WS: dialogue.clarification(user_id, source_message_id)
        WS-->>FE: 展示追问
    else 参数完整
        MA-->>WS: dialogue.decision(user_id, source_message_id)
        MA-->>WS: execution.processing(user_id, source_message_id)
        MA->>DATA: 按 time_range 查询候选事实
        DATA-->>MA: candidate_facts
        opt 存在候选歧义
            MA->>LLM: 范围内指代消解(candidate_facts)
            LLM-->>MA: single / range / ambiguous / not_found
        end

        alt 仍需用户选择
            MA-->>WS: selection.required(user_id, source_message_id)
            WS-->>FE: 展示候选
            U->>FE: 选择候选
            FE->>WS: selection.submit
            WS->>MA: 继续执行编排
        else 可调用子Agent
            MA->>SA: 调用目标函数(SubAgentInput)
            SA-->>MA: AgentResponseEnvelope
            alt 仅展示
                MA-->>WS: execution.result(user_id, source_message_id)
                WS-->>FE: 展示结果
            else 需要写入确认
                MA->>DATA: 创建写入请求
                DATA-->>MA: write_request_id
                MA-->>WS: write.confirmation_required(user_id, source_message_id)
                WS-->>FE: 展示确认卡片
                U->>FE: 确认或拒绝
                FE->>WS: write.decide
                WS->>MA: 处理确认决定
                MA->>DATA: 应用已确认写入
                DATA-->>MA: WriteDecisionResult
                MA-->>WS: write.applied / execution.result(user_id, source_message_id)
                WS-->>FE: 展示最终结果
            end
        end
    end
Loading

10. MVP 最小业务闭环数据库设计

10.1 保留表

表名 用途 保留原因
users 用户账号 登录、用户归属、业务用户唯一 ID
user_profiles 全局用户画像 长任务拆分和重排需要读取
long_goals 长目标 长任务拆分、目标复盘、任务级画像归属
task_items 统一事项表 保存日程、待办、长目标子任务;其中只有 subtask 关联长目标
conversation_messages 对话消息 保存文本、ASR 文本、OCR 文本和原始媒体 URL
feedback_records 执行反馈 反馈、重排、复盘的事实来源
task_profile_snapshots 任务级画像 长任务拆分时写入的当前快照
write_requests 待确认写入请求 所有写入候选的统一确认门禁
operation_confirmations 用户确认记录 记录用户确认或拒绝

10.2 暂不保留表

表名 处理方式 原因
agent_run_records MVP 暂不实现 用户明确系统审计模块先不实现
audit_events MVP 暂不实现 用户明确系统审计模块先不实现
task_profile_observations 暂不保留 任务级画像只保留长任务创建时写入的当前快照,减少冗余来源表
replan_proposals 暂不保留 重排候选可存入 write_requests.payload,确认后直接更新事项
replan_proposal_changes 暂不保留 变更列表作为写入请求 payload 的一部分
replan_applications 暂不保留 应用结果由 write_requests 和业务表状态体现

10.3 核心表字段

users

字段 类型 必填 说明
id uuid 主键
business_user_id text 业务生成的用户唯一 ID
email text 登录邮箱,唯一
password_hash text 密码哈希
display_name text 昵称
status text active / disabled
is_deleted boolean 软删除标记
deleted_at timestamptz 软删除时间
created_at timestamptz 创建时间
updated_at timestamptz 更新时间

user_profiles

字段 类型 必填 说明
id uuid 主键
user_id uuid 用户 ID
profile_data jsonb 全局画像结构化数据
is_deleted boolean 软删除标记
created_at / updated_at timestamptz 时间字段

long_goals

字段 类型 必填 说明
id uuid 主键
user_id uuid 用户 ID
title text 长目标标题
description text 目标说明
plan_overview text 全周期粗略规划文本
start_at timestamptz 开始时间
deadline_at timestamptz 截止时间
status text active / completed / cancelled
version integer 乐观锁版本
is_deleted boolean 软删除标记
created_at / updated_at / deleted_at timestamptz 时间字段

task_items

字段 类型 必填 说明
id uuid 主键
user_id uuid 用户 ID
long_goal_id uuid subtask 允许关联长目标;scheduletodo 必须为空
item_type text schedule / todo / subtask
title text 事项标题
description text 描述
start_at timestamptz 开始时间
end_at timestamptz 结束时间
due_at timestamptz 截止时间
status text planned / in_progress / completed / cancelled / deferred
version integer 乐观锁版本
is_deleted boolean 软删除标记
created_at / updated_at / deleted_at timestamptz 时间字段

conversation_messages

字段 类型 必填 说明
id uuid 主键,作为 source_message_id 使用
user_id uuid 用户 ID
message_index integer 单一对话框内递增序号
role text user / assistant / system / tool
modality text text / image / audio
raw_content text 文本原文、ASR 文本或 OCR 文本
source_url text 原始媒体 URL
metadata jsonb 统一消息元数据,保存消息类型、追问状态、回填关联和执行上下文
created_at timestamptz 创建时间

conversation_messages.metadata

conversation_messages.metadata 采用扁平化固定键结构,不再额外拆表。

字段 类型 必填 说明
schema_version integer 元数据版本,MVP 固定为 1
message_kind text input / clarification_question / clarification_answer / decision / execution_processing / selection_required / selection_submit / selection_cancel / execution_result / confirmation_request / confirmation_decision / system_notice / error
client_message_id text 客户端幂等标识;用户消息必填,系统消息可空
trace_id text 模型调用或链路追踪标识
question_id uuid 追问消息自身 ID;仅 clarification_question 需要
question_status text open / answered / expired
question_type text normal / long_task_split / disambiguation / confirmation
expires_at timestamptz 追问过期时间
reply_to_question_id uuid 用户回答所对应的追问消息 ID
target_agent_name text 相关子 Agent 名称
target_function_name text 相关子 Agent 函数名
missing_fields jsonb 仍缺失的字段名列表
parsed_params jsonb 已解析出的结构化参数
time_range jsonb 结构化时间范围
write_request_id uuid 写入请求 ID
decision text confirmed / rejected

一致性规则:

场景 规则
元数据类型来源 message_kind 由 WS type 或后端事件类型派生,不能手填成另一个语义
用户首次输入 message_kind=inputclient_message_id 必填
生成反问 message_kind=clarification_questionquestion_id 必填且等于该消息的 conversation_messages.idquestion_status=openexpires_at 必填
用户回答反问 message_kind=clarification_answerreply_to_question_id 必填且必须指向一条 question_status=openclarification_question
反问被消费 服务端将原 clarification_question.question_status 更新为 answered
反问过期 服务端将原 clarification_question.question_status 更新为 expired
执行层结果 message_kind=decision / execution_result / confirmation_request / confirmation_decision 之一,按结果填充对应字段

示例:

{
  "schema_version": 1,
  "message_kind": "clarification_question",
  "client_message_id": "c_001",
  "question_id": "b7f0c1d8-8c7a-4a75-9f63-9d2b8be6b2b1",
  "question_status": "open",
  "question_type": "long_task_split",
  "expires_at": "2026-07-23T18:00:00+08:00",
  "target_agent_name": "long_task_split_agent",
  "target_function_name": "生成长任务拆分候选",
  "missing_fields": ["deadline_at", "duration_minutes"]
}
{
  "schema_version": 1,
  "message_kind": "clarification_answer",
  "client_message_id": "c_002",
  "reply_to_question_id": "b7f0c1d8-8c7a-4a75-9f63-9d2b8be6b2b1",
  "parsed_params": {
    "deadline_at": "2026-08-01T18:00:00+08:00",
    "duration_minutes": 120
  }
}

feedback_records

字段 类型 必填 说明
id uuid 主键
user_id uuid 用户 ID
task_item_id uuid 反馈目标事项
source_message_id uuid 来源对话消息
feedback_status text completed / not_completed / partially_completed / deferred / cancelled
normalized_feedback text 规范化反馈文本
duration_minutes integer 实际耗时
occurred_at timestamptz 反馈发生时间
is_deleted boolean 软删除标记
created_at / updated_at / deleted_at timestamptz 时间字段

task_profile_snapshots

字段 类型 必填 说明
id uuid 主键
user_id uuid 用户 ID
long_goal_id uuid 长目标 ID
profile_summary text 长任务拆分 Agent 在创建长任务时输出的任务级画像总结
source_message_id uuid 创建该长目标的来源对话消息
version integer 版本
is_deleted boolean 软删除标记
created_at / updated_at / deleted_at timestamptz 时间字段

write_requests

字段 类型 必填 说明
id uuid 主键
user_id uuid 用户 ID
source_message_id uuid 来源消息
action text create / update / delete / feedback / replan / goal_split
target_type text task_item / long_goal / feedback / profile
target_id uuid 目标对象 ID
payload jsonb 待确认写入载荷
payload_hash text 防止前端篡改载荷
status text pending / confirmed / rejected / applied / expired
expires_at timestamptz 过期时间
created_at / updated_at timestamptz 时间字段

operation_confirmations

字段 类型 必填 说明
id uuid 主键
write_request_id uuid 写入请求 ID
user_id uuid 用户 ID
decision text confirmed / rejected
idempotency_key text 确认事件幂等键
created_at timestamptz 确认时间