ChatDev/docs/user_guide/zh/dynamic_execution.md
2026-01-07 16:24:01 +08:00

277 lines
7.4 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Dynamic 执行模式指南
Dynamic 执行模式允许在边级别定义并行处理行为,支持 Map扇出和 Tree扇出+归约)两种模式。当消息通过配置了 `dynamic` 的边传递时,目标节点会根据拆分结果动态扩展为多个并行实例。
## 1. 概述
| 模式 | 描述 | 输出 | 适用场景 |
|------|------|------|----------|
| **Map** | 扇出执行,将消息拆分为多个单元并行处理 | `List[Message]`(打平结果) | 批量处理、并行查询 |
| **Tree** | 扇出+归约,并行处理后按组递归合并 | 单个 `Message` | 长文本摘要、层级聚合 |
## 2. 配置结构
Dynamic 配置定义在**边**上,而非节点:
```yaml
edges:
- from: Source Node
to: Target Node
trigger: true
carry_data: true
dynamic: # 边级动态执行配置
type: map # map 或 tree
split: # 消息拆分策略
type: message # message | regex | json_path
# pattern: "..." # regex 模式必填
# json_path: "..." # json_path 模式必填
config: # 模式特定配置
max_parallel: 5 # 最大并发数
```
### 2.1 核心概念
- **动态边**:配置了 `dynamic` 的边,其传递的消息会触发目标节点的动态扩展
- **静态边**:未配置 `dynamic` 的边,其传递的消息会**复制**到所有动态扩展实例
- **目标节点扩展**:目标节点根据 split 结果被"虚拟"扩展为多个并行实例
### 2.2 多入边一致性规则
> [!IMPORTANT]
> 当一个节点有多条入边配置了 `dynamic` 时,所有动态边的配置**必须完全一致**type、split、config否则执行时会报错。
## 3. Split 拆分策略
Split 定义如何将通过边的消息拆分为并行执行单元。
### 3.1 message 模式(默认)
每条通过边的消息作为独立执行单元。这是最常用的模式。
```yaml
split:
type: message
```
**执行行为**
- 源节点输出 4 条消息通过动态边
- 拆分为 4 个并行单元,目标节点执行 4 次
### 3.2 regex 模式
使用正则表达式从文本内容中提取匹配项。
```yaml
split:
type: regex
pattern: "(?s).{1,2000}(?:\\s|$)" # 每 2000 字符切分
```
**典型用例**
- 按段落拆分:`pattern: "\\n\\n"`
- 按行拆分:`pattern: ".+"`
- 按固定长度:`pattern: "(?s).{1,N}"`
### 3.3 json_path 模式
从 JSON 格式输出中按路径提取数组元素。
```yaml
split:
type: json_path
json_path: "$.items[*]" # JSONPath 表达式
```
## 4. Map 模式详解
Map 模式将消息拆分后并行执行目标节点,输出结果打平为 `List[Message]`
### 4.1 配置项
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `max_parallel` | int | 10 | 最大并发执行数 |
### 4.2 执行流程
```mermaid
flowchart LR
Source["源节点输出"] --> Edge["动态边 (map)"]
Edge --> Split["拆分"]
Split --> U1["单元 1"]
Split --> U2["单元 2"]
Split --> U3["单元 N"]
U1 --> P1["目标节点 #1"]
U2 --> P2["目标节点 #2"]
U3 --> P3["目标节点 #N"]
P1 --> Merge["合并结果"]
P2 --> Merge
P3 --> Merge
Merge --> Output["List[Message]"]
```
## 5. Tree 模式详解
Tree 模式在 Map 基础上增加归约层,将并行结果按组递归合并,最终输出单个结果。
### 5.1 配置项
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `group_size` | int | 3 | 每组归约的元素数量,最小为 2 |
| `max_parallel` | int | 10 | 每层最大并发执行数 |
### 5.2 执行流程
```mermaid
flowchart TB
subgraph Layer1["第一层:并行执行"]
I1["单元 1"] --> R1["结果 1"]
I2["单元 2"] --> R2["结果 2"]
I3["单元 3"] --> R3["结果 3"]
I4["单元 4"] --> R4["结果 4"]
I5["单元 5"] --> R5["结果 5"]
I6["单元 6"] --> R6["结果 6"]
end
subgraph Layer2["第二层:分组归约 (group_size=3)"]
R1 & R2 & R3 --> G1["归约组 1"]
R4 & R5 & R6 --> G2["归约组 2"]
end
subgraph Layer3["第三层:最终归约"]
G1 & G2 --> Final["最终结果"]
end
```
## 6. 静态边消息复制
当目标节点同时有动态入边和静态入边时:
- **动态边消息**:按 split 策略拆分,每个单元执行一次目标节点
- **静态边消息****复制**到每个动态扩展实例
```yaml
nodes:
- id: Task Generator
type: passthrough
config: ...
- id: Extra Requirement
type: literal
config:
content: "请使用简洁的语言"
- id: Processor
type: agent
config:
name: gpt-4o
role: 处理任务
edges:
- from: Task Generator
to: Processor
dynamic: # 动态边4 条任务 → 4 个并行单元
type: map
split:
type: message
config:
max_parallel: 10
- from: Extra Requirement
to: Processor # 静态边:复制到所有 4 个实例
trigger: true
carry_data: true
```
**执行结果**Processor 执行 4 次,每次收到 1 条任务 + "请使用简洁的语言"
## 7. 完整示例
### 7.1 旅行规划Map + Tree 组合)
```yaml
graph:
nodes:
- id: Eat Planner
type: literal
config:
content: 请规划在上海吃什么
role: user
- id: Play Planner
type: literal
config:
content: 请规划在上海玩什么
role: user
- id: Stay Planner
type: literal
config:
content: 请规划在上海住哪里
role: user
- id: Collector
type: passthrough
config:
only_last_message: false
- id: Travel Executor
type: agent
config:
name: gpt-4o
role: 你是旅行规划师,请按照用户请求进行规划
- id: Final Aggregator
type: agent
config:
name: gpt-4o
role: 请将输入的内容整合成一份完整的旅行计划
edges:
- from: Eat Planner
to: Collector
- from: Play Planner
to: Collector
- from: Stay Planner
to: Collector
- from: Collector
to: Travel Executor
dynamic: # Map 扇出3 个规划请求 → 3 个并行执行
type: map
split:
type: message
config:
max_parallel: 10
- from: Travel Executor
to: Final Aggregator
dynamic: # Tree 归约3 个结果 → 1 个最终计划
type: tree
split:
type: message
config:
group_size: 2
max_parallel: 10
```
### 7.2 长文档摘要Tree 模式)
```yaml
edges:
- from: Document Source
to: Summarizer
dynamic:
type: tree
split:
type: regex
pattern: "(?s).{1,2000}(?:\\s|$)" # 2000 字符切分
config:
group_size: 3
max_parallel: 10
```
## 8. 性能建议
- **控制并发**:设置合理的 `max_parallel` 避免触发 API 限流
- **优化拆分粒度**:过细的拆分增加开销,过粗则无法充分并行
- **Tree 组大小**`group_size=2-4` 通常是较好的选择
- **监控成本**Dynamic 模式会显著增加 API 调用次数
## 9. 相关文档
- [边配置指南](../edges.md)
- [工作流编排指南](../workflow_authoring.md)
- [Agent 节点配置](../nodes/agent.md)