You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

12 KiB

PLAN4 — 流编辑器深度重构:LLM→智能体→流节点→工作流 四层架构

一、问题诊断

当前架构痛点(逐一定位代码行级别)

# 问题 根因位置 影响
1 LLM/智能体与节点未打通 engine.py#L101-L118 LLMNodeAgent 每次硬编码新建 OpenAIChatModel,忽略节点配置中 model/temperature/system_prompt 节点的LLM配置表单完全无效
2 节点只有壳,无法配置 FlowNode.vue 固定 Top/Bottom Handle,条件节点只有一个出口 条件分支无法区分 true/false
3 连线位置漂移 FlowEdge.vue 自定义 SVG path + 没有绑定 vue-flow edge marker 线条起点/终点不精准
4 条件分支不可控 engine.py#L277-L293 ConditionNodeAgent 只返回固定字符串 + 拓扑排序不支持跳过 即使 LLM 判断了真假,引擎也不会分支
5 触发节点无实际参数 FlowEditor 触发节点只有标签,无企微回调 URL / webhook 配置 无法真正接入企微触发
6 AgentFactory 未集成 engine.py 从未调用 factory.py 智能体复用、缓存管理能力全部浪费

二、目标架构:四层递进模型

┌──────────────────────────────────────────────┐
│  第四层: 工作流 (Workflow)                    │
│  多个节点串联的执行拓扑图,含条件分支、循环    │
│  → FlowEngine.execute()                      │
├──────────────────────────────────────────────┤
│  第三层: 流节点 (Flow Node)                   │
│  每个节点是可配置的 Agent 实例                │
│  → LLMNodeAgent / ToolNodeAgent / ...        │
├──────────────────────────────────────────────┤
│  第二层: 智能体 (Agent)                       │
│  封装了 LLM + 工具 + 系统提示词的 agent       │
│  → AgentFactory.get_agent(agent_type, config) │
├──────────────────────────────────────────────┤
│  第一层: LLM 模型 (Model)                     │
│  底层大语言模型配置 (api_key, model, base_url) │
│  → config.py Settings / 模型配置面板           │
└──────────────────────────────────────────────┘

用户操作流程:新建 Agent(选定模型+提示词+工具)→ 拖入流编辑器作为节点 → 连线组装工作流 → 发布到企微


三、实施方案

P0 — 核心打通(必须完成)

P0-1: 节点 Handle 重构 — 按节点类型动态分配输入/输出端口

文件: FlowNode.vue

现状: 所有节点固定 Top=target, Bottom=source,条件节点无法双出口。

目标:

trigger:       Top(target) ←可有可无  |  Bottom(source)
llm:           Left(target)  |  Right(source)
tool:          Left(target)  |  Right(source)
mcp:           Left(target)  |  Right(source)
wecom_notify:  Left(target)  |  无出口(终节点)  OR  Bottom(source)
condition:     Left(target)  |  Right(source=true) + Bottom(source=false)
rag:           Left(target)  |  Right(source)
output:        Left(target)  |  无出口

实施方案:

  1. 为条件节点增加两个 HandlePosition.Right (id="true") 和 Position.Bottom (id="false")
  2. 为终节点(output/wecom_notify)移除 source Handle
  3. FlowEditor.vue 中 onConnect 记录 sourceHandle,条件节点时记录含 true/false 分支信息
  4. 保存时 edges 格式增加 condition 字段:{source, target, condition: "true"|"false"}

P0-2: LLM节点集成 AgentFactory — 使用真实 Agent 配置

文件: engine.py#L101-L160

现状: LLMNodeAgent.reply() 每次新建模型,忽略节点 config

实施方案:

class LLMNodeAgent(AgentBase):
    async def reply(self, msg: Msg, **kwargs) -> Msg:
        # 从节点 config 读取参数,而非硬编码
        system_prompt = self.config.get("system_prompt", "")
        model_name = self.config.get("model", settings.LLM_MODEL)
        temperature = float(self.config.get("temperature", 0.7))
        agent_id = self.config.get("agent_id", "")  # 可选:关联已有 Agent

        # 优先使用 AgentFactory 获取或创建 agent
        if agent_id:
            agent = await Agents.get_or_create(agent_id, model_name, system_prompt)
        else:
            agent = await self._create_agent(model_name, system_prompt, temperature)

        result = await agent(msg)
        return self._to_msg(result)

P0-3: 条件分支引擎 — 支持 true/false 两条路径

文件: engine.py#L277-L340 + engine.py#L45-L75

现状: 拓扑排序线性执行,无法跳过分支。

实施方案:

FlowEngine.execute() 从纯拓扑排序改为 DAG 条件遍历

async def execute(self, input_msg, context):
    nodes = self.definition["nodes"]
    edges = self.definition["edges"]

    # 构建邻接表: node_id -> [(target_id, condition)]
    graph = self._build_graph(nodes, edges)

    # 找到起始节点(入度为0的节点)
    start_nodes = self._find_start_nodes(graph)

    # BFS/DFS 带条件遍历
    result = await self._traverse(start_nodes[0], input_msg, context, graph)

    return result

async def _traverse(self, node_id, msg, context, graph):
    agent = self._get_agent(node_id)
    result = await agent.reply(msg)
    context["_node_results"][node_id] = str(result)

    # 如果是条件节点,根据判断结果选择分支
    next_nodes = graph.get(node_id, [])
    for target_id, cond in next_nodes:
        if cond is None or cond == "true":
            await self._traverse(target_id, result, context, graph)

    return result

关键: 条件节点执行后解析 condition:true|xxxcondition:false|xxx,只沿对应分支继续。

P0-4: 连线位置修复 — 使用 vue-flow 原生 Handle 机制

文件: FlowEditor.vue

现状: elements 用的是普通数组,节点自定义组件通过 id 查找,vue-flow 无法正确渲染 SVG 连线。

实施方案:

  1. 使用 useVueFlowaddNodes/addEdges API 代替手动 elements.value.push
  2. 注册 @connect 事件,让 vue-flow 原生处理连线渲染
  3. 删除 FlowEdge.vue 自定义 edge(vue-flow 内置 bezier 曲线更精准)
  4. 条件节点的两条边使用不同颜色:true=绿, false=红
const { addNodes, addEdges, onConnect: onVueConnect } = useVueFlow()

function onConnect(connection: Edge) {
  const newEdge = {
    ...connection,
    id: `edge_${connection.source}_${connection.target}`,
    type: connection.sourceHandle === 'false' ? 'smoothstep-red' : 'default',
    animated: true,
    style: connection.sourceHandle === 'false'
      ? { stroke: '#F56C6C' }
      : { stroke: '#409EFF' },
  }
  addEdges([newEdge])
}

P1 — 节点配置增强(提升灵活性)

P1-1: LLM节点 — 支持选择已有 Agent

文件: FlowEditor.vue LLM 配置区域

  • 新增 agent_id 下拉框:从后端 GET /api/agents 加载已有智能体列表
  • 选择 Agent 后自动填入 system_promptmodeltemperature
  • 不选 Agent 则手动填写(当前行为保留)

P1-2: 触发节点 — 企微 Webhook URL 配置

文件: FlowEditor.vue trigger 配置区域

  • 触发节点增加 wecom_webhook_urlevent_type 字段
  • event_type 支持:text_message / button_click / enter_chat
  • 发布流时自动注册企微回调(如果配置了 webhook)

P1-3: 节点配置持久化增强 — 支持 JSON Schema

后端 schema 变更: schemas/init.py

FlowNode.config 目前是 dict = {},改为结构化的各类型:

class LLMNodeConfig(BaseModel):
    system_prompt: str = ""
    model: str = "gpt-4o-mini"
    temperature: float = 0.7
    agent_id: str = ""

class ToolNodeConfig(BaseModel):
    tool_name: str = ""

class ConditionNodeConfig(BaseModel):
    condition: str = ""

class WeComNotifyNodeConfig(BaseModel):
    message_template: str = ""
    target: str = "@all"

class FlowNode(BaseModel):
    id: str | None = None
    type: str  # trigger/llm/tool/mcp/wecom_notify/condition/rag/output
    label: str
    config: LLMNodeConfig | ToolNodeConfig | ... = {}

P1-4: 新增 Agent 管理 API(后端)

新文件: backend/modules/agent/router.py

提供 GET/POST/PUT/DELETE /api/agents,管理可复用的 Agent:

# Agent 模型
class Agent(Base):
    __tablename__ = "agents"
    name, system_prompt, model, temperature, tools: list[str], status

这样 FlowEditor 的 LLM 节点可以通过 API 获取已有 Agent 列表。


P2 — 体验完善

P2-1: 撤销/重做 (Ctrl+Z / Ctrl+Y)

使用 vue-flow 内置的 useUndoRedo composable。

P2-2: 节点缩略图 MiniMap 增强

当前 MiniMap 已导入但不可用,改为真正的 Pane 节点缩略图。

P2-3: 流模板市场

预置 3-5 个常用工作流模板(文档处理流、企微通知流、数据分析流)。


四、文件变更清单

文件 变更类型 说明
frontend/src/views/flow/FlowNode.vue 重写 按节点类型动态 Handle
frontend/src/views/flow/FlowEdge.vue 删除 用 vue-flow 内置 edge
frontend/src/views/flow/FlowEditor.vue 重大重构 useVueFlow API、Agent选择、条件边
backend/modules/flow_engine/engine.py 重大重构 AgentFactory集成、条件DAG遍历
backend/modules/flow_engine/router.py 修改 新增agent列表查询端点
backend/modules/agent/router.py 新建 Agent CRUD API
backend/models/__init__.py 修改 新增Agent模型
backend/schemas/__init__.py 修改 新增Agent schema + FlowNode结构化config
frontend/src/api/index.ts 修改 新增agentApi
frontend/src/router/index.ts 修改 新增agent管理路由

五、实施顺序

Phase 1 (P0-1, P0-4)  →  Handle重构 + 连线修复       [前端为主]
Phase 2 (P0-3)        →  条件分支引擎                 [后端为主]
Phase 3 (P0-2, P1-1)  →  LLM节点集成AgentFactory       [前后端联动]
Phase 4 (P1-2 ~ P1-4) →  节点配置增强 + Agent管理API   [前后端联动]
Phase 5 (P2-1 ~ P2-3) →  体验完善                     [前端为主]