---
name: workflow-guide
description: 工作流与多步任务指南。当用户说"创建工作流"、"多步任务"、"自动化流程"时立即调用。
allowed-tools: execute_workflow,reloadWorkflows
---

# 工作流（Workflow）开发指南

## 概述

工作流引擎用于处理多步骤任务，通过 `execute_workflow` 工具执行。工作流由多个步骤组成，支持脚本、条件分支、循环、延时、工具调用等类型。

## 工作流存放位置

```
项目目录/
└── .agent/
    └── workflows/           # 工作流定义目录
        └── my-workflow.json  # 工作流 JSON 定义
        └── another.js         # 或 JS 文件（导出 default 工作流）
```

## 自动加载与注册

将工作流文件放入 `.agent/workflows/` 目录后，系统会自动：

1. 加载所有 `.json` 和 `.js` 文件
2. 将工作流注册为 `workflow_<文件名>` 工具

例如 `my-workflow.json` 会注册为 `workflow_my_workflow` 工具，可直接调用。

## 重载工作流

创建或修改工作流后，调用 `reloadWorkflows` 重载：

```json
{
  "tool": "reloadWorkflows",
  "args": {}
}
```

## 使用方式

### 方式一：直接执行（任意工作流）

```json
{
  "tool": "execute_workflow",
  "args": {
    "workflow": "my-workflow", // 工作流名称（自动从 .agent/workflows/ 加载）
    "input": { "变量名": "值" }
  }
}
```

### 方式二：执行已注册的工作流工具

```json
{
  "tool": "workflow_my_workflow",
  "args": {
    "input": { "变量名": "值" }
  }
}
```

## 重要注意事项

1. **script 必须用 return 返回值**：`script` 是函数体，不是表达式
2. **JSON 中不能使用多行字符串**：所有 script 内容写成单行，用分号分隔
3. **JSON 中不能有注释**：注释会导致 JSON 解析失败

## 工作流步骤类型

### 支持的步骤类型

| 类型         | 说明            | 自动推断                                    |
| ------------ | --------------- | ------------------------------------------- |
| `tool`       | 工具调用        | 有 `tool` 字段                              |
| `script`     | JavaScript 脚本 | 有 `code` 或 `script` 字段                  |
| `condition`  | 条件分支        | 有 `branches` 字段                          |
| `switch`     | 开关分支        | 有 `value` + `branches`                     |
| `try`        | 异常捕获        | 有 `try` 或 `catch` 字段                    |
| `parallel`   | 并行执行        | `"parallel": true` 或 `"mode": "parallel"`  |
| `sequential` | 顺序执行        | 有 `steps` 字段                             |
| `loop`       | 循环执行        | 有 `steps` + `loopVariable`/`maxIterations` |
| `delay`      | 延时等待        | 有 `delayMs` 字段                           |
| `workflow`   | 嵌套工作流      | 有 `workflow` 字段                          |
| `message`    | 发送消息        | 有 `message` 字段                           |
| `think`      | 主动思考        | 有 `topic` 字段                             |

### 1. script - 脚本步骤

执行 JavaScript 脚本，**必须用 return 返回值**：

```json
{
  "type": "script",
  "name": "步骤名称",
  "outputVariable": "result",
  "script": "var x=10; context.variables.count=x+1; return context.variables.count;"
}
```

**正确写法**：

```json
{ "script": "return context.variables.value + 1;" }
```

**错误写法**（缺少 return）：

```json
{ "script": "context.variables.value + 1;" }
```

- `outputVariable`: 可选，将返回值存入 `context.variables`
- `context.variables`: 所有步骤共享的变量对象
- `context.lastResult`: 上一步的输出结果

### 2. tool - 工具调用步骤

在工作流中调用框架注册的工具：

```json
{
  "type": "tool",
  "name": "发送通知",
  "tool": "notification_send",
  "args": {
    "title": "标题",
    "message": "内容"
  },
  "outputVariable": "result"
}
```

**参数说明**：

| 字段             | 类型   | 必填 | 说明               |
| ---------------- | ------ | ---- | ------------------ |
| `tool`           | string | 是   | 工具名称           |
| `args`           | object | 否   | 工具参数           |
| `outputVariable` | string | 否   | 结果保存到的变量名 |

**args 中支持变量引用**：

使用 `{{variableName}}` 语法引用 context.variables 中的变量：

```json
{
  "type": "tool",
  "name": "发送通知",
  "tool": "notification_send",
  "args": {
    "title": "IP 信息",
    "message": "当前公网IP: {{currentIp}}"
  }
}
```

**重要：使用 `{{result}}` 引用上一步结果（推荐）**

上一步骤的结果自动保存在 `{{result}}` 中，可以直接提取字段：

```json
{
  "type": "tool",
  "name": "获取IP",
  "tool": "fetch",
  "args": {
    "url": "https://api.ipify.org?format=json"
  }
},
{
  "type": "tool",
  "name": "发送通知",
  "tool": "notification_send",
  "args": {
    "title": "IP 信息",
    "message": "当前公网IP: {{result.body.ip}}"
  }
}
```

支持的引用格式：

| 格式                           | 说明                       |
| ------------------------------ | -------------------------- |
| `{{result}}`                   | 上一步完整结果             |
| `{{result.body}}`              | 提取 body 字段             |
| `{{result.body.ip}}`           | 从 body 提取嵌套字段       |
| `{{result.body.data[0].name}}` | 支持数组索引               |
| `{{lastResult}}`               | result 的别名              |
| `{{lastResult.error}}`         | 从错误对象提取信息         |
| `{{variables.xxx}}`            | 显式引用 context.variables |
| `{{input.xxx}}`                | 引用工作流输入参数         |

**自动 JSON 解析**：如果字段值是 JSON 字符串，会自动解析为对象后再提取嵌套字段。

### 3. loop - 循环步骤

重复执行一组步骤：

```json
{
  "type": "loop",
  "name": "循环3次",
  "maxIterations": 3,
  "loopVariable": "i",
  "steps": [{ "type": "script", "name": "执行内容", "script": "..." }]
}
```

- `maxIterations`: 最大迭代次数
- `loopVariable`: 循环计数器变量名（从 0 开始）

### 4. condition - 条件分支

根据条件选择执行分支：

```json
{
  "type": "condition",
  "name": "判断条件",
  "branches": [
    {
      "name": "条件1",
      "condition": "context.variables.value > 10",
      "steps": [...]
    },
    {
      "name": "条件2",
      "condition": "context.variables.value <= 10",
      "steps": [...]
    }
  ]
}
```

### 5. switch - 开关分支

根据值匹配执行对应分支（类似编程语言的 switch-case）：

```json
{
  "type": "switch",
  "value": "{{status}}",
  "branches": [
    { "case": "success", "steps": [...] },
    { "case": "error", "steps": [...] },
    { "case": "pending", "steps": [...] }
  ],
  "default": { "steps": [...] }
}
```

- `value`: 要匹配的值，支持 `{{variable}}` 引用
- `branches`: 分支数组，匹配第一个 `case` 等于 `value` 的分支
- `default`: 默认分支（可选）

### 6. try - 异常捕获

尝试执行，失败时执行 catch 分支：

```json
{
  "type": "try",
  "name": "尝试执行",
  "try": {
    "steps": [
      { "type": "tool", "tool": "可能失败的工具", "args": {...} }
    ]
  },
  "catch": {
    "steps": [
      { "type": "tool", "tool": "notification_send", "args": {"message": "执行失败: {{lastError}}"} }
    ]
  }
}
```

- `try`: 尝试执行的步骤
- `catch`: 捕获异常后执行的步骤

### 7. parallel - 并行执行

多个步骤同时并行执行：

```json
{
  "type": "parallel",
  "name": "并行获取数据",
  "steps": [
    { "type": "tool", "tool": "fetch", "args": { "url": "https://api1.com" }, "output": "data1" },
    { "type": "tool", "tool": "fetch", "args": { "url": "https://api2.com" }, "output": "data2" },
    { "type": "tool", "tool": "fetch", "args": { "url": "https://api3.com" }, "output": "data3" }
  ]
}
```

返回数组形式的执行结果。

### 8. workflow - 嵌套工作流

在一个工作流中调用另一个工作流：

```json
{
  "type": "workflow",
  "name": "调用子工作流",
  "workflow": {
    "name": "子工作流名称",
    "steps": [...]
  },
  "input": {
    "param1": "{{parentVar}}"
  }
}
```

子工作流的输出会合并到父工作流的上下文变量中。

### 9. delay - 延时步骤

等待指定毫秒数：

```json
{
  "type": "delay",
  "name": "等待1秒",
  "delayMs": 1000
}
```

### 10. sequential - 顺序步骤

将多个步骤组合为顺序执行（可嵌套使用）：

```json
{
  "type": "sequential",
  "name": "顺序执行",
  "steps": [
    { "type": "script", "name": "步骤1", "script": "return 1;" },
    { "type": "script", "name": "步骤2", "script": "return 2;" }
  ]
}
```

## sessionId 传递

工作流执行时会自动获取当前 sessionId，所有 tool 调用都会使用该 sessionId，确保通知发送到当前会话。

## 完整示例

### 示例：获取IP并发送通知

**推荐写法**（使用 `{{result}}` 直接引用上一步结果）：

```json
{
  "name": "get-ip-notify",
  "description": "获取本机IP并发送通知",
  "steps": [
    {
      "type": "tool",
      "name": "获取IP信息",
      "tool": "fetch",
      "args": {
        "url": "https://api.ipify.org?format=json",
        "proxy": true
      }
    },
    {
      "type": "tool",
      "name": "发送通知",
      "tool": "notification_send",
      "args": {
        "title": "IP 信息",
        "message": "当前公网IP: {{result.body.ip}}"
      }
    }
  ]
}
```

**旧写法**（仍支持，但不推荐）：

```json
{
  "name": "get-ip-notify-old",
  "steps": [
    {
      "type": "tool",
      "tool": "fetch",
      "args": { "url": "https://api.ipify.org?format=json" },
      "outputVariable": "ipResult"
    },
    {
      "type": "script",
      "outputVariable": "currentIp",
      "script": "var r=context.variables.ipResult; return (r&&r.success&&r.body)?(typeof r.body==='object'?r.body.ip:r.body.trim()):'获取失败';"
    },
    {
      "type": "tool",
      "tool": "notification_send",
      "args": { "message": "当前公网IP: {{currentIp}}" }
    }
  ]
}
```

### 示例：循环处理任务列表

```json
{
  "name": "process-items",
  "description": "循环处理列表中的每个项目",
  "steps": [
    {
      "type": "script",
      "name": "初始化列表",
      "outputVariable": "items",
      "script": "context.variables.items=['任务A','任务B','任务C']; return context.variables.items;"
    },
    {
      "type": "loop",
      "name": "处理每个任务",
      "maxIterations": 3,
      "loopVariable": "i",
      "steps": [
        {
          "type": "script",
          "name": "处理任务",
          "outputVariable": "processed",
          "script": "var item=context.variables.items[context.variables.i]; context.variables.processed=(context.variables.processed||[]); context.variables.processed.push(item+'_完成'); return item;"
        }
      ]
    }
  ]
}
```

### 示例：并行获取多个数据源

```json
{
  "name": "multi-source-fetch",
  "description": "并行获取多个数据源",
  "steps": [
    {
      "type": "parallel",
      "name": "并行获取数据",
      "steps": [
        {
          "type": "tool",
          "tool": "fetch",
          "args": { "url": "https://api.baidu.com" },
          "output": "baiduData"
        },
        {
          "type": "tool",
          "tool": "fetch",
          "args": { "url": "https://api.bbc.com" },
          "output": "bbcData"
        },
        {
          "type": "tool",
          "tool": "fetch",
          "args": { "url": "https://api.reddit.com" },
          "output": "redditData"
        }
      ]
    },
    {
      "type": "tool",
      "tool": "notification_send",
      "args": {
        "message": "数据获取完成: 百度 {{result[0].length}} 字节, BBC {{result[1].length}} 字节"
      }
    }
  ]
}
```

### 示例：try-catch 异常处理

```json
{
  "name": "safe-execute",
  "description": "带异常处理的工作流",
  "steps": [
    {
      "type": "try",
      "name": "尝试执行",
      "try": {
        "steps": [
          { "type": "tool", "tool": "fetch", "args": { "url": "https://可能失败的api.com" } }
        ]
      },
      "catch": {
        "steps": [
          {
            "type": "script",
            "outputVariable": "errorMsg",
            "script": "return 'API 调用失败，使用备用数据';"
          }
        ]
      }
    },
    {
      "type": "tool",
      "tool": "notification_send",
      "args": {
        "message": "结果: {{result.result || result.error}}"
      }
    }
  ]
}
```

### 示例：switch 分支处理

```json
{
  "name": "status-handler",
  "description": "根据状态分发处理",
  "steps": [
    {
      "type": "script",
      "outputVariable": "status",
      "script": "return 'success';"
    },
    {
      "type": "switch",
      "value": "{{status}}",
      "branches": [
        {
          "case": "success",
          "steps": [
            { "type": "tool", "tool": "notification_send", "args": { "message": "操作成功" } }
          ]
        },
        {
          "case": "error",
          "steps": [
            { "type": "tool", "tool": "notification_send", "args": { "message": "操作失败" } }
          ]
        },
        {
          "case": "pending",
          "steps": [
            { "type": "tool", "tool": "notification_send", "args": { "message": "操作进行中" } }
          ]
        }
      ],
      "default": {
        "steps": [
          { "type": "tool", "tool": "notification_send", "args": { "message": "未知状态" } }
        ]
      }
    }
  ]
}
```

## 注意事项

1. **优先使用 `{{result}}` 引用**：上一步结果直接用 `{{result.field}}` 提取，比 script 更简洁
2. **script 必须 return**：`script` 是函数体，必须用 return 返回值
3. **JSON 中 script 单行写**：用分号分隔多个语句，不要换行
4. **JSON 中不能有注释**：注释会导致 JSON 解析失败
5. **context.variables** 在所有步骤间共享，可存储中间结果
6. **context.input** 是工作流的输入参数
7. 循环变量 `i` 从 0 开始计数
8. 条件分支的 `condition` 是 JavaScript 表达式字符串
9. **自动 JSON 解析**：`{{result.body}}` 如果是 JSON 字符串会自动解析
10. **类型自动推断**：如果步骤没有指定 `type`，会根据字段自动推断类型
11. **`${stepId.output}` 引用**：可引用指定 id 步骤的输出（兼容旧格式）
12. **`input` 字段**：可传递上一步输出给工具（兼容旧格式）
13. **try-catch 异常处理**：使用 try 包裹可能失败的步骤，catch 捕获错误

## 最佳实践

1. 为每个步骤设置有意义的 `name`
2. 使用 `outputVariable` 保存需要跨步骤共享的数据
3. 循环前确保有合理的 `maxIterations` 限制
4. 条件分支要有兜底的 `condition: "true"` 分支
5. 复杂的业务逻辑优先使用脚本步骤
6. **script 必须 return**：`script` 是函数体，必须用 return 返回值
7. **JSON 中 script 单行写**：用分号分隔多个语句，不要换行
8. **并行获取独立数据**：使用 `parallel` 同时获取多个数据源，节省时间
9. **使用 try-catch**：对可能失败的步骤使用异常捕获，避免整个工作流中断
10. **嵌套工作流**：将复杂工作流拆分为子工作流，提高复用性和可维护性

**错误示例**：

```json
// ❌ 错误 - script 没有 return
{ "type": "script", "script": "context.variables.count + 1;" }

// ❌ 错误 - JSON 多行字符串
{
  "script": "
    const a = 10;
    return a + 1;
  "
}

// ❌ 错误 - JSON 中有注释
{
  "script": "return 1; // 这是注释"
}

// ❌ 错误 - switch 缺少 default 兜底
{
  "type": "switch",
  "value": "{{status}}",
  "branches": [
    { "case": "success", "steps": [...] }
  ]
  // 没有 default 分支，匹配不到会静默忽略
}
```

**正确示例**：

```json
// ✅ 正确
{ "type": "script", "outputVariable": "count", "script": "return (context.variables.count||0) + 1;" }

// ✅ 正确 - 复杂逻辑拆成多步
{ "type": "script", "script": "context.variables.a=10; context.variables.b=20; return context.variables.a+context.variables.b;" }

// ✅ 正确 - switch 有 default 兜底
{
  "type": "switch",
  "value": "{{status}}",
  "branches": [
    { "case": "success", "steps": [...] }
  ],
  "default": { "steps": [{ "type": "tool", "tool": "notification_send", "args": {"message": "未知状态"} }] }
}
```
