agent-skills 可观测性清单解析:从 On-Call 问题出发构建结构化日志、RED/USE 指标与症状驱动告警
本篇以 agent-skills 仓库中的 references/observability-checklist.md 为主体,系统拆解这份生产环境遥测(Telemetry)核查清单的完整脉络:如何从 On-Call 问题定义信号、如何用结构化日志与 RED/USE 指标避免基数爆炸、如何用 OpenTelemetry 打通分布式追踪、如何用"症状驱动"告警替代"原因驱动"告警,以及功能上线前必须通过的遥测门禁(Pre-Launch Gate)。读完本文,你将掌握一套可直接用于生产功能开发的埋点核查流程,并理解该清单在 agent-skills 技能体系中的定位与配套技能 observability-and-instrumentation 的协作方式。
一、清单定位:技能包里的"速查参考"层
agent-skills 是一个面向 AI 编码代理的工程技能包,其目录结构遵循"渐进式披露(Progressive disclosure)"设计:skills/ 下每个技能以 SKILL.md 为入口,而 references/ 目录存放 7 份补充性核查清单,供技能在需要时按需加载,以最小化 token 消耗(见 README.md 的 "How Skills Work" 一节)。
observability-checklist.md 在其中承担"速查版"角色。其开篇即声明:
Quick reference for instrumenting production code. Use alongside the
observability-and-instrumentationskill.
在 skills/observability-and-instrumentation/SKILL.md 的结尾(Verification 一节之后),也有反向引用:"For the at-a-glance version of this list, including the pre-launch instrumentation gate, see ../../references/observability-checklist.md."。也就是说,技能文档负责完整的七步流程与反合理化论证(Rationalizations / Red Flags),而本清单浓缩为可直接逐项打勾的核查条目,并在技能基础上额外提供了"仪表盘(Dashboards)"与"上线前门禁(Pre-Launch Gate)"两个独立小节。README.md 的 Reference Checklists 表格对它的概括是:"On-call questions, structured logging, RED/USE metrics, tracing, symptom-based alerting, pre-launch gate"。
二、从 On-Call 问题出发:给遥测定义用途
清单第一个小节是 "On-Call Questions (Start Here)",核心论断是:"Telemetry without a question is noise"(没有问题的遥测就是噪声)。在动手埋点之前,需满足三个条目:
- [ ] 写下 2–4 个 On-Call 工程师会针对该功能提出的问题;
- [ ] 下文每一类信号都必须映射到这些问题之一;
- [ ] 每个问题匹配到正确的信号类型:指标告诉你"有什么问题"(metrics say that something is wrong),追踪告诉你"哪里出问题"(traces say where),日志告诉你"为什么"(logs say why)。
仓库中的评测夹具 evals/fixtures/observability-and-instrumentation/operations.md 给出了这个环节的落地范例——"支付重试"功能的 On-Call 问题清单:
- 重试是否成功恢复了网关的瞬时故障?
- 哪个网关、哪类失败在导致重试耗尽?
- 是否存在同一笔支付被重复扣款?
- 哪些客户可见的支付现在需要人工介入?
该夹具同时划定了敏感数据边界:支付 ID 与尝试 ID 是安全的关联标识符,而卡号、客户邮箱、网关原始响应严禁入日志。这与清单在结构化日志一节中引用的 security-and-hardening 硬性规则相互印证(对应技能 skills/security-and-hardening/SKILL.md)。
三、结构化日志核查项
清单 "Structured Logging" 小节共 8 个核查条目,逐条解读如下:
-
日志必须结构化(JSON),事件名稳定——不是自由拼接的字符串。这一点在仓库夹具 evals/fixtures/observability-and-instrumentation/payment-retry.js 中有一个反面教材:
console.log(`retry ${attempt} failed: ${error.message}`);这行模板字符串无法被过滤、聚合或告警。配套的 skills/observability-and-instrumentation/SKILL.md 给出了改造后的正例:
event: 'payment_failed'的稳定事件名加上paymentId、provider、errorCode、attempt等机器可读字段,并配了error/warn/info/debug四级日志的语义对照表(error= 不变量被破坏、可能有人需要处理;warn= 降级但已处理;info= 重要业务事件;debug= 生产环境默认关闭)。 -
每行日志携带 correlation/request ID,在系统边界生成或接收;
-
关联 ID 必须跨所有出站调用与异步边界传播(HTTP 头、队列元数据)。技能文档中给出了 Express 中间件实现:在请求边界读取
x-request-id头或生成crypto.randomUUID(),用logger.child({ requestId: req.id })派生子日志器并回写响应头; -
日志级别语义一致(见上一条的四级定义);
-
任何日志行不得包含密钥、token、密码或未脱敏的 PII——清单明确标注这是
security-and-hardening技能的硬性规则; -
字段白名单制——不允许整体输出请求/响应体,不允许输出认证头;
-
外部服务调用只记录元数据:端点、状态、时延、尝试次数、脱敏后的标识符;
-
抽查真实日志输出——确认是结构化字段而不是
[object Object]。
最后一条值得强调:清单把"验证实际输出"作为核查项而非建议,呼应了技能文档 "Verification" 一节中 "confirm fields are structured (not [object Object])" 的要求。
四、指标核查项:RED/USE、直方图与基数红线
"Metrics" 小节的 7 个条目可以归为三组规则:
覆盖规则(RED + USE)
- 对每个端点和每个外部依赖都埋 RED 三指标:Rate(速率)、Errors(错误率)、Duration(时延);
- 对每个资源(队列、连接池、主机)埋 USE:Utilization(利用率)、Saturation(饱和度)、Errors(错误)。
统计规则
- 时延必须是直方图(histogram),p50/p95/p99 可查询——"never an average"(绝不用平均值)。技能文档补充了原因:"an average hides the 1% of users having a terrible experience";
- 队列深度与处理时长要对每个 worker/队列单独跟踪。
基数规则(清单中最关键的一组)
- 所有 label 必须来自小而固定的集合(路由模板、状态码类别、服务商名);
- 严禁无界 label 值:不得出现 user ID、tenant ID、邮箱、原始 URL、请求 ID、错误消息文本;
- 状态码按类别归组(用
5xx而不是503)。
技能文档把这条称为 "Cardinality is the failure mode":每一种唯一 label 组合都是一条独立时间序列,无界值会让指标后端撑不住;这些高基数信息应该放进日志和追踪里。仓库附带的示例代码展示了带有限定 label 集合的直方图定义(Prometheus prom-client,技能文档注明这只是一种常见后端选择,RED/USE 与基数规则与厂商无关):
const httpDuration = new Histogram({
name: 'http_request_duration_seconds',
help: 'HTTP request duration',
labelNames: ['method', 'route', 'status_class'], // '2xx', not '200'
buckets: [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5],
});
文档同时给出正误对照:route="/api/tasks/:id"、status_class="5xx"、provider="stripe" 是合格 label;user_id、email、request_id、完整 URL、错误消息文本则永远不该成为 label。
五、分布式追踪核查项
"Distributed Tracing" 小节 7 个条目覆盖了追踪接入的完整生命周期:
- OpenTelemetry(或等价物)在服务启动时初始化,先于其他导入——技能文档的示例是独立的
tracing.ts入口文件,NodeSDK携带serviceName与自动插桩器,"must be imported before anything else"; - 对 HTTP、gRPC、数据库客户端启用自动插桩,代码量趋近于零;
- 追踪上下文在每次出站调用中传播、在每次入站请求中提取,协议为 W3C
traceparent/tracestate; - 上下文必须跨越异步边界存活——队列消息需携带 trace 元数据,否则"trace dies at the gap"(追踪在间隙处断掉);
- 手工 span 只包裹有意义的内部工作单元(如
applyDiscounts、chargeProvider),并附带 On-Call 会用来过滤的属性; - span 属性中不出现密钥或 PII;
- 采样策略:默认低比率的 head-based 采样;若后端支持 tail sampling,错误请求 100% 保留。
六、告警核查项:症状驱动 + 两级严重度
"Alerting" 小节 7 个条目浓缩了 SRE 领域的两条硬规则:
症状驱动,而非原因驱动
Every alert is symptom-based (error rate, p99 latency, queue age) — causes (CPU, disk, restarts) go to dashboards, not pagers.
技能文档给出了对照表:错误率 >1% 持续 5 分钟、p99 时延 >2s、队列积压 >10 分钟属于值得 page 的症状;CPU 85%、某个 pod 重启、磁盘 70% 属于原因,应上仪表盘而不是打给值班人员。原因驱动告警会在"一切正常时误报,在你没预测到的故障时漏报";症状驱动告警则在"用户受损时精确触发,与具体原因无关"。
其余核查条目
- 每条告警必须可行动——"忽略它、会自愈"的告警直接删除;
- 每条告警链接到 runbook,最少三行:它意味着什么、第一条要跑的查询、升级路径;
- 阈值与持续时间必须由 SLO 或历史数据论证,而非拍脑袋;
- 只保留两级严重度:
page(用户可见,立即处理)与ticket(降级,本周内处理)——清单原话:第三级会"变成训练人们忽略一切的噪声"; - 每条新告警试触发一次:确认它到达了正确的渠道、runbook 链接可点;
- 不存在"每天触发并被例行确认、无人处理"的告警。
七、仪表盘核查项
"Dashboards" 小节仅 4 条,但针对性很强:
- [ ] 存在服务健康仪表盘:错误率、p99 时延、流量、饱和度;
- [ ] 依赖健康面板展示每个下游服务的错误率与时延;
- [ ] 仪表盘回答的是清单开头的 On-Call 问题——而不是"everything except the answer"(什么都显示、就是不显示答案);
- [ ] 默认时间范围合理(1h–6h,而不是 30d)。
第四条隐含的操作含义:值班工程师打开仪表盘的默认视图应直接对准"事故当下"的时间窗口。
八、验证遥测本身:把埋点当代码对待
"Verify the Telemetry" 小节开宗明义:"Instrumentation is code; it can be wrong"(埋点也是代码,同样会写错)。四个验证条目构成闭环:
- 在 staging 人为制造一个错误 → 通过 correlation ID 在日志中找到它;
- 发送测试流量 → 指标序列带着预期的 label 和合理数值出现;
- 在追踪 UI 中端到端跟踪一个请求 → 没有断掉的 span;
- 一个人为诱导的故障仅凭遥测数据即可诊断,无需读源码。
第 4 条是最强的验收标准:如果诊断过程需要翻代码,说明遥测本身存在盲区。这一节与技能文档 "7. Verify the telemetry itself" 完全对应,是该技能"验证不可妥协(Verification is non-negotiable)"设计原则的体现。
九、Pre-Launch Gate:上线前遥测门禁
清单最后的 "Pre-Launch Gate" 是相对技能文档独有的强化——在功能进入生产环境之前,以下条目必须全部为真:
- [ ] 结构化日志正在流入日志聚合系统;
- [ ] 每个新端点和每个新依赖的 RED 指标已在仪表盘可见;
- [ ] 至少一条症状驱动告警已配置,附 runbook,且已试触发;
- [ ] 一个请求可以被追踪它经过的每一个服务;
- [ ] On-Call 知道 runbook 放在哪里。
清单末尾将"上线当天的监控时序与回滚触发条件"交给 shipping-and-launch 技能(skills/shipping-and-launch/SKILL.md)——该技能定义了灰度发布阶梯(canary → 5% → 25% → 100% 的监控窗口)与回滚计划,本清单则确保喂给那些监控的遥测管道是完整的。两者形成"埋点就绪 → 发布可观测"的衔接。
十、在仓库中如何使用与验证这份清单
从源码结构看,这份清单的可用性在仓库层面有三重保障:
- 评测用例锚定行为。evals/cases/observability-and-instrumentation.json 定义了针对该技能的评测:prompt 为 "Instrument a new payment-retry feature so on-call can operate it.",期望输出为 "On-call questions defined first, then structured logs, RED metrics, and symptom-based alerts that answer them",并列出四项可核查预期——先写 On-Call 问题、结构化事件日志带 correlation id、指标避免无界基数、告警为症状驱动且可行动。这四个预期与清单的四个核心小节一一对应,说明清单条目本身就是评测断言的素材。
- 正反夹具成对出现。payment-retry.js 提供"未插桩"的基线代码(含
console.log反模式),operations.md 提供"On-Call 问题 + 敏感数据边界"的输入上下文,代理的任务就是按清单把它改造成可运营代码。 - README 的引用表。README.md 在 Reference Checklists 表格中把本清单概括为 "On-call questions, structured logging, RED/USE metrics, tracing, symptom-based alerting, pre-launch gate",可作为检索本清单内容的官方目录。
使用方式上,若你在自己的仓库中为 AI 编码代理安装该技能包(各工具的安装方式见 docs/getting-started.md),当代理执行"为某功能加埋点"类任务时,observability-and-instrumentation 技能负责流程,本清单则作为逐项打勾的验收标准:先确认 On-Call 问题已写就,再逐项核对日志、指标、追踪、告警、仪表盘五组条目,最后以 "Verify the Telemetry" 的四项演练和 Pre-Launch Gate 的五条门禁作为收尾判据。
结语
references/observability-checklist.md 的价值在于把散落在技能长文档中的埋点规则压缩成一份"可执行判据":每个条目都是一个能回答"是/否"的检查点,且全部回溯到可操作的工程动作——写下问题、白名单字段、限定 label 集合、试触发告警、诱导故障验证。配合 skills/observability-and-instrumentation/SKILL.md 的完整流程与 evals/fixtures/observability-and-instrumentation/ 下的正反夹具,它构成了一套从"问题定义"到"上线门禁"的完整可观测性验收链条。
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 StartedRust0627
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