Skip to content

架构设计-主agent感知层接口设计(初稿) #70

Description

@yyy-router

1. 文档目的

本文按照《函数级接口合作方式》的要求,定义母 AI 编排模块中“感知层”的函数级接口、前后端 API、依赖函数、内部流程、Python 数据结构、数据库查缺补漏和风险边界。

本文只覆盖当前负责人范围:

  1. 接收用户原始输入。
  2. 读取最近 20 条对话记录。
  3. 识别用户意图。
  4. 判断要调用哪个子 Agent、哪个函数。
  5. 解析调用参数。
  6. 补全缺失参数。
  7. 触发反问机制。
  8. 输出结构化决策结果。

不覆盖范围:

  1. 子 Agent 业务结果生成。
  2. 上下文事实装配。
  3. 指代消解候选查询。
  4. 确认后落盘。
  5. 数据库事务执行。

这些不覆盖范围由母 AI 编排模块执行层、全局数据模块或具体子 Agent 承接。

2. 感知层定位

感知层的核心职责是把用户自然语言输入转换成“执行层可以继续处理的结构化决策”。

用户输入
→ 感知层读取最近 20 条对话
→ 意图识别
→ 子 Agent / 函数路由
→ 参数解析
→ 参数完整性校验
    → 完整:输出结构化决策给执行层
    → 不完整:输出反问结果给前端

长任务拆分是特殊分支:

识别为长任务拆分
→ 检查最近 20 条对话中是否已有长任务拆分问题和用户回答
    → 已有:复用历史回答,解析为长任务拆分参数,输出给执行层
    → 没有:一次性生成长任务拆分需要询问的问题,返回前端

3. 前后端 API 设计

3.1 API 清单

页面 / 场景 API 名称 HTTP 方法 路径建议 承接模块 请求参数 响应数据 数据来源 是否写入 是否需要确认 数据库缺口 数据流转说明
AI 对话页 提交用户输入进行感知分析 POST /api/agent/perception/analyze 母 AI 编排模块 user_idraw_contentmodalitysource_urlclient_message_idcurrent_time PerceptionAnalyzeResponse conversation_messages、LLM 管理模块 前端把用户最新输入提交给后端;后端先保存或接收已保存的当前消息,再读取最近 20 条对话,调用感知层完成意图识别、函数路由和参数解析;若参数完整,返回执行层决策;若缺参数,返回反问问题;该 API 不调用子 Agent、不写业务事实、不创建确认请求
AI 对话页 提交反问回答继续感知分析 POST /api/agent/perception/answer 母 AI 编排模块 user_idraw_contentmodalitysource_urlclient_message_idreply_to_question_idcurrent_time PerceptionAnalyzeResponse conversation_messages、LLM 管理模块 建议补充 metadata.reply_to_question_id 约定 前端提交用户对反问问题的回答;后端读取最近 20 条对话,其中包含上一轮反问和当前回答;感知层重新识别当前任务链路并解析参数;若补齐,输出给执行层;若仍缺失,继续返回反问

3.2 API 数据结构

from datetime import datetime
from typing import Any, Literal
from uuid import UUID

from pydantic import BaseModel, Field


InputModality = Literal["text", "voice_asr", "image_ocr"]


class PerceptionAnalyzeRequest(BaseModel):
    user_id: UUID
    raw_content: str
    modality: InputModality
    source_url: str | None = None
    client_message_id: str | None = None
    current_time: datetime


class PerceptionAnswerRequest(PerceptionAnalyzeRequest):
    reply_to_question_id: str


class PerceptionAnalyzeResponse(BaseModel):
    status: Literal[
        "ready_for_execution",
        "need_clarification",
        "unsupported_intent",
        "error",
    ]
    decision: "PerceptionDecision | None"
    clarification: "ClarificationRequest | None"
    error_message: str | None = None

4. 模块对外函数接口表

所属模块 函数中文名称 函数类型 调用方 输入参数 返回值 依赖数据 依赖模块 是否写入 是否需要确认 失败处理 数据库缺口 数据流转说明
母 AI 编排模块 分析用户输入 生成候选 前端交互与展示模块 user_idraw_contentmodalitysource_urlclient_message_idcurrent_time PerceptionAnalyzeResponse 最近 20 条 conversation_messages 全局数据模块、LLM 管理模块 输入为空返回 error;意图不支持返回 unsupported_intent;参数缺失返回 need_clarification 前端提交用户输入;函数读取最近 20 条对话,把当前输入和历史上下文交给意图识别;识别后解析参数并校验完整性;完整则返回执行层决策;不完整则返回反问;该函数不调用子 Agent、不落盘业务事实
母 AI 编排模块 分析反问回答 生成候选 前端交互与展示模块 user_idraw_contentmodalitysource_urlclient_message_idreply_to_question_idcurrent_time PerceptionAnalyzeResponse 最近 20 条 conversation_messages、上一轮反问内容 全局数据模块、LLM 管理模块 找不到上一轮反问时,退化为普通“分析用户输入”;仍缺参数则继续返回反问 建议统一 conversation_messages.metadata.question_id 前端提交对反问的回答;函数读取最近 20 条对话,从历史中恢复上一轮缺失字段和当前回答;重新进行参数解析和完整性校验;完整则返回执行层决策
母 AI 编排模块 生成长任务拆分问题 触发 母 AI 编排模块 user_idraw_contentrecent_messagescurrent_time ClarificationRequest 最近 20 条 conversation_messages LLM 管理模块 LLM 生成失败时返回固定兜底问题 当意图识别命中长任务拆分,且最近 20 条对话中不存在可复用的长任务拆分问答时,函数一次性生成本轮需要询问的问题,并返回前端;该函数不生成拆分计划、不写长期目标
母 AI 编排模块 输出感知层决策 展示 母 AI 编排模块执行层 intent_resultparsed_paramsmissing_fieldsrecent_messages PerceptionDecision 无数据库事实,只依赖前序解析结果 缺失 agent_namefunction_name 时返回 error 将意图识别结果和参数解析结果包装成统一决策对象,交给执行层;执行层后续负责上下文装配、指代消解和子 Agent 调用

5. 模块依赖函数表

所属模块 依赖模块 需要的函数中文名称 依赖原因 输入参数 返回值 是否强依赖 缺失时处理
母 AI 编排模块 全局数据模块 查询最近对话记录 感知层需要最近 20 条对话作为意图识别上下文 user_idlimit=20before_message_id 可选 recent_messages: list[ConversationMessageDTO] 无法进行上下文连续判断,返回错误
母 AI 编排模块 LLM 管理模块 调用结构化模型 意图识别、参数解析、反问生成都需要 LLM 输出结构化结果 prompt_namemessagesoutput_schemamodel_config structured_outputtrace_id 返回 error,提示稍后重试
母 AI 编排模块 全局数据模块 保存对话消息 当前用户输入和反问回答需要进入对话记录,供后续 20 条窗口使用 user_idrolemodalityraw_contentsource_urlmetadata ConversationMessageDTO 如果上游已保存当前消息,则不重复保存;否则返回错误

6. 模块内部函数表

所属模块 内部函数中文名称 上游函数 下游函数 输入参数 返回值 依赖数据 是否调用 LLM 是否写入 失败处理 数据流转说明
母 AI 编排模块 标准化用户输入 分析用户输入 读取最近对话 raw_contentmodalitysource_urlcurrent_time NormalizedUserInput raw_content 为空返回错误 将文本、ASR 文本或 OCR 文本统一包装为标准输入对象;该函数不做意图识别
母 AI 编排模块 读取最近对话 标准化用户输入 构造感知上下文 user_idcurrent_message_idlimit=20 recent_messages conversation_messages 查询失败返回错误 调用全局数据模块读取最近 20 条对话;按时间正序交给后续 LLM;该函数不裁剪数据库事实
母 AI 编排模块 构造感知上下文 读取最近对话 识别用户意图 normalized_inputrecent_messages PerceptionContext 最近 20 条对话 对话为空时仅使用当前输入 把当前输入和最近对话拼成 LLM 可用上下文;只保留对意图识别有用的信息
母 AI 编排模块 识别用户意图 构造感知上下文 判断是否长任务拆分 PerceptionContextavailable_functions IntentRecognitionResult 子 Agent 能力表 无法识别时返回 unsupported_intent 通过 LLM 一次性判断子 Agent 和函数;不单独拆入口分类 Agent,避免多一次模型调用
母 AI 编排模块 判断是否长任务拆分 识别用户意图 检查长任务历史问答 / 解析调用参数 intent_resultrecent_messages LongTaskBranchDecision 最近 20 条对话 判断异常时走常规参数解析 如果命中长任务拆分,则进入专用流程;否则进入常规参数解析
母 AI 编排模块 检查长任务历史问答 判断是否长任务拆分 解析长任务回答 / 生成长任务拆分问题 recent_messagesraw_content LongTaskQuestionMemory 最近 20 条对话 未找到则返回空记忆 检查最近 20 条对话中是否已有长任务拆分问题和用户回答;有则复用,不重复生成
母 AI 编排模块 生成长任务拆分问题 检查长任务历史问答 输出反问结果 raw_contentrecent_messages ClarificationRequest 最近 20 条对话 LLM 失败时返回兜底问题 对长任务拆分一次性生成待问问题;这些问题用于收集拆分所需信息,不是普通缺参
母 AI 编排模块 解析调用参数 判断是否长任务拆分 / 检查长任务历史问答 校验参数完整性 intent_resultPerceptionContextfunction_schema ParsedParams 最近 20 条对话、目标函数定义 解析失败返回缺失字段 根据目标子 Agent 函数定义解析字段;常规意图直接解析,长任务拆分可结合历史问答解析
母 AI 编排模块 校验参数完整性 解析调用参数 生成常规反问 / 输出感知层决策 parsed_paramsrequired_fields ParameterCompletenessResult 缺少必填字段则返回缺失列表 检查目标函数必填参数是否齐全;该函数不调用 LLM
母 AI 编排模块 生成常规反问 校验参数完整性 输出反问结果 missing_fieldsraw_contentrecent_messages ClarificationRequest 最近 20 条对话 LLM 失败时返回模板化问题 常规流程参数不足时生成追问问题和备选项;不进入执行层
母 AI 编排模块 输出感知层决策 校验参数完整性 母 AI 编排模块执行层 intent_resultparsed_paramsrecent_messagestrace_id PerceptionDecision 控制字段缺失返回错误 将感知层结果包装为执行层输入;执行层后续负责指代消解、上下文事实查询和子 Agent 调用

7. Python 数据结构声明

from datetime import datetime
from typing import Any, Literal
from uuid import UUID

from pydantic import BaseModel, Field


InputModality = Literal["text", "voice_asr", "image_ocr"]

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


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: dict[str, Any]
    created_at: datetime


class NormalizedUserInput(BaseModel):
    user_id: UUID
    raw_content: str
    modality: InputModality
    source_url: str | None
    current_time: datetime
    current_message_id: UUID | 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 PerceptionContext(BaseModel):
    user_id: UUID
    current_input: NormalizedUserInput
    recent_messages: list[ConversationMessageDTO]
    available_functions: list[AgentFunctionDefinition]


class IntentRecognitionResult(BaseModel):
    agent_name: AgentName
    function_name: str
    intent_summary: str
    is_long_task_split: bool = False


class ParsedParams(BaseModel):
    agent_name: AgentName
    function_name: str
    params: dict[str, Any]
    missing_fields: list[str]


class ClarificationOption(BaseModel):
    label: str
    value: str


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


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


class PerceptionDecision(BaseModel):
    agent_name: AgentName
    function_name: str
    params: dict[str, Any]
    recent_messages: list[ConversationMessageDTO]
    trace_id: str | None
    needAskAgain: bool = False


class PerceptionAnalyzeResponse(BaseModel):
    status: Literal[
        "ready_for_execution",
        "need_clarification",
        "unsupported_intent",
        "error",
    ]
    decision: PerceptionDecision | None
    clarification: ClarificationRequest | None
    error_message: str | None = None

8. 数据库查缺补漏表

接口 / 函数名称 需要的数据 当前来源 是否可直接获得 是否可推导 缺口类型 建议补充 风险等级
读取最近对话 最近 20 条对话、角色、原文、模态、资源 URL、时间 conversation_messages user_id + message_index DESC 查询,再正序传给 LLM
分析反问回答 当前回答对应上一轮哪个问题 conversation_messages.metadata 部分可获得 缺约定 约定 metadata.question_idmetadata.reply_to_question_idmetadata.clarification_reason
检查长任务历史问答 历史中是否已有长任务拆分问题和回答 conversation_messages.raw_contentmetadata 部分可获得 缺元数据约定 建议长任务拆分反问消息写入 metadata.clarification_reason = long_task_split_questions
识别用户意图 子 Agent 能力表和函数定义 代码配置或 LLM 管理模块提示词 非数据库 由母 AI 编排模块维护静态能力表,MVP 不入库
解析调用参数 目标函数必填字段 代码配置或 LLM 管理模块提示词 非数据库 每个子 Agent 提供函数定义清单

9. 风险说明

风险 说明 MVP 处理方式
意图识别误判 LLM 可能选错子 Agent 或函数 统一输出 agent_namefunction_name,执行层可做二次校验;无法识别时返回 unsupported_intent
参数解析不完整 用户表达模糊或缺字段 缺必填参数时必须返回反问,不进入执行层
长任务重复提问 最近对话中已有问题和回答,但系统重复生成 先检查最近 20 条对话中的长任务问答元数据;能复用则不重新生成
反问链路丢失 用户回答无法关联上一轮问题 通过 metadata.question_idreply_to_question_id 约定降低风险
上下文窗口不足 最近 20 条无法覆盖很久之前的任务链路 MVP 先接受该限制;长期再引入任务链路状态或摘要
感知层越界 感知层直接查业务事实或调用子 Agent 文档明确感知层只输出结构化决策;指代消解和子 Agent 调用由执行层处理

10. 感知层输出到执行层的契约

PerceptionAnalyzeResponse.status = "ready_for_execution" 时,执行层只依赖 decision 字段:

字段 执行层使用方式
agent_name 决定调用哪个子 Agent
function_name 决定调用子 Agent 的哪个函数
params 作为执行层上下文装配和指代消解的基础参数
recent_messages 作为后续子 Agent 输入的一部分
trace_id 与 LangSmith 或系统日志关联
needAskAgain 必须为 false,否则不能进入执行层

执行层后续职责:

  1. 根据 params 查询数据库事实。
  2. 做指代消解和候选对象确认。
  3. 组装子 Agent 输入。
  4. 调用子 Agent。
  5. 根据子 Agent 响应触发展示或确认落盘。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions