gstack 的 OpenClaw 原生技能:investigate 系统化调试方法论详解
gstack 在 openclaw/skills/ 目录下为 OpenClaw 编排器提供了一组"原生方法论技能"(native methodology skills),其中 gstack-openclaw-investigate 是面向对话式调试场景的完整工作流:它把"先找根因、再谈修复"的铁律固化为五个可执行阶段,并配套模式库、假设验证、三次试错熔断和结构化调试报告。读完本文,你将掌握这套在 AI 代理(Agent)环境下约束"打地鼠式修 Bug"的完整方法论,并了解它如何嵌入 gstack 与 OpenClaw 的集成架构中运行。
技能定位:何时触发、如何被分发
该技能的 frontmatter 定义了它的触发条件与身份:
name: gstack-openclaw-investigate
description: Use when asked to debug, fix a bug, investigate an error, or do root cause analysis, and when users report errors, stack traces, unexpected behavior, or say something stopped working.
注意 frontmatter 只有 name 和 description 两个字段——这不是疏漏,而是 OpenClaw 原生技能的刻意设计。test/openclaw-native-skills.test.ts 中的测试会逐一读取四个原生技能(investigate、office-hours、ceo-review、retro)的 frontmatter,断言其"能解析为 YAML 且只包含 name 和 description 两个键":
const OPENCLAW_NATIVE_SKILLS = [
'openclaw/skills/gstack-openclaw-investigate/SKILL.md',
'openclaw/skills/gstack-openclaw-office-hours/SKILL.md',
'openclaw/skills/gstack-openclaw-ceo-review/SKILL.md',
'openclaw/skills/gstack-openclaw-retro/SKILL.md',
];
// ...
expect(Object.keys(parsed).sort()).toEqual(['description', 'name']);
这种"最小 frontmatter"约束保证了技能可以被 clawhub install 直接发布到 ClawHub,而不依赖 Claude Code 侧的 hooks、preamble 等基础设施。docs/OPENCLAW.md 明确说明这些技能是"gstack 方法论面向 OpenClaw 对话场景的手工适配版本,不带任何 gstack 基础设施(no browse, no telemetry, no preamble)"。
在 OpenClaw 的分发体系中,该技能属于 HEAVY 层级。openclaw/agents-gstack-section.md 中的 Dispatch Routing 规定了五档派发(SIMPLE / MEDIUM / HEAVY / FULL / PLAN),其中 HEAVY 档对应"需要特定 gstack 方法论"的场景,/investigate 就在其技能清单内:
**HEAVY:** needs a specific gstack methodology
→ sessions_spawn(runtime: "acp", prompt: "Load gstack. Run /qa https://...")
Skills: /cso, /review, /qa, /ship, /investigate, /design-review, /benchmark, /gstack-upgrade
判定启发式也很明确:代码改动小于 10 行走 SIMPLE;多文件但思路明确走 MEDIUM(注入 gstack-lite-CLAUDE.md 的五条规划纪律);用户点名特定技能走 HEAVY。三条不可协商的行为规则也适用于此:总是 spawn 会话而不是让用户自己打开 Claude Code;用户提到仓库时先解析仓库路径;报告直接回到聊天中,用户无需离开 Telegram。
Iron Law:先根因,后修复
整个方法论只有一句话的总纲,且被放在最醒目位置:
NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST.
只修症状会造成"打地鼠"式调试。每一个没有触及根因的修复,都会让下一个 Bug 更难找到。先找根因,再修。
这条铁律在文档末尾的 Important Rules 中又被三条硬规则反复强化:3 次以上修复失败就停下质疑架构;绝不能应用自己无法验证的修复;绝不说"this should fix it"("这应该能修好")——必须跑测试、给出证据。
Phase 1:根因调查(Root Cause Investigation)
原则是"先收集上下文,再形成任何假设",共五步:
-
收集症状(Collect symptoms):读错误信息、堆栈和复现步骤。用户上下文不足时,一次只问一个问题——不要一次抛五个问题。
-
读代码(Read the code):从症状回溯代码路径到潜在成因;搜索所有引用,阅读失败点附近的逻辑。
-
检查近期变更(Check recent changes):
git log --oneline -20 -- <affected-files>关键提问:之前能工作吗?什么变了?如果是回归,根因就在 diff 里。
-
复现(Reproduce):能否确定性触发?不能的话,先收集更多证据再继续。
-
查记忆(Check memory):检索同一区域的既往调试记录。同一批文件反复出 Bug 是"架构异味"(architectural smell)。
阶段产出是一个具体且可测试的主张:"Root cause hypothesis: ..."——说清楚"哪里错了"以及"为什么错"。
值得一提的是,gstack 的 Claude Code 完整版技能 investigate/SKILL.md 在第 5 步上更重:它会通过 frontmatter 中的 gbrain.context_queries 自动注入"本仓库既往调查"(按 repo:{repo_slug} 标签过滤的 timeline 记录)、~/.gstack/projects/{repo_slug}/learnings.jsonl 的最近 10 条 learnings 等上下文;正文还附带一段调用 gstack-learnings-search 检索历史经验、以及基于 hypothesis 关键词二次检索的脚本。OpenClaw 版本则把这些基础设施收敛为一句"查记忆"指令——这正是"方法论源(methodology source)而非移植代码库(ported codebase)"这一集成哲学的体现:OpenClaw 侧的记忆系统(memory/ 目录、brain repo)承担上下文职责,gstack 只提供流程骨架。
Phase 2:模式分析(Pattern Analysis)
原文档给出了六类已知 Bug 模式,构成一个"签名 → 检查位置"的速查表:
| 模式 | 签名 | 检查位置 |
|---|---|---|
| 竞态条件(Race condition) | 间歇性、与时间相关 | 共享状态的并发访问 |
| 空值传播(Nil/null propagation) | NoMethodError、TypeError | 可选值上缺失的守卫 |
| 状态损坏(State corruption) | 数据不一致、部分更新 | 事务、回调、hooks |
| 集成失败(Integration failure) | 超时、意外响应 | 外部 API 调用、服务边界 |
| 配置漂移(Configuration drift) | 本地正常、staging/prod 失败 | 环境变量、feature flags、数据库状态 |
| 陈旧缓存(Stale cache) | 显示旧数据、清缓存后恢复 | Redis、CDN、浏览器缓存 |
表格之外的两个补充动作同样关键:
- 检查项目已知的同类问题(如
TODOS.md)和同一区域的既往修复提交——同一文件反复出 Bug 是架构异味,不是巧合; - 外部检索先脱敏(Sanitize first):若 Bug 不匹配任何已知模式,再去搜索错误类型,但必须先剥掉主机名、IP、文件路径、SQL 片段和客户数据;搜索的是"错误类别",不是原始报错文案。
这条脱敏规则与 gstack 仓库自身的 redact-* 系列实现(如 lib/redact-engine.ts、lib/redact-patterns.ts)在理念上一致:任何离开本地环境的错误信息,都要先过一遍敏感数据过滤。
Phase 3:假设验证(Hypothesis Testing)
在写任何修复代码之前,先验证假设:
-
确认假设:在疑似根因处加临时日志、断言或调试输出,跑复现步骤,看证据是否吻合。
-
假设错误时:先脱敏搜索错误信息,然后回到 Phase 1 收集更多证据——不许猜。
-
三次试错规则(3-strike rule):3 个假设都失败就 STOP,并向用户说明:
"3 hypotheses tested, none match. This may be an architectural issue rather than a simple bug."
随后给出三个选项:带着新假设继续调查、升级给人工评审(需要熟悉系统的人)、或加埋点等下次自然触发。
文档还列出了三类"红旗信号",看到任何一条就该慢下来:
- "先快速修一下(for now)"——没有"暂时"这回事,要么修对,要么升级;
- 还没追踪数据流就提议修复——那是在猜;
- 每次修复都在别处暴露新问题——说明层次错了,不是代码错了。
Phase 4:实现(Implementation)
根因确认后,实现阶段有五道纪律:
- 修根因,不修症状——消除实际问题所需的最小改动。
- 最小 diff:改动最少的文件、最少的行数,克制重构相邻代码的冲动。
- 写回归测试,且必须双向证明:没有修复时失败(证明测试有意义),有修复时通过(证明修复有效)。
- 跑完整测试套件,不允许任何回归。
- 改动超过 5 个文件时必须先向用户示警——对一个 Bug 修复来说这是很大的爆炸半径,需要用户确认后再继续。
Claude Code 完整版技能对第 5 点给出了标准的 AskUserQuestion 话术(Proceed / Split / Rethink 三选项),OpenClaw 版本保留了指令本身——因为对话场景下"直接说"就是它的交互方式。
Phase 5:验证与报告(Verification & Report)
- 新鲜验证(Fresh verification):重新复现最初的 Bug 场景并确认已修复——"This is not optional"。
- 跑测试套件,输出结构化调试报告:
DEBUG REPORT
- Symptom: 用户观察到的现象
- Root cause: 实际错在哪里
- Fix: 改了什么,附文件引用
- Evidence: 测试输出、证明修复有效的复现记录
- Regression test: 新测试的位置
- Related: 同区域的历史 Bug、架构备注
- Status: DONE | DONE_WITH_CONCERNS | BLOCKED
最后一步是把报告按当天日期存入 memory/,供未来的会话检索引用——这与 gstack-openclaw-retro 把每周回顾快照存为 memory/retro-YYYY-MM-DD.json 做趋势对比是同一种记忆持久化模式:OpenClaw 的 memory/ 目录既是调试报告的归宿,也是跨会话学习的基础。
完成状态协议与硬性规则
技能结尾的 Important Rules 是所有阶段的收敛约束:
- 3 次以上修复失败 → 停下,质疑架构。是架构错了,不是假设错了;
- 绝不应用无法验证的修复。复现不了、确认不了的,就不要发布;
- 绝不说"this should fix it"。验证并证明它——跑测试;
- 改动超过 5 个文件 → 先向用户示警再继续;
- 完成状态只有三种:
DONE— 找到根因、修复已应用、回归测试已写、全部测试通过;DONE_WITH_CONCERNS— 修复了但无法完全验证(如间歇性 Bug、需要 staging 环境);BLOCKED— 调查后根因仍不明,已升级。
这套状态协议与 gstack 各技能通用的 Completion Status Protocol(DONE / DONE_WITH_CONCERNS / BLOCKED / NEEDS_CONTEXT)保持一致,使得编排器可以机器可判定地识别任务结局。
与 Claude Code 完整版 investigate 的关系
理解 OpenClaw 版与 investigate/SKILL.md 的分工,有助于把握整个集成架构:
| 维度 | Claude Code 版 investigate/ |
OpenClaw 版 openclaw/skills/ |
|---|---|---|
| frontmatter | name、triggers、hooks(Edit/Write 时检查 freeze 边界)、gbrain 上下文查询、preamble tier | 仅 name + description(受测试强制约束) |
| 运行前置 | 完整 preamble(更新检查、会话标记、遥测、learnings 加载) | 无 preamble,直接执行方法论 |
| 记忆机制 | gstack-learnings-search / gstack-learnings-log CLI |
OpenClaw 的 memory/ 目录约定 |
| 发布方式 | 随 gstack 安装到 ~/.claude/skills/gstack |
clawhub install 发布到 ClawHub |
docs/OPENCLAW.md 对整体架构的定位是:"gstack integrates with OpenClaw as a methodology source, not a ported codebase"。OpenClaw 的 ACP runtime 原生 spawn Claude Code 会话,gstack 提供让这些会话更可靠的规划纪律与方法论——"这是一个编码为提示词文本的轻量协议。没有守护进程,没有 JSON-RPC,提示词就是桥梁(The prompt is the bridge)"。gstack-openclaw-investigate 正是这条路线下最典型的产物:完整继承五阶段调试纪律与全部硬规则,同时剥掉所有 gstack 运行时基础设施,让方法论本身成为可移植的资产。
小结
- 触发:调试请求、报错、堆栈、"昨天还能跑"类描述 →
gstack-openclaw-investigate; - 铁律:先根因调查,后修复;3 次假设失败即熔断并质疑架构;
- 五阶段:症状收集与 git 回溯 → 六类模式匹配(外部检索先脱敏)→ 假设验证 → 最小 diff + 双向回归测试 → 新鲜验证与 DEBUG REPORT;
- 产物:按日期落盘
memory/的调试报告,DONE / DONE_WITH_CONCERNS / BLOCKED三态收尾; - 工程保障:
test/openclaw-native-skills.test.ts守护 frontmatter 形态,bun run gen:skill-docs --host openclaw再生成全套 OpenClaw 工件。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00