尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Pilot Shell 强制执行TDD:RED-GREEN-REFACTOR 完整机制解析
Pilot Shell 强制执行TDDRED-GREEN-REFACTOR 完整机制解析【免费下载链接】pilot-shellHow real engineers run Claude Code and Codex: spec-driven planning, enforced TDD, persistent memory, and quality enforcement on all levels. Make your agents production-ready.项目地址: https://gitcode.com/GitHub_Trending/cl/pilot-shellPilot Shell是一套让 Claude Code 和 Codex 像真正的工程师一样工作的完整方案规格驱动的计划、强制 TDD、持久记忆和多层质量门禁。本文将完整解析它是如何把经典的RED-GREEN-REFACTOR测试驱动开发循环从一句口号变成 Agent 每次写代码时都被机械执行的硬机制——而不是靠模型自觉。为什么需要强制执行TDD大模型写代码时最大的问题是它倾向于先写实现再补一个看起来通过的测试。测试成了事后橡皮图章断言错得离谱也能绿业内研究显示 AI 生成的测试断言错误率超过 62%。Pilot Shell 的解法很直接在 pilot/rules/testing.md 中把 TDD 定为默认姿态——⛔ 默认先有失败的测试再写生产代码。RED一个针对期望行为的最小测试→ 确认它因正确的原因失败 → GREEN让测试通过的最简实现→ REFACTOR在测试全绿时重构。但规则只是给 Agent 看的提示词可能不被遵守。Pilot Shell 的第二层武器是Hooks钩子在 Agent 的每一次文件编辑之后自动运行一段检查脚本用编辑时提醒把 TDD 循环焊死在开发流程里。机制入口PostToolUse 钩子与 file_checkerTDD 检查的接线点在钩子清单 pilot/hooks/hooks.json 中事件PostToolUse工具使用完成后触发匹配器Write | Edit | MultiEdit凡是写文件/改文件的工具调用执行的命令file_checker.pyfile_checker.py 是统一质量门一次钩子运行里同时做三件事——文件质量检查各语言的格式/lint 规则、TDD 检查、字符集检查最后把告警合并成一条上下文注入给 Agent。它的_tdd_check函数file_checker.py#L41-L87是整个 TDD 强制执行的大脑具体判定逻辑复用 pilot/hooks/_checkers/tdd.py。值得注意的是它的非阻塞设计警告通过 post_tool_use_context 以additionalContext形式附加给 Agent——它提醒但从不阻止编辑。质量靠持续施压而非一棍打死这避免了钩子误伤导致的死锁体验。TDD 判官的五步判定流程每次你或 Agent写下一个非测试文件_tdd_check都会跑完下面这条流水线任何一步命中即放行全部未命中则发出 TDD 提醒第 1 步排除非代码文件。should_skip 维护两张黑名单.md、.json、.yaml、.sql等 20 多种无逻辑扩展名以及/dist/、/node_modules/、/terraform/、/migrations/等 20 多种生成物目录。改文档、改配置、改 IaC天然不需要测试。第 2 步排除测试文件本身。is_test_file 识别各语言的测试命名约定Python 的test_*.py/*_test.py、TypeScript 的.test.ts/.spec.ts、Go 的_test.go、.NET 的*Tests.cs。写测试不需要为测试写测试。第 3 步排除琐碎编辑。is_trivial_edit 会逐行对比编辑前后的差异三种情况视为琐碎而放行琐碎编辑类型示例纯 import 变更增删import/from ... import纯删除新增行是旧行的子序列删掉几行废弃代码纯大写常量赋值只新增MAX_RETRIES 5这类常量这避免了改个 import 就被提醒写测试的噪音。第 4 步核心检查——这个模块有测试吗按语言分派到各自的探测器语言探测器寻找什么Pythonhas_python_test_file同目录test_模块名.py或向上最多 15 层的tests/、__tests__/目录TypeScripthas_typescript_test_file名字.test.ts/.spec.ts并自动处理 PascalCase → kebab-case 转换Gohas_go_test_file模块名_test.go.NEThas_dotnet_test_file类名Tests.cs并识别MyApp.Tests这类测试项目如果找不到对应的测试文件还有两个宽容出口has_test_importing_module 会扫描测试目录里是否有测试实际 import 了该模块功能测试/集成测试也算数.NET 还有 is_dotnet_logic_free通过剥离注释和字符串后保守判定这个.cs文件只有接口/枚举/POCO没有任何可测逻辑才放行。第 5 步Python 专属识别 RED 阶段。这是最精巧的一环见下一节。最聪明的一步识别正在 RED的编辑TDD 的 RED 阶段有个悖论你写失败测试、然后修实现时先有测试在文件系统层面根本不成立——测试是刚写的、实现马上才补。朴素的检查器会在整个 RED 阶段疯狂报警。Pilot Shell 的解法是读取 pytest 的失败缓存has_related_failing_test从被编辑文件的目录开始向上逐级查找.pytest_cache/v/cache/lastfailed解析其中的失败测试列表若存在test_当前模块名或当前模块名_test命名的失败用例——说明你正在修一个为自己而失败的测试这正是合法的 RED→GREEN 过渡放行。换句话说钩子不仅会找有没有测试文件还能读懂测试运行器的状态区分无测试和测试正在失败等实现。这一步让强制执行与真实开发节奏真正咬合。警告长什么样一条注入给 Agent 的提醒当所有出口都没命中钩子会输出一条形如这样的提醒作为上下文注入当前会话TDD Reminder: No test file found for payment module Consider creating test_payment.py first.Agent 看到后按规则补写测试。配合 pilot/skills/spec-implement/steps/02-tdd-loop.md 中的执行流程完整的 TDD 循环是RED:写失败测试 → 确认它因功能缺失而非语法错误失败GREEN:写最小实现让测试通过REFACTOR:在测试保持绿色时改进代码配套防线垂直切片、Bugfix 车道与测试精简Hook 只是编辑时提醒这一层Pilot Shell 用另外三条规则把机制补完整 禁止水平切片。02-tdd-loop.md 明确禁止先把计划里所有 RED 测试写完、再统一写实现——批量写的测试锚定在你想象的函数签名上而不是真实行为上。TDD 循环必须按任务垂直推进一个测试 → 一个实现 → 下一个。如果你发现自己排了 3 个以上还没跑 GREEN 的 RED 测试停下来先完成第一个循环。 Bugfix 没有逃生通道。通用流程里文档、配置、格式化和带Trivial:理由的小改动可以跳过 RED但 Bugfix 计划永远不合格testing.md#L21没有复现测试的 bug 修复就是橡皮图章。Bugfix 车道 强制三任务结构写复现测试 (RED)→根因修复 (GREEN)→质量门且复现测试必须在第一次运行时失败——如果第一次就通过了说明测试写错了或 bug 已修必须停下重查。✂️ 测试精简Test Parsimony。新公共类需要新测试时上限是 1 个单测类 1 个功能测试类测试应结构不敏感只响应行为变化。这防止了为凑覆盖率而堆测试的反模式也让第 4 步的有测试吗检查保持宽松合理——已有的行为测试面就算数不执着于test_模块.py的形式。小结Pilot Shell 的 TDD 强制执行可以概括为四层协同规则层pilot/rules/testing.md告诉 Agent 先失败测试、后实现的原则与例外钩子层pilot/hooks/_checkers/tdd.py每次文件编辑后机械地检查测试是否先于/伴随实现并能识别 RED 阶段、豁免琐碎编辑以非阻塞提醒方式施压技能层spec-implement 的 TDD Loop把 RED-GREEN-REFACTOR 固化为按任务垂直切片的执行步骤Bugfix 走无例外的三任务车道审计层Trivial:豁免、断言质量变异检查等声明都会被后续的变更评审和验证技能对照 diff 审计。结果就是TDD 不再依赖模型记得自己该先写测试而是变成一条每个编辑动作都会触发的物理回路——这正是production-ready agents的核心含义。【免费下载链接】pilot-shellHow real engineers run Claude Code and Codex: spec-driven planning, enforced TDD, persistent memory, and quality enforcement on all levels. Make your agents production-ready.项目地址: https://gitcode.com/GitHub_Trending/cl/pilot-shell创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

AI智能体沙箱逃逸与评分器攻击:安全加固实战指南

AI智能体沙箱逃逸与评分器攻击:安全加固实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/8 14:04:11
从JVM到Java平台:多语言运行时与云原生演进解析

从JVM到Java平台:多语言运行时与云原生演进解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/12 23:37:35
服务器不确定管理口地址---使用NetbootM教程

服务器不确定管理口地址---使用NetbootM教程

后台私信说链接过期了,新的分享链接已更新,软件获取方式需通过复制链接跳转,或扫码获取。 1、下载地址:通过网盘分享的文件:服务器BMC登录工具.rar 链接: https://pan.baidu.com/s/1w5ZmLVewFsVlvt5hcmFAJg?pwd8evf …

📅 2026/9/8 13:23:01
MORE NEWS

更多资讯

📰

启动报Port 8088 was already in use?先查是谁占的

启动报Port 8088 was already in use?先查是谁占的 项目启动报 Port 8088 was already in use,意思很直白:这个端口已经有人占了。 先说原理:端口是"门牌号",一间房只住一个进程 端口就是一台机器上的门牌号…

📰

担心文档上云?本地运行的办公AI才敢放心用

单位上周开了个会,主题是"AI 提效",散会时领导补了一句:涉及客户资料的文档,不许往云端传。这话一出,会议室里本来跃跃欲试的同事全蔫了——大家平时用的那些在线 AI,文档一上传就不知道存哪儿去…

📰

先能用,再好用:从烂尾复盘到两周上线,全栈项目的‘原型—快速迭代‘方法论

先能用,再好用:从烂尾复盘到两周上线,全栈项目的“原型—快速迭代”方法论 全栈学习路径的文章已经很多了:怎么选技术栈、怎么搭环境、怎么记文档,几乎每个方向都有人写。但一个更扎心的问题很少有人正面讨论——为什…

📰

深度思考模式把 ARC-AGI-2 从 17.6% 拉到 45.1%:对照 Gemini 3 Pro 的三份能力评测,看‘会思考‘改写了哪些边界

深度思考模式把 ARC-AGI-2 从 17.6% 拉到 45.1%:对照 Gemini 3 Pro 的三份能力评测,看“会思考”改写了哪些边界 一、先说结论:变强的不是“知识”,而是“解法” 每次新模型发布,评测榜单都会涨几个点,大…

📰

1.c++入门篇

1.c中的关键字asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutablestaticunionwchar_tcatchexplicitnamespacestatic_castunsigneddefaultcharexportnewstructusingfriendclassext…

📰

《江灯合声》:有可行的分框版,也仍可以选择连续鸣谢

武汉江岸区栎坡合唱团在免费节目册《江灯合声》中,以表格集中鸣谢资助者。各家共同要求改为独立小框,团里仍想保留表格。现有全名与支持事项清楚可见,双方此前未承诺具体排版。我支持保留表格。补充的试排材料让选择更具体:分框能…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬