传统服务出错时,可以查看状态码、日志和调用链。LLM 应用即使返回 200,也可能答非所问、成本异常或工具调用错误。

因此 LLMOps 的可观测对象不只是服务器,还包括 Prompt、模型、知识检索、工具调用、Token、费用和最终输出。Dify 将这些信息组织成 Trace,并可导出到多种观测平台。

本文介绍 AI 应用应该观测什么,以及如何避免追踪系统反过来影响主链路或泄露数据。


一、为什么普通监控不够

一次“回答质量差”可能由多种原因造成:

  • Prompt 模板或变量拼装错误;
  • 对话历史被错误截断;
  • RAG 没有召回正确文档;
  • Rerank 把相关结果排到后面;
  • 模型版本或参数发生变化;
  • Agent 选错工具或重复调用;
  • 工具返回异常但被模型掩盖;
  • 输出审核截断了最终内容。

CPU、内存和 HTTP 延迟无法解释这些问题。必须还原一次调用内部经历了什么。

1.1 三类可观测数据

类型 例子 主要用途
Metrics 延迟、Token、费用、失败率 看趋势和告警
Logs 错误、节点状态、规则命中 定位具体事件
Traces Workflow、Node、Model、Tool 父子关系 还原完整链路

三者互补:指标发现异常,Trace 缩小范围,日志解释细节。


二、Dify 的追踪层级

2.1 一次请求的层次

flowchart TB
    Request["Conversation / API Request"] --> Workflow["Workflow Run"]
    Workflow --> Node1["Knowledge Retrieval"]
    Workflow --> Node2["LLM Node"]
    Workflow --> Node3["Agent Node"]
    Node1 --> Retrieve["Dataset Retrieval"]
    Node2 --> Model["Model Invocation"]
    Node3 --> Tool["Tool Invocation"]
    Node3 --> Model2["Model Invocation"]

需要稳定标识:

  • trace_id:整条链路;
  • span_id:某个步骤;
  • parent_span_id:父子关系;
  • workflow_run_id:工作流执行;
  • node_execution_id:节点执行;
  • conversation_idmessage_id:对话上下文;
  • tenant_idapp_id:数据归属。

没有统一 ID,数据库日志、模型日志和外部 Trace 平台就无法关联。

2.2 Trace 事件

Dify 的 TraceTask 覆盖多种对象:

  • Conversation 与 Message;
  • Workflow 与 Node Execution;
  • LLM 与 Prompt Generation;
  • Dataset Retrieval;
  • Tool Invocation;
  • Moderation;
  • Suggested Questions。

每种事件结构不同,但最终都应转换成统一的 Trace/Span 模型。

2.3 节点数据

一个节点至少应记录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"node_id": "llm_1",
"node_type": "llm",
"status": "succeeded",
"started_at": "...",
"elapsed_time": 1.42,
"inputs": {},
"outputs": {},
"execution_metadata": {
"total_tokens": 1520,
"total_price": "0.0032",
"currency": "USD"
}
}

输入输出帮助复现问题,但也最容易包含隐私和密钥,不能默认无限期完整保存。


三、模型调用应该记录什么

3.1 基础维度

  • Provider、模型名和版本;
  • 流式或非流式;
  • Temperature、Top P、Max Tokens;
  • 输入与输出 Token;
  • 首 Token 延迟和总延迟;
  • 重试次数和结束原因;
  • Prompt 模板版本;
  • 工具数量与结构化输出模式。

3.2 时间指标

模型调用不能只记录总耗时:

1
总延迟 = 排队 + DNS/连接 + 供应商处理 + 流式传输

关键指标:

  • TTFT:从请求发出到首个 Token;
  • TPOT:后续每 Token 平均时间;
  • E2E Latency:从用户请求到最终响应完成;
  • Queue Time:进入执行器到真正调用模型。

TTFT 变慢可能是供应商排队,E2E 变慢也可能是 RAG 或工具耗时。

3.3 费用

1
模型费用 = 输入 Token × 输入单价 + 输出 Token × 输出单价

Agent 还需要汇总每轮模型与工具费用。单次请求便宜,不代表工作流整体便宜。

价格配置应带版本和币种。供应商调价后,历史账单不能用新价格重新计算。


四、异步 Trace 导出

4.1 为什么不能同步上报

如果每个节点结束都同步请求外部平台:

  • 观测平台抖动会增加用户延迟;
  • 外部故障可能拖垮工作流;
  • 节点多时产生大量网络请求;
  • Trace 写入超时会占用业务连接。

Dify 使用 TraceQueueManager 产生任务,再由异步任务处理外部上报。

flowchart LR
    Runtime["Workflow Runtime"] --> QueueManager["TraceQueueManager"]
    QueueManager --> Queue["Ops Trace Queue"]
    Queue --> Worker["Trace Worker"]
    Worker --> Adapter["Provider Adapter"]
    Adapter --> Langfuse["Langfuse"]
    Adapter --> LangSmith["LangSmith"]
    Adapter --> Others["Phoenix / MLflow / Opik ..."]

业务主链路只负责投递轻量事件,失败时也不应让用户请求失败。

4.2 队列设计

  • Trace 任务具有明确 Schema 与版本;
  • 队列设置容量,防止观测数据挤占业务资源;
  • 上报失败有限重试并进入死信记录;
  • 批量发送降低网络开销;
  • 相同 Trace 内事件保持可重建顺序;
  • Worker 水平扩展时使用幂等事件 ID;
  • 积压严重时可采样或降级,而不是阻塞主流程。

4.3 Provider Adapter

Dify 通过适配器支持 Langfuse、LangSmith、Opik、Weave、Arize/Phoenix、MLflow 等平台。内部事件只定义一次,各适配器负责字段映射。

这和模型 Provider 的设计类似:核心系统依赖统一协议,第三方差异留在边界层。


五、从观测到排障

5.1 回答质量差

按链路检查:

  1. 用户输入是否正确进入变量池;
  2. Prompt 模板版本是否符合预期;
  3. RAG Query 是否正确;
  4. 召回文档、分数与 Rerank 顺序;
  5. 最终送入模型的消息;
  6. 模型、参数和结束原因;
  7. 输出是否被后处理或审核修改。

5.2 延迟升高

现象 可能原因
所有节点都慢 Worker 排队或基础设施问题
只有 LLM TTFT 慢 模型供应商排队或网络问题
检索节点慢 向量库、Embedding 或过滤条件
工具节点慢 第三方 API 或沙箱冷启动
最后才变慢 输出审核、持久化或流式连接阻塞

Trace 的价值是把“请求慢”拆成具体 Span。

5.3 成本突增

常见原因:

  • 对话历史没有正确裁剪;
  • RAG 返回过多长文本;
  • Agent 重复调用模型;
  • Prompt 意外包含大变量;
  • 切换到更昂贵模型;
  • 失败重试重复计费。

告警应同时包含模型、应用、租户、Token 和调用轮数。


六、隐私与多租户隔离

Trace 可能包含用户问题、知识库内容、工具结果、文件地址和模型凭证,敏感度往往高于普通日志。

6.1 最小化原则

  • 默认记录元数据和摘要,不默认记录全部正文;
  • 对 Authorization、Cookie、API Key 和密码字段脱敏;
  • 支持按应用关闭输入输出采集;
  • 对个人信息做删除或哈希化;
  • 设置独立保留周期;
  • 导出到第三方前获得组织授权;
  • 用户删除数据时同步清理相关 Trace。

6.2 租户边界

  • Trace 查询必须带 tenant_id
  • 外部平台的 Project 或 Dataset 按租户/环境隔离;
  • Provider 配置和缓存键包含应用、租户;
  • Trace SDK 实例不能错误复用其他租户的凭证;
  • 后台任务携带明确身份,不能只靠全局上下文。

异步线程、全局 SDK 和缓存是最容易发生跨租户串数据的位置。


七、指标与告警建议

7.1 系统指标

  • Workflow 成功率、P50/P95/P99 延迟;
  • Node 各类型失败率和耗时;
  • 模型 TTFT、吞吐和限流率;
  • Tool 调用成功率;
  • RAG 召回耗时和空结果率;
  • Trace 队列长度、丢弃量和导出失败率。

7.2 业务与质量指标

  • 每次会话平均 Token 与费用;
  • Agent 平均迭代次数;
  • 用户点赞、点踩和重新提问率;
  • 引用覆盖率和无依据回答率;
  • 人工转接率;
  • Prompt/模型版本之间的质量差异。

可观测性告诉我们发生了什么,评测系统才判断回答是否足够好,两者不能互相替代。


八、总结

Dify 的 Trace 体系体现了以下原则:

  1. Trace 按请求、工作流、节点、模型和工具组织父子关系;
  2. 统一 ID 串联数据库记录、运行事件和外部平台;
  3. 模型调用同时记录质量上下文、延迟、Token 和费用;
  4. Trace 通过独立队列异步导出,不阻塞业务;
  5. Provider Adapter 屏蔽不同观测平台协议;
  6. 观测失败不能影响用户请求;
  7. 输入输出采集遵循最小化、脱敏和保留周期;
  8. 缓存、SDK 实例和异步任务都必须保持租户隔离;
  9. 指标、日志、Trace 和离线评测共同构成 LLMOps 闭环。

好的可观测性不是保存所有内容,而是在成本和隐私可控的前提下,让一次 AI 决策可以解释、定位和比较。