关于 built-in-metrics
用于为现有 Provider 调用添加 LaunchDarkly Agent 指标的技能,帮助开发者选择合适的埋点方式,记录耗时、Token、结果,并在适用时追踪流式 TTFT。
主要功能
- 01检查 Provider 调用类型与 SDK 用法
- 02从四种埋点层级中选择方案
- 03记录耗时、Token 和调用结果
- 04为流式响应追踪 TTFT
- 05在 Monitoring 中验证指标
适用场景
- 01为对话式模型调用添加埋点
- 02追踪单次 Provider 调用指标
- 03为自定义 Provider 添加 Token 与错误追踪
- 04检查流式延迟和生成指标
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ launchdarkly/ ai-tooling --skill built-in-metrics安装后在 Claude Code 中输入/built-in-metrics确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/anthropic-tracking.mdbedrock-tracking.mdgemini-tracking.mdlangchain-tracking.mdmetrics-api.mdopenai-tracking.mdstrands-tracking.mdstreaming-tracking.md详细介绍
Agent 指标埋点
你正在使用一种技能,它会围绕现有的提供方调用接入 LaunchDarkly Agent 指标。你的任务是审查现有实现,从下方的层级阶梯中选择合适的层级,并以尽可能精简的方式完成埋点,同时采集 Monitoring 选项卡所需的指标(耗时、输入/输出 token、成功/错误,以及流式传输时的 TTFT)。
最重要的一点:始终优先选择与调用形式相符的最高层级。选择更低的层级(“只编写手动跟踪器调用”)看似灵活,实际却会导致实现不一致、指标遗漏,并沿用 SDK 已经不再推荐的旧模式。
四级阶梯
这是官方 SDK README(Python 核心、Node 核心以及所有提供方包)推荐的顺序。从最高层级开始检查,选中第一个适用的层级后停止:
| 层级 | 模式 | 适用场景 | 自动跟踪 |
|---|---|---|---|
| 1 — 托管运行器 | Python:ai_client.create_model(...) 返回 ManagedModel,然后执行 await model.run(...)。Node: aiClient.createModel(...) 返回 ManagedModel,然后执行 await model.run(...)。 | 调用属于对话式调用(包含聊天历史、按轮次交互)。这是提供方 README 首推的方式。 | 耗时、token、成功/错误——所有指标都由系统自动跟踪,无需调用跟踪器。 |
2 — 提供方包 + trackMetricsOf | tracker.trackMetricsOf(Provider.getAIMetricsFromResponse, () => providerCall())。目前提供方包包括:Node 的 @launchdarkly/server-sdk-ai-openai、-langchain、-vercel,以及 Python 的 launchdarkly-server-sdk-ai-openai、-langchain。 | 调用形式不是聊天循环(单次补全、结构化输出、Agent 步骤),但框架或提供方有对应的包。 | 封装器自动跟踪耗时和成功/错误;包内置的 getAIMetricsFromResponse 提取器负责跟踪 token。 |
3 — 自定义提取器 + trackMetricsOf | 使用相同的 trackMetricsOf 封装,但自行编写一个小函数,将提供方响应映射到 LDAIMetrics(token + 成功)。 | 没有对应的提供方包(直接调用 Anthropic、Gemini、Cohere、自定义 HTTP)。 | 封装器自动跟踪耗时和成功/错误;自定义提取器负责跟踪 token。 |
| 4 — 原始手动跟踪 | 分别调用 trackDuration、trackTokens、trackSuccess/trackError;对于流式传输,还要调用 trackTimeToFirstToken。 | 需要 TTFT 的流式传输、特殊的响应形式、部分跟踪,以及任何无法通过第 2~3 级清晰封装的情况。 | 只跟踪你明确调用的指标——务必自行确保不遗漏。 |
所有提供方——OpenAI、LangChain、Vercel、Bedrock、Anthropic、Gemini、自定义 HTTP——都采用相同的通用形式:Node 使用 tracker.trackMetricsOf(getAIMetricsFromResponse, () => providerCall()),Python 使用 tracker.track_metrics_of(get_ai_metrics_from_response, provider_call)。每个提供方唯一不同的部分是提取器:从对应的 @launchdarkly/server-sdk-ai-<provider>(或 ldai_<provider>)包导入 getAIMetricsFromResponse,或者编写一个返回 LDAIMetrics 的简短自定义函数。跟踪器没有提供方专属的方法。
工作流
1. 探查现有调用点
选择层级之前,先找到提供方调用,并回答以下问题:
- 调用形式? 是聊天循环(历史记录 + 轮次制)、单次补全、Agent 步骤,还是其他形式?→ 决定使用第 1 层还是第 2 层。
- 框架? 原始提供方 SDK?LangChain / LangGraph?Vercel AI SDK?CrewAI?Strands?→ 决定适用哪个第 2 层提供方包(如果有)。
- 提供方? OpenAI、Anthropic、Bedrock、Gemini、Azure、自定义 HTTP?→ 与下方的包可用性矩阵交叉核对。
- 是否流式传输? 如果是,则需要跟踪 TTFT,这意味着 TTFT 部分需要使用第 4 层,即使其他部分使用第 2 层。
- 语言? Python 还是 Node?两者的提供方包覆盖范围不同。
- 是否已使用配置? 如果没有,先转到
configs-create——跟踪需要 tracker,可通过在completion_config()/completionConfig()/createModel()返回的配置对象上调用create_tracker()/createTracker()获取。 - 是否使用当前 SDK API? 如果调用点使用
aiclient.config(...)/aiClient.config(...),或构造了默认的AIConfig(...)/LDAIConfig,则使用的是 0.20 之前的 API。请先在此工作中完成迁移,再添加跟踪:aiclient.config(...)→ 对于单次补全/聊天,使用aiclient.completion_config(...);对于 Agent 模式,使用aiclient.agent_config(...)(保持调用签名一致)。Node 版本相同,只是使用 camelCase。- 默认的
AIConfig(...)→AICompletionConfigDefault(...)或AIAgentConfigDefault(...)(Node:LDAICompletionConfigDefault/LDAIAgentConfigDefault)。AIConfig是 SDK 返回的基类;它不是有效的默认值构造函数,应使用带类型的*Default变体。 - 如果结果通过元组解包获取(
config, tracker = aiclient.config(...)),请移除解包——新方法只返回一个配置对象。通过config.create_tracker()/aiConfig.createTracker()获取 tracker。 - 对于更深入的重写(调用点也硬编码了模型/提示词),请转交给
migrate,而不是在此处执行完整迁移。
2. 查找第 2 层选项
使用此矩阵判断你的场景是否支持第 2 层(提供方包)。如果不支持,则降至第 3 层(自定义提取器)。如果调用形式是聊天循环,无论此矩阵中的内容如何,都应先转到第 1 层。
| 框架 / 提供方 | Python 提供方包 | Node 提供方包 | 参考 |
|---|---|---|---|
| OpenAI(直接使用 SDK) | launchdarkly-server-sdk-ai-openai | @launchdarkly/server-sdk-ai-openai | openai-tracking.md |
| LangChain / LangGraph | launchdarkly-server-sdk-ai-langchain | @launchdarkly/server-sdk-ai-langchain | langchain-tracking.md |
| Vercel AI SDK | — | @launchdarkly/server-sdk-ai-vercel | (请使用 Vercel 提供方文档) |
| AWS Bedrock(Converse 或 InvokeModel) | —(使用 LangChain-aws 或自定义提取器) | —(使用 LangChain-aws 或自定义提取器) | bedrock-tracking.md |
| Anthropic 直接使用 SDK | — | — | anthropic-tracking.md |
| Gemini / Google GenAI | — | — | gemini-tracking.md |
| Strands Agents | —(第 3 层自定义提取器) | —(第 3 层自定义提取器) | strands-tracking.md |
| Cohere、Mistral、自定义 HTTP | — | — | 第 3 层自定义提取器 |
| 任意提供方,流式传输 + TTFT | —(仅第 4 层) | trackStreamMetricsOf(不含 TTFT)+ 手动跟踪 TTFT | streaming-tracking.md |
3. 参照匹配的示例进行实现
确定层级和提供商后,打开相应的参考文件并遵循其中的模式。参考文件始终先列出 Tier 1 示例,然后是 Tier 2/3,最后是 Tier 4。遇到与应用形态匹配的第一个层级时就停止。
适用于所有层级的注意事项:
- 在进行受跟踪的调用前,务必检查
config.enabled。 如果配置已禁用,说明用户已关闭该功能——应直接采用应用使用的回退方式(缓存响应、错误、降级路径),而不是调用提供商。 - 包装现有调用,不要重写。 Tier 2 和 Tier 3 专为围绕未经修改的提供商调用进行集成而设计。如果你发现自己为了适配跟踪器而重写调用,那就说明选错了层级——应降一级。
- 错误由
trackMetricsOf内部处理。 包装器会捕获异常,在内部记录trackError(),然后重新抛出——不要再额外添加except: tracker.trackError(),这不但没有作用,还会触发至多一次的保护机制。Tier 1 会自动处理成功和错误两种路径。在 Tier 4(手动、流式处理、track_duration_of)中,则由调用方负责调用错误跟踪函数。 - 关闭前务必刷新。 关闭客户端前调用
ldClient.flush()(Python:ldclient.get().flush();Node:await ldClient.flush())。否则,尚未发送的事件可能会丢失,无论是短时运行的脚本还是长期运行的服务都一样。在 Node 中,ldClient.close()会返回一个 Promise;请使用await等待它。
4. 验证
确认 Monitoring 选项卡中显示了数据:
- 通过已埋点的路径发送一个真实请求。
- 在 LaunchDarkly 中打开该配置 → Monitoring 选项卡。持续时间、Token 计数和生成次数应在 1–2 分钟内显示。
- 强制触发一个错误(错误的 API 密钥、将
max_tokens设为零,或其他方式),并确认错误计数增加。 - 如果使用流式处理:确认显示 TTFT。如果没有显示,你可能用
trackMetricsOf包装了流的创建,却没有手动添加trackTimeToFirstToken调用——请参阅 streaming-tracking.md。
快速参考:追踪器方法
通过配置对象上的工厂方法获取追踪器:tracker = config.create_tracker()(Python)或 const tracker = aiConfig.createTracker()(Node)。每次执行只调用一次工厂方法,并在所有调用中复用返回的 tracker——每次调用工厂方法都会生成一个新的 runId,用于标记该追踪器发出的每个追踪事件,以便将单次执行中的事件关联起来(通过导出的事件 / 下游系统)。目前,监控选项卡会聚合事件,而不会按运行分组——导出事件或在 UI 外查询时,runId 很有用;SDK 的至多一次保护机制也以它作为键。以下方法是原始 API 表面——大多数时候不应单独调用它们;请使用 trackMetricsOf 或 Tier-1 托管运行器。列出这些方法是为了便于你在现有代码中识别它们,并在确实需要 Tier 4 时选用合适的方法。
| 方法(Python ↔ Node) | Tier | 功能 |
|---|---|---|
track_metrics_of(extractor, fn) / trackMetricsOf(extractor, fn) | 2 / 3 | 包装提供方调用,捕获耗时 + 成功 / 错误,并调用你的提取器获取 token。这是默认的通用追踪器。 |
track_metrics_of_async(extractor, fn)(Python) | 2 / 3 | 上述方法的异步版本。 |
trackStreamMetricsOf(extractor, streamFn)(仅 Node) | 2 / 3 | 流式版本。如果提取器处理数据块,则会捕获每个数据块的用量。不会自动捕获 TTFT。 |
track_duration(ms) / trackDuration(ms) | 4 | 记录以毫秒为单位的延迟。 |
track_duration_of(fn) / trackDurationOf(fn) | 4 | 包装可调用对象并自动记录耗时。不会捕获 token 或成功状态——请与显式调用配合使用。 |
track_tokens(TokenUsage) / trackTokens({input, output, total}) | 4 | 记录 token 用量。 |
track_time_to_first_token(ms) / trackTimeToFirstToken(ms) | 4 | 记录流式响应的 TTFT。 |
track_success() / trackSuccess() | 4 | 标记生成成功。监控选项卡要统计该生成,此项必不可少。 |
track_error() / trackError() | 4 | 标记生成失败。同一请求中不要同时调用 trackSuccess()。 |
track_feedback({kind}) / trackFeedback({kind}) | 任意 | 记录反馈 UI 中的赞 / 踩。独立于成功 / 错误流程。 |
track_tool_call(name) / trackToolCall(name) | 任意 | 按名称记录单次工具调用。两个 SDK 均支持。 |
track_tool_calls([names]) / trackToolCalls([names]) | 任意 | 批量版本——一次调用中记录多个工具调用。 |
track_judge_result(result) / trackJudgeResult(result) | 任意 | 记录程序化评审结果。result.sampled 表示是否运行了评估。 |
相关技能
configs-create— 如果应用尚无配置,这是前置步骤custom-metrics— 在此技能捕获的 Agent 指标之上,添加业务指标(转化率、解决率、留存率)online-evals— 对抽样的实时请求进行自动质量评分(LLM-as-judge);与此处的指标互为补充migrate— 从硬编码迁移到 AgentControl 的第 4 阶段会委托给此技能