尧图精选

Sandcastle 实现型 Agent 提示词设计:从 Issue 到 Commit 的自动化工作流实战

🕒 发布时间:2026/9/26 7:35:59 📁 来源:尧图网络
【免费下载链接】sandcastleOrchestrate sandboxed coding agents in TypeScript with sandcastle.run()项目地址https://gitcode.com/gh_mirrors/sandcastl/sandcastle点击查看免费下载导读implement-prompt.md是 Sandcastle 项目中“实现型工作流”implement agent workflow的提示词模板它把一个 GitHub Issue 变成一次可交付的编码任务拉取 Issue 上下文、在指定分支上通过红-绿-重构循环编写代码、运行类型检查与测试、最后以规范格式提交。本文基于该文档结合 .sandcastle/agent-workflows/implement/implement.ts 等仓库源码讲解该提示词的结构、占位符机制、内置 shell 块、执行约束与配套工作流让你能直接复现并定制属于自己的“Issue 自动实现”Agent。一、文档定位Sandcastle 的“实现”环节在 Sandcastle 的编排体系中一条完整的自动化开发流水线通常包含四个阶段可参见 .sandcastle/run.ts 中的三阶段编排Plan计划读取开放 Issue分析依赖关系产出可并行执行的任务清单.sandcastle/plan-prompt.mdImplement实现针对每个 Issue在独立分支上写代码、跑测试、提交本文主角 .sandcastle/implement-prompt.mdReview评审对实现结果做代码审查并直接优化.sandcastle/review-prompt.mdMerge合并把各分支合并回主干并关闭 Issue.sandcastle/merge-prompt.md。implement-prompt.md是整个流水线中最核心的“执行单元”它把“如何完成一个 Issue”这件事完整地委托给 Agent并用严格的规则约束其行为边界。二、提示词结构逐段拆解原文档由六个相互衔接的部分组成TASK、CONTEXT、EXPLORATION、EXECUTION、FEEDBACK LOOPS、COMMIT最后以THE ISSUE与FINAL RULES收尾。下面逐一说明每段的职责与可替换变量。1. TASK明确任务入口# TASK Fix issue #{{ISSUE_NUMBER}}: {{ISSUE_TITLE}} Pull in the issue using gh issue view, with comments. If it has a parent PRD, pull that in too. Only work on the issue specified. Work on branch {{BRANCH}}. Make commits, run tests, and close the issue when done.这一段的要点任务原子性Only work on the issue specified明确限定 Agent 只能处理指定 Issue禁止发散到其他任务——这是FINAL RULES中 “ONLY WORK ON A SINGLE TASK” 的呼应。上下文获取通过 GitHub CLI 的gh issue view带--comments拉取 Issue 详情如果该 Issue 关联了父级 PRD产品需求文档也要一并读取保证实现者理解需求全貌。注意该模板中写着 “close the issue when done”但文档后半部分THE ISSUE段明确要求 “Do not close the issue - this will be done later”。这是模板演进留下的一个矛盾点——在配套的 .sandcastle/agent-workflows/implement/prompt.md 中这一规则被统一为“不 push、不关 Issue、不编辑标签、不创建 PR”。实践时应以后者为准把“关闭 Issue”的职责留给合并阶段。2. CONTEXT注入最近提交历史# CONTEXT Here are the last 10 commits: recent-commits !git log -n 10 --format%H%n%ad%n%B--- --dateshort /recent-commits这里展示了 Sandcastle 提示词的两大动态机制!反引号 shell 块以!开头包裹在反引号中的内容会被 Sandcastle 在提示词预处理阶段原地执行并把命令输出嵌入提示词见 src/PromptPreprocessor.ts。这里的git log -n 10会把最近 10 条提交的哈希、日期、正文注入recent-commits标签让 Agent 在动手前了解仓库最近的演变。{{KEY}}占位符{{ISSUE_NUMBER}}、{{ISSUE_TITLE}}、{{BRANCH}}会在运行时被promptArgs中的实际值替换机制详见 src/PromptArgumentSubstitution.ts。git log的参数解读--format%H%n%ad%n%B---%H为完整提交哈希%n为换行%ad为按--dateshort格式化的日期YYYY-MM-DD%B为提交正文---作为提交之间的分隔符-n 10只取最近 10 条控制注入上下文的体量。3. EXPLORATION先探索再动手# EXPLORATION Explore the repo and fill your context window with relevant information that will allow you to complete the task. Pay extra attention to test files that touch the relevant parts of the code.这段没有硬性命令但它设定了关键的行为准则实现前必须探索仓库、填充上下文窗口并特别强调“优先阅读与改动点相关的测试文件”。这正是仓库 .sandcastle/CODING_STANDARDS.md 中“通过公共接口验证行为而非实现细节”测试理念的前置——Agent 只有先看懂现有测试才能写出符合项目风格的测试。4. EXECUTION红-绿-重构循环# EXECUTION If applicable, use RGR to complete the task. 1. RED: write one test 2. GREEN: write the implementation to pass that test 3. REPEAT until done 4. REFACTOR the code这里定义了 TDD测试驱动开发的完整循环RGR 即 RED-GREEN-REFACTORRED先写一个会失败的测试GREEN写最小实现让它通过REPEAT重复直到任务完成REFACTOR最后整理代码。与 .sandcastle/CODING_STANDARDS.md 的 “TDD Workflow: Vertical Slices” 完全一致“Do NOT write all tests first, then all implementation”而应“一个测试、一个实现、循环往复”每个测试都回应上一轮循环中学到的东西且“Never refactor while RED”。在配套的 .sandcastle/agent-workflows/implement/prompt.md 中还有一个重要补充不要擅自发明新的测试接缝比如为了单独测试而抽取函数这会“创造意大利面条式测试”只有在已存在测试接缝时才做红-绿-重构。5. FEEDBACK LOOPS提交前的质量闸门# FEEDBACK LOOPS Before committing, run npm run typecheck and npm run test to ensure the tests pass.这是硬性质量门禁每次提交前必须运行npm run typecheck和npm run test。本仓库的 package.json 中定义了两条对应脚本前者做全量类型检查后者运行完整的 vitest 测试套件见 vitest.config.ts。任何实现只有在通过这两道闸门后才有资格进入提交环节。6. COMMIT规范化的提交消息# COMMIT Make a git commit. The commit message must: 1. Start with RALPH: prefix 2. Include task completed PRD reference 3. Key decisions made 4. Files changed 5. Blockers or notes for next iteration Keep it concise.提交消息有严格的五要素结构以RALPH:前缀开头这是本流水线的统一提交标识评审阶段的 .sandcastle/review-prompt.md 也要求提交以RALPH: Review -开头包含“任务已完成”的说明与 PRD 引用记录关键决策为什么这样实现列出变更文件记录阻塞项或留给下一轮迭代的备注。同时要求“Keep it concise”——结构完整但文字精炼。要注意的是配套的 implement prompt 采用的是 conventional commits约定式提交风格二者可根据流水线版本选择核心是让提交消息可被下游评审与合并环节读取。7. THE ISSUE 与 FINAL RULES收尾规则# THE ISSUE If the task is not complete, leave a comment on the GitHub issue with what was done. Do not close the issue - this will be done later. Once complete, output promiseCOMPLETE/promise. # FINAL RULES ONLY WORK ON A SINGLE TASK.收尾部分定义了三个关键行为未完成时在 GitHub Issue 上留言说明已做的工作而不是悄悄结束不关闭 Issue关闭动作由后续的 Merge 环节统一执行见 .sandcastle/merge-prompt.md 中 “For each branch that was merged, close its issue”完成标志Agent 必须输出promiseCOMPLETE/promise结构化标记供编排代码.sandcastle/agent-workflows/shared/run-with-extraction.ts解析提取。ONLY WORK ON A SINGLE TASK是最终红线单个 Agent 会话只处理单个任务保证每次运行结果可追踪、可评审。三、提示词如何被真实调用实现层源码解析implement-prompt.md不是孤立文档它在两处被真实调用下面分别解析。1. 单 Issue 直连实现implement.ts.sandcastle/agent-workflows/implement/implement.ts 是“一个 Issue 一个 Agent”的最简调用方式const ISSUE_NUMBER required(ISSUE_NUMBER); const ISSUE_TITLE required(ISSUE_TITLE); const BRANCH required(BRANCH); try { const issueContext safeSh(gh issue view ${ISSUE_NUMBER} --comments) || Issue #${ISSUE_NUMBER}: ${ISSUE_TITLE}; const result await sandcastle.run({ name: implement-#${ISSUE_NUMBER}, agent: claudeAgent(), sandbox: noSandbox(), logging: { type: stdout }, promptFile: path.join(import.meta.dirname, prompt.md), promptArgs: { ISSUE_NUMBER, ISSUE_TITLE, BRANCH, ISSUE_CONTEXT: issueContext, }, }); // ...这段代码展示了模板中所有{{KEY}}的来源占位符来源{{ISSUE_NUMBER}}环境变量ISSUE_NUMBER经required()校验缺失即退出{{ISSUE_TITLE}}环境变量ISSUE_TITLE{{BRANCH}}环境变量BRANCH{{ISSUE_CONTEXT}}运行时通过gh issue view NUMBER --comments拉取值得注意的几个工程细节required()校验定义在 .sandcastle/agent-workflows/shared/common.ts环境变量缺失会打印错误并process.exit(1)保证编排不会带着残缺参数运行safeSh降级gh issue view失败如未登录、网络问题时返回空字符串并用Issue #N: TITLE兜底Agent 依然可以基于标题开工noSandbox()本次实现运行在宿主机直接执行见 src/sandboxes/no-sandbox.ts适合在本地仓库上直接跑需要隔离环境时可换成docker()见 src/sandboxes/docker.ts提交数量校验git rev-list --count main..HEAD统计当前分支领先main的提交数如果为 0 则调用fail()报错——“Agent 结束了但没产生任何提交”这是对“假完成”的第一道防线。2. 多 Issue 并行编排run.ts.sandcastle/run.ts 展示了完全不同的调用形态——Plan/Implement/Review/Merge 四阶段循环实现阶段运行在独立的 git worktree 沙箱中await using sandbox await sandcastle.createSandbox({ sandbox: docker(), branch: issue.branch, copyToWorktree: [node_modules], hooks: { sandbox: { onSandboxReady: [{ command: npm install npm run build }], }, }, }); const result await sandbox.run({ name: Implementer # issue.number, agent: sandcastle.claudeCode(claude-opus-4-8), promptFile: ./.sandcastle/implement-prompt.md, promptArgs: { TASK_ID: String(issue.number), ISSUE_TITLE: issue.title, BRANCH: issue.branch, }, });关键点createSandbox为每个 Issue 创建独立 worktree分支即issue.branchcopyToWorktree: [node_modules]预拷贝依赖避免重复安装onSandboxReady钩子在沙箱就绪后执行npm install npm run build使用sandcastle.claudeCode(claude-opus-4-8)指定 Claude Code Agent对比 implement.ts 中通过claudeAgent()并注入CLAUDE_CODE_OAUTH_TOKEN的另一种认证方式见 .sandcastle/agent-workflows/shared/common.ts这里的promptArgs使用TASK_ID而非ISSUE_NUMBER说明模板中的占位符键名可以按编排方需求替换——模板用{{ISSUE_NUMBER}}还是{{TASK_ID}}只要与promptArgs的键一一对应即可实现完成后如果result.commits.length 0立即在同一沙箱中运行评审 AgentReviewer #N使用 .sandcastle/review-prompt.md实现与评审共享同一个 worktree 状态。四、占位符与 shell 块机制的底层原理模板中同时使用了{{KEY}}与!反引号两种动态语法二者由 Sandcastle 核心库在把提示词交给 Agent 前处理其实现位于 src/PromptArgumentSubstitution.ts。占位符替换{{KEY}}类型PromptArgs Recordstring, string | number | boolean只接受字符串、数字、布尔三种值替换规则{{KEY}}用promptArgs[KEY].toString()替换严格校验fail-fast 设计参见 ADR docs/adr/0020-prompt-expansion-fails-fast.md模板中引用了占位符但promptArgs没有对应键 → 抛出PromptError“Prompt argument {{KEY}} has no matching value in promptArgs”键存在但值为null/undefined→ 同样报错promptArgs提供了多余键模板未引用→ 打印警告除非该键在silentKeys中内置键SOURCE_BRANCH、TARGET_BRANCH见BUILT_IN_PROMPT_ARG_KEYS不允许被promptArgs覆盖内联提示词prompt: ...不允许携带promptArgs因为内联内容原样透传占位符不会生效——必须改用promptFile才能使用{{KEY}}替换。正是这套严格的 fail-fast 校验保证了implement-prompt.md中任何一个{{KEY}}缺失时运行会立即失败并给出明确报错而不是把带着空占位符的提示词发给 Agent 造成“幻觉式”的误执行。Shell 块执行!反引号!反引号中的命令如git log -n 10 ...在提示词预处理阶段于宿主机上执行输出直接嵌入recent-commits之类的标签中。从 src/PromptArgumentSubstitution.ts 的源码看这类 shell 块在原始模板中被标记且在参数替换时会被消毒剥离伪造标记防止通过promptArgs注入任意命令——这是提示词注入防护的重要一环。五、如何在仓库中扩展与定制实现工作流如果你要在自己的 Sandcastle 流水线中复用或改造这个实现提示词仓库提供了完整的可参考形态最简单任务参考 .sandcastle/agent-workflows/implement/implement.ts直接以noSandbox()在本机运行环境变量传参并行多任务参考 .sandcastle/run.ts先由 .sandcastle/plan-prompt.md 产出planJSON再用docker()沙箱 worktree 并行执行MAX_PARALLEL 4控制并发上限带评审的实现参考 .sandcastle/agent-workflows/implement-pr/implement-pr.ts用sandcastle.Output.object()声明结构化输出配合 .sandcastle/agent-workflows/shared/run-with-extraction.ts把 Agent 产出的评论、回复等结果提取为 JSON 落盘并校验“有提交或有评论”才算有效完成。定制时注意保持提示词的内在一致性占位符键名与promptArgs对齐、FINAL RULES中的单一任务约束、提交消息结构、promiseCOMPLETE/promise结束标记——这些是编排代码能够可靠解析和判断完成状态的契约。若提示词与编排逻辑如“是否关闭 Issue”存在冲突应像仓库中 implement-prompt 的两个版本那样以运行时的实际规则为准并保持版本同步。六、小结implement-prompt.md的价值在于它把“实现一个 Issue”这件复杂工作压缩成了一段可编排、可验证、可复用的提示词契约结构上任务 → 上下文 → 探索 → 执行 → 反馈 → 提交 → 收尾六段闭环机制上{{KEY}}占位符负责注入参数!shell 块负责注入动态仓库信息两者都在运行前由核心库完成严格的替换与校验行为上单一任务、红-绿-重构、提交前必跑 typecheck 与 test、规范化提交消息、完成时输出promiseCOMPLETE/promise。配合 .sandcastle/agent-workflows/implement/implement.ts 与 .sandcastle/run.ts 两种调用形态你可以从“单 Issue 自动实现”平滑扩展到“多 Issue 并行实现 评审 合并”的完整自动化流水线——这正是 Sandcastle 作为沙箱化编码 Agent 编排器的核心使用场景。赞分享【免费下载链接】sandcastleOrchestrate sandboxed coding agents in TypeScript with sandcastle.run()项目地址https://gitcode.com/gh_mirrors/sandcastl/sandcastle点击查看免费下载相关推荐深入解析 uv 的 Issue 上下文增量更新机制update-issue-context 自动化提示词设计与工作流实现深入解析 uv 的 Issue 上下文增量更新机制update issue context 自动化提示词设计与工作流实现 uv 仓库中的 update iss包管理器开发工具CLIOpenChamber Issue-Intake Agent 提示词设计用 OpenCode 单代理替代双 Bot 的 Issue 分流工作流OpenChamber Issue Intake Agent 提示词设计用 OpenCode 单代理替代双 Bot 的 Issue 分流工作流 本文深入剖析AI Agent人工智能代码智能体交互助手Ekko Agent 内置 gh-issues 技能实战从 GitHub Issue 分流到 Pull Request 的自动化工作流Ekko Agent 内置 gh issues 技能实战从 GitHub Issue 分流到 Pull Request 的自动化工作流 本篇技术指南以 EkkAI 应用人工智能AI Agent本地部署前端后端工作流自动化上一篇数字时代的建筑师在Awesome Agent Skills中构建负责任的AI下一篇OpenDrop仿真结果分析图表绘制与统计方法创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →