14 changed files with 1250 additions and 260 deletions
@ -0,0 +1,277 @@ |
|||||
|
# PLAN4 — 流编辑器深度重构:LLM→智能体→流节点→工作流 四层架构 |
||||
|
|
||||
|
## 一、问题诊断 |
||||
|
|
||||
|
### 当前架构痛点(逐一定位代码行级别) |
||||
|
|
||||
|
| # | 问题 | 根因位置 | 影响 | |
||||
|
|---|------|----------|------| |
||||
|
| 1 | **LLM/智能体与节点未打通** | [engine.py#L101-L118](file:///c:/Users/刘泽明/Documents/Git/hg-agents/backend/modules/flow_engine/engine.py#L101-L118) `LLMNodeAgent` 每次硬编码新建 `OpenAIChatModel`,忽略节点配置中 `model`/`temperature`/`system_prompt` | 节点的LLM配置表单完全无效 | |
||||
|
| 2 | **节点只有壳,无法配置** | [FlowNode.vue](file:///c:/Users/刘泽明/Documents/Git/hg-agents/frontend/src/views/flow/FlowNode.vue) 固定 Top/Bottom Handle,条件节点只有一个出口 | 条件分支无法区分 true/false | |
||||
|
| 3 | **连线位置漂移** | [FlowEdge.vue](file:///c:/Users/刘泽明/Documents/Git/hg-agents/frontend/src/views/flow/FlowEdge.vue) 自定义 SVG path + 没有绑定 vue-flow edge marker | 线条起点/终点不精准 | |
||||
|
| 4 | **条件分支不可控** | [engine.py#L277-L293](file:///c:/Users/刘泽明/Documents/Git/hg-agents/backend/modules/flow_engine/engine.py#L277-L293) `ConditionNodeAgent` 只返回固定字符串 + 拓扑排序不支持跳过 | 即使 LLM 判断了真假,引擎也不会分支 | |
||||
|
| 5 | **触发节点无实际参数** | FlowEditor 触发节点只有标签,无企微回调 URL / webhook 配置 | 无法真正接入企微触发 | |
||||
|
| 6 | **AgentFactory 未集成** | [engine.py](file:///c:/Users/刘泽明/Documents/Git/hg-agents/backend/modules/flow_engine/engine.py) 从未调用 [factory.py](file:///c:/Users/刘泽明/Documents/Git/hg-agents/backend/agentscope_integration/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](file:///c:/Users/刘泽明/Documents/Git/hg-agents/frontend/src/views/flow/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. 为条件节点增加两个 `Handle`:`Position.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](file:///c:/Users/刘泽明/Documents/Git/hg-agents/backend/modules/flow_engine/engine.py#L101-L160) |
||||
|
|
||||
|
**现状**: `LLMNodeAgent.reply()` 每次新建模型,忽略节点 `config`。 |
||||
|
|
||||
|
**实施方案**: |
||||
|
```python |
||||
|
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](file:///c:/Users/刘泽明/Documents/Git/hg-agents/backend/modules/flow_engine/engine.py#L277-L340) + [engine.py#L45-L75](file:///c:/Users/刘泽明/Documents/Git/hg-agents/backend/modules/flow_engine/engine.py#L45-L75) |
||||
|
|
||||
|
**现状**: 拓扑排序线性执行,无法跳过分支。 |
||||
|
|
||||
|
**实施方案**: |
||||
|
|
||||
|
将 `FlowEngine.execute()` 从纯拓扑排序改为 **DAG 条件遍历**: |
||||
|
|
||||
|
```python |
||||
|
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|xxx` 或 `condition:false|xxx`,只沿对应分支继续。 |
||||
|
|
||||
|
#### P0-4: 连线位置修复 — 使用 vue-flow 原生 Handle 机制 |
||||
|
|
||||
|
**文件**: [FlowEditor.vue](file:///c:/Users/刘泽明/Documents/Git/hg-agents/frontend/src/views/flow/FlowEditor.vue#L247-L268) |
||||
|
|
||||
|
**现状**: `elements` 用的是普通数组,节点自定义组件通过 `id` 查找,vue-flow 无法正确渲染 SVG 连线。 |
||||
|
|
||||
|
**实施方案**: |
||||
|
1. 使用 `useVueFlow` 的 `addNodes`/`addEdges` API 代替手动 `elements.value.push` |
||||
|
2. 注册 `@connect` 事件,让 vue-flow 原生处理连线渲染 |
||||
|
3. 删除 [FlowEdge.vue](file:///c:/Users/刘泽明/Documents/Git/hg-agents/frontend/src/views/flow/FlowEdge.vue) 自定义 edge(vue-flow 内置 bezier 曲线更精准) |
||||
|
4. 条件节点的两条边使用不同颜色:true=绿, false=红 |
||||
|
|
||||
|
```typescript |
||||
|
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_prompt`、`model`、`temperature` |
||||
|
- 不选 Agent 则手动填写(当前行为保留) |
||||
|
|
||||
|
#### P1-2: 触发节点 — 企微 Webhook URL 配置 |
||||
|
|
||||
|
**文件**: FlowEditor.vue trigger 配置区域 |
||||
|
|
||||
|
- 触发节点增加 `wecom_webhook_url` 和 `event_type` 字段 |
||||
|
- `event_type` 支持:`text_message` / `button_click` / `enter_chat` |
||||
|
- 发布流时自动注册企微回调(如果配置了 webhook) |
||||
|
|
||||
|
#### P1-3: 节点配置持久化增强 — 支持 JSON Schema |
||||
|
|
||||
|
**后端 schema 变更**: [schemas/__init__.py](file:///c:/Users/刘泽明/Documents/Git/hg-agents/backend/schemas/__init__.py#L179-L181) |
||||
|
|
||||
|
`FlowNode.config` 目前是 `dict = {}`,改为结构化的各类型: |
||||
|
|
||||
|
```python |
||||
|
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: |
||||
|
|
||||
|
```python |
||||
|
# 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) → 体验完善 [前端为主] |
||||
|
``` |
||||
@ -1,29 +0,0 @@ |
|||||
<template> |
|
||||
<path |
|
||||
:d="`M0,0 C${offset},0 ${targetX - sourceX - offset},${targetY - sourceY} ${targetX - sourceX},${targetY - sourceY}`" |
|
||||
class="flow-edge-path" |
|
||||
/> |
|
||||
</template> |
|
||||
|
|
||||
<script setup lang="ts"> |
|
||||
import { computed } from 'vue' |
|
||||
|
|
||||
const props = defineProps<{ |
|
||||
id: string |
|
||||
sourceX: number |
|
||||
sourceY: number |
|
||||
targetX: number |
|
||||
targetY: number |
|
||||
}>() |
|
||||
|
|
||||
const offset = computed(() => Math.abs(props.targetX - props.sourceX) * 0.5) |
|
||||
</script> |
|
||||
|
|
||||
<style scoped> |
|
||||
.flow-edge-path { |
|
||||
fill: none; |
|
||||
stroke: #b1b1b7; |
|
||||
stroke-width: 2; |
|
||||
stroke-linecap: round; |
|
||||
} |
|
||||
</style> |
|
||||
@ -0,0 +1,123 @@ |
|||||
|
|
||||
|
基于 AgentScope 搭建一个无代码(No-Code)的大模型智能体工作流平台是一个非常具有商业价值和技术深度的方向。你提出的 “LLM -> 智能体(Agent) -> 流节点(Node) -> 工作流(Workflow)” 逐层递进的架构逻辑非常清晰,完全契合目前主流的 AI 编排平台(如 Coze, Dify, FastGPT)的设计哲学。 |
||||
|
AgentScope 本身自带了 Msg(消息传递)、Agent(智能体封装)和 Pipeline(流程控制)的底层抽象,这为你做上层无代码可视化封装提供了极好的基础。 |
||||
|
以下我为你设计的系统大纲以及具体实现的落地思路: |
||||
|
第一部分:核心概念映射设计(架构分层) |
||||
|
在你的无代码平台中,这四层架构如何与前端 UI 和后端的 AgentScope 对应: |
||||
|
层级 平台抽象概念 (UI 展示) AgentScope 底层映射 作用描述 |
||||
|
1. LLM 模型配置中心 (选择模型、填 API Key) ModelWrapper (模型配置) 提供纯粹的推理能力,相当于大脑的神经元。 |
||||
|
2. 智能体 Agent 调试面板 (人设、提示词、工具箱、知识库) AgentBase (如 DialogAgent, ReActAgent) 赋予 LLM 具体的人格、记忆和执行动作的能力(大脑+手脚)。 |
||||
|
3. 流节点 画布上的单个卡片 (输入参数、执行逻辑、输出变量) 自定义的 Node Wrapper 或 Pipeline 原子件 将 Agent 包装成流水线上的一个工位,规定好它的标准输入和输出格式。 |
||||
|
4. 工作流 拖拽连线构成的有向无环图 (DAG) Pipeline (如 Sequential, IfElse, Switch) 编排全局逻辑,决定数据流的走向,协调多个 Agent 协作。 |
||||
|
第二部分:平台系统大纲设计 |
||||
|
1. 前端架构 (可视化画布) |
||||
|
技术栈: React / Vue3 + React Flow / Vue Flow (核心拓扑图库) |
||||
|
核心模块: |
||||
|
节点组件库 (Node Panel): 包含触发器节点、Agent 节点、逻辑节点(条件分支、循环)、工具节点(HTTP 请求、代码执行)、结束节点。 |
||||
|
画布区 (Canvas): 拖拽连线,支持缩放、对齐、自动布局。 |
||||
|
配置面板 (Property Panel): 点击节点后,右侧弹出详细配置(如给 Agent 节点选定某个 LLM,配置 Prompt 和连线变量映射)。 |
||||
|
调试终端 (Debug Panel): 实时查看工作流的执行日志和 Agent 对话过程。 |
||||
|
2. 后端架构 (业务与 API 层) |
||||
|
技术栈: Python + FastAPI + PostgreSQL + Redis |
||||
|
核心模块: |
||||
|
资产管理: 管理用户的 API Keys、Prompts、工具定义(Tools)、知识库(RAG 向量存储)。 |
||||
|
蓝图管理: 接收前端发来的 JSON DAG(有向无环图),保存为工作流草稿或发布版本。 |
||||
|
调度 API: 触发工作流执行的接口(支持同步返回或 SSE 流式输出)。 |
||||
|
3. 核心执行引擎 (Workflow Engine based on AgentScope) |
||||
|
解析器 (Graph Parser): 将前端的 JSON 拓扑图解析为执行图。 |
||||
|
封装器 (AgentScope Builder): 动态实例化 AgentScope 的 Model, Agent 和 Pipeline。 |
||||
|
运行时 (Runtime): 维护运行时的上下文(Context / Memory),捕获 AgentScope 生成的 Msg,并通过 WebSocket/SSE 推送给前端。 |
||||
|
第三部分:具体怎么实现好?(核心实现思路) |
||||
|
要将前端连线变成 AgentScope 的代码执行,关键在于**“图的解析与执行”**。以下是具体的落地步骤: |
||||
|
步骤 1:定义标准化的 JSON 数据结构 |
||||
|
前端的 React Flow 导出的图结构必须规范化,这是前后端沟通的桥梁。 |
||||
|
code |
||||
|
JSON |
||||
|
{ |
||||
|
"workflow_id": "wf_001", |
||||
|
"nodes": [ |
||||
|
{ |
||||
|
"id": "node_start", |
||||
|
"type": "StartNode", |
||||
|
"data": { "input_schema": ["user_query"] } |
||||
|
}, |
||||
|
{ |
||||
|
"id": "node_agent_1", |
||||
|
"type": "AgentNode", |
||||
|
"data": { |
||||
|
"agent_name": "内容规划师", |
||||
|
"llm_config": "gpt-4o-config", |
||||
|
"sys_prompt": "你是一个规划师,根据用户的 {{user_query}} 生成大纲。", |
||||
|
"memory_type": "default" |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
"id": "node_end", |
||||
|
"type": "EndNode" |
||||
|
} |
||||
|
], |
||||
|
"edges": [ |
||||
|
{ "source": "node_start", "target": "node_agent_1" }, |
||||
|
{ "source": "node_agent_1", "target": "node_end" } |
||||
|
] |
||||
|
} |
||||
|
步骤 2:在后端实现 Node 到 AgentScope 的映射 |
||||
|
在 Python 后端,你需要写一个引擎来解析上面的 JSON。AgentScope 提供了灵活的机制。 |
||||
|
实现思路A:静态生成法(推荐用于初期) |
||||
|
将前端 JSON 翻译成一段标准的 Python 脚本(利用 Jinja2 模板),然后在沙箱环境中 subprocess 运行它。这种方式最简单,调试也方便。 |
||||
|
实现思路B:动态执行法(推荐用于生产,更易于流式反馈) |
||||
|
在内存中动态构建 AgentScope 对象,并利用拓扑排序执行。 |
||||
|
你可以自己写一个 DAG 执行器,把 AgentScope 的 Agent 包装在你的节点类中: |
||||
|
code |
||||
|
Python |
||||
|
import agentscope |
||||
|
from agentscope.agents import DialogAgent |
||||
|
from agentscope.message import Msg |
||||
|
|
||||
|
class AgentNodeWrapper: |
||||
|
def __init__(self, node_config): |
||||
|
self.config = node_config |
||||
|
# 1. 动态初始化模型配置 |
||||
|
agentscope.init(model_configs=[self.config['llm_config']]) |
||||
|
|
||||
|
# 2. 动态实例化 AgentScope 的 Agent |
||||
|
self.agent = DialogAgent( |
||||
|
name=self.config['agent_name'], |
||||
|
sys_prompt=self.config['sys_prompt'], |
||||
|
model_config_name=self.config['llm_config']['config_name'] |
||||
|
) |
||||
|
|
||||
|
def execute(self, input_context): |
||||
|
# input_context 是上一级节点传来的字典或 Msg |
||||
|
# 3. 变量替换:将 prompt 里的 {{xxx}} 替换为 input_context 里的真实值 |
||||
|
prompt = self.render_prompt(self.config['sys_prompt'], input_context) |
||||
|
|
||||
|
# 4. 封装为 AgentScope 的 Msg |
||||
|
msg = Msg(name="System", role="user", content=prompt) |
||||
|
|
||||
|
# 5. 调用 AgentScope 的核心执行方法 |
||||
|
response = self.agent(msg) |
||||
|
|
||||
|
# 6. 返回结果给下一个节点 |
||||
|
return response.content |
||||
|
步骤 3:利用 AgentScope 的 Pipeline 处理复杂路由 |
||||
|
AgentScope 原生提供了 SequentialPipeline, IfElsePipeline, SwitchPipeline, ForLoopPipeline。 |
||||
|
当解析 JSON 时发现有条件分支: |
||||
|
前端是一个 "If/Else 节点"。 |
||||
|
后端将其翻译为 AgentScope 的 IfElsePipeline。将该节点前置 Agent 的输出作为 condition 判定函数,走入不同的下一级 Agent 链路。 |
||||
|
步骤 4:上下文与数据流 (Data Flow) 管理 |
||||
|
工作流最难的是数据穿透(比如节点 C 需要用到节点 A 的输出)。 |
||||
|
解决方案: 引入一个全局的 WorkflowContext 对象(类似一个字典 dict)。 |
||||
|
每个节点执行完毕后,将它的输出写入 Context[node_id_output] = result。 |
||||
|
下级节点在执行前,根据连线规则,从 Context 中提取所需的变量,拼接到当前 Agent 的输入 Msg 中。 |
||||
|
第四部分:开发推进建议(MVP 最小可行性产品) |
||||
|
不要一开始就做大而全,建议按以下 3 个迭代阶段推进: |
||||
|
Phase 1 (验证期): 线性工作流。 |
||||
|
只做一条直线的连线:开始 -> Agent A -> Agent B -> 结束。 |
||||
|
打通前端 React Flow 连线 -> 后端解析 -> AgentScope SequentialPipeline 执行 -> 打印日志。 |
||||
|
Phase 2 (进阶期): 引入分支与工具。 |
||||
|
增加 If/Else 节点(底层映射 AgentScope 的 IfElsePipeline)。 |
||||
|
给 Agent 节点增加 Tools 配置面板,利用 AgentScope 自带的工具(WebSearch, Python执行等),构建 ReAct Agent 节点。 |
||||
|
Phase 3 (体验期): 完善流式响应与记忆。 |
||||
|
将后端的执行过程通过 Server-Sent Events (SSE) 实时推送前端,实现打字机效果。 |
||||
|
接入 AgentScope 的 Memory 管理模块,实现多轮对话状态下的工作流触发。 |
||||
Loading…
Reference in new issue