ClawTraces 数据采集
本 Skill 帮助用户从本地 OpenClaw 日志中采集符合要求的 session 数据,转换为 Anthropic 标准 trajectory 格式,并提交到数据收集服务器。
工作流程
按以下顺序执行,每一步完成后再进行下一步。
步骤 1:环境准备(认证 + 环境检查)
认证和环境检查作为一个整体自动完成,中间不需要额外提示。
1.1 认证检查
python3 /{{baseDir}}/scripts/lib/auth.py
脚本输出 JSON,包含 authenticated 字段。
- 已认证:直接进入 1.2。
- 未认证:
- 必须先向用户询问手机号,等用户回复后才能继续。 直接问:"请提供你的手机号(11 位数字)",然后 停下来等待用户回复。绝对不要自己编造或使用任何默认手机号。
- 用户回复手机号后,发送验证码:
其中python3 -c " import sys; sys.path.insert(0, '/{{baseDir}}/scripts') from lib.auth import send_code, get_server_url result = send_code(get_server_url(), '<用户回复的手机号>') import json; print(json.dumps(result, indent=2)) "<用户回复的手机号>替换为用户实际提供的号码。 - 告诉用户"验证码已发送,请查看短信并回复验证码",然后 再次停下来等待用户回复验证码。
- 用户回复验证码后,验证:
python3 -c " import sys; sys.path.insert(0, '/{{baseDir}}/scripts') from lib.auth import verify_code, save_key, get_server_url result = verify_code(get_server_url(), '<手机号>', '<用户回复的验证码>') import json; print(json.dumps(result, indent=2)) if result.get('key'): save_key(result['key']) " - 失败则提示错误并允许重试
1.2 环境检查
python3 /{{baseDir}}/scripts/env_check.py
脚本会自动检查并修复三项配置:
- cache-trace:开启诊断日志(enabled + includeSystem),记录真实 system prompt
- thinking level:确保全局和所有 agent 的 thinkingDefault 至少为 high,提升推理质量
- model reasoning:确保自定义 provider 中白名单模型的 reasoning 为 true,启用推理能力
处理结果:
- 配置已正确:无需额外操作。
- 配置被自动修改:
- 将脚本输出的修改明细(
fixes字段)完整展示给用户,让用户知道对 openclaw.json 做了哪些改动 - 自动重启 OpenClaw:
openclaw gateway restart - 说明 cache-trace 仅记录重启后的新对话,之前的对话无法补充 system prompt 数据。如果当前没有重启后产生的新 session,本次扫描可能无结果,建议用户正常使用一段时间后再来采集。
- 将脚本输出的修改明细(
1.3 完成提示
-
如果 1.2 配置被修改(
changed: true):本次流程到此结束,不继续后续步骤。输出:✅ 环境已就绪!cache-trace 已开启并已重启 OpenClaw。 由于 cache-trace 只记录重启后的新对话,当前没有可采集的数据。 请正常使用 OpenClaw 一段时间后,再运行
/clawtraces采集数据。 -
如果 1.2 配置已正确(
changed: false):输出以下提示,然后停下来等待用户指令:✅ 环境已就绪。你可以:
- 📋 采集数据 — 列出可采集的对话,选择后提交
- 📊 查看进度 — 已提交多少条、查看提交记录
- 📦 提交 Harness — 提交你的 SOUL.md、USER.md 等配置文件
必须原样输出上面的提示,不要自行增减内容,然后停下来等待用户回复。 用户回复后根据语义判断进入步骤 2(采集)、步骤 5(查看进度)或步骤 5.5(提交 Harness)。
步骤 2:采集数据
触发:用户表达了想要采集、提交、查看对话清单的意图。常见表达包括"看看有哪些"、"采集"、"全部"、"最近 N 条"、"帮我处理"等。
2.1 列出对话清单
python3 /{{baseDir}}/scripts/scan_adapter.py --adapter openclaw --list-only
脚本输出 JSON 对象(分页),包含以下字段:
items:当前页的对话列表(默认每页 10 条),每项包含index(序号)、session_id、model、started_at、ended_at、file_size_kb、topic、statustotal:对话总数page:当前页码page_size:每页条数has_more:是否有下一页
status 字段说明:
| status 值 | 含义 | 能否处理 |
|---|---|---|
null | 正常,可直接处理提交 | ✅ |
"active" | 当前活跃对话(尚未 /new 或 /reset) | ✅ 需通过 --sessions 显式指定 |
"rejected" | 之前的扫描中被硬过滤(如轮次不足、模型不合格) | ❌ |
"model_mismatch" | 使用的模型不在采集白名单中 | ❌ |
将 items 以表格形式展示给用户。status 映射为中文标记:
null→ 不显示"active"→⚡活跃中"rejected"→❌不合格"model_mismatch"→⚠️模型不符
示例:
找到 85 个对话记录,显示第 1-10 条:
# 开始时间 结束时间 模型 摘要 状态 1 04-04 14:00 04-04 15:30 claude-opus-4-6 帮我调试一下这个内存泄漏... ⚡活跃中 2 04-04 10:30 04-04 12:15 claude-opus-4-6 帮我把这个 React 组件重构一下... ... 10 04-01 11:00 04-01 12:00 claude-sonnet-4-6 分析用户留存数据... 其中 {N} 个可直接处理(无状态标记的)。还有 75 条,回复「更多」查看下一页。 提示:标记为「⚡活跃中」的对话尚未结束。如果确认已完成,可以选择它来处理;但提交后若继续在该对话中聊天,新增内容将无法补充到已提交的记录中。建议在对话完全结束后再提交。
你想处理哪些?回复"全部"、"前 3 个"、"第 1、3、5 个"等即可。
分页:当 has_more 为 true 时,展示"还有 {total - page*page_size} 条,回复「更多」查看下一页"。用户说"更多"时执行:
python3 /{{baseDir}}/scripts/scan_adapter.py --adapter openclaw --list-only --page 2
继续展示下一页内容,累加到之前的列表上下文中。页码递增直到 has_more 为 false。
如果列表为空(total 为 0):输出无可用数据的提示,流程结束。
2.2 按用户选择处理
用户可能说:
- "全部" → 不传
--sessions,走默认全量处理(只处理status: null的对话) - "前 N 个" / "最近 N 条" → 从清单中取前 N 个
status: null的 session_id(跳过有状态标记的) - "第 1、3、5 个" → 从清单取对应序号的 session_id。如果用户选择了
status: "active"的对话,通过--sessions显式指定(可以处理)。如果用户选择了"rejected"或"model_mismatch"的对话,告知无法处理并说明原因 - 直接给 session_id → 直接使用
确定要处理的 session_id 列表后,执行:
python3 /{{baseDir}}/scripts/scan_adapter.py --adapter openclaw --sessions <id1> <id2> <id3>
快捷方式:指定数量
如果用户在一开始就说了"最近 3 条"、"处理 5 个"等指定数量的表达,可以跳过列表直接使用 --limit 参数:
python3 /{{baseDir}}/scripts/scan_adapter.py --adapter openclaw --limit <N>
快捷方式:按日期范围
如果用户说"最近一周的"、"只要 4 月的"、"从 3 月 20 号开始"等指定日期范围的表达:
将用户的日期表达转换为 YYYY-MM-DD 格式,使用 --since 参数:
python3 /{{baseDir}}/scripts/scan_adapter.py --adapter openclaw --since <YYYY-MM-DD>
--since 可与 --limit 组合使用。例如"最近一周的前 5 条":
python3 /{{baseDir}}/scripts/scan_adapter.py --adapter openclaw --since 2026-03-29 --limit 5
处理结果(所有模式共用)
脚本会自动:
- 按硬性规则过滤(模型、轮次 > 5)
- 按数字指标过滤(用户消息平均长度、长消息数)
- 从 cache-trace 提取真实 system prompt(自动模式下无数据则跳过;
--sessions显式指定时使用重建 prompt) - 为每个通过的 session 自动生成启发式 domain(基于工具使用模式)和 title(基于第一条用户消息)
- 生成 .trajectory.json 文件和 .stats.json 文件
脚本 stdout 输出 JSON 对象,包含两个字段:
candidates:通过所有过滤的候选列表(session_id、turns、domain、model 等摘要字段)filter_report:过滤报告,包含total_found(发现总数)、total_scanned(实际处理数)、pre_filter(前置过滤计数)、passed(通过数)、filtered_count(被过滤数)、filtered(每个被过滤 session 的 session_id、topic、reason、detail)
展示过滤报告:当 filter_report.filtered_count > 0 时,向用户展示过滤摘要。按 reason 分组,默认展示每条的 detail 和 session_id,例如:
扫描了 15 个 session,8 个通过,7 个被过滤:
- 3 个轮次不足: · 3 turns (min 6): session_id_1 · 4 turns (min 6): session_id_2 · 2 turns (min 6): session_id_3
- 2 个无 cache-trace 数据: · no system prompt available: session_id_4 · no system prompt available: session_id_5
- 1 个质量检查未通过: · long user messages (0) < 1: session_id_6
- 1 个转换错误: · tool_error_abort: session_id_7
如果候选数量为 0:本次流程结束,不继续后续步骤。基于 filter_report 展示具体原因:
本次扫描处理了 {total_scanned} 个 session,但全部被过滤:
- {reason 分组}: {count} 个
如需了解具体哪些 session 被过滤及原因,可以查看详情。
如果 total_found 为 0,说明没有使用支持模型的对话,单独说明。
如果有候选:展示扫描结果(候选数量、每个 session 的模型、轮次和启发式 domain),然后继续步骤 3。启发式 domain(由工具使用模式推断)和启发式 title(第一条用户消息截断)直接作为最终值使用;数据的语义质检下沉到服务端打分 + 人工终审阶段。
步骤 3:Harness 门槛检查(进入提交前)
在展示待提交列表之前,先检查是否需要强制提交 Harness:
python3 -c "
import sys; sys.path.insert(0, '/{{baseDir}}/scripts')
from submit import query_count
from lib.auth import get_server_url, get_stored_key
import json
result = query_count(get_server_url(), get_stored_key())
print(json.dumps(result, indent=2))
"
检查返回的 workspace_force_required、workspace_threshold、workspace_submitted、count 字段:
- 如果
workspace_force_required == true且count >= workspace_threshold且workspace_submitted == false:- 告知用户:「你已提交 {count} 条数据(达到 {threshold} 条阈值),需要先提交 Harness 才能继续采集。」
- 自动进入步骤 5.5(提交 Harness)
- Harness 提交成功后继续步骤 4;用户拒绝则流程结束
- 否则:直接进入步骤 4
步骤 4:提交
展示最终待提交列表,格式如下:
找到 N 条可提交的日志:
1. 为 React 项目添加用户认证模块 | 软件开发 | 8 轮
2. 分析 Q1 销售数据并生成报告 | 数据分析 | 12 轮
是否确认提交这 N 条记录?
每条展示标题、领域名称和轮次,不再展示 session_id。
必须等待用户明确确认后才能提交。
用户确认后运行:
python3 /{{baseDir}}/scripts/submit.py
提交完成后展示:本次提交数量 + 你累计已提交的数量(注意:这是当前用户个人的提交总数,不是全平台的)。并提示用户可以说「查看提交记录」来查看历史提交。
workspace_required 错误处理:如果提交过程中某条记录返回 workspace_required 错误(服务端 403),说明用户需要先提交 Harness。告知用户原因,自动进入步骤 5.5。Harness 提交成功后,可重新运行提交。
提交脚本的输出中包含 workspace_threshold、workspace_submitted、workspace_force_required 字段,用于判断是否触发步骤 4.5。
步骤 4.5:Harness 采集(条件触发)
触发条件:步骤 4 提交完成后,如果满足以下两个条件则触发:
- 用户累计提交数量 ≥
workspace_threshold(阈值由服务端控制) workspace_submitted为 false(尚未提交过 Harness)
如果不满足条件,静默跳过此步骤。
注意:此步骤是推荐性提示,无论 workspace_force_required 是否启用都会触发。用户可以拒绝。强制拦截由步骤 3 和服务端 403 保证。
触发后:
4.5.1 征询同意
告知用户:
你已提交 {count} 条数据(达到 {threshold} 条阈值)。为提升数据质量,我们希望采集你的 Harness(SOUL.md、USER.md 等配置文件)。这是一次性采集,所有文件会在本地自动脱敏后再提交。是否同意?
等待用户确认。 用户拒绝则跳过此步骤。
4.5.2 本地打包 + 脱敏
用户同意后,先执行打包(不上传):
python3 /{{baseDir}}/scripts/workspace_bundle.py --bundle-only
脚本输出 JSON,包含每个 workspace 的打包结果和脱敏报告:
workspaces[].zip_file— 生成的 zip 文件名workspaces[].zip_size— 文件大小workspaces[].scrub_report.total_redactions— 脱敏替换总数workspaces[].scrub_report.by_category— 按类别统计(如{"手机号": 2, "邮箱": 1})workspaces[].scrub_report.files_scrubbed— 被脱敏的文件列表及各自的替换详情
4.5.3 展示脱敏信息,确认提交
必须将脱敏信息展示给用户,让用户了解隐私处理情况:
-
如果有脱敏操作(
total_redactions > 0):打包完成。以下文件中检测到敏感信息并已自动脱敏:
文件 脱敏项 SOUL.md 手机号 ×2, 邮箱 ×1 memory/user_profile.md API Key ×1 共 {total} 处敏感信息已替换为占位符(如
[PHONE]、[EMAIL]),原始内容不会上传。 是否确认提交? -
如果没有脱敏操作(
total_redactions == 0):打包完成,未检测到需要脱敏的敏感信息。是否确认提交?
等待用户确认。
4.5.4 上传
用户确认后执行上传:
python3 /{{baseDir}}/scripts/workspace_bundle.py --upload-only
展示上传结果(成功/失败的 workspace 数量)。
步骤 5:查询(可选)
触发:用户说「查看提交记录」「提交了多少条」「查看进度」等。
python3 /{{baseDir}}/scripts/query.py [--page N] [--page-size N]
展示已提交的 session 列表,每条包含标题、领域、模型、轮次、提交时间。默认每页 20 条,支持分页。
以表格形式展示:
提交记录(共 {total} 条)
# 标题 领域 模型 轮次 提交时间 1 为 React 项目添加认证 软件开发 claude-opus-4-6 8 2026-04-08 14:30 ...
用户说「更多」或「下一页」时加载下一页。
步骤 5.5:独立 Harness 提交
触发:用户说「提交 Harness」「提交 Workspace」「提交工作区配置」「workspace」等。
5.5.1 查询已提交状态
python3 -c "
import sys; sys.path.insert(0, '/{{baseDir}}/scripts')
from submit import query_count
from lib.auth import get_server_url, get_stored_key
import json
print(json.dumps(query_count(get_server_url(), get_stored_key()), indent=2))
"
读取返回的 workspace_submitted 字段。
5.5.2 已提交过的提醒(workspace_submitted == true)
如果用户之前已经提交过 Harness,不要拒绝,而是原样输出以下提示并 停下来等待用户回复:
你之前已经提交过 Harness。如果你本地的配置文件有了更新(比如 SOUL.md、USER.md、memory/ 下的内容有新变化),可以再提交一份最新版本,后端会保留所有历史版本作为参考。
是否需要提交一份新版本?
- 用户确认("好"、"提交"、"更新"等)→ 进入 5.5.3
- 用户拒绝("不用"、"算了"等)→ 流程结束
如果 workspace_submitted == false(首次提交),直接进入 5.5.3,不需要展示上面的提醒。
5.5.3 本地打包 + 脱敏
python3 /{{baseDir}}/scripts/workspace_bundle.py --bundle-only
5.5.4 展示脱敏报告,征询用户确认
展示格式与步骤 4.5.3 一致(按文件列出脱敏项,或说明未检测到敏感信息),然后等待用户确认。
5.5.5 上传
python3 /{{baseDir}}/scripts/workspace_bundle.py --upload-only
展示上传结果。
步骤 6:重新提交(独立操作)
当用户明确要求"重新提交"某条记录时使用。必须提供 session_id,不提供则要求用户补充。
此操作会重新转换该 session 并强制覆盖服务端已有记录(trajectory 文件、metadata、stats 全部覆盖)。
流程
- 确认认证状态(同步骤 1.1)
- 用户提供的 session_id 对应的 trajectory 文件必须已存在于
output/目录。如果不存在,需要先重新运行扫描转换(步骤 2)生成该文件,再继续。 - 运行重新提交:
python3 /{{baseDir}}/scripts/submit.py --resubmit {session_id}
- 展示结果(是否覆盖成功、累计提交数)。
注意:此步骤仅在用户明确说"重新提交 xxx"时触发,正常的批量提交流程(步骤 2-4)不会使用 force 参数。
401 处理
在任何步骤中,如果 API 返回 401(unauthorized),说明 key 已失效:
- 通知用户 key 已失效
- 自动清除本地 key(脚本已自动完成)
- 重新进入步骤 1.1 的认证流程(跳过 1.2 环境检查,因为环境配置不受 key 失效影响)
- 认证成功后,从发生 401 的步骤继续执行
数据目录
数据文件存放在 workspace 根目录的 .clawtraces/ 下(与 .clawhub/ 同级),独立于 skill 安装目录,不受升级影响:
{workspace}/.clawtraces/
├── .env # API key + server URL
└── output/
├── {session_id}.trajectory.json # 转换后的 Anthropic trajectory 文件
├── {session_id}.stats.json # session 元数据
└── manifest.json # 提交记录 + 拒绝记录(已处理 session 跟踪)
注意事项
- 认证完成后必须原样输出提示文案并等待用户指令,不要自动开始采集,不要自行增减提示内容
--list-only是轻量操作(只读索引和文件元数据),不消耗大量资源--limit N只处理最近 N 个对话--since YYYY-MM-DD只处理该日期之后的对话,可与--limit组合使用--sessions指定的对话会跳过"活跃"和"已提交"的自动过滤,因为用户明确选择了它们--list-only列出除已提交外的所有对话(包括活跃、已拒绝、模型不符的),用status字段区分- 默认处理(不带
--sessions)仍然严格过滤:只处理白名单模型、非活跃、非已拒绝的对话 - 用户消息中的隐私信息(Sender 身份、时间戳)会在转换时自动清除
- System prompt 从 cache-trace 提取。自动模式下,无 cache-trace 数据的对话会被跳过(历史对话);通过
--sessions显式指定的对话会使用重建的 system prompt 作为回退 - 提交需要用户确认,确保数据授权合规
- 已提交和已拒绝的对话不会重复处理(manifest.json 跟踪)
- 面向用户的文案中统一使用"对话"而非"session",session_id 等技术字段仅在内部处理时使用