Files
social-app/docs/plans/2026-03-04-agent-hard-reset-design.md
T

8.7 KiB
Raw Blame History

Agent 后端硬切重构设计

目标

  • 一次性移除现有 Agent 运行时代码、测试和旧文档契约,避免新旧方案并存。
  • 仅从后端重新设计 Agent 体系,不依赖前端实现细节。
  • 新方案必须满足以下六项要求:
    1. 配置层可通过 .env 驱动 LLM API Key。
    2. 对话与 resume 通过 Celery 队列处理,不阻塞 Web 主线程。
    3. v1/agent 仅负责路由组织与服务调用,核心逻辑在 core/agent
    4. 按 CrewAI 官方模型组织 Agent/Task/Crew/Flow/Tools。
    5. 按 AG-UI 协议输出事件,优先使用 ag-ui-crewai 适配库。
    6. 使用 LiteLLM 统计每次 LLM 调用的 token 和 cost。

设计原则

  • 单一职责:HTTP 层只做协议和鉴权,编排与执行下沉到核心层。
  • 异步优先:长耗时推理、工具调用、恢复流程全部异步化。
  • 协议优先:AG-UI 作为唯一事件契约,不维护自定义事件方言。
  • 可观测性优先:每次 run、每次 stage、每次 LLM 调用可追踪。
  • 配置单一来源:所有密钥和模型配置只走 core.config.settings

目标架构

1) 分层

  • backend/src/v1/agent/
    • router.py: 暴露 HTTP/SSE 接口。
    • schemas.py: 请求/响应 DTO 和输入校验。
    • dependencies.py: DI 装配。
    • service.py: 薄服务,仅调用 core/agent 应用服务。
  • backend/src/core/agent/
    • application/: run/resume 应用服务。
    • domain/: run 状态机、resume 幂等语义、错误模型。
    • infrastructure/crewai/: CrewAI Agent/Task/Crew/Flow 装配与执行。
    • infrastructure/agui/: AG-UI 事件映射与 SSE 序列化。
    • infrastructure/litellm/: LiteLLM 客户端与 usage/cost 拦截器。
    • infrastructure/queue/: Celery task producer/consumer。

1.1) 配置来源与合并策略

  • Agent 运行配置由两部分组成:
    • 数据库存量配置:system_agents(每种 agent_type 对应 llm 与 llm_config)。
    • 静态模板配置:backend/src/core/config/static/crewai/*.yaml(角色描述、任务模板、workflow、tools)。
  • 合并策略:
    • llmllm_configsystem_agents 为准。
    • prompt 模板、task 描述、flow stage、tool 白名单以 static/crewai 为准。
    • 若任一 agent_type 在 system_agents 缺失,运行前失败并返回受控错误。

2) 核心运行链路

  1. POST /api/v1/agent/runs 只负责参数校验和鉴权。
  2. 路由调用 AgentRunAppService.enqueue_run(),写入 run 记录并投递 Celery。
  3. Worker 执行 run_agent_task
    • 读取 run 上下文。
    • 构建 CrewAI Agent/Task/Crew/Flow
    • 通过 ag-ui-crewai 将执行事件转为 AG-UI 标准事件。
    • 每次 LLM 调用由 LiteLLM 中间层记录 token/cost。
  4. 事件落库并发布到事件通道(Redis Stream/Channel)。
  5. SSE 接口从事件通道读取并持续推送,直到 RUN_FINISHEDRUN_ERROR

3) Resume 链路

  1. POST /api/v1/agent/runs/{run_id}/resume 校验 interrupt_id 与决策 payload。
  2. 调用 enqueue_resume() 投递 resume_agent_task
  3. Worker 在事务内做并发控制:
    • run_id + interrupt_id 幂等锁。
    • 过期校验与状态迁移。
  4. 恢复后继续 CrewAI Flow,事件按 AG-UI 继续输出。

4) Session 状态持久化

  • 使用 sessions.state_snapshot 作为运行态单一快照来源。
  • 快照至少包含:
    • run 上下文(thread_id、run_id、stage
    • pending_tool_callstool_call_id、tool_name、args、status、expires_at
    • correlation 索引(tool_call_id -> message_id / step_id
  • 所有中断/恢复均以 state_snapshot 事务更新为准,避免内存态漂移。

5) 会话与消息落库模型

  • 会话主表:sessions
    • 新建 run 时写入:id/user_id/session_type/status=running/last_activity_at
    • 运行中持续更新:statuslast_activity_atmessage_counttotal_tokenstotal_coststate_snapshot
    • 运行结束更新:
      • 成功:status=completed
      • 失败:status=failed
  • 消息表:messages
    • 用户输入落库为 role=user(每次 run 开始时先写入)。
    • 模型输出落库为 role=assistant(按最终聚合文本落库,保留 metadata 记录增量信息)。
    • 工具调用结果落库为 role=tool,并写入 tool_namemetadata.tool_call_id
    • seq 由每个 session_id 内单调递增分配,满足 uq_messages_session_seq
  • 计量落库:每次 LLM 调用的 usage/cost 先写消息级,再聚合更新到 session 级。

六项要求落地映射

要求 1: .env 驱动 LLM API Key

  • 新增 LLMSettingscore.config.settings.Settings,统一定义:
    • SOCIAL_LLM__PROVIDER_KEYS__DASHSCOPE
    • SOCIAL_LLM__PROVIDER_KEYS__MINIMAX
    • SOCIAL_LLM__PROVIDER_KEYS__MOONSHOT
    • SOCIAL_LLM__PROVIDER_KEYS__DEEPSEEK
    • SOCIAL_LLM__PROVIDER_KEYS__ARK
    • SOCIAL_LLM__PROVIDER_KEYS__ZAI
  • 禁止 os.environ 直接读取密钥。

要求 2: 对话和 resume 走 Celery

  • Web 层不直接执行编排。
  • run/resume 一律入队,Worker 处理,Web 仅做事件流转发。
  • 加入任务级超时、重试、死信策略。

要求 3: v1 仅路由与调用

  • v1/agent/service.py 仅保留应用服务调用和错误映射。
  • 任何编排、状态机、工具执行逻辑禁止进入 v1

要求 4: CrewAI 官方流程

  • 采用 CrewAI 原生对象:AgentTaskCrewFlow
  • tools 通过 CrewAI Tool 机制注册,不做平行实现。
  • 任务模板与 agent 配置集中化(静态模板 + 运行时拼装)。
  • 配置拼装明确依赖 system_agents + static/crewai,不再使用双套来源。

要求 5: AG-UI + ag-ui-crewai

  • 事件集遵循 AG-UI 协议,生命周期闭环:
    • RUN_STARTED
    • 流式消息和工具事件
    • 终态 RUN_FINISHEDRUN_ERROR
  • 优先引入 ag-ui-crewai 做 CrewAI 到 AG-UI 的桥接,避免重复造轮子。

要求 6: LiteLLM token/cost 统计

  • 所有 LLM 调用通过 LiteLLM 统一出入口。
  • 按调用粒度记录:input_tokensoutput_tokenstotal_tokenscostcurrency
  • 按 run 粒度聚合并落库,支持后续计费和审计。

数据与可观测性

  • 保留现有 Agent 相关表结构,不在本次硬切做数据库破坏性变更。
  • 新增事件日志与调用指标落点(如已有字段不足,后续增量迁移)。
  • 日志使用结构化字段:run_idtask_idstagetool_namellm_modellatency_ms
  • 持久化原则:run/resume 的关键状态变更必须可重放,禁止仅保存在内存。

事务边界

  • run 入口事务:创建或加载 session + 写入用户消息。
  • worker 执行事务(可分阶段短事务):
    • 阶段开始:更新 session.status/state_snapshot
    • LLM 返回:写 assistant/tool 消息 + 更新 token/cost 聚合。
    • 中断:写 pending_tool_callsstate_snapshot 并提交。
    • 完成:更新终态 session.status 并提交。
  • resume 事务:校验 interrupt_id 与 ownershipCAS 更新 state_snapshot,然后进入后续执行事务。

错误处理与安全

  • API Key 缺失启动即失败,不进入运行态。
  • 外部工具入参统一白名单和 schema 校验。
  • resume 决策必须鉴权与会话所有权校验。
  • 错误响应遵循 RFC 7807,避免泄漏敏感上下文。

工具调用与恢复语义

  • 工具分三类:
    • 前端工具:由 RunAgentInput.tools 提供能力声明,触发 interrupt,由客户端执行并回传 result。
    • 后端工具(需审批):先 interrupt 给前端审批;审批通过后由后端执行,不由前端执行。
    • 后端工具(直执):后端直接执行。
  • 一致性约束:
    • 每个 tool_result 必须携带 tool_call_id
    • 后端仅接受当前 state_snapshot.pending_tool_calls 中存在且状态合法的 tool_call_id
    • 若收到未知/已消费/过期 tool_call_id,立即产出 RUN_ERROR 并记录审计日志。

测试策略

  • 单元测试:
    • 配置解析与 key 解析
    • run/resume 状态机与幂等
    • LiteLLM usage 聚合
  • 集成测试:
    • API 入队
    • Worker 消费
    • SSE 事件顺序与终态
  • E2E
    • run 成功链路
    • interrupt + resume 链路
    • tool 调用链路

迁移策略

  • 阶段 0(本次):硬切删除旧代码、旧测试、旧文档契约。
  • 阶段 1:搭建新架构骨架和最小可运行 run 流程。
  • 阶段 2:接入 CrewAI + ag-ui-crewai + LiteLLM 完整链路。
  • 阶段 3:补齐可观测性、压测与稳定性治理。

验收标准

  • 后端仓库不存在旧 v1/agentcore/agent 旧实现。
  • 所有 Agent 相关旧测试与旧文档契约已移除。
  • 新方案设计文档明确覆盖六项要求并可进入实现阶段。