进程构建器
为保姆事件源编排框架创建新的进程定义。
快速参考
进程位于:plugins/babysitter/skills/babysit/process/
├── methodologies/ # 可重用的开发方法(TDD,BDD,Scrum等)
│ └── [name]/
│ ├── README.md # 文档
│ ├── [name].js # 主进程
│ └── examples/ # 示例输入
│
└── specializations/ # 特定领域的进程
├── [category]/ # 工程专业化(直接子代)
│ └── [process].js
└── domains/
└── [domain]/ # 商业,科学,社会科学
└── [spec]/
├── README.md
├── references.md
├── processes-backlog.md
└── [process].js
3阶段工作流程
第1阶段:研究与文档
创建基础文档:
# 检查现有的专业化
ls plugins/babysitter/skills/babysit/process/specializations/
# 检查方法论
ls plugins/babysitter/skills/babysit/process/methodologies/
创建:
README.md- 概览,角色,目标,用例,常见流程references.md- 外部参考,最佳实践,链接到源
第2阶段:识别进程
创建processes-backlog.md,列出识别出的进程:
# 进程积压 - [专业化名称]
## 识别出的进程
- [ ] **进程名称** - 该进程完成什么的简短描述
- 参考:[方法论或标准的链接]
- 输入:列出关键输入
- 输出:列出关键输出
- [ ] **另一个进程** - 描述
...
第3阶段:创建进程文件
创建.js进程文件,遵循SDK模式(见下文)。
进程文件结构
每个进程文件遵循此模式:
/**
* @进程 [类别]/[进程名称]
* @描述 清晰描述进程端到端完成什么
* @输入 { inputName: 类型, 可选输入?: 类型 }
* @输出 { success: 布尔值, 输出名称: 类型, 工件: 数组 }
*
* @example
* const result = await orchestrate('[类别]/[进程名称]', {
* inputName: '值',
* 可选输入: '可选值'
* });
*
* @参考
* - 书籍:"相关书籍标题" 作者
* - 文章:[标题](https://链接)
* - 标准:ISO/IEEE参考
*/
import { defineTask } from '@a5c-ai/babysitter-sdk';
/**
* [进程名称]进程
*
* 方法论:简要描述方法
*
* 阶段:
* 1. 阶段名称 - 发生什么
* 2. 阶段名称 - 发生什么
* ...
*
* 好处:
* - 好处1
* - 好处2
*
* @param {Object} 输入 - 进程输入
* @param {string} 输入.inputName - 输入描述
* @param {Object} ctx - 进程上下文(见SDK)
* @returns {Promise<Object>} 进程结果
*/
export async function process(inputs, ctx) {
const {
inputName,
可选输入 = '默认值',
// ...带有默认值的解构
} = 输入;
const 工件 = [];
// ============================================================================
// 第1阶段:[阶段名称]
// ============================================================================
ctx.log?.('info', '开始第1阶段...');
const phase1Result = await ctx.task(someTask, {
// 任务输入
});
工件.push(...(phase1Result.artifacts || []));
// 人工审核的断点(如果需要)
await ctx.breakpoint({
问题:'审核结果并批准继续吗?',
标题:'第1阶段审核',
上下文:{
运行ID:ctx.runId,
文件:[
{路径:'工件/output.md', 格式:'markdown', 标签:'输出'}
]
}
});
// ============================================================================
// 第2阶段:[阶段名称] - 并行执行示例
// ============================================================================
const [result1, result2, result3] = await ctx.parallel.all([
() => ctx.task(task1, { /* 参数 */ }),
() => ctx.task(task2, { /* 参数 */ }),
() => ctx.task(task3, { /* 参数 */ })
]);
// ============================================================================
// 第3阶段:[迭代示例]
// ============================================================================
let 迭代 = 0;
let 目标达成 = false;
while (!目标达成 && 迭代 < 最大迭代次数) {
迭代++;
const iterResult = await ctx.task(iterativeTask, {
迭代,
先前结果:/* ... */
});
目标达成 = iterResult.meetsTarget;
if (!目标达成 && 迭代 % 3 === 0) {
// 定期检查点
await ctx.breakpoint({
问题:`迭代 ${迭代}:目标未达成。继续吗?`,
标题:'进度检查点',
上下文:{ /* ... */ }
});
}
}
// ============================================================================
// 完成
// ============================================================================
return {
成功:目标达成,
迭代次数:迭代,
工件,
// ...其他输出匹配@输出
};
}
// ============================================================================
// 任务定义
// ============================================================================
/**
* 任务:[任务名称]
* 目的:这个任务完成什么
*/
const someTask = defineTask({
名称:'任务名称',
描述:'这个任务做什么',
// 任务定义 - 由编排器外部执行
// 这返回一个TaskDef,描述如何运行任务
输入:{
inputName: { 类型:'字符串', 必需:true },
可选输入:{ 类型:'数字', 默认值:10 }
},
输出:{
结果:{ 类型:'对象' },
工件:{ 类型:'数组' }
},
async run(inputs, taskCtx) {
const effectId = taskCtx.effectId;
return {
类型:'节点', // 或 '代理', '技能', 'shell', '断点'
标题:`任务:${inputs.inputName}`,
节点:{
入口:'脚本/任务运行器.js',
参数:['--input', inputs.inputName, '--effect-id', effectId]
},
io:{
输入Json路径:`任务/${effectId}/input.json`,
输出Json路径:`任务/${effectId}/结果.json`
},
标签:['类别', '子类别']
};
}
});
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() |
确定性时间 | 返回当前日期(或提供的时间) |
ctx.log?.(level, msg, data?) |
日志记录 | 可选的日志记录助手 |
ctx.runId |
运行标识符 | 当前运行的唯一ID |
任务类型
| 类型 | 用例 | 执行器 |
|---|---|---|
node |
脚本,构建,测试 | Node.js进程 |
agent |
LLM驱动的分析,生成 | Claude代码代理 |
skill |
Claude代码技能 | 技能调用 |
shell |
系统命令 | Shell执行 |
breakpoint |
人工批准 | 断点UI/服务 |
sleep |
时间门 | 编排者调度 |
orchestrator_task |
内部编排器工作 | 自我路由 |
断点模式
基本批准门
await ctx.breakpoint({
问题:'批准继续吗?',
标题:'检查点',
上下文:{ 运行ID:ctx.runId }
});
带文件引用(UI显示)
await ctx.breakpoint({
问题:'审核生成的规范。它满足要求吗?',
标题:'规范审核',
上下文:{
运行ID:ctx.runId,
文件:[
{路径:'工件/spec.md', 格式:'markdown', 标签:'规范' },
{路径:'工件/spec.json', 格式:'json', 标签:'JSON模式' },
{路径:'src/implementation.ts', 格式:'代码', 语言:'typescript', 标签:'实现' }
]
}
});
条件断点
if (qualityScore < targetScore) {
await ctx.breakpoint({
问题:`质量分数 ${qualityScore} 低于目标 ${targetScore}。继续迭代或接受当前结果?`,
标题:'质量门',
上下文:{
运行ID:ctx.runId,
数据:{ qualityScore, targetScore, 迭代 }
}
});
}
常见模式
质量收敛循环
let quality = 0;
let 迭代 = 0;
const targetQuality = inputs.targetQuality || 85;
const maxIterations = inputs.maxIterations || 10;
while (quality < targetQuality && 迭代 < maxIterations) {
迭代++;
ctx.log?.('info', `迭代 ${迭代}/${maxIterations}`);
// 执行改进任务
const improvement = await ctx.task(improveTask, { 迭代 });
// 评分质量(并行检查)
const [coverage, lint, security, tests] = await ctx.parallel.all([
() => ctx.task(coverageTask, {}),
() => ctx.task(lintTask, {}),
() => ctx.task(securityTask, {}),
() => ctx.task(runTestsTask, {})
]);
// 代理评分整体质量
const score = await ctx.task(agentScoringTask, {
coverage, lint, security, tests, 迭代
});
quality = score.overall;
ctx.log?.('info', `质量:${quality}/${targetQuality}`);
if (quality >= targetQuality) {
ctx.log?.('info', '质量目标达成!');
break;
}
}
return {
成功:quality >= targetQuality,
质量,
迭代次数:迭代
};
带审核的分阶段工作流程
// 第1阶段:研究
const research = await ctx.task(researchTask, { 主题:inputs.topic });
await ctx.breakpoint({
问题:'审核研究结果后再进行计划。',
标题:'研究审核',
上下文:{ 运行ID:ctx.runId }
});
// 第2阶段:计划
const plan = await ctx.task(planningTask, { 研究 });
await ctx.breakpoint({
问题:'审核计划后再实施。',
标题:'计划审核',
上下文:{ 运行ID:ctx.runId }
});
// 第3阶段:实施
const implementation = await ctx.task(implementTask, { 计划 });
// 第4阶段:验证
const verification = await ctx.task(verifyTask, { 实施, 计划 });
await ctx.breakpoint({
问题:'最终审核后再完成。',
标题:'最终批准',
上下文:{ 运行ID:ctx.runId }
});
return { 成功:verification.passed, 计划, 实施 };
并行扇出与聚合
// 扇出到多个并行分析
const analyses = await ctx.parallel.map(components, component =>
ctx.task(analyzeTask, { component }, { 标签:`analyze:${component.name}` })
);
// 聚合结果
const aggregated = await ctx.task(aggregateTask, { analyses });
return { 分析, 摘要:aggregated.summary };
测试进程
CLI命令
# 创建一个新的运行
保姆运行:创建 \
--process-id methodologies/my-process \
--entry ./plugins/babysitter/skills/babysit/process/methodologies/my-process.js#process \
--inputs ./test-inputs.json \
--json
# 迭代运行
保姆运行:迭代 .a5c/runs/<runId> --json
# 列出待办任务
保姆任务:列表 .a5c/runs/<runId> --pending --json
# 发布任务结果
保姆任务:发布 .a5c/runs/<runId> <effectId> \
--status ok \
--value ./result.json
# 检查运行状态
保姆运行:状态 .a5c/runs/<runId>
# 查看事件
保姆运行:事件 .a5c/runs/<runId> --limit 20 --reverse
示例测试输入文件
{
"feature": "使用JWT的用户认证",
"acceptanceCriteria": [
"用户可以使用电子邮件和密码注册",
"用户可以登录并接收JWT令牌",
"无效的凭据被拒绝"
],
"testFramework": "jest",
"targetQuality": 85,
"maxIterations": 5
}
进程构建器工作流程
1. 收集需求
询问用户:
| 问题 | 目的 |
|---|---|
| 领域/类别 | 确定目录位置 |
| 进程名称 | kebab-case标识符 |
| 目标 | 进程应该完成什么? |
| 输入 | 进程需要什么数据? |
| 输出 | 它产生什么工件/结果? |
| 阶段 | 有哪些主要步骤? |
| 质量门 | 人类应该在哪里审核? |
| 迭代策略 | 固定阶段vs.收敛循环? |
2. 研究类似进程
# 查找类似进程
ls plugins/babysitter/skills/babysit/process/methodologies/
ls plugins/babysitter/skills/babysit/process/specializations/
# 阅读类似进程以寻找模式
cat plugins/babysitter/skills/babysit/process/methodologies/atdd-tdd/atdd-tdd.js | head -200
# 检查方法论README结构
cat plugins/babysitter/skills/babysit/process/methodologies/atdd-tdd/README.md
3. 检查方法论积压
cat plugins/babysitter/skills/babysit/process/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
- [ ] 从
@a5c-ai/babysitter-sdk导入 - [ ] 主
export async function process(inputs, ctx) - [ ] 输入解构带有默认值
- [ ] 清晰的阶段注释(
// === PHASE N: NAME ===) - [ ] 通过
ctx.log?.('info', message)记录日志 - [ ] 通过
ctx.task(taskDef, inputs)执行任务 - [ ] 在关键决策点设置断点
- [ ] 整个过程中收集工件
- [ ] 返回对象匹配@outputs模式
按类型示例
方法论进程(atdd-tdd风格)
/**
* @进程 methodologies/my-methodology
* @描述 我的质量收敛开发方法论
* @输入 { feature: 字符串, 目标质量?: 数字 }
* @输出 { 成功:布尔值, 质量:数字, 工件:数组 }
*/
export async function process(inputs, ctx) {
const { feature, 目标质量 = 85 } = inputs;
// ...实现
}
专业化进程(游戏开发风格)
/**
* @进程 specializations/game-development/core-mechanics-prototyping
* @描述 通过迭代原型和验证核心游戏机制
* @输入 { prototypeName: 字符串, mechanicsToTest: 数组, 引擎?: 字符串 }
* @输出 { 成功:布尔值, mechanicsValidated: 数组, playtestResults: 对象 }
*/
export async function process(inputs, ctx) {
const { prototypeName, mechanicsToTest, 引擎 = 'Unity' } = inputs;
// ...实现
}
领域进程(科学/研究风格)
/**
* @进程 specializations/domains/science/bioinformatics/sequence-analysis
* @描述 使用标准生物信息学工作流程分析基因组序列
* @输入 { sequences: 数组, analysisType: 字符串, 参考基因组?: 字符串 }
* @输出 { 成功:布尔值, alignments: 数组, variants: 数组, 报告:对象 }
*/
export async function process(inputs, ctx) {
const { sequences, analysisType, 参考基因组 = 'GRCh38' } = inputs;
// ...实现
}
资源
- SDK参考:
plugins/babysitter/skills/babysit/reference/sdk.md - 方法论积压:
plugins/babysitter/skills/babysit/process/methodologies/backlog.md - 专业化积压:
plugins/babysitter/skills/babysit/process/specializations/backlog.md - 示例:ATDD/TDD:
plugins/babysitter/skills/babysit/process/methodologies/atdd-tdd/ - 示例:规格驱动:
plugins/babysitter/skills/babysit/process/methodologies/spec-driven-development.js - README:根
README.md用于完整的框架文档