# PRD 模板 - 内容生产工作流(非编程任务) > 基于 Ralph 模式改造,适用于视频制作、文章发布、研究分析等非编程任务。 --- ## 📋 prd.json - 结构化任务清单 ```json { "version": "1.0", "projectName": "项目名称", "projectType": "content-production | video | research | multi-step-task", "created": "YYYY-MM-DD", "description": "项目简要描述", "userStories": [ { "id": "1", "title": "任务描述(动宾结构,越具体越好)", "branchName": "feature/xxx", "passes": false, "assignedTo": "agentId 或 human", "qualityGate": { "type": "file-exists | command-output | human-review | llm-judge", "description": "如何判断此任务完成", "command": "(可选)验证命令", "expected": "(可选)预期输出" }, "notes": "执行过程中的备注/心得" } ], "qualityCheckCommands": { "description": "项目级质量检查命令(非 story 级别)" } } ``` --- ## ✅ Quality Gate 类型说明 | 类型 | 适用场景 | 判断方式 | |------|---------|---------| | `file-exists` | 文件生成类任务 | 检查文件是否生成 | | `command-output` | 命令执行类 | 验证命令退出码或输出 | | `human-review` | 创意/审核类 | 需要人工确认(不可完全消除) | | `llm-judge` | 内容质量评估 | LLM 评估输出质量 | --- ## 📄 适用场景模板 ### 场景 A:视频制作 ```json { "projectName": "AI 工具对比视频", "projectType": "video", "userStories": [ { "id": "1", "title": "撰写 3 分钟视频脚本(AI 工具对比)", "qualityGate": {"type": "file-exists", "description": "脚本文件存在且 > 500 字"}, "notes": "" }, { "id": "2", "title": "收集/生成视频素材片段", "qualityGate": {"type": "file-exists", "description": "素材文件夹存在且包含 > 3 个片段"}, "notes": "" }, { "id": "3", "title": "FFmpeg 剪辑拼接成完整视频", "qualityGate": {"type": "command-output", "description": "ffprobe 检查视频时长 3min±10s"}, "notes": "" }, { "id": "4", "title": "生成封面图", "qualityGate": {"type": "file-exists", "description": "封面图存在"}, "notes": "" }, { "id": "5", "title": "上传到 B 站", "qualityGate": {"type": "human-review", "description": "人工确认视频已发布"}, "notes": "" } ] } ``` ### 场景 B:文章发布公众号 ```json { "projectName": "公众号文章 - AI 趋势分析", "projectType": "content-production", "userStories": [ { "id": "1", "title": "使用 Last30Days 研究 AI 趋势", "qualityGate": {"type": "file-exists", "description": "生成的研究报告存在"}, "notes": "" }, { "id": "2", "title": "生成摘要、金句、观点提炼", "qualityGate": {"type": "command-output", "description": "输出包含摘要+3个以上金句"}, "notes": "" }, { "id": "3", "title": "生成文章配图", "qualityGate": {"type": "file-exists", "description": "配图文件存在"}, "notes": "" }, { "id": "4", "title": "排版并预览(HTML/Markdown)", "qualityGate": {"type": "human-review", "description": "人工预览确认格式无误"}, "notes": "" }, { "id": "5", "title": "发布到公众号", "qualityGate": {"type": "human-review", "description": "人工确认已群发"}, "notes": "" } ] } ``` ### 场景 C:竞品动态追踪 ```json { "projectName": "竞品分析 - Cursor vs Windsurf", "projectType": "research", "userStories": [ { "id": "1", "title": "Last30Days 搜索两个竞品近 30 天动态", "qualityGate": {"type": "file-exists", "description": "生成两个研究文件"}, "notes": "" }, { "id": "2", "title": "抓取竞品官网更新页面", "qualityGate": {"type": "file-exists", "description": "页面内容已保存"}, "notes": "" }, { "id": "3", "title": "生成对比分析报告", "qualityGate": {"type": "command-output", "description": "报告文件 > 1000 字"}, "notes": "" }, { "id": "4", "title": "保存到 Obsidian 知识库", "qualityGate": {"type": "file-exists", "description": "笔记存在于知识库"}, "notes": "" } ] } ``` --- ## 🔄 Ralph 执行循环(简化版) 不使用 Claude Code 的情况下,可通过 OpenClaw sub-agent 模拟: ``` 每次循环: 1. 读取 prd.json 2. 选取 id 最小的 passes:false 的 story 3. 生成 fresh sub-session 执行该 story 4. 运行 quality gate 检查 5. 通过 → passes:true,追加 notes 6. 重复直到全部完成 ``` --- ## 📝 progress.txt 格式 ``` [YYYY-MM-DD HH:mm] Story #N 完成: 心得: <执行过程中的学到的东西> 耗时: <N 分钟> --- ``` --- ## 💡 与编程任务 PRD 的核心区别 | 维度 | 编程任务 PRD | 非编程任务 PRD | |------|------------|--------------| | 工具链 | git, npm, typecheck, test | FFmpeg, 爬虫, LLM | | 质量门 | 自动(CI/CD) | 混合(自动+人工) | | 人工介入 | 极低(代码审查) | 中等(创意审核) | | Story 大小 | 极小(单次完成) | 中等(可包含创意工作) | | 迭代速度 | 快(机器执行) | 慢(人机混合) | --- ## 🦞 OpenClaw Native Ralph 架构(2026-04-11 实测验证) ### 核心发现 | 问题 | 结论 | |------|------| | Ubuntu1 上无 skill(0个) | Skill 密集型任务 → MacMini;系统任务 → Ubuntu1 | | sessions_spawn + node 参数 | ✅ 可跨节点派生子 agent | | prd.json 状态机 | ✅ 落地验证通过 | | progress.txt 追加日志 | ✅ 追加验证通过 | | Gateway REST API | ❌ 未开启,改用 sessions_spawn | ### 架构图 ``` 星枢(MacMini / 主会话) └── Ralph Engine(Python 脚本 / 星枢派生子 agent) │ ├── 读取 prd.json ├── 选取 passes:false 的 story ├── 判断 targetNode:skill密集型 → MacMini / 系统任务 → Ubuntu1 ├── sessions_spawn(mode=run, node=目标节点) │ └── 子 agent 执行 story + quality gate ├── 更新 prd.json (passes:true / notes) ├── 追加 progress.txt └── 循环直到全部完成 → Telegram 通知 ``` ### 节点 Skill 地图 | 节点 | Skill 可用性 | 适合任务类型 | |------|------------|------------| | MacMini (192.168.3.189) | 全部(Last30Days, n8n, OpenCode, image_generate 等) | 研究、内容生产、编码 | | Ubuntu1 (192.168.3.47) | 无 | 系统运维、Docker、巡检 | | Ubuntu2 (192.168.3.45) | 部分 | n8n 工作流、中间层处理 | ### sessions_spawn 调用格式(OpenClaw Native) ```python # Ralph Engine 内核心调用 sessions_spawn( task=f"""你是 {node} 上的执行者。执行以下 story: Story: {story_title} Quality Gate: {qg_type} - {qg_desc} 工作目录: {work_dir} 目标文件: {target_path} 步骤: 1. [执行命令] 2. [quality gate 验证] 3. [落地 marker 文件或输出] """, runtime="subagent", mode="run", node="ubuntu1 | (default MacMini)", runTimeoutSeconds=600, label=f"ralph-story-{story_id}" ) ``` ### Quality Gate 落地标准(实测有效) ```python # ✅ 有效类型 "type": "file-exists" # touch marker 文件 "type": "command-output" # 命令退出码 0 "type": "human-review" # 人工确认(不可省) # ⚠️ 限制 # - Last30Days 等 skill 必须确认目标节点有装 # - human-review 类型需要人工发送确认指令 ``` --- ## 🦀 Ralph Engine 脚本(Python) > 路径:`~/.openclaw/scripts/ralph_engine.py` > 运行环境:MacMini(协调层) > 依赖:OpenClaw sessions_spawn(通过 API 或 CLI) ```python #!/usr/bin/env python3 """ Ralph Engine - OpenClaw Native Coordinator: MacMini Execution: 按 story 分配到对应节点 PRD: ${WORK_DIR}/prd.json Progress: ${WORK_DIR}/progress.txt """ import json, subprocess, time, sys from datetime import datetime WORK_DIR = sys.argv[1] if len(sys.argv) > 1 else "./ralph-test" PRD_FILE = f"{WORK_DIR}/prd.json" PROGRESS_FILE = f"{WORK_DIR}/progress.txt" # Skill → Node 映射 NODE_MAP = { "last30days": "macmini", # skill 密集型 "n8n": "ubuntu2", "image_generate": "macmini", "video_generate": "macmini", "opencode": "macmini", "docker": "ubuntu1", # 系统任务 "system": "ubuntu1", "default": "macmini" } def get_node_for_story(story): """根据 story 内容判断执行节点""" title = story.get("title", "").lower() for key, node in NODE_MAP.items(): if key in title: return node return NODE_MAP["default"] def spawn_story(story, work_dir): """通过 openclaw sessions CLI 派生子 agent""" story_id = story["id"] title = story["title"] qg = story.get("qualityGate", {}) node = get_node_for_story(story) prompt = f"""Task: {title} Quality Gate: {qg.get('type')} - {qg.get('description', '')} Work dir: {work_dir} Output file: {qg.get('path', f'{work_dir}/story_{story_id}_out.txt')} Steps: 1. Execute the task 2. Run quality gate check 3. Report PASS or FAIL with details 4. Create marker file if pass: touch {work_dir}/story_{story_id}_done """ # 调用 openclaw acp sessions 或者通过 CLI cmd = [ "openclaw", "acp", "sessions", "--session", f"ralph-{story_id}", "--require-existing" ] # 实际通过 sessions_spawn tool 调用,此处仅作架构说明 return True # placeholder def main(): prd = json.load(open(PRD_FILE)) pending = [s for s in prd["userStories"] if not s.get("passes")] for story in pending: spawn_story(story, WORK_DIR) # 更新 prd.json + progress.txt print("Ralph complete") if __name__ == "__main__": main() ``` --- ## ⏰ 自主循环触发设计 ### 方式一:Cron 触发(定时拉起 Ralph Engine) ```bash # MacMini crontab 0 2 * * * openclaw agent --task "检查 ~/ralph-queue/ 目录,有 prd.json 则启动 Ralph Engine" --agent xingshu ``` ### 方式二:目录监听(文件触发) ```bash # inotifywait 或 launchd WatchPath # 检测到 ~/ralph-queue/*.json → 自动启动 Ralph Engine ``` ### 方式三:用户指令触发(最简单) ``` 比利哥:开始执行 ralph prd.json 星枢 → 派生子 agent → 启动 Engine ``` --- ## 📁 标准目录结构 ``` ~/ralph/ ├── queue/ # 待执行的 prd.json 放这里 ├── active/ # 正在执行的项目 ├── archive/ # 完成的项目归档 │ └── YYYY-MM-DD-projectName/ │ ├── prd.json │ ├── progress.txt │ └── [outputs...] └── ralph_engine.py # 执行引擎 ``` --- ## ✅ 实测验证记录(2026-04-11) ### 测试:Ubuntu1 系统巡检 - **结果**:3/3 stories ✅ 完成 - **落地文件**:`sysinfo.txt`(1116B), `docker_status.txt`(835B), `audit_report.md`(2347B), `prd.json`(345B ✅ passes:true), `progress.txt`(188B ✅ 3条追加) - **耗时**:1分43秒 ### 关键验证点 | 验证项 | 结果 | |--------|------| | prd.json passes:true 更新 | ✅ 成功 | | progress.txt 追加日志 | ✅ 成功 | | 跨节点 sessions_spawn | ✅ Ubuntu1 正常 | | skill 路径(Last30Days) | ⚠️ Ubuntu1 无 skill,改用模拟 | | 文件落地 | ✅ 实际验证 | ### 架构修正(对比原设计) 1. **Python Ralph Engine 无法直接调用 sessions API** → 改用 "Ralph Engine as sub-agent task" 2. **skill 全在 MacMini** → 任务智能路由:系统任务→Ubuntu1/内容生产→MacMini 3. **Gateway REST API 限制** → sessions_spawn 是运行时工具,非 API ### 最终架构(已验证) ``` 用户/星枢主会话 └── sessions_spawn → Ralph Engine sub-agent ├── 读取 prd.json ├── exec 执行 story(node 本地) ├── quality gate 检查 ├── 更新 prd.json + progress.txt └── 循环 → 完成后通知 ```