用途
motel-debug 是一个调试技能,配合 motel 使用。motel 是一个本地 OpenTelemetry 采集与查询服务器,用于收集 traces 和日志。该技能的核心主张是:代理仅凭代码猜测问题原因是不够的,需要实际的运行时数据,而 motel 就是提供这些证据的本地服务器。
主要能力
- 通过运行时证据(traces、日志)而非猜测来调试应用。
- 提供默认本地服务器配置:基础 URL 为 http://127.0.0.1:27686,OTLP traces 端点为 POST /v1/traces,OTLP logs 端点为 POST /v1/logs,查询 API 为 GET /api/*,OpenAPI 文档为 GET /openapi.json,请求头为 Content-Type: application/json,默认无认证。若用户提供不同的 motel URL,则使用该 URL。
- 支持服务发现(GET /api/services)、健康检查(GET /api/health)。
- 支持 trace 搜索、span 搜索、日志搜索,以及 AI/LLM 调用搜索与统计。
- 提供属性过滤:attr.<key>=<value> 精确匹配,attrContains.<key>=<substring> 大小写不敏感子串匹配。
- 提供 trace 关联导航:GET /api/traces/<trace-id>/spans 和 GET /api/spans/<span-id>/logs。
- 附带清理脚本 scripts/clear-motel-debug.ts,可确定性移除 JS/TS 文件中 #region motel debug 与 #endregion motel debug 之间的所有代码块,并在标记不匹配时报错。
使用方式
工作流分为八个步骤:
-
验证 motel 是否运行,若未运行则启动。检查 GET /api/health,返回 200 则继续;若失败则以后台守护进程方式启动:motel start。motel start 确保机器全局托管守护进程运行,将运行时文件写入 ${XDG_STATE_HOME:-~/.local/state}/motel/,并返回 JSON 状态。该命令幂等且跨本地项目共享。若 motel 不在 PATH 中,回退使用 bunx @kitlangton/motel start。启动后重新检查健康端点(可能需要 1-2 秒就绪)。若仍失败,读取 ${XDG_STATE_HOME:-~/.local/state}/motel/daemon.log 并向用户展示错误。其他生命周期命令:motel status(JSON 状态)、motel stop(停止共享托管守护进程)。
-
生成假设。在改动任何代码前,生成 3-5 个关于缺陷原因的具体假设,要求精确。
-
使用带标签的调试块进行埋点。添加确认或否定所有假设所需的最小埋点。每个调试块必须包裹在 #region motel debug / #endregion motel debug 标记中,包含 debug.hypothesis 属性,并使用代码库已有的追踪/日志机制。结构化属性键包括:debug.session(分组本次调试会话的所有埋点)、debug.hypothesis(关联具体假设)、debug.step(流程中的位置)、debug.label(人类可读描述)。埋点位置选择:函数入口带参数、函数出口带返回值、关键操作前后的值、分支执行路径、状态变更与中间值、疑似错误或边界值。指南:至少 1 个埋点,不超过 10 个,典型范围 2-6 个。
-
复现问题。若存在失败测试则直接运行;若复现简单则自行编写并运行;否则请用户复现并提供清晰编号步骤。建立复现路径后,后续迭代复用该路径。
-
分析证据。查询 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>"。对每个假设评估为 CONFIRMED、REJECTED 或 INCONCLUSIVE,并引用具体 span、日志或属性值作为证据。
-
仅在获得证据后修复。修复时保留所有调试埋点,修复尽可能小且有针对性,复用现有架构和模式,不过度设计。
-
验证修复。在埋点仍激活的情况下再次复现问题,对比修复前后的证据,引用具体日志行或 span 属性证明修复有效。若修复失败:回退被否定假设的代码改动,从不同子系统生成新假设,增加更多埋点并迭代。
-
清理。仅在修复验证通过且用户确认无遗留问题后:运行清理脚本或手动移除代码块,运行 git diff 确认仅保留有意的修复。
查询模式示例:
curl http://127.0.0.1:27686/api/health curl http://127.0.0.1:27686/api/services
Trace 搜索
curl "http://127.0.0.1:27686/api/traces/search?service=<service>&operation=<text>&attr.debug.session=<session>"
Span 搜索(支持 traceId 限定单个 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>"
日志搜索(支持严重级别过滤、大小写不敏感正文搜索)
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 调用搜索(紧凑摘要带预览)
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 调用详情(完整 prompt/response 载荷)
curl "http://127.0.0.1:27686/api/ai/calls/<span-id>"
AI 统计
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。
适用场景
- 用户希望基于 traces 或日志进行运行时证据调试。
- 需要定位应用缺陷根因,且仅凭代码分析不足。
- 需要追踪 AI/LLM 调用(prompt、response、token 使用、错误状态)。
- 需要将调试日志与具体 span、父操作、时序和完整 trace 树关联。
限制与规则
- 不要记录密钥、令牌、密码或原始 PII。
- 在修复后验证成功前不要移除埋点。
- 不要使用 setTimeout、sleep 或人为延迟作为“修复”。
- 不要让被否定假设的代码改动累积,应回退。
- 若目标仓库使用 Effect,在更改运行时接线或添加埋点前阅读 references/effect.md。
- 若无法运行清理脚本,手动删除每个标记块,然后 grep 搜索 #region motel debug 确认无残留。
- 标记是语言注释包装器,非 JS/TS 文件需适配注释语法(如 Python 用 # #region motel debug)。
- 关于收费、价格、平台支持等具体信息,资料中暂未提供。