将 OpenTelemetry GenAI 跟踪连接到结果事件
OpenTelemetry 跟踪和 Telemetry 结构化事件解决了 AI 代理调查的不同部分。将详细的模型、代理和工具跨度保存在与 OTLP 兼容的可观测性后端中。当您想要检查 SQL 的成功、成本、延迟、发布、帐户、移交或审核的产品价值时,向 Telemetry 发送较小的终端结果事件。
Telemetry 不公开 OTLP 端点,也不是 OpenTelemetry 跟踪后端。连接是应用程序拥有的相关标识符,而不是每个跨度的第二个导出。
将每个系统用于其预期工作
OpenTelemetry 迹线非常适合回答:
- 哪个跨度或工具在一次慢速运行中占主导地位;
- 控制如何在代理、模型、检索和工具操作之间移动;
- 哪种异常或依赖性解释了个别失败;
- 经批准的痕量保留边界内存在哪些详细属性。
紧凑的结果事件非常适合回答:
- 哪个版本的终端任务成功率最高;
- 对于每个接受的结果,哪个工作流程成本最高;
- 本周工具重试或人工交接是否增加;
- 哪个客户层受到有限错误类别的影响;
- 提示或模型版本后评估分数是否发生变化。
不要将所有跨度属性复制到事件中。确定哪些聚合问题需要持久列并将这些字段列入许可名单。
刻意映射语义
OpenTelemetry 生成式 AI 语义约定 定义了模型、代理和工具操作的不断发展的属性和跨度约定。固定您的服务使用的语义约定和工具库版本,然后在升级期间检查映射。
| OpenTelemetry概念 | Telemetry 活动场地 | 指导 |
|---|---|---|
| 活动跨度跟踪 ID | trace_id |
批准后安全关联指针;请勿将其用作帐户身份 |
| 应用程序运行或操作 ID | run_id 或 operation_id |
优先使用应用程序标识符进行重试和以后审核的连接 |
gen_ai.operation.name |
operation_name |
保持有界操作类别 |
gen_ai.provider.name |
provider |
使用固定仪器发出的提供程序值 |
| 请求或响应模型 | model |
选择并记录一种含义,或分别保留 requested_model 和 response_model |
| 输入和输出使用 | input_tokens、output_tokens |
记录一次数字使用情况;不要重复计算推理标记细节 |
| 代理人身份 | agent_name 或 agent_version |
使用稳定的逻辑名称而不是生成的实例标识符 |
| 跨度状态或异常 | status、error_type |
将不受限制的消息转换为列入白名单的应用程序类别 |
语义约定在成熟时可能会发生变化。不要假设在一个 SDK 或框架中观察到的属性在任何地方都具有相同的稳定性或可用性。将精确映射视为版本化应用程序代码。
在跟踪旁边发出一个最终结果
此 JavaScript 包装器读取当前跟踪 ID 并在代理运行后记录应用程序结果。通过配置的OpenTelemetry SDK继续导出迹线;只有选定的字段才会转到 Telemetry。
import { trace } from "@opentelemetry/api";
import telemetry from "telemetry-sh";
telemetry.init(process.env.TELEMETRY_API_KEY);
export async function runSupportAgent({
agent,
input,
operationId,
accountId,
release,
}) {
const startedAt = Date.now();
let status = "success";
let errorType;
let result;
try {
result = await agent.run(input);
return result;
} catch (error) {
status = "failed";
errorType = classifyAgentError(error);
throw error;
} finally {
const activeSpan = trace.getActiveSpan();
const traceId = activeSpan?.spanContext().traceId;
await telemetry.log("agent_run_completed", {
operation_id: operationId,
trace_id: traceId,
workflow: "support_resolution",
account_id: accountId,
status,
error_type: errorType,
duration_ms: Date.now() - startedAt,
human_handoff: result?.handoffRequired ?? false,
tool_call_count: result?.toolCallCount ?? 0,
release,
});
}
}
使事件传递失败成为非致命的,除非业务工作流程明确要求否则。使用短超时、有界重试、正常关闭以及 批处理、背压和关闭 中的交付指导。
仅添加一次模型用法
如果 OpenTelemetry 工具已经观察到提供者请求,则不会自动将请求使用情况放入 Telemetry 中。确定聚合 SQL 问题是否需要单独的 llm_request_completed 事件。
当发生这种情况时,为每个计费请求发出一个事件:
operation_id、run_id和可选的经批准的trace_id;provider、requested_model、response_model和service_tier;- 输入、缓存输入、输出和其他单独定义的令牌类别;
estimated_cost_usd和版本化定价源;latency_ms、status、attempt、feature和release。
不要从跨度持续时间中得出成本。使用提供商报告的使用情况和经过审查的费率表,然后将估算值与提供商发票进行核对。 OpenAI 请求成本指南 显示了这种模式。
保护数据边界
生成式人工智能遥测可能包含异常敏感的数据。默认情况下不将这些字段发送到 Telemetry:
- 提示或补全内容;
- 系统指令或思路内容;
- 检索到的文档文本或嵌入;
- 工具参数、工具响应、shell 输出或文件内容;
- 授权标头、cookie、API 密钥、数据库凭据或连接字符串;
- 无限制的例外消息或 OpenTelemetry 行李;
- 未通过产品收集和保留审核的个人数据。
优先选择 input_category、output_category、tool_name、error_type、policy_result 和 review_outcome 等类别。在致电任一出口商之前应用许可名单;从仪表板中删除字段不会将其从存储的数据中删除。
查询结果并保留跟踪链接
使用 SQL 进行聚合比较,同时保留响应者需要的相关指针:
SELECT
release,
workflow,
COUNT(*) AS completed_runs,
SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS successful_runs,
SUM(CASE WHEN human_handoff THEN 1 ELSE 0 END) AS handoffs,
ROUND(AVG(duration_ms), 0) AS average_duration_ms,
MAX(trace_id) AS example_trace_id
FROM agent_run_completed
WHERE timestamp_utc >= now() - INTERVAL '7 days'
GROUP BY release, workflow
ORDER BY completed_runs DESC;
MAX(trace_id) 只是该组中的示例指针,而不是代表性跟踪。要进行调查,请打开基础行,选择相关运行,并将其 trace_id 粘贴到跟踪后端。如果该后端支持稳定的 URL 模板,请在访问控制的内部工具中构建链接,而不是将供应商凭据或私有主机名作为事件字段发送。
验证连接
生产推出前:
- 生成一次成功运行、一次工具失败、一次恢复重试和一次终端失败。
- 确认跟踪后端包含预期的生成树。
- 确认 Telemetry 每次运行包含一个终端事件以及预期的请求或工具事件。
- 比较跟踪和事件相关标识符。
- 验证提示、完成、参数、凭据和私人内容是否不存在。
- 测试导出器速度缓慢或不可用时的行为。
- 文档所有者、保留、语义约定版本、采样和调查移交。
有关一般架构和 SDK 示例,请阅读 Telemetry 与 OpenTelemetry。对于特定于代理的结果设计,请继续 使用 SQL 评估 AI 代理 和 AI代理监控产品边界。