关于 process-builder
process-builder 是用于在 babysitter 事件溯源编排框架中创建流程定义的 Agent 技能,指导作者从需求调研到实现和验证,并遵循该框架的 SDK 模式。
主要功能
- 01三阶段流程创建工作流
- 02方法论与专业领域流程指南
- 03SDK 任务、并行与人工检查点模式
- 04流程结构和元数据要求
- 05基于命令行的流程测试指南
适用场景
- 01起草新的开发方法论流程
- 02构建特定领域的编排流程
- 03为工作流添加人工审核点
- 04运行测试前检查流程文件
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ a5c-ai/ babysitter --skill process-builder安装后在 Claude Code 中输入/process-builder确认已加载。
详细介绍
流程构建器
为 babysitter 事件溯源编排框架创建新的流程定义。
快速参考
Processes live in: library/
├── methodologies/ # Reusable development approaches (TDD, BDD, Scrum, etc.)
│ └── [name]/
│ ├── README.md # Documentation
│ ├── [name].js # Main process
│ └── examples/ # Sample inputs
│
└── specializations/ # Domain-specific processes
├── [category]/ # Engineering specializations (direct children)
│ └── [process].js
└── domains/
└── [domain]/ # Business, Science, Social Sciences
└── [spec]/
├── README.md
├── references.md
├── processes-backlog.md
└── [process].js
三阶段工作流
阶段 1:研究与文档编写
创建基础文档:
# Check existing specializations
ls library/specializations/
# Check methodologies
ls library/methodologies/
创建:
README.md- 概述、角色、目标、用例和常见流程references.md- 外部参考资料、最佳实践和来源链接
阶段 2:确定流程
创建 processes-backlog.md,列出已确定的流程:
# Processes Backlog - [Specialization Name]
## Identified Processes
- [ ] **process-name** - Short description of what this process accomplishes
- Reference: [Link to methodology or standard]
- Inputs: list key inputs
- Outputs: list key outputs
- [ ] **another-process** - Description
...
阶段 3:创建流程文件
按照 SDK 模式创建 .js 流程文件(见下文)。
流程文件结构
每个流程文件都遵循以下模式:
/**
* @process [category]/[process-name]
* @description Clear description of what the process accomplishes end-to-end
* @inputs { inputName: type, optionalInput?: type }
* @outputs { success: boolean, outputName: type, artifacts: array }
*
* @graph
* domains: [domain:software-engineering]
* skillAreas: [skill-area:your-skill-area]
* topics: [topic:your-topic]
* roles: [role:your-role]
* workflows: [workflow:your-workflow]
*
* @example
* const result = await orchestrate('[category]/[process-name]', {
* inputName: 'value',
* optionalInput: 'optional-value'
* });
*
* @references
* - Book: "Relevant Book Title" by Author
* - Article: [Title](https://link)
* - Standard: ISO/IEEE reference
*/
import { defineTask } from '@a5c-ai/babysitter-sdk';
/**
* [Process Name] Process
*
* Methodology: Brief description of the approach
*
* Phases:
* 1. Phase Name - What happens
* 2. Phase Name - What happens
* ...
*
* Benefits:
* - Benefit 1
* - Benefit 2
*
* @param {Object} inputs - Process inputs
* @param {string} inputs.inputName - Description of input
* @param {Object} ctx - Process context (see SDK)
* @returns {Promise<Object>} Process result
*/
export async function process(inputs, ctx) {
const {
inputName,
optionalInput = 'default-value',
// ... destructure with defaults
} = inputs;
const artifacts = [];
// ============================================================================
// PHASE 1: [PHASE NAME]
// ============================================================================
ctx.log?.('info', 'Starting Phase 1...');
const phase1Result = await ctx.task(someTask, {
// task inputs
});
artifacts.push(...(phase1Result.artifacts || []));
// Breakpoint for human review (when needed)
await ctx.breakpoint({
question: 'Review the results and approve to continue?',
title: 'Phase 1 Review',
context: {
runId: ctx.runId,
files: [
{ path: 'artifacts/output.md', format: 'markdown', label: 'Output' }
]
}
});
// ============================================================================
// PHASE 2: [PHASE NAME] - Parallel Execution Example
// ============================================================================
const [result1, result2, result3] = await ctx.parallel.all([
() => ctx.task(task1, { /* args */ }),
() => ctx.task(task2, { /* args */ }),
() => ctx.task(task3, { /* args */ })
]);
// ============================================================================
// PHASE 3: [ITERATION EXAMPLE]
// ============================================================================
let iteration = 0;
let targetMet = false;
while (!targetMet && iteration < maxIterations) {
iteration++;
const iterResult = await ctx.task(iterativeTask, {
iteration,
previousResults: /* ... */
});
targetMet = iterResult.meetsTarget;
if (!targetMet && iteration % 3 === 0) {
// Periodic checkpoint
await ctx.breakpoint({
question: `Iteration ${iteration}: Target not met. Continue?`,
title: 'Progress Checkpoint',
context: { /* ... */ }
});
}
}
// ============================================================================
// COMPLETION
// ============================================================================
return {
success: targetMet,
iterations: iteration,
artifacts,
// ... other outputs matching @outputs
};
}
// ============================================================================
// TASK DEFINITIONS
// ============================================================================
/**
* Task: [Task Name]
* Purpose: What this task accomplishes
*/
const someTask = defineTask({
name: 'task-name',
description: 'What this task does',
// Task definition - executed externally by orchestrator
// This returns a TaskDef that describes HOW to run the task
inputs: {
inputName: { type: 'string', required: true },
optionalInput: { type: 'number', default: 10 }
},
outputs: {
result: { type: 'object' },
artifacts: { type: 'array' }
},
async run(inputs, taskCtx) {
const effectId = taskCtx.effectId;
return {
kind: 'node', // or 'agent', 'skill', 'shell', 'breakpoint'
title: `Task: ${inputs.inputName}`,
node: {
entry: 'scripts/task-runner.js',
args: ['--input', inputs.inputName, '--effect-id', effectId]
},
io: {
inputJsonPath: `tasks/${effectId}/input.json`,
outputJsonPath: `tasks/${effectId}/result.json`
},
labels: ['category', 'subcategory']
};
}
});
SDK 上下文 API 参考
ctx 对象提供以下内置功能:
| 方法 | 用途 | 行为 |
|---|---|---|
ctx.task(taskDef, args, opts?) | 执行任务 | 返回结果或抛出类型化异常 |
ctx.breakpoint(payload) | 人工审批关卡 | 暂停,直到人工批准 |
ctx.sleepUntil(isoOrEpochMs) | 基于时间的关卡 | 暂停,直到指定时间 |
ctx.parallel.all([...thunks]) | 并行执行 | 并发运行互不依赖的任务 |
ctx.parallel.map(items, fn) | 并行映射 | 通过任务函数映射各项 |
ctx.now() | 确定性时间 | 返回当前 Date(或提供的时间) |
ctx.log?.(level, msg, data?) | 日志记录 | 可选的日志辅助函数 |
ctx.runId | 运行标识符 | 当前运行的唯一 ID |
任务类型
| 类型 | 用例 | 执行器 |
|---|---|---|
node | 脚本、构建、测试 | Node.js 进程 |
agent | 由大模型驱动的分析与生成 | Claude Code Agent |
skill | Claude Code 技能 | 技能调用 |
shell | 系统命令 | Shell 执行 |
breakpoint | 人工审批 | 断点 UI/服务 |
sleep | 时间关卡 | 编排器调度 |
orchestrator_task | 编排器内部工作 | 自路由 |
断点模式
基本审批关卡
await ctx.breakpoint({
question: 'Approve to continue?',
title: 'Checkpoint',
context: { runId: ctx.runId }
});
带文件引用(供 UI 显示)
await ctx.breakpoint({
question: 'Review the generated specification. Does it meet requirements?',
title: 'Specification Review',
context: {
runId: ctx.runId,
files: [
{ path: 'artifacts/spec.md', format: 'markdown', label: 'Specification' },
{ path: 'artifacts/spec.json', format: 'json', label: 'JSON Schema' },
{ path: 'src/implementation.ts', format: 'code', language: 'typescript', label: 'Implementation' }
]
}
});
条件断点
if (qualityScore < targetScore) {
await ctx.breakpoint({
question: `Quality score ${qualityScore} is below target ${targetScore}. Continue iterating or accept current result?`,
title: 'Quality Gate',
context: {
runId: ctx.runId,
data: { qualityScore, targetScore, iteration }
}
});
}
常见模式
质量收敛循环
let quality = 0;
let iteration = 0;
const targetQuality = inputs.targetQuality || 85;
const maxIterations = inputs.maxIterations || 10;
while (quality < targetQuality && iteration < maxIterations) {
iteration++;
ctx.log?.('info', `Iteration ${iteration}/${maxIterations}`);
// Execute improvement tasks
const improvement = await ctx.task(improveTask, { iteration });
// Score quality (parallel checks)
const [coverage, lint, security, tests] = await ctx.parallel.all([
() => ctx.task(coverageTask, {}),
() => ctx.task(lintTask, {}),
() => ctx.task(securityTask, {}),
() => ctx.task(runTestsTask, {})
]);
// Agent scores overall quality
const score = await ctx.task(agentScoringTask, {
coverage, lint, security, tests, iteration
});
quality = score.overall;
ctx.log?.('info', `Quality: ${quality}/${targetQuality}`);
if (quality >= targetQuality) {
ctx.log?.('info', 'Quality target achieved!');
break;
}
}
return {
success: quality >= targetQuality,
quality,
iterations: iteration
};
带评审的分阶段工作流
// Phase 1: Research
const research = await ctx.task(researchTask, { topic: inputs.topic });
await ctx.breakpoint({
question: 'Review research findings before proceeding to planning.',
title: 'Research Review',
context: { runId: ctx.runId }
});
// Phase 2: Planning
const plan = await ctx.task(planningTask, { research });
await ctx.breakpoint({
question: 'Review plan before implementation.',
title: 'Plan Review',
context: { runId: ctx.runId }
});
// Phase 3: Implementation
const implementation = await ctx.task(implementTask, { plan });
// Phase 4: Verification
const verification = await ctx.task(verifyTask, { implementation, plan });
await ctx.breakpoint({
question: 'Final review before completion.',
title: 'Final Approval',
context: { runId: ctx.runId }
});
return { success: verification.passed, plan, implementation };
并行扇出与聚合
// Fan out to multiple parallel analyses
const analyses = await ctx.parallel.map(components, component =>
ctx.task(analyzeTask, { component }, { label: `analyze:${component.name}` })
);
// Aggregate results
const aggregated = await ctx.task(aggregateTask, { analyses });
return { analyses, summary: aggregated.summary };
测试流程
CLI 命令
# Create a new run
babysitter run:create \
--process-id methodologies/my-process \
--entry ./library/methodologies/my-process.js#process \
--inputs ./test-inputs.json \
--json
# Iterate the run
babysitter run:iterate .a5c/runs/<runId> --json
# List pending tasks
babysitter task:list .a5c/runs/<runId> --pending --json
# Post a task result
babysitter task:post .a5c/runs/<runId> <effectId> \
--status ok \
--value ./result.json
# Check run status
babysitter run:status .a5c/runs/<runId>
# View events
babysitter run:events .a5c/runs/<runId> --limit 20 --reverse
测试输入文件示例
{
"feature": "User authentication with JWT",
"acceptanceCriteria": [
"Users can register with email and password",
"Users can login and receive a JWT token",
"Invalid credentials are rejected"
],
"testFramework": "jest",
"targetQuality": 85,
"maxIterations": 5
}
流程构建器工作流
1. 收集需求
询问用户:
| 问题 | 用途 |
|---|---|
| 领域/类别 | 确定目录位置 |
| 流程名称 | kebab-case 标识符 |
| 目标 | 流程应完成什么? |
| 输入 | 流程需要哪些数据? |
| 输出 | 流程会生成哪些产物/结果? |
| 阶段 | 主要步骤有哪些? |
| 质量关卡 | 哪些环节需要人工评审? |
| 迭代策略 | 固定阶段还是收敛循环? |
2. 研究类似流程
# Find similar processes
ls library/methodologies/
ls library/specializations/
# Read similar process for patterns
cat library/methodologies/atdd-tdd/atdd-tdd.js | head -200
# Check methodology README structure
cat library/methodologies/atdd-tdd/README.md
3. 检查方法论待办清单
cat library/methodologies/backlog.md
4. 创建流程
对于方法论:
- 创建
methodologies/[name]/README.md(完整文档) - 创建
methodologies/[name]/[name].js(流程实现) - 创建
methodologies/[name]/examples/(示例输入)
对于专门化:
- 如果是特定领域:
specializations/domains/[domain]/[spec]/ - 如果是工程类:
specializations/[category]/[process].js - 首先创建 README.md、references.md 和 processes-backlog.md
- 然后创建各个 process.js 文件
5. 验证结构
检查清单:
- JSDoc 标头包含 @process、@description、@inputs、@outputs、@example、@references
- 包含带有相关 atlas 节点 ID 的
@graph块(至少一个领域) - 从
@a5c-ai/babysitter-sdk导入 - 主函数为
export async function process(inputs, ctx) - 输入解构时设置默认值
- 阶段注释清晰(
// === PHASE N: NAME ===) - 通过
ctx.log?.('info', message)记录日志 - 通过
ctx.task(taskDef, inputs)执行任务 - 在关键决策点设置断点
- 全程收集产物
- 返回对象与 @outputs 架构一致
按类型划分的示例
方法论流程(atdd-tdd 风格)
/**
* @process methodologies/my-methodology
* @description My development methodology with quality convergence
* @inputs { feature: string, targetQuality?: number }
* @outputs { success: boolean, quality: number, artifacts: array }
*/
export async function process(inputs, ctx) {
const { feature, targetQuality = 85 } = inputs;
// ... implementation
}
专业化流程(game-development 风格)
/**
* @process specializations/game-development/core-mechanics-prototyping
* @description Prototype and validate core gameplay mechanics through iteration
* @inputs { prototypeName: string, mechanicsToTest: array, engine?: string }
* @outputs { success: boolean, mechanicsValidated: array, playtestResults: object }
*/
export async function process(inputs, ctx) {
const { prototypeName, mechanicsToTest, engine = 'Unity' } = inputs;
// ... implementation
}
领域流程(science/research 风格)
/**
* @process specializations/domains/science/bioinformatics/sequence-analysis
* @description Analyze genomic sequences using standard bioinformatics workflows
* @inputs { sequences: array, analysisType: string, referenceGenome?: string }
* @outputs { success: boolean, alignments: array, variants: array, report: object }
*/
export async function process(inputs, ctx) {
const { sequences, analysisType, referenceGenome = 'GRCh38' } = inputs;
// ... implementation
}
Atlas 图元数据
每个生成的流程文件都必须在其文件头注释中包含一个 @graph JSDoc 块,以及标准的 @process、@description、@inputs 和 @outputs 标签。
格式
/**
* @process specializations/my-domain/my-process
* @description ...
* @inputs { ... }
* @outputs { ... }
*
* @graph
* domains: [domain:software-engineering, domain:devops]
* skillAreas: [skill-area:caching-strategies]
* topics: [topic:microservices, topic:event-sourcing]
* roles: [role:backend-engineer, role:sre]
* workflows: [workflow:code-review]
*/
如何选择节点 ID
阅读 atlas 图领域目录(packages/atlas/graph/domain/)以查找有效的节点 ID。该目录按类别包含 YAML 文件:
domains/— 高层领域节点(例如domain:software-engineering、domain:devops、domain:data-engineering)skill-areas/— 具体技能领域节点topics/— 细分主题节点roles/— 角色节点(工程师、从业者、研究人员)workflows/— 工作流节点
选择 2–4 条与流程确实相关的边。不要猜测 ID——请阅读实际的 YAML 文件以查找有效 ID。至少,每个流程都必须引用一个 domain: 节点。
为什么这很重要
此元数据会将流程连接到 atlas 知识图谱。预构建生成器脚本会解析 @graph 块,并创建图节点和边,以便用户发现流程。不包含此块的流程不会出现在基于图的搜索结果或推荐中。
资源
- SDK 参考:
library/reference/sdk.md - 方法论待办事项:
library/methodologies/backlog.md - 专业化待办事项:
library/specializations/backlog.md - 示例:ATDD/TDD:
library/methodologies/atdd-tdd/ - 示例:规范驱动:
library/methodologies/spec-driven-development.js - README:根目录中的
README.md,包含完整的框架文档
评论
支持 Markdown