1. OpenClaw Agent 上线后为什么必须补可观测性
OpenClaw 跑在本地或内网,一边接模型做意图决策,一边调度技能去动文件、发请求、查数据。它不像普通 Web 服务那样只有一条请求链路,而是「模型决策 + 技能执行 + 集群调度」三层叠加。上线初期大家往往只关心能不能跑通,等真正进了生产环境,问题就来了:某条指令卡了 40 秒没人知道卡在哪、某个技能昨天开始失败率飙升、某个 Worker 节点悄悄离线、某个账号在凌晨高频调用敏感技能。这些都不是靠tail -f能解决的。
AI Agent observability 说白了就是给 Agent 装一套「天眼系统」,核心回答四个问题:谁在什么时候发了什么指令、这条指令经过了哪些环节、每个环节耗时和结果如何、出问题时能不能自动喊人。它由四层构成——日志(Logs)记录发生了什么,指标(Metrics)度量运行得好不好,追踪(Traces)串起全链路怎么走的,告警(Alerts)在异常时主动通知。四层缺一层,排查就会断链。
适合读这篇的人很明确:负责把 OpenClaw 做成稳定企业平台的运维和 SRE、遇到过任务莫名卡住却查不到原因的平台管理员、需要满足内控和审计要求的团队负责人。这篇不空谈概念,直接交付可复制的日志字段规范、监控指标清单、追踪埋点配置和告警规则模板,并且把多模型调用凭证统一收敛到 TaoToken 通道,让「模型调用」这一层也进入可观测范围。下面按落地顺序一步步来。
2. TaoToken 统一 Key 通道接入与凭证前置准备
在搭可观测性之前,先把模型调用这一层的凭证管起来。原因很直接:OpenClaw 的追踪链路里,「模型调用」是一个关键 span,如果每个技能、每个节点各自散落着不同的 Key,你既没法统一统计调用量,也没法在 Key 失效时快速定位是哪条链路挂了。TaoToken 提供统一的 API 通道,把多模型调用凭证集中到一处管理,OpenClaw 侧只需要认一个 Base URL 和一把 Key。
先到控制台创建 Key。打开 https://taotoken.net/console ,登录后进入 API Keys 页面新建一把,命名建议带上用途,比如openclaw-prod-agent,方便后续在日志里按 Key 维度做归因。创建后立刻复制保存,页面刷新后不再完整显示。
拿到 Key 之后,OpenClaw 的模型接入配置需要填三件套:Base URL、API Key、Model ID。Base URL 统一填https://taotoken.net/api,注意这里不带任何查询参数。Model ID 按你实际要用的模型填写,比如claude-sonnet-4-5或gpt-4o这类,具体可用列表在接入文档里查:https://taotoken.net/doc 。如果你用的是 Claude Code 这类工具做辅助开发,它的 Anthropic 兼容入口在 https://taotoken.net/claude-code-anthropic ,配置方式同理。
这里有个容易踩的坑:很多人把 Base URL 写成带/v1后缀或者带 UTM 参数的地址,结果请求 404 或鉴权失败。记住 API 地址就是干净的https://taotoken.net/api,路径拼接由 SDK 自己处理。另外,Key 不要硬编码进技能脚本,统一放到环境变量或配置中心,这样日志里可以只记录 Key 的指纹(比如后四位),既满足审计又不泄露凭证。
凭证统一之后,你在日志和指标里就能按「Key → 模型 → 技能」的维度做聚合。比如发现某个模型调用失败率突然升高,能立刻判断是这一把 Key 的问题还是模型侧的问题,而不是在十几个散落的配置里翻找。这一步做完,可观测性的「模型调用层」才算有了统一入口。
3. 可复制配置:日志字段规范、指标清单与追踪埋点
这一节给可直接落地的配置片段。先定日志格式,OpenClaw 的日志建议全部走 JSON 结构化,方便后续被 Loki 或 ELK 采集解析。下面是一份字段规范,覆盖访问、审计、技能执行、系统四类:
{ "traceId": "oc-trace-8f3a2b", "spanId": "span-04", "timestamp": "2026-03-21T14:30:00.120Z", "level": "INFO", "type": "skill_exec", "userId": "zhangsan", "sourceIp": "10.20.3.15", "skill": "desk-file-archive", "paramsHash": "a1b2c3", "success": true, "costMs": 1240, "model": "claude-sonnet-4-5", "keyFingerprint": "****7f2a", "message": "执行完成" }字段说明几个关键点:traceId和spanId是全链路追踪的骨架,必须每条日志都带;paramsHash存参数哈希而不是明文,避免日志里泄露敏感内容;keyFingerprint记录 Key 后四位,用于归因但不暴露完整凭证;type字段区分access、audit、skill_exec、system四类,采集时按类型分流到不同索引。
指标清单按三层整理,可以直接照着做 Prometheus 的 metric 定义:
| 层级 | 指标名 | 类型 | 说明 |
|---|---|---|---|
| 网关层 | oc_gateway_qps | Counter | 每秒请求数 |
| 网关层 | oc_auth_fail_total | Counter | 鉴权失败累计 |
| 网关层 | oc_http_error_rate | Gauge | 4xx/5xx 占比 |
| 技能层 | oc_skill_calls_total | Counter | 技能调用次数,带 skill 标签 |
| 技能层 | oc_skill_success_rate | Gauge | 成功率 |
| 技能层 | oc_skill_duration_ms | Histogram | 耗时分布,算 P50/P95 |
| 技能层 | oc_model_calls_total | Counter | 模型调用次数,带 model 标签 |
| 集群层 | oc_worker_online | Gauge | 在线 Worker 数 |
| 集群层 | oc_task_queue_depth | Gauge | 任务排队数 |
| 集群层 | oc_node_cpu_usage | Gauge | 节点 CPU 占用 |
追踪埋点配置,OpenClaw 一条指令的链路是「接收 → 意图解析 → 权限校验 → 技能调度 → 执行 → 返回」。在每个环节入口生成子 span,继承同一个 traceId。下面是一段埋点伪代码,用 OpenTelemetry 风格写:
from opentelemetry import trace tracer = trace.get_tracer("openclaw.agent") def handle_instruction(user_id, instruction): with tracer.start_as_current_span("receive_instruction") as root: trace_id = root.get_span_context().trace_id with tracer.start_as_current_span("intent_parse"): intent = parse_intent(instruction) with tracer.start_as_current_span("auth_check"): check_permission(user_id, intent) with tracer.start_as_current_span("skill_dispatch") as dispatch: dispatch.set_attribute("skill", intent.skill) result = execute_skill(intent) return result告警规则模板用 Prometheus 的 alerting rules 写,下面几条是必开的:
groups: - name: openclaw_agent rules: - alert: SkillFailureRateHigh expr: rate(oc_skill_calls_total{success="false"}[5m]) / rate(oc_skill_calls_total[5m]) > 0.05 for: 2m labels: severity: warning annotations: summary: "技能失败率超过 5%" - alert: InstructionTimeout expr: histogram_quantile(0.95, rate(oc_skill_duration_ms_bucket[5m])) > 10000 for: 1m labels: severity: critical - alert: WorkerOffline expr: oc_worker_online < 1 for: 30s labels: severity: critical - alert: AuthFailSpike expr: rate(oc_auth_fail_total[1m]) > 20 for: 1m labels: severity: warning这几段配置拼起来,日志、指标、追踪、告警四层就有了基线。注意for字段别省,避免瞬时抖动触发误报。
4. 验证请求与成功结果:从一条指令看全链路
配置写完必须验证,否则你不知道埋点是否真的串起来了。验证分三步:发一条测试指令、查日志、看追踪。
先发一条最简单的技能调用,比如让 OpenClaw 执行一个文件归档技能。在 OpenClaw 控制台或通过 API 发指令:
curl -X POST https://your-openclaw-host/api/instruction \ -H "Authorization: Bearer <your-openclaw-token>" \ -H "Content-Type: application/json" \ -d '{"userId":"zhangsan","instruction":"归档 /tmp/test 目录"}'请求返回后,去日志系统按traceId检索。如果日志采集正常,你应该能看到一条type: access的接收日志、一条type: audit的权限校验日志、一条type: skill_exec的执行日志,三条共享同一个traceId。用 Loki 查询的话大概是这样:
{job="openclaw"} |= "oc-trace-8f3a2b"正常输出应该能看到时间戳递增的三条记录,costMs字段分别对应各环节耗时。如果只看到一条,说明埋点没继承 traceId,回去检查 span 的父子关系。
接着看追踪。打开 Jaeger 或你用的追踪后端,按 traceId 搜索,应该看到一棵调用树:
traceId: oc-trace-8f3a2b ├── 0ms receive_instruction ├── 120ms intent_parse ├── 180ms auth_check ├── 220ms skill_dispatch (skill=desk-file-archive) ├── 240ms model_call (model=claude-sonnet-4-5) └── 1340ms return_result这棵树能直接告诉你时间花在哪:如果model_call占了 900ms,那瓶颈在模型侧;如果auth_check异常长,那是权限服务的问题。最后看指标,在 Grafana 里查oc_skill_success_rate,应该显示 100%,oc_skill_duration_ms的 P95 应该在合理范围。告警规则此时不应触发,如果触发了说明阈值设得太紧。
验证通过的标准是:一条指令能在日志里按 traceId 串起来、在追踪里看到完整调用树、在指标大盘上看到计数增加。这三样都对了,可观测性基线就算立住了。
5. 本篇常见报错排查:401、local proxy failed、reading choices、OAuth
落地过程中最容易卡在几个具体报错上,逐个说清楚。
401 Unauthorized。这个最常见,八成是 Key 或 Base URL 配错。先确认 Base URL 是https://taotoken.net/api,不带多余路径和参数。再确认 Key 没有多余空格,环境变量读取时有没有被引号包进去。如果 Key 刚创建,确认没有误删。排查命令可以直接打一次模型列表接口:
curl https://taotoken.net/api/v1/models \ -H "Authorization: Bearer $TAOTOKEN_API_KEY"返回 200 说明凭证没问题,返回 401 就回去重新生成 Key。
local proxy failed。这个报错通常出现在 OpenClaw 节点通过本地网络出口访问模型通道时。先检查节点到taotoken.net的网络连通性,用curl -v看卡在哪一步。如果是 DNS 解析失败,检查节点的 resolv.conf;如果是连接超时,检查防火墙出站规则是否放行了 443。注意不要用任何非正规的网络工具去绕,企业环境应该走合规的出口策略。
reading choices 报错。这个一般出现在解析模型返回时,choices字段读不到。原因通常是返回体不是预期的 JSON 结构,可能是鉴权失败返回了错误页,也可能是模型 ID 写错导致返回了错误信息。排查方法:把原始返回体打出来看,确认choices字段是否存在。如果返回的是 HTML 错误页,说明请求根本没到模型层,回去查 Base URL。
OAuth 相关报错。如果你用 Claude Code 或类似工具接入,可能会遇到 OAuth 流程问题。这类工具走的是 Anthropic 兼容入口,配置时 Base URL 填https://taotoken.net/claude-code-anthropic,Key 用同一把。如果报 OAuth token 无效,检查是不是把 API Key 和 OAuth token 搞混了,两者不是一回事。重新走一遍接入文档里的配置步骤即可。
排查时记住一个原则:先确认凭证和地址,再看网络连通性,最后看返回体内容。大部分报错都出在前两步。
6. 把可观测性做成日常:从基线到持续运营
基线搭好只是开始,真正让 Agent 可看、可管、可排查,靠的是日常运营。几个实操建议。
日志保留策略要分层:普通运行日志保留 90 天够用,审计日志建议 180 天以上,因为内控和审计往往要求可追溯。存储上,审计日志单独放一个索引,权限收紧,只有安全团队能查。技能执行日志可以按技能名分索引,方便按技能做聚合分析。
指标大盘建议固定几个面板:今日指令总数、技能成功率 TOP10 和失败率 TOP10、最活跃用户 TOP10、集群健康状态、异常告警实时显示。这几个面板每天上班扫一眼,异常基本跑不掉。技能失败率 TOP10 尤其有用,能快速发现哪个技能在退化。
告警渠道接企业微信或钉钉机器人,告警文案带上 traceId,点进去就能直接查链路。下面是一个告警文案模板:
【OpenClaw 告警】 类型:技能执行失败 技能:desk-file-archive 用户:zhangsan 时间:2026-03-21 14:31 错误:目标路径无写入权限 traceId:oc-trace-8f3a2b告警阈值别设太紧,失败率 5%、超时 10s、节点离线 30s 这几个是经过验证的合理起点。设太紧会被误报淹没,设太松又失去意义,上线后根据实际数据微调。
最后,把模型调用凭证统一收敛到 TaoToken 通道这件事,本身就是可观测性的一部分。凭证集中之后,模型调用量、失败率、Key 维度归因都能统一统计,不用在多个配置里对账。接入文档在 https://taotoken.net/doc ,模型对话调试入口在 https://taotoken.net/chat ,长期跑编码和 Agent 任务的团队可以看 Coding Plan:https://taotoken.net/coding-plan 。把这些入口和你的日志、指标、追踪、告警四层接起来,OpenClaw 才算真正从「能跑」走到「可运营」。