跳到主要内容

可观测性

运行时可以追踪经过其 AI 服务的调用。插件也可以给这些调用外层的工作命名,例如一次智能体回合或辅助任务,让相关操作出现在同一棵追踪树中。记录功能默认关闭。

:::warning 启用前请先确认 追踪数据可能包含提示词、回答和其他私人文本。请选择你信任的接收端。如果来源中可能有凭据或其他机密,请先添加脱敏规则,再开启记录。 :::

运行时记录什么​

调用观测类型记录的数据
语言模型请求generation消息、工具声明、合并后的采样参数、模型输出、工具调用、token 用量、首 token 耗时和结束原因
向量嵌入embedding输入文本,以及向量数量和维度;不保存向量本身
重排序span查询、文档和分数
图像生成span提示词、选项、媒体类型和图像大小;不保存图像字节
语音合成或转写span文本或音频大小,以及转写结果或媒体类型
决策span状态、问题和回答

错误会附在观测记录上,同时仍会返回给调用方。完成的观测先进入后台队列,因此写入追踪不在服务调用的响应路径上。如果接收端写入失败,受影响的批次会丢失,运行时只记录一次该错误。

提供方报告模型名称和 token 数量时,运行时会一并记录。插件创建外层观测时,还可以设置稳定的追踪名称、会话 ID、用户 ID 和标签。这些字段可用于 Langfuse 的筛选和会话分组;调用插件没有提供时,运行时不会自行编造。

配置记录​

打开 设置 -> 可观测性。页面包含以下选项:

  • 使用记录调用开启或关闭追踪。
  • 在记录发送到中选择每日 JSONL 文件、Langfuse 接收端,或同时使用两者。
  • 通过记录的内容保留完整输入输出或缩短后的摘要。每个值的摘要长度默认是 500 个字符。
  • 开启保留原始请求后,运行时会保存语言模型提供方发出的请求体。此项默认关闭,而且可能显著增大追踪记录。
  • 在隐藏匹配的内容中每行填写一个正则表达式。匹配内容会在截断或发送前替换为 [redacted]。无效表达式会被忽略,并写入 DSH 日志。

选择文件输出时,文件夹留空表示使用 DSH 主目录下的 traces。运行时每天创建一个 trace-<日期>.jsonl 文件,每行写入一条观测或评分记录。

Langfuse 区域需要服务器地址、可选的环境名称和两个凭据引用。默认引用为 AI_PROVIDERS_LANGFUSE_PUBLIC_KEY 和 AI_PROVIDERS_LANGFUSE_SECRET_KEY。密钥值保存在 DSH 的凭据存储中。由环境变量提供的值会显示为只读。

Langfuse 与兼容接收端​

运行时通过 OpenTelemetry HTTP/JSON 把 span 发送到 <服务器>/api/public/otel/v1/traces,其中包含 Langfuse 观测属性和 v4 摄取请求头。评分发送到 <服务器>/api/public/scores。

这套方式适用于 Langfuse,也适用于明确实现了上述 Langfuse 摄取端点和属性的系统。普通 OTLP 收集器并不足够,除非它另外提供这层兼容。配置前请查看接收系统的文档。

在 Langfuse 中,语言模型调用显示为 generation,向量嵌入显示为 embedding。外层工作可以使用 agent、tool、span 或 event。观测名称应保持稳定,因为已保存视图、仪表盘和评估器都可以按名称和类型筛选。

重放一次语言模型请求​

如果需要完整请求体,请开启 保留原始请求,并使用完整内容记录。然后运行:

node scripts/replay-trace.mjs <trace.jsonl>

脚本会列出记录下来的语言模型调用。添加 --span <id> --url <端点> 可再次发送其中一个请求。--set temperature=0 可以修改顶层字段,--times <次数> 可以重复请求。输出会报告结束原因、工具调用、文本长度和 token 数量。偶发失败需要重复多次,才能判断差异是否有意义。

重放功能会把记录的请求体发往你指定的 URL。发送前请先检查内容,尤其是在启用了完整内容或原始请求记录时。

从插件添加外层观测​

ctx.aiTrace 只在记录开启时存在。请用 ctx.get('aiTrace') 查找,这样追踪关闭或运行时未安装时,插件仍能正常工作。

const tracer = ctx.get('aiTrace')
const turn = tracer?.start({
name: 'run-turn',
kind: 'agent',
input: text,
trace: { name: 'run-turn', sessionId: storyId },
})
const unlink = turn === undefined ? undefined : tracer?.link(chatId, turn.ref)

// 此后带有该聊天 ID 的模型调用会嵌套在这个回合下。

unlink?.()
turn?.end({ output: answer })

公开的追踪器提供四种常见用法:

  • run(start, work) 在异步工作期间把 span 设为当前观测,并在工作结束时结束它。
  • start(start) 返回一个句柄,适合流式任务等稍后才结束的工作。调用方需要自行执行 end()。
  • link(key, span) 为无法继承异步上下文的工作指定父观测。运行时把语言模型请求的会话 ID 用作这个 key。
  • score(span, score) 给某条追踪或观测附加数值、布尔值或分类评分。

没有外层观测的服务调用会自行创建一条追踪。