oh-my-openagent 编程 Skills 深度分析
oh-my-openagent 的编程 skills 不是提示词模板,是可执行的工程纪律契约。每条 skill 是一个状态机:定义触发条件、强制前置阅读、分阶段执行、自检环。
核心 skills 共有六条:
1. programming 负责跨语言编码纪律(覆盖 Go、Python、Rust、TypeScript)
2. refactor 实现 6 阶段安全重构协议
3. debugging 提供假设驱动的调试循环
4. git-master 管工作流
5. review-work 管代码审查
6. start-work 做计划编排。
一、programming — 跨语言编码纪律
设计哲学:6 条公理
所有语言规则都从这 6 条公理推导出来。
第一条:类型系统是你的证明系统。 让非法状态不可表示。编译器是你跑过的最便宜的测试。
第二条:解析,不验证。 不可信输入在边界恰好被解析为类型化值一次;边界之内接收类型化值,永不重复验证。
第三条:一个名字就是一个概念。 UserId 不是 string,Seconds 不是 Milliseconds。每个语义原语用 newtype 包装。
第四条:穷举变体匹配,始终。 禁止用 if/elif/else 区分 tagged variant,只用 match 加 assert_never。
第五条:信任框架保证,只在边界验证。 不对类型系统已经证明的值做空检查、不对不会抛异常的代码做 try/except。
第六条:测试驱动,用正确形状的测试。 Red → Green → Refactor,Given/When/Then 结构。
跨语言铁律
这 6 条公理落到四个语言上,各有不同的实现方式。
默认不可变。 Python 用 frozen=True, slots=True 的数据类。Rust 默认 let 而非 let mut。TypeScript 用 readonly。Go 不导出字段。四个语言,同一个原则。
尊重原语。 Python 用 NewType("UserId", int),Rust 用 struct UserId(u64),TypeScript 用 branded type,Go 用 type UserID string。核心思想一样:不让原始类型裸奔。
穷举匹配。 Python 用 match 加 assert_never,Rust 的 match 编译器强制穷举,TypeScript 用 switch 加 assertNever,Go 用 sealed interface 加 exhaustive linter。每个语言都有自己的穷举检查手段,不用 if/else 凑合。
错误处理。 Python 用带类型的 exception dataclass,Rust 用 thiserror enum,TypeScript 用 Error 子类,Go 用
errors.New 加带类型 struct 再加 %w 包装。没有裸字符串错误。
边界捕获。 Python 只捕获预期的异常,Rust 的 ? 无处不在但只传播声明过的错误类型,TypeScript 的 catch 必须窄化再重抛,Go 每个 (T, error) 返回值都要检查。
资源管理(RAII)。 Python 用 with 和 async with,Rust 用 Drop trait,TypeScript 用 using 和 await using,Go 用经典的 defer x.Close()。
2026 年技术栈(逐语言)
Python: uv 管包,basedpyright 做全量类型检查,ruff 同时做 lint 和格式化,pytest 跑测试,FastAPI 做 web,SQLAlchemy 2.x async 管数据库,typer 加 rich 做 CLI,structlog 记日志,pydantic-ai 对接 LLM 和 Agent。
Rust: cargo 管包,rustc 加 clippy pedantic 做类型和 lint,rustfmt 格式化,cargo-nextest 跑测试,axum 做 web,sqlx 管数据库,clap 做 CLI,tracing 记日志。LLM 调用通过 subprocess 桥接到 Python。
TypeScript: Bun 做包管理兼运行时,tsc --noEmit 在 strict 模式做类型检查,Biome 替代 ESLint 和 Prettier,bun test 或 vitest 跑测试,Hono 做 web,Drizzle 做 ORM,@clack/prompts 做 CLI 交互,pino 记日志,Vercel AI SDK 对接 LLM。
Go: go modules 管包,golangci-lint v2 加 nilaway 做类型和 lint,gofumpt 格式化,go test -race -shuffle=on 跑测试,gin 或 chi 做 web,sqlc 加 pgx 做数据库(不是 GORM),cobra 做 CLI,log/slog 记日志,net/http 直接调用 LLM API。
代码坏味道(自动触发审查)
文件超过 250 行纯逻辑代码就是缺陷,必须拆分。
函数超过 3 个参数就是坏味,应该分组为类型化值对象。
破坏操作后的冗余验证(写完之后马上读回来检查)是 AI 生成代码的典型防御性膨胀,直接删掉。
否定形式命名(isNotValid、noErrors)重命名为肯定形式。
强制写后审查环
每次写完代码后,Agent 必须自问 10 个问题:
文件有单一职责吗,能用一句话命名吗;边界纯净吗,不可信输入在边界被解析了吗;变体区分用了穷举匹配而非 if/else 吗;有没有 Any、unwrap、@ts-ignore 这样的逃脱舱口;有没有对类型已证明值做多余的防御性空检查;有没有只被调用一次的一次性 helper 函数;新行为被测试锁定吗;参数超过 3 个吗;破坏操作后有多余的重新查询验证吗;有没有否定命名的东西。
二、refactor — 6 阶段安全重构协议
重构不是"打开文件,开始改"。oh-my-openagent 把它做成了一个 6 阶段的状态机。
Phase 0 是意图门:先解析请求类型,验证自己是否真正理解了要做什么。很多 AI 重构失败在这一步——它没确认就动手了。
Phase 1 是代码库分析:并行启动 5 个 explore agent,加上 LSP 做精确定义查找和引用分析,加上 ast-grep 做结构化模式匹配。三路并进。
Phase 2 构建代码地图:生成依赖图、标记影响区域、评估每步的风险等级。
Phase 3 评估测试覆盖:如果覆盖率不够,拒绝激进重构。
Phase 4 生成计划:Plan agent 把重构分解为多个原子步骤,每一步都可以独立验证。
Phase 5 执行重构:每一步的模式是 LSP 安全重命名 → 运行 lsp_diagnostics 验证 → 提交 git checkpoint。一步一个 checkpoint,出问题立即回滚。
Phase 6 最终验证:跑全量测试套件、类型检查、lint、构建。四项全绿才算通过。
核心原则就五个:理解再修改(先 LSP 再动手)、预览再执行(ast-grep 先 dry-run 再 apply)、每步验证、失败即停、覆盖不足就阻塞。
五个工具各司其职:LSP 负责精确定义查找和引用分析,ast-grep 做结构化模式匹配和批量替换,explore agent 做并行的代码库模式发现,Plan agent 生成详细的重构步骤,Oracle agent 应付复杂的架构决策。
当重构步骤中独立文件操作超过 3 个时,自动启用 team mode。一个 Lead(叫 Sisyphus)纯编排不写代码。两个 quick worker 做机械编辑(LSP 重命名、提取变量)。两个 unspecified-low worker 做逻辑重构(提取函数、模式转换)。外面还有一个独立的 verifier 负责验证,不参与重构本身。
三、debugging — 假设驱动的调试循环
调试 skill 有两条核心纪律。第一,运行时真相胜过代码阅读——每个关于 bug 原因的声明,必须来自观察到的状态,不能是从看代码编出来的可信故事。第二,不留痕迹——所有调试产物都记录到 .debug-journal.md 日志,完成后全部清除。
具体执行分 10 个阶段。
Phase 0 做环境评估——搞清楚运行时类型、端口、符号表、环境变量。
Phase 1 建日志文件追踪所有产物。
Phase 2 是关键:形成至少 3 个假设,必须跨正交轴(不是同一维度的 3 个变体),每个假设要有区分性证据。
Phase 3 并行调查,可以用 team mode 的 debug-squad 或者异步子代理。
Phase 4 是 Oracle Triple:连续两轮调查失败后,从正交角度生成 3 个 Oracle 提示。
Phase 5 只在证据耗尽且有政策影响时才升级给用户决策。
Phase 6 根因确认规则很严格:只有当切换疑似原因能切换 bug 时才算确认。
Phase 7 开始 TDD 修复——先写失败的 red test,最小 green 修复,不扩展范围。
Phase 8 手动 QA,实际使用系统——tmux、Playwright、curl,不是只跑测试。
Phase 9 清理,按日志回滚所有产物,验证 git diff 只有修复和测试。
Phase 10 过 4 个证据门做最终验证。
调试 skill 还有一个独特的设计:
每个运行时都有必读的参考文件,不读就不能动手,因为这个运行时的调试工具和行为和其他运行时不同。
Python 的 pdb、ipdb、debugpy、pytest --pdb 语义各自不同。Node.js 的 tsx 加 node inspect 有静默 source-map 失败。
Rust 的 Release 构建剥离了调试符号,tokio 任务需要 tokio-console 才能看到。Go 的 goroutine 泄漏和 recover panic 默认静默。macOS 原生二进制的 SIP、Mach-O、lldb 行为与 Linux 完全不同。甚至打包应用二进制(看起来像 Mach-O 或 ELF 但实际是 JS)需要完全不同的调试策略。
四、skill 设计的通用模式
从这三条 skill 里能提炼出 oh-my-openagent 设计 philosophy 的六个通用模式。
第一,强制前置阅读。 每条 skill 开头都是"读这个参考文件。不读就别动手。"这不是建议,是硬性门控。Phase 0 的 LANGUAGE GATE 用全大写写死了:"DO NOT WRITE OR EDIT A SINGLE LINE OF CODE BEFORE COMPLETING THIS GATE."这不是给人类的,是给 AI Agent 的约束。
第二,引用外部化。 SKILL.md 本身是精简的索引,90% 的知识存在 references/ 子目录里。触发 skill 时只加载 SKILL.md(体积小),按需加载 references(按语言、按场景)。这是渐进式披露在 skill 层的应用。
第三,状态机阶段。 每条 skill 都是明确编号的阶段序列,每个阶段有四个要素:进入条件、工具或代理调用指令、完成标记、失败处理路径。不是段落散文,是状态机。
第四,自我审查环。 执行完不算完——必须通过自检环。programming 有 10 个问题,debugging 有 4 个证据门,refactor 每一步都要验证。这是 AI 写代码最容易跳过的步骤,oh-my-openagent 把它写死了。
第五,代理组合。 skill 不是让单个 agent 执行,而是编排多个 agent 协作。explore agent 做人肉搜索,plan agent 生成详细计划,oracle agent 应付困难决策,后台 agent 做并行探索,team mode 协调多 agent 协作重构。skill 是 conductor,不是 executor。
第六,技术栈锁定。 不泛泛说"用好的实践"——每个语言在 2026 年的正确工具链是写死的:uv 而非 pip,Biome 而非 ESLint 加 Prettier,sqlc 而非 GORM。这是可执行的判断,不是可讨论的风格。当工具链被锁定,AI 就没有选择余地,也就不会在选工具上浪费时间或选错。
来源:oh-my-openagent packages/shared-skills/skills/, 2026-06-18