Braintrust追踪ClaudeCode技能Skill braintrust-tracing

这个技能用于在Braintrust平台中追踪和监控Claude Code会话,包括钩子架构、子代理相关性、调试和状态管理。它帮助开发者和AI工程师优化AI代码生成工具,实现性能监控、问题排查和数据收集。关键词:Braintrust, Claude Code, 追踪, 调试, AI代理, 钩子架构, 子代理相关性, 状态管理, 性能监控, 数据收集。

AI智能体 0 次安装 0 次浏览 更新于 3/14/2026

名称: braintrust-追踪 描述: Claude Code 的 Braintrust 追踪 - 钩子架构、子代理相关性、调试 用户可调用: false

Claude Code 的 Braintrust 追踪

Braintrust 中追踪 Claude Code 会话的全面指南,包括子代理相关性。

架构概述

                         父会话
                    +---------------------+
                    |  会话开始       |
                    |  (创建根)     |
                    +----------+----------+
                               |
                    +----------v----------+
                    |  用户提示提交   |
                    |  (创建回合)     |
                    +----------+----------+
                               |
          +--------------------+--------------------+
          |                    |                    |
+---------v--------+  +--------v--------+  +--------v--------+
| 工具使用后      |  | 工具使用后     |  | 工具使用前      |
| (读取跨度)      |  | (编辑跨度)     |  | (任务 - 注入) |
+------------------+  +-----------------+  +--------+--------+
                                                    |
                                         +----------v----------+
                                         |   子代理         |
                                         |   会话开始      |
                                         |   (新根_跨度_id)|
                                         +----------+----------+
                                                    |
                                         +----------v----------+
                                         |   子代理停止      |
                                         |   (有会话_id)  |
                                         +---------------------+

钩子事件流

钩子 触发器 创建 关键字段
会话开始 会话开始 根跨度 会话_id, 根_跨度_id
用户提示提交 用户发送提示 回合跨度 提示, 回合_编号
工具使用前 工具运行前 (修改任务提示) 工具_输入.提示
工具使用后 工具运行后 工具跨度 工具_名称, 输入, 输出
停止 回合完成 LLM 跨度 模型, 令牌, 工具_调用
子代理停止 子代理完成 (无跨度) 子代理的 会话_id
会话结束 会话结束 (完成根) 回合_计数, 工具_计数

追踪层次

会话 (任务跨度) - 根_跨度_id = 会话_id
|
+-- 回合 1 (任务跨度)
|   |
|   +-- claude-sonnet (llm 跨度) - 模型调用与工具_使用
|   +-- 读取 (工具跨度)
|   +-- 编辑 (工具跨度)
|   +-- claude-sonnet (llm 跨度) - 工具后的响应
|
+-- 回合 2 (任务跨度)
|   |
|   +-- claude-sonnet (llm 跨度)
|   +-- 任务 (工具跨度) -----> [子代理会话 - 独立追踪]
|   +-- claude-sonnet (llm 跨度)
|
+-- 回合 3 ...

子代理追踪:什么有效和什么无效

什么无效

会话开始不接收任务提示。

我们尝试通过工具使用前钩子将追踪上下文注入任务提示:

# 工具使用前钩子注入:
[BRAINTRUST_TRACE_CONTEXT]
{"根_跨度_id": "abc", "父_跨度_id": "xyz", "项目_id": "123"}
[/BRAINTRUST_TRACE_CONTEXT]

但会话开始只接收会话元数据,不接收修改后的提示。注入的上下文丢失了。

什么有效

父会话中的任务跨度包含所有内容:

  • 代理Id - 子代理运行的标识符
  • 总令牌数, 总工具使用计数 - 指标
  • 内容 - 完整代理响应/摘要
  • 工具_输入.提示 - 原始任务提示
  • 工具_输入.子代理_类型 - 代理类型 (例如 “oracle”)

子代理停止钩子接收子代理的 会话_id

  • 这等于子代理的孤立追踪 根_跨度_id
  • 允许父任务跨度和子追踪之间的相关性

相关性模式

当前状态: 子代理创建孤立追踪 (新 根_跨度_id)。

相关方法:

  1. 查询父会话的任务跨度以获取代理元数据
  2. 匹配 代理Id 或时间与孤立追踪
  3. 子代理的 会话_id = 其追踪的 根_跨度_id

未来解决方案 (尚未实现):

子代理停止触发 -> 将会话_id写入临时文件
工具使用后 (任务) -> 读取临时文件 -> 添加子_会话_id到任务跨度元数据

这将链接:任务.代理Id + 任务.子_会话_id -> 孤立追踪 根_跨度_id

状态管理

每会话状态文件

~/.claude/state/braintrust_sessions/
  {会话_id}.json       # 每会话状态

每个会话文件包含:

{
  "根_跨度_id": "abc-123",
  "项目_id": "proj-456",
  "回合_计数": 5,
  "工具_计数": 23,
  "当前_回合_跨度_id": "turn-789",
  "当前_回合_开始": 1703456789,
  "开始时间": "2025-12-24T10:00:00.000Z",
  "是_子代理": false
}

全局状态

~/.claude/state/braintrust_global.json   # 缓存项目_id
~/.claude/state/braintrust_hook.log      # 调试日志

调试命令

检查追踪是否激活

# 实时查看钩子日志
tail -f ~/.claude/state/braintrust_hook.log

# 检查会话是否有状态
cat ~/.claude/state/braintrust_sessions/*.json | jq -s '.'

# 验证环境
echo "TRACE_TO_BRAINTRUST=$TRACE_TO_BRAINTRUST"
echo "BRAINTRUST_API_KEY=${BRAINTRUST_API_KEY:+set}"

直接查询 Braintrust

# 列出最近会话
uv run python -m runtime.harness scripts/braintrust_analyze.py --sessions 5

# 分析最后会话
uv run python -m runtime.harness scripts/braintrust_analyze.py --last-session

# 回放特定会话
uv run python -m runtime.harness scripts/braintrust_analyze.py --replay <session-id>

# 查找子代理追踪 (孤立根)
uv run python -m runtime.harness scripts/braintrust_analyze.py --agent-stats

调试钩子执行

# 启用详细日志记录
export BRAINTRUST_CC_DEBUG=true

# 手动测试钩子
echo '{"会话_id":"test-123","类型":"resume"}' | \
  bash "$CLAUDE_PROJECT_DIR/.claude/plugins/braintrust-tracing/hooks/session_start.sh"

# 测试工具使用前 (任务注入)
echo '{"会话_id":"test-123","工具_名称":"Task","工具_输入":{"提示":"test"}}' | \
  bash "$CLAUDE_PROJECT_DIR/.claude/plugins/braintrust-tracing/hooks/pre_tool_use.sh"

故障排除清单

  1. 无追踪出现:

    • 检查 .claude/settings.local.json 中的 TRACE_TO_BRAINTRUST=true
    • 验证 API 密钥:echo $BRAINTRUST_API_KEY
    • 检查日志:tail -20 ~/.claude/state/braintrust_hook.log
  2. 子代理未链接:

    • 这是预期的 - 子代理创建孤立追踪
    • 使用 --agent-stats 查找代理活动
    • 通过时间或父任务跨度中的 代理Id 相关性
  3. 缺少跨度:

    • 检查会话状态中的 当前_回合_跨度_id
    • 确保停止钩子运行 (回合完成)
    • 在日志中查找 “创建失败” 错误
  4. 状态损坏:

    • 移除会话状态:rm ~/.claude/state/braintrust_sessions/*.json
    • 清除全局缓存:rm ~/.claude/state/braintrust_global.json

关键文件

文件 目的
.claude/plugins/braintrust-tracing/hooks/common.sh 共享实用程序、API、状态管理
.claude/plugins/braintrust-tracing/hooks/session_start.sh 创建根跨度、处理子代理上下文
.claude/plugins/braintrust-tracing/hooks/user_prompt_submit.sh 每用户消息创建回合跨度
.claude/plugins/braintrust-tracing/hooks/pre_tool_use.sh 将追踪上下文注入任务提示
.claude/plugins/braintrust-tracing/hooks/post_tool_use.sh 创建工具跨度、捕获代理/技能元数据
.claude/plugins/braintrust-tracing/hooks/stop_hook.sh 创建 LLM 跨度、完成回合
.claude/plugins/braintrust-tracing/hooks/session_end.sh 完成会话、触发学习提取
scripts/braintrust_analyze.py 查询和分析追踪会话
~/.claude/state/braintrust_sessions/ 每会话状态文件
~/.claude/state/braintrust_hook.log 调试日志

环境变量

变量 必需 默认 描述
TRACE_TO_BRAINTRUST - 设置为 "true" 启用
BRAINTRUST_API_KEY - Braintrust 的 API 密钥
BRAINTRUST_CC_PROJECT claude-code 项目名称
BRAINTRUST_CC_DEBUG false 详细日志记录
BRAINTRUST_API_URL https://api.braintrust.dev API 端点

会话学习

我们学到的关于子代理追踪的知识 (2025年12月)

尝试过: 通过工具使用前钩子将追踪上下文注入任务提示。

结果: 失败 - 会话开始只接收会话元数据,不接收提示。

发现: 任务跨度已包含丰富的子代理数据:

  • 元数据.代理_类型 - 来自 子代理_类型 的代理类型
  • 元数据.技能_名称 - 来自技能工具的技能
  • 工具_输入 - 发送给代理的完整提示
  • 工具_输出 - 代理响应

当前相关路径:

  1. 父会话任务跨度有 代理Id 和时间
  2. 子代理创建孤立追踪,根_跨度_id = 会话_id
  3. 子代理停止提供子代理的 会话_id
  4. 手动相关性:匹配时间或使用 会话_id 链接

未来工作: 在子代理停止后,从工具使用后写入 子_会话_id 到任务跨度元数据。

我们学到的关于子代理相关性的知识

问题

  • 通过任务工具生成的子代理创建孤立的 Braintrust 追踪
  • 父会话有带 代理Id 的任务跨度,子代理有独立的 会话_id
  • 它们之间没有内置链接

什么无效

1. 通过工具使用前的提示注入

会话开始钩子只接收会话元数据 (会话_id, 类型, cwd),不接收提示。注入的追踪上下文从未被看到。

钩子接收:

{
  "会话_id": "...",
  "类型": "start|resume|compact|clear",
  "cwd": "...",
  "环境": {...}
}

没有提示字段 - 在会话开始时无法进行上下文注入。

2. 子代理停止 → 工具使用后文件交接

竞态条件。这些是独立的异步钩子,没有时间保证:

  • 子代理停止在子代理会话结束时触发
  • 工具使用后 (任务) 在任务工具完成时触发
  • 它们之间没有顺序保证
  • 写入相关性文件创建竞态

3. 工具使用前相关性文件

会话开始无法访问 任务_跨度_id,因为它没有上下文关于哪个任务生成了它。工具使用前修改提示但不创建会话开始可以可靠访问的状态文件。

什么有效

后处理匹配以构建数据集:

父会话任务跨度包含:

  • 代理Id - 子代理运行的标识符
  • 总令牌数, 总工具使用计数 - 聚合指标
  • 内容 - 完整代理响应/摘要
  • 工具_输入.提示 - 原始任务提示
  • 工具_输入.子代理_类型 - 代理类型 (例如 “oracle”)
  • 开始/结束时间戳

子代理会话包含:

  • 会话_id (等于孤立追踪 根_跨度_id)
  • 开始/结束时间戳
  • 所有内部跨度和工具调用

相关策略:

  1. 导出父会话追踪 (查询父 根_跨度_id)
  2. 导出子代理追踪 (查询在父时间窗口内创建的所有会话)
  3. 匹配:
    • 时间:任务跨度结束 ≈ 子代理会话结束
    • 元数据:任务提示中的 子代理_类型
    • ID:子代理停止钩子提供 会话_id (可捕获和记录)

架构洞察

会话开始输入是故意最少的 - 它不包含提示或工具上下文:

interface SessionStartInput {
  会话_id: string;
  类型: "start" | "resume" | "compact" | "clear";
  cwd: string;
  环境: { [key: string]: string };
  // 无:提示, 工具_上下文, 任务_跨度_id, 父_跨度_id
}

此设计边界防止了钩子时间的实时相关性。

建议

对于构建具有子代理相关性的代理运行数据集:

  1. 会话内日志记录: 在日志或状态中捕获子代理停止 会话_id
  2. 会话后导出: 查询 Braintrust API 获取父和子代理追踪
  3. 离线相关性: 在脚本中通过时间和元数据匹配追踪
  4. 不要尝试实时链接: 钩子没有必要的上下文

示例脚本模式:

# 1. 导出父会话
braintrust_analyze.py --replay <parent-session-id> > parent_traces.json

# 2. 查询孤立的子代理追踪 (在父时间窗口内创建的)
braintrust_analyze.py --agent-stats > all_agent_traces.json

# 3. 在 Python 中相关:
#    - 父任务跨度 -> 代理Id, 时间戳, 子代理_类型
#    - 孤立追踪 -> 根_跨度_id, 时间戳
#    - 通过时间和类型匹配

这种方法可靠、可测试,且不需要钩子维护隐式状态。