Files
zclaw_openfang/plans/cryptic-imagining-peach.md
iven aa6a9cbd84
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
feat: 新增技能编排引擎和工作流构建器组件
refactor: 统一Hands系统常量到单个源文件
refactor: 更新Hands中文名称和描述

fix: 修复技能市场在连接状态变化时重新加载
fix: 修复身份变更提案的错误处理逻辑

docs: 更新多个功能文档的验证状态和实现位置
docs: 更新Hands系统文档

test: 添加测试文件验证工作区路径
2026-03-25 08:27:25 +08:00

645 lines
22 KiB
Markdown
Raw Permalink 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.

# Pipeline DSL 架构设计
> **目标**: 在 ZCLAW 中实现 OpenMagic 类教育功能,支持多步骤自动化工作流
> **原则**: 用户只看到 PipelineHands/Skills 作为内部实现被隐藏
---
## 1. 背景
### 1.1 问题
当前 Hands + Skills 架构存在以下局限:
- **流程编排**: Skills 是静态提示模板,无法定义执行流程
- **状态管理**: 复杂场景需要跨多个步骤传递状态
- **可扩展性**: 不同行业需要不同的生成流程
- **前端绑定**: Hands 动作无法直接映射到 UI 组件
### 1.2 需求
- 输入课题 → 自动生成大纲 → 并行生成场景 → 渲染预览 → 导出文件
- 支持垂直扩展(不同学科)和水平扩展(跨行业)
- 内部播放预览 + 文件导出PPTX/HTML/PDF
---
## 2. 架构设计
### 2.1 分层架构
```
┌─────────────────────────────────────────────────────────┐
│ User Interface │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ Pipeline List│ │ Pipeline Run│ │ Result Preview │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Pipeline Engine (新增) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ DSL Parser │ │ Executor │ │ State Manager │ │
│ │ YAML/TOML │ │ DAG Runner │ │ Context Store │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌─────────────┐ ┌─────────────────┐
│ Skills (隐藏) │ │ Hands (隐藏)│ │ Exporters │
│ prompt templates│ │ executors │ │ pptx/html/pdf │
└─────────────────┘ └─────────────┘ └─────────────────┘
```
### 2.2 核心组件
#### A. Pipeline DSL (声明式配置)
```yaml
# pipelines/education/classroom.yaml
apiVersion: zclaw/v1
kind: Pipeline
metadata:
name: classroom-generator
displayName: 互动课堂生成器
category: education
description: 输入课题,自动生成完整互动课堂
spec:
inputs:
- name: topic
type: string
required: true
label: 课题名称
placeholder: 例如:牛顿第二定律
- name: difficulty
type: select
options: [初级, 中级, 高级]
default: 中级
- name: export_formats
type: multi-select
options: [pptx, html, pdf]
default: [pptx, html]
steps:
# Step 1: 解析输入
- id: parse_input
action: llm.generate
template: skills/classroom-generator/parse.md
input:
topic: ${inputs.topic}
difficulty: ${inputs.difficulty}
output: parsed_data
# Step 2: 生成大纲
- id: generate_outline
action: llm.generate
template: skills/classroom-generator/outline.md
input: ${steps.parse_input.output}
output: outline
# Step 3: 并行生成场景
- id: generate_scenes
action: parallel
each: ${steps.generate_outline.output.items}
max_workers: 4
step:
action: llm.generate
template: skills/classroom-generator/scene.md
input:
item: ${item}
index: ${index}
output: scenes[]
# Step 4: 渲染课堂
- id: render
action: classroom.render
input:
outline: ${steps.generate_outline.output}
scenes: ${steps.generate_scenes.output}
output: classroom_data
# Step 5: 导出文件
- id: export
action: file.export
formats: ${inputs.export_formats}
input: ${steps.render.output}
output: export_paths
outputs:
classroom_id: ${steps.render.output.id}
preview_url: /classroom/${steps.render.output.id}
export_files: ${steps.export.output}
```
#### B. Pipeline Executor (执行引擎)
```rust
// crates/zclaw-pipeline/src/executor.rs
pub struct PipelineExecutor {
skill_registry: Arc<SkillRegistry>,
hand_registry: Arc<HandRegistry>,
llm_driver: Arc<dyn LlmDriver>,
state: PipelineState,
}
impl PipelineExecutor {
pub async fn execute(&self, pipeline: &Pipeline, inputs: Value) -> Result<PipelineOutput> {
let mut context = ExecutionContext::new(inputs);
for step in &pipeline.spec.steps {
match &step.action {
Action::LlmGenerate { template, input } => {
let prompt = self.render_template(template, &context)?;
let response = self.llm_driver.generate(prompt).await?;
context.set_output(&step.id, response);
}
Action::Parallel { each, step, max_workers } => {
let items = context.resolve(each)?;
let results = self.execute_parallel(step, items, *max_workers).await?;
context.set_output(&step.id, results);
}
Action::ClassroomRender { input } => {
let data = context.resolve(input)?;
let classroom = self.render_classroom(data).await?;
context.set_output(&step.id, classroom);
}
Action::FileExport { formats, input } => {
let paths = self.export_files(formats, input).await?;
context.set_output(&step.id, paths);
}
}
}
Ok(context.extract_outputs(&pipeline.outputs))
}
}
```
#### C. State Manager (状态管理)
```rust
// crates/zclaw-pipeline/src/state.rs
pub struct ExecutionContext {
inputs: Value,
steps_output: HashMap<String, Value>,
variables: HashMap<String, Value>,
}
impl ExecutionContext {
// 解析表达式 ${steps.generate_outline.output.items}
pub fn resolve(&self, expr: &str) -> Result<Value> {
// 支持的表达式:
// ${inputs.topic} - 输入参数
// ${steps.xxx.output} - 步骤输出
// ${item} - 循环变量
// ${index} - 循环索引
}
pub fn set_output(&mut self, step_id: &str, value: Value) {
self.steps_output.insert(step_id.to_string(), value);
}
}
```
---
## 3. 文件结构
### 3.1 新增 Crate
```
crates/zclaw-pipeline/
├── Cargo.toml
├── src/
│ ├── lib.rs
│ ├── parser.rs # YAML/TOML DSL 解析
│ ├── executor.rs # 执行引擎
│ ├── state.rs # 状态管理
│ ├── actions/ # 内置动作
│ │ ├── mod.rs
│ │ ├── llm.rs # LLM 调用
│ │ ├── parallel.rs # 并行执行
│ │ ├── render.rs # 渲染
│ │ └── export.rs # 导出
│ └── types.rs # 类型定义
```
### 3.2 Pipeline 配置目录
```
pipelines/
├── education/ # 教育类
│ ├── classroom.yaml # 互动课堂
│ ├── quiz-generator.yaml # 测验生成
│ └── flashcard.yaml # 闪卡生成
├── marketing/ # 营销类
│ ├── campaign.yaml # 营销方案
│ └── content-calendar.yaml # 内容日历
├── legal/ # 法律类
│ └── contract-review.yaml # 合同审查
└── _templates/ # 模板
└── base.yaml
```
### 3.3 隐藏 Skills/Hands
Skills 和 Hands 文件保留,但:
- 不在 UI 中直接展示
- 只通过 Pipeline DSL 引用
- 作为内部实现细节
---
## 4. 前端集成
### 4.0 设计原则
- **Pipeline 页面** - 类似 Hands 页面,展示所有可用 Pipeline
- **双触发入口** - 页面直接触发 + 对话中 Agent 引导触发
- **Agent 智能推荐** - 识别用户意图,推荐合适的 Pipeline
### 4.1 Pipeline 页面 (新增)
#### 页面布局 (参考 Hands 页面)
```
┌─────────────────────────────────────────────────────────────┐
│ Pipelines [+ 新建] │
├─────────────────────────────────────────────────────────────┤
│ [全部] [教育] [营销] [法律] [研发] [更多...] │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 📚 互动课堂生成 │ │ 📝 测验生成器 │ │
│ │ │ │ │ │
│ │ 输入课题,自动 │ │ 根据内容生成 │ │
│ │ 生成完整课堂 │ │ 选择题/填空题 │ │
│ │ │ │ │ │
│ │ [开始生成] │ │ [开始生成] │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 📊 营销方案生成 │ │ ⚖️ 合同审查 │ │
│ │ │ │ │ │
│ │ 输入产品信息, │ │ 上传合同文档, │ │
│ │ 生成营销策略 │ │ 自动审查风险点 │ │
│ │ │ │ │ │
│ │ [开始生成] │ │ [开始生成] │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
```
#### Pipeline 卡片组件
```typescript
interface PipelineCard {
id: string;
icon: string; // emoji 或图标
displayName: string;
description: string;
category: string;
tags: string[];
usage_count: number; // 使用次数(用于排序推荐)
last_used?: Date;
}
```
#### Pipeline 运行对话框
```
┌─────────────────────────────────────────┐
│ 互动课堂生成器 [×] │
├─────────────────────────────────────────┤
│ │
│ 课题名称 * │
│ ┌───────────────────────────────────┐ │
│ │ 牛顿第二定律 │ │
│ └───────────────────────────────────┘ │
│ │
│ 难度等级 │
│ ○ 初级 ● 中级 ○ 高级 │
│ │
│ 导出格式 │
│ ☑ PPTX ☑ HTML ☐ PDF │
│ │
│ [取消] [开始生成] │
└─────────────────────────────────────────┘
```
### 4.2 对话中触发 (Agent 引导)
#### Agent 系统提示词注入
```typescript
// 在 Agent 系统提示词中注入 Pipeline 信息
const systemPrompt = `
你是一个智能助手。用户可能会描述一些任务需求,你可以推荐使用合适的 Pipeline 工具。
可用的 Pipeline 工具:
${pipelines.map(p => `- ${p.displayName}: ${p.description}`).join('\n')}
当用户的需求匹配某个 Pipeline 时:
1. 简要说明该 Pipeline 能做什么
2. 询问用户是否要使用
3. 如果用户同意,调用 run_pipeline 工具启动
示例:
用户: "帮我做一个关于光合作用的课件"
你: "我可以使用【互动课堂生成器】为你自动生成完整课件,包括幻灯片、讲解和测验。需要开始吗?"
`;
```
#### Agent 推荐行为模式
**主动推荐策略**(需求模糊时也推荐):
```typescript
// Agent 识别潜在需求的模式
const intentPatterns = [
// 教育类
{ keywords: ["准备.*课", "备课", "教案", "教学"], pipeline: "classroom-generator", confidence: 0.7 },
{ keywords: ["学生.*测验", "出题", "考试"], pipeline: "quiz-generator", confidence: 0.8 },
// 营销类
{ keywords: ["推广.*方案", "营销计划", "宣传"], pipeline: "marketing-campaign", confidence: 0.75 },
{ keywords: ["内容.*日历", "发布.*计划"], pipeline: "content-calendar", confidence: 0.7 },
// 法律类
{ keywords: ["合同.*审查", "条款.*风险", "法律.*检查"], pipeline: "contract-review", confidence: 0.8 },
];
// Agent 行为:
// 1. 监听用户对话内容
// 2. 匹配潜在需求模式
// 3. 当 confidence > 0.6 时,主动询问
// 4. 用户确认后启动 Pipeline
```
#### 对话触发流程
**场景 1: 需求明确**
```
用户: 帮我做一个关于牛顿第二定律的课件
┌─────────────────────────────────────┐
│ Agent 分析意图 │
│ - 关键词: 课件、牛顿第二定律 │
│ - 匹配 Pipeline: classroom-generator │
│ - confidence: 0.95 (直接推荐) │
└─────────────────────────────────────┘
```
**场景 2: 需求模糊(主动推荐)**
```
用户: 我在准备下周的物理课,讲力学部分
┌─────────────────────────────────────┐
│ Agent 分析意图 │
│ - 关键词: 准备课、物理、力学 │
│ - 匹配 Pipeline: classroom-generator │
│ - confidence: 0.72 (主动询问) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Agent 回复 │
│ "物理课准备啊!力学是个重要主题。 │
│ │
│ 我可以帮你:【互动课堂生成器】 │
│ • 自动生成力学课件大纲 │
│ • 创建互动幻灯片 │
│ • 生成课后测验 │
│ │
│ 要试试吗?课题就是'力学基础'" │
└─────────────────────────────────────┘
```
┌─────────────────────────────────────┐
│ Agent 回复 │
│ "我可以使用【互动课堂生成器】为你 │
│ 自动生成完整课件,包括: │
│ • 结构化大纲 │
│ • 互动幻灯片 │
│ • AI 老师讲解 │
│ • 课后测验 │
│ │
│ 需要开始生成吗?" │
└─────────────────────────────────────┘
▼ (用户: 好的)
┌─────────────────────────────────────┐
│ Agent 调用工具 │
│ run_pipeline( │
│ id: "classroom-generator", │
│ inputs: { │
│ topic: "牛顿第二定律", │
│ difficulty: "中级" │
│ } │
│ ) │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ Pipeline 执行 & 进度反馈 │
│ Agent: "正在生成课堂大纲..." │
│ Agent: "正在生成第 3/8 个场景..." │
│ Agent: "课堂生成完成!" │
│ [预览课堂] [下载 PPTX] │
└─────────────────────────────────────┘
```
### 4.3 API 设计
```typescript
// kernel-client.ts 扩展
// 列出 Pipelines
async listPipelines(options?: {
category?: string;
search?: string;
}): Promise<Pipeline[]>
// 获取 Pipeline 详情
async getPipeline(id: string): Promise<PipelineDetail>
// 运行 Pipeline
async runPipeline(request: {
pipelineId: string;
inputs: Record<string, any>;
}): Promise<{ runId: string }>
// 获取运行进度
async getPipelineProgress(runId: string): Promise<{
status: 'running' | 'completed' | 'failed';
currentStep: string;
percentage: number;
message: string;
}>
// 获取运行结果
async getPipelineResult(runId: string): Promise<{
outputs: Record<string, any>;
files: { name: string; url: string; size: number }[];
}>
// 订阅进度事件
onPipelineProgress(runId: string, callback: (progress) => void): () => void
```
### 4.4 结果预览页
- 白板/幻灯片渲染器
- Agent 授课播放器
- 测验交互组件
- 导出文件下载
### 4.5 路由结构
```typescript
// 新增路由
/pipelines // Pipeline 列表页
/pipelines/:id // Pipeline 详情/运行页
/pipelines/run/:runId // 运行结果/进度页
/classroom/:id // 课堂预览页 (Pipeline 产出)
```
---
## 5. 实现步骤
### Phase 1: Pipeline 基础 (1 周)
1. 创建 `zclaw-pipeline` crate
2. 实现 DSL Parser (YAML → Pipeline struct)
3. 实现 ExecutionContext 状态管理
4. 实现基础 Executor (顺序执行)
### Phase 2: 核心动作 (1 周)
1. 实现 `llm.generate` 动作
2. 实现 `parallel` 动作
3. 实现 `classroom.render` 动作
4. 实现 `file.export` 动作
### Phase 3: 前端集成 (1 周)
1. Pipeline 列表 API
2. Pipeline 运行 API
3. 进度订阅
4. 结果获取
### Phase 4: 教育模板 (1 周)
1. classroom-generator.yaml
2. 前端预览组件
3. 测试验证
---
## 6. 验证方案
### 6.1 单元测试
```rust
#[test]
fn test_pipeline_parse() {
let yaml = r#"
apiVersion: zclaw/v1
kind: Pipeline
...
"#;
let pipeline = PipelineParser::parse(yaml).unwrap();
assert_eq!(pipeline.metadata.name, "classroom-generator");
}
#[test]
fn test_expression_resolve() {
let ctx = ExecutionContext::new(json!({
"inputs": {"topic": "test"},
"steps": {"parse": {"output": {"items": [1, 2, 3]}}}
}));
let value = ctx.resolve("${steps.parse.output.items}").unwrap();
assert_eq!(value, json!([1, 2, 3]));
}
```
### 6.2 集成测试
```bash
# 启动 Pipeline
curl -X POST http://localhost:50051/pipelines/classroom-generator/run \
-d '{"topic": "牛顿第二定律", "difficulty": "中级"}'
# 检查进度
curl http://localhost:50051/pipelines/runs/{run_id}/progress
# 获取结果
curl http://localhost:50051/pipelines/runs/{run_id}/result
```
### 6.3 E2E 测试
1. 在 UI 中选择 "互动课堂生成器"
2. 输入课题,点击生成
3. 观察进度条,等待完成
4. 预览生成的课堂
5. 下载 PPTX/HTML 文件
---
## 7. 扩展性设计
### 7.1 添加新 Pipeline
只需创建新的 YAML 文件:
```yaml
# pipelines/marketing/campaign.yaml
apiVersion: zclaw/v1
kind: Pipeline
metadata:
name: marketing-campaign
category: marketing
spec:
steps:
- id: analyze_brand
action: llm.generate
template: skills/marketing/brand-analysis.md
# ...
```
### 7.2 添加新 Action
```rust
// 在 actions/ 目录添加新动作
pub struct CustomAction;
impl ActionExecutor for CustomAction {
async fn execute(&self, ctx: &ExecutionContext, config: &Value) -> Result<Value> {
// 实现自定义逻辑
}
}
```
### 7.3 条件分支 (未来)
```yaml
steps:
- id: check_type
action: condition
branches:
- when: ${inputs.type == 'video'}
then: generate_video
- when: ${inputs.type == 'text'}
then: generate_text
```