如何为 Dify 的 ops tracing 开发并注册自定义观测后端 provider
2026/9/10 13:50:54 网站建设 项目流程

如何为 Dify 的 ops tracing 开发并注册自定义观测后端 provider

【免费下载链接】difyBuild Agentic workflows, RAG pipelines, with rich AI model and tool support on one collaborative workspace. Deploy on cloud, VPC, or self-hosted, so teams move from prototype to production without rebuilding the stack.项目地址: https://gitcode.com/GitHub_Trending/di/dify

如果你的 Dify 应用产生的 ops tracing 数据(工作流、消息、工具调用、内容审核等)需要发送到一个 Dify 官方没有内置的观测后端,就需要自己开发一个 trace provider 包,并在 API 核心中完成注册。本文基于仓库中 trace providers 说明 和现有参考实现(trace-langfusetrace-langsmithtrace-opiktrace-mlflow等),给出从建包到注册的完整操作路径。

先明确一个架构前提:与 VDB provider 不同,trace provider不会通过 entry points 自动发现。API 核心会在你注册 provider id 与映射之后,从 ops_trace_manager.py 显式导入你的包。因此开发分四步:建包、实现 config 与 trace 实例、在 API 核心注册、接入apiuv workspace。

三层结构的分工如下:

位置职责
契约api/core/ops/base_trace_instance.pyapi/core/ops/entities/trace_entity.pyapi/core/ops/entities/config_entity.pyBaseTraceInstanceBaseTracingConfig以及带类型的*TraceInfo载荷
注册表api/core/ops/ops_trace_manager.pyTracingProviderEnumOpsTraceProviderConfigMap—— 将 provider 字符串映射到 config 类、加密键和 trace 类
你的包api/providers/trace/trace-<name>/Pydantic config +BaseTraceInstance子类

运行时,OpsTraceManager会解密已存储的凭据、构建你的 config 模型、缓存 trace 实例,并用具体的BaseTraceInfo子类型调用trace(trace_info)

创建 provider 包

每个 provider 是api/providers/trace/下普通的 uv workspace 成员。按 README 给出的布局,以trace-mybackend为例(下文代码中的mybackendMyBackend均为示例名,请整体替换为你自己的 provider 名):

  • api/providers/trace/trace-mybackend/pyproject.toml—— 项目名dify-trace-mybackend,依赖你的后端 SDK;
  • api/providers/trace/trace-mybackend/src/dify_trace_mybackend/—— 包含config.pymybackend_trace.py、可选的entities/目录,以及一个空的py.typed文件(PEP 561),让 API 的类型检查器把该包当作有类型标注处理;按 README 要求,在pyproject.toml[tool.setuptools.package-data]中为该导入名列出py.typed

pyproject.toml的最小形式可参考现有包 trace-mlflow/pyproject.toml:

[project] name = "dify-trace-mybackend" version = "0.0.1" dependencies = [ "你的后端 SDK>=版本", ] description = "Dify ops tracing provider (MyBackend)." [tool.setuptools.packages.find] where = ["src"]

写 config 前建议先读一个参考实现,例如 MLflow config 和 MLflow trace 类。

实现配置模型:BaseTracingConfig 子类

在包内新建config.py,从core.ops.entities.config_entity继承BaseTracingConfig,用 Pydantic validator 校验字段,并在适当处复用core.ops.utils里的辅助函数(README 明确列出的有validate_urlvalidate_url_with_pathvalidate_project_name)。参考实现中的字段校验写法:

@field_validator("tracking_uri") @classmethod def tracking_uri_validator(cls, v, info: ValidationInfo): if isinstance(v, str) and v.startswith("databricks"): raise ValueError(...) return validate_url_with_path(v, "http://localhost:5000")

(以上片段摘自 config.py 中MLflowConfig的真实代码。)

config 的字段按 manager 的使用方式分两类,你必须在后文注册时如实地列出它们:

  • secret_keys—— 存储时会被加密的字段名(API key、token、密码);
  • other_keys—— 非密钥的连接设置(host、project 名、endpoint)。

manager 的encrypt_tracing_config/decrypt_tracing_config会依据这两个列表做加解密与合并;若列表与实际字段不符,加密/解密逻辑就会出错。

实现 trace 实例:BaseTraceInstance 子类

在包内新建mybackend_trace.py,继承 BaseTraceInstance 并实现:

def trace(self, trace_info: BaseTraceInfo) -> None: ...

在方法内用isinstance对具体类型分发(README 建议参考trace_langfusetrace_langsmith的完整写法)。载荷类型定义在api/core/ops/entities/trace_entity.py,包括:

  • WorkflowTraceInfoWorkflowNodeTraceInfoDraftNodeExecutionTrace
  • MessageTraceInfoToolTraceInfoModerationTraceInfoSuggestedQuestionTraceInfo
  • DatasetRetrievalTraceInfoGenerateNameTraceInfoPromptGenerationTraceInfo

可以忽略后端不支持的类别,现有 provider 常常对未处理的类型做 no-op 处理,不必强行覆盖全部类型。

如果需要租户范围的账户上下文,可调用基类提供的get_service_account_with_tenant(app_id)(它会返回带有已设置 tenant 的服务账户Account,见 base_trace_instance.py)。

另外,OpsTraceManager还保留了三个会调用你实例方法的入口(见 ops_trace_manager.py):

  • check_trace_config_is_effective:用你的 config 类构建实例后调用trace_instance(config).api_check()
  • get_trace_config_project_key:调用trace_instance(config).get_project_key()
  • get_trace_config_project_url:调用trace_instance(config).get_project_url()

如果你的后端能提供“配置是否可用”的自检或项目地址,就实现这三个方法,让控制台侧的配置校验链路走通。

在 API 核心中注册 provider

这是必须修改上游代码的部分,Dify 需要两处改动才知道你的 provider 存在:

  1. TracingProviderEnum(config_entity.py)—— 新增一个成员,其是存储在 app tracing 配置中的稳定字符串(README 示例为"mybackend"):
class TracingProviderEnum(StrEnum): ARIZE = "arize" ... MYBACKEND = "mybackend"
  1. OpsTraceProviderConfigMap.__getitem__(ops_trace_manager.py)—— 为该枚举成员新增一个match分支,返回:

    • config_class:你的 Pydantic config 类型
    • secret_keys/other_keys:上面列出的字段名列表
    • trace_instance:你的BaseTraceInstance子类

    在你的分支内部懒加载导入包,这样未安装可选依赖时会抛出清晰的ImportError(该方法会把ImportError包装成Provider {key} is not installed.):

case TracingProviderEnum.MYBACKEND: from dify_trace_mybackend.config import MyBackendConfig from dify_trace_mybackend.mybackend_trace import MyBackendDataTrace return { "config_class": MyBackendConfig, "secret_keys": ["api_key"], "other_keys": ["host"], "trace_instance": MyBackendDataTrace, }

secret_keys/other_keys必须与config.py中的字段一一对应(示例中的"api_key""host"仅为占位,按你的实际字段替换)。

如果漏掉这个match分支,provider 字符串将无法解析,该应用的 tracing 会被直接禁用(get_ops_trace_instance遇到KeyError时返回None)。

接入 api workspace 并同步依赖

在 api/pyproject.toml 中做两处改动(现有 provider 的写法见该文件[tool.uv.sources][dependency-groups]段):

  1. [tool.uv.sources]—— 添加dify-trace-mybackend = { workspace = true }
  2. [dependency-groups]—— 添加trace-mybackend = ["dify-trace-mybackend"];如果该 provider 要随默认捆绑一起发行,再把dify-trace-mybackend加进trace-all组。

改完元数据后,在api/目录下执行:

uv sync

验证与限制

可用的判定方式都来自文档与注册链路的实际行为:

  • 依赖可导入uv sync成功后,match分支内的懒加载导入不再抛ImportError。若包未安装,manager 会报Provider {key} is not installed.
  • provider 字符串可解析:在provider_config_map[tracing_provider]处(即get_ops_trace_instance内部)能命中你的分支;README 明确说明缺失match分支时,provider 字符串无法解析、tracing 对该应用失效。
  • 配置自检:如果你的实例实现了api_check(),控制台保存 tracing 配置时的有效性检查(check_trace_config_is_effective)会真正调用它并依据其返回判断配置是否生效。

需要注意的边界:trace plugin 不走 entry points 发现机制,注册完全依赖上述显式导入;secret_keys中的值在落库前由encrypt_token(tenant_id, value)加密,"*"前缀的掩码值会保留原配置项,因此字段名列表写错会直接影响加密/解密正确性。后续扩展时,可对照 trace-mlflow 的 trace 类 看一个 provider 如何把WorkflowTraceInfoMessageTraceInfo等类型映射到具体后端的 span 结构。

【免费下载链接】difyBuild Agentic workflows, RAG pipelines, with rich AI model and tool support on one collaborative workspace. Deploy on cloud, VPC, or self-hosted, so teams move from prototype to production without rebuilding the stack.项目地址: https://gitcode.com/GitHub_Trending/di/dify

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询