Langfuse 文档 中文 英文原文 ↗
文档 / 一个好的 trace 看起来是什么样?

一个好的 trace 看起来是什么样?

你看到 traces 出现在 Langfuse 中,但你怎么知道是否做得好?这里有几件你可以查看和优化的事情。

Trace 结构不仅仅是美观——许多 Langfuse 功能构建在其之上:

结构良好的 trace 让今天的调试更快,而稳定的名称和有意义的输入/输出让你的评估器、仪表盘和实验在应用演进时继续工作。

一个 trace 的范围是什么?

Langfuse 的数据模型有三个分组级别:observations(单个步骤)通过 trace_id 分组为 traces,traces 可以通过 session_id 分组为 sessions。

一个 trace 代表你应用中一个自包含的工作单元。典型 trace 的好例子:

如果其中多个按顺序发生,例如多轮对话,或馈入最终报告的几次 agent 运行,那就是 sessions 的用武之地。每一步都是自己的 trace,而 session 将它们绑在一起。对于聊天机器人,这意味着每回合一个 trace、每对话一个 session——你无法预先知道对话何时结束,而每回合模型保持 traces 小巧且易于在 session 视图中导航。

一个 trace 在 Langfuse UI 中显示为 trace 树和 agent 图:

Trace 树

Agent 图

查看 trace 树

当你点击一个 trace 时,你会看到 trace 树。有两件事你可以检查:

正确的步骤是否显示出来?

你应该看到你的 LLM 调用、工具调用和其他重要步骤在树中表示。它们应该有正确的 observation 类型

例如

框架集成通常会自动设置这些类型。如果你手动埋点,可以通过 as_type 参数(Python)或 asType(JS/TS)设置它们。完整列表参见 observation 类型文档

嵌套是否正确?

工具调用应嵌套在编排该步骤的 agentspan 下,作为请求它的 generation 的兄弟节点,这样树就能显示每个动作属于哪个步骤,而不是让工具调用悬在 trace 根。

框架集成通常会自动做对。如果你手动埋点,参见嵌套 observations

是否有你不需要的噪声?

并非树中的每个 observation 都对理解你的应用做了什么有用。HTTP spans、数据库查询和框架内部通常会增加混乱,而不给你有意义的洞察。如果你看到像这样的 observations 污染你的 trace 树,你可以将它们过滤掉

trace 树中的噪声 spans

选择好的名称

Observation 和 trace 名称在许多地方使用:

由于名称在所有这些地方被引用,请像对待 API 一样对待它们:当名称更改时,针对旧名称的评估器、仪表盘查询和保存的过滤器会静默停止匹配。刻意选择名称,并期望保持它们稳定。

使用主动语态。 以 observation 执行的动作命名,动词在前:classify-intentretrieve-contextgenerate-responsesummarize-results。这让 trace 树读起来像你应用所做事情的描述,并使过滤特定步骤更容易。

将动态值排除在名称之外。 使用 process-order,而非 process-order-8945generate-response-retry-2。名称应标识操作,而非它的单次执行——否则每个 trace 都会产生新名称,你无法再分组、过滤或定位它们。将运行特定的值放在元数据中。(这与 OpenTelemetry 对 span 名称推荐的低基数规则相同。)

尽量不要以使用的 AI 模型命名 observations(gpt-4oclaude-sonnet)。一旦你更换模型,所有引用该名称的过滤器、评估器和仪表盘都会失效。模型已经是 generation observations 上的单独属性,请改用那个。

选择有意义的输入和输出

通常,建议操作具有输入和/或输出。如果一个 observation 两者都没有,问问自己该 observation 是否真的有用,或者你是否可以删除它。

根 observation 值得最多关注:trace 级输入和输出派生自它。它们显示在追踪表中,被评估器读取,并在数据集实验中跨运行对比。将它们设置为审阅者一眼所需的内容——对于聊天机器人,输入为用户消息,输出为助手响应——而非函数参数的原始 JSON blob。如果你需要原始负载用于调试,请将它放在元数据中。

对于你最常查看的 observations,多花点心思设置它们。你可能会在追踪和 session 屏幕上创建预过滤视图。你在这里过滤的 observations 将是被查看最多的。对于这些,问问自己:我需要什么才能一眼快速评估一个 trace/session?

带输入和输出的追踪表

GENERATION observations 的典型输入/输出:

大多数输入/输出可以渲染为可读的、带角色标签的对话,而非原始 JSON blob。如果你的显示为原始 JSON,你可以查看格式:它应该是标准 OpenAI 格式的消息列表(每个带 rolecontent),并且仅当工具调用位于 assistant 消息的 tool_calls 数组中、且每个调用的 arguments 作为 JSON 编码字符串给出时(例如 ""),才将它们渲染为卡片。

如果你的输入和输出字段意外显示为空,参见为什么我的 trace 的输入和输出为空?

有用的属性

Observations 有许多对你的用例可能有用的属性。这些将让你能够在过滤、打分和制作仪表盘方面走得更远。

为上下文添加元数据

元数据是每个 observation 上灵活的键值存储。它是任何有用上下文但不属于名称或输入/输出的内容的合适位置。实践中有用的元数据示例:

你可以在 Langfuse UI 中按元数据键过滤,当你需要查找具有特定特征的 traces 时这很有帮助。

在 generations 上追踪模型、tokens 和成本

如果你想了解你的 LLM 使用成本,按模型、按用户、按功能细分,你需要在你的 generation observations 上有三样东西:

大多数集成会自动捕获所有这些。如果你手动埋点,参见 token 和成本追踪文档

你可以在 Langfuse UI 中的 GENERATION observation 上看到这些属性。

Langfuse 中的 Generation 属性

将标签用于业务级维度

标签支持跨对你业务重要的维度进行过滤和指标细分。好的标签回答诸如"我们的 webapi 用户之间的延迟有何不同?"之类的问题。

标签的一个属性是它们不可变且必须在 observation 创建时设置。这使它们非常适合你预先知道的事情(请求来自哪里、它属于哪个功能),但不适合你后来才知道的事情。

如果你需要基于事后确定的事情标记 traces,例如 LLM-as-a-judge 评估结果,请改用分数

将提示词关联到 traces

如果你在 Langfuse 中管理提示词,你可以将它们关联到你的 generations。这让你能够看到给定 trace 使用了哪个提示词版本,并追踪指标如何跨提示词版本变化。当你迭代提示词并想对比性能时很有用。

设置环境

设置 environment 属性(productionstagingdevelopment),以便你的测试 traces 不会污染生产仪表盘和评估。

用用户 ID 追踪用户

设置用户 ID 将 traces 连接到特定用户,从而解锁 Langfuse 中的每用户视图。如果你想回答以下问题,这很有用:

用 session ID 分组相关 traces

如果你的应用涉及逻辑上属于一起的多个 traces,将它们分组为一个 session。这给你一个 session 回放视图,你可以在其中按顺序看到完整的交互。

这在以下情况有意义:

如果你的应用是单请求/单响应,调用之间没有连续性,你可能不需要 sessions。

Langfuse 中的 Sessions 视图

非官方中文翻译 · 图片/视频/代码均链接官方资源 · 版权归 Langfuse GmbH 所有 查看英文原文 ↗