关于 motel-debug
面向软件调试的技能,要求以 Motel 收集的运行时追踪和日志验证假设,再据证据修复并复测。它将假设、埋点、复现、验证和清理组织成明确流程。
主要功能
- 01通过 Motel 查询追踪与日志
- 02先提出可验证的故障假设
- 03添加带标记和属性的调试埋点
- 04依据运行时证据验证修复
- 05验证完成后清理临时埋点
适用场景
- 01调查仅凭代码难以定位的故障
- 02通过追踪定位请求执行路径
- 03验证修复是否解决可复现问题
- 04比较修复前后的运行时证据
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ kitlangton/ motel --skill motel-debug安装后在 Claude Code 中输入/motel-debug确认已加载。
附带文件references/effect.mdscripts/clear-motel-debug.ts
详细介绍
Motel Debug
你处于调试模式。请使用运行时证据进行调试,而不是猜测。
Agent 仅根据代码进行猜测。你需要实际的运行时数据。Motel 是本地 OpenTelemetry 服务,用于收集追踪和日志——请将其用作证据闭环。
默认本地服务详情:
- 基础 URL:
http://127.0.0.1:27686 - OTLP 追踪:
POST /v1/traces - OTLP 日志:
POST /v1/logs - 查询 API:
GET /api/* - OpenAPI:
GET /openapi.json - 标头:
Content-Type: application/json - 身份验证:默认无
如果用户提供了其他 motel URL,请使用该 URL,而不是默认值。
工作流
1. 确认 motel 正在运行——如果没有,则启动它
检查 GET /api/health。如果返回 200,则继续。
如果失败(连接被拒绝、超时、非 200),则 motel 未在运行。 将其作为后台守护进程启动——不要启动 TUI,因为它是交互式的,会阻塞你的 shell:
motel start
motel start 可确保机器级全局托管的守护进程正在运行,将
运行时文件写入 ${XDG_STATE_HOME:-~/.local/state}/motel/,并返回
JSON 状态信息。该命令是幂等的,可供本地项目共享。如果 motel 不在 PATH 上,请回退到 bunx @kitlangton/motel start。
启动后,再次检查 GET /api/health(服务可能需要 1–2s 才能就绪)。如果仍然失败,请读取 ${XDG_STATE_HOME:-~/.local/state}/motel/daemon.log 获取错误信息,并告知用户。
其他生命周期命令,供参考:
motel status # JSON status (running? pid? originating workdir?)
motel stop # stop the shared managed daemon for all local projects
需要时,通过 GET /api/services 查找报告服务。
2. 生成假设
在修改任何代码之前,先针对 bug 产生3-5 个具体假设。描述要准确——“缓存键未包含用户 ID”比“缓存有问题”更好。
3. 使用带标签的调试代码块进行插桩
添加足以并行确认或排除所有假设的最少插桩。每个调试代码块都必须:
- 使用
#region motel debug/#endregion motel debug标记包裹 - 包含
debug.hypothesis属性,将其关联到某个具体假设 - 使用代码库已有的追踪/日志机制(跨度、结构化日志、注解——而非原始
fetch调用)
为每处调试插桩添加结构化属性标签,以便后续查询。请复用以下键:
| 键 | 用途 |
|---|---|
debug.session | 将本次调试会话的所有插桩归为一组 |
debug.hypothesis | 关联到某个具体假设(例如 "cache-miss"、"A") |
debug.step | 流程中的位置(例如 "entry"、"before-write"、"after-read") |
debug.label | 对此处捕获内容的易读说明 |
根据假设选择日志记录位置:
- 函数入口处记录参数
- 函数出口处记录返回值
- 关键操作前后的值
- 分支执行路径(运行了哪个 if/else)
- 状态变更和中间值
- 疑似错误值或边缘情况值
指南:
- 至少需要 1 个插桩点;绝不要跳过插桩
- 不要超过 10 个——如果你认为需要更多,请缩小假设范围
- 通常为 2-6 个
4. 重现问题
- 如果存在失败的测试,直接运行
- 如果重现过程简单(CLI 命令、curl、简单脚本),自行编写并运行
- 否则,请用户重现——提供清晰的编号步骤,并提醒他们在需要时重启
- 确定重现路径后,后续每次迭代都复用该路径
5. 分析证据
查询 motel 中的调试插桩:
curl "http://127.0.0.1:27686/api/spans/search?service=<service>&attr.debug.hypothesis=<id>"
curl "http://127.0.0.1:27686/api/logs/search?service=<service>&attr.debug.session=<session>"
curl "http://127.0.0.1:27686/api/traces/search?service=<service>&attr.debug.hypothesis=<id>"
针对每个假设,评估其状态:已确认、已排除或无法确定——引用具体跨度、日志或属性值作为证据。
6. 仅依据证据修复
没有运行时证据时,不要修复。修复时:
- 保留所有调试插桩——暂时不要移除
- 尽可能采用小范围、针对性强的修复
- 复用现有架构和模式;不要过度设计
7. 验证修复
在仪表检测仍处于启用状态时,再次复现问题。比较修复前后的证据:
- 引用具体的日志行或 span 属性,证明修复有效
- 如果修复失败:撤销基于被否定假设所做的代码更改(不要让推测性的修复不断累积),从其他子系统提出新假设,添加更多仪表检测,然后继续迭代
- 迭代是预期之中的。花更多时间收集更多数据,能带来更好的修复效果。
8. 清理
仅在修复已验证并且用户确认没有遗留问题后:
- 运行清理脚本或手动移除代码块(参见下方的清理部分)
- 运行
git diff,确认只剩下有意保留的修复
仪表检测规则
使用以下精确标记包裹每个临时调试代码块:
// #region motel debug
// temporary debug instrumentation
// #endregion motel debug
使用代码库已有的追踪和日志记录机制。这些标记是语言注释包装器——对于非 JS/TS 文件,请调整注释语法(例如,Python 中使用 # #region motel debug)。
请勿:
- 记录机密、令牌、密码或原始 PII
- 在修复后的验证成功前移除仪表检测
- 使用
setTimeout、sleep或人为延迟作为“修复” - 累积基于被否定假设所做的代码更改——请撤销这些更改
查询模式
属性搜索的两个筛选前缀:
| 前缀 | 匹配类型 | 示例 |
|---|---|---|
attr.<key>=<value> | 精确匹配 | attr.debug.hypothesis=cache-miss |
attrContains.<key>=<substring> | 不区分大小写的子字符串匹配 | attrContains.ai.prompt.messages=hello world |
curl http://127.0.0.1:27686/api/health
curl http://127.0.0.1:27686/api/services
# Trace search
curl "http://127.0.0.1:27686/api/traces/search?service=<service>&operation=<text>&attr.debug.session=<session>"
# Span search (supports traceId to scope to one trace)
curl "http://127.0.0.1:27686/api/spans/search?service=<service>&traceId=<trace-id>&attr.debug.hypothesis=<id>"
curl "http://127.0.0.1:27686/api/spans/search?service=<service>&attrContains.ai.prompt.messages=<phrase>"
# Log search (supports severity filter, case-insensitive body search)
curl "http://127.0.0.1:27686/api/logs/search?service=<service>&severity=ERROR&body=<text>"
curl "http://127.0.0.1:27686/api/logs/search?service=<service>&attrContains.debug.label=<substring>"
# AI call search (compact summaries with previews)
curl "http://127.0.0.1:27686/api/ai/calls?model=gpt-5.4&sessionId=<session>"
curl "http://127.0.0.1:27686/api/ai/calls?text=<phrase>&status=error"
# AI call detail (full prompt/response payloads)
curl "http://127.0.0.1:27686/api/ai/calls/<span-id>"
# AI stats
curl "http://127.0.0.1:27686/api/ai/stats?groupBy=model&agg=total_input_tokens"
curl http://127.0.0.1:27686/openapi.json
当有更多数据可用时,列表和搜索响应会包含 meta.nextCursor。
Motel 提供与追踪相关联的数据——你可以查看调试日志所属的 span、父级操作、时间信息以及完整的追踪树。使用 GET /api/traces/<trace-id>/spans 和 GET /api/spans/<span-id>/logs 浏览这些关联数据。
对于 AI/LLM 调用,使用 /api/ai/calls 获取简洁且可搜索的摘要(包含提示词/响应预览和令牌用量),使用 /api/ai/calls/<span-id> 获取完整负载。
Effect
如果目标仓库使用 Effect,请在更改运行时接线或添加仪表检测前阅读 references/effect.md。
清理
需要确定性清理时,请使用随附的脚本 scripts/clear-motel-debug.ts。该脚本会移除 JS/TS 文件中 #region motel debug 和 #endregion motel debug 之间的所有代码块,并在标记不匹配时失败。
如果无法运行该脚本,请手动删除所有标记代码块,然后搜索 #region motel debug,确认没有任何残留。