Pass app_id to model plugins for provider-side cost attribution

用户在 Dify 平台中构建了自定义模型插件(例如为 Amazon Bedrock 的 Converse API 添加 requestMetadata 标签进行成本追踪),但在模型插件中只能获取 user_id ,而无法获取 app_id 。这导致无法将 LLM 调用与具体应用关联,从而无法实现按应

快速结论:该报错或功能缺失场景是当你在 Dify 中通过自定义模型插件(如 Amazon Bedrock、OpenAI、Anthropic 等)进行请求时,发现无法获取当前请求所属的 app_id,导致无法在提供商标记请求以实现按应用成本归因。优先排查 Dify 版本是否低于包含该修复的版本,并确认模型插件分发路径是否缺少 app_id 字段传递。

问题场景

用户在 Dify 平台中构建了自定义模型插件(例如为 Amazon Bedrock 的 Converse API 添加 requestMetadata 标签进行成本追踪),但在模型插件中只能获取 user_id,而无法获取 app_id。这导致无法将 LLM 调用与具体应用关联,从而无法实现按应用的成本归因仪表板(如 Grafana)。而工具插件(Tool Plugins)已经可以传递 app_id,模型插件路径却存在此不对称问题。

报错原文

# Tool plugin dispatch (core/plugin/impl/tool.py) — app_id is included
data={
    "user_id": user_id,
    "conversation_id": conversation_id,
    "app_id": app_id,
    "message_id": message_id,
    "data": { ... },
}

# Model plugin dispatch (core/plugin/impl/model.py) — app_id is missing
data=jsonable_encoder({
    "user_id": user_id,
    "data": { ... },
})

原因分析

这是 Dify 模型插件分发路径的设计不对称问题。在插件架构引入(PR #13836)时,模型插件路径被保留了最小数据传递,因为模型可能在没有应用上下文的场景下被调用(如 RAG 索引、标题生成、建议问题等),因此未包含 app_id。但工具插件路径却包含了 app_id。该问题在 Dify 主仓库(langgenius/dify)和插件 SDK 仓库(langgenius/dify-plugin-sdks)中均有体现。

环境排查

  • Dify 版本:确认当前使用版本是否早于或晚于该问题修复 PR(langgenius/dify#35859langgenius/dify-plugin-sdks#313)。
  • 检查 api/core/plugin/impl/model.py 文件中模型插件分发数据是否只包含 user_id 而不包含 app_id
  • 检查 api/core/plugin/impl/tool.py 工具插件分发数据是否包含 app_id 以对比确认不对称问题存在。
  • 插件守护进程(dify-plugin-daemon)版本:该问题不需要修改守护进程,但需确认其 InvokePluginRequest 结构是否已包含 AppID 字段(该问题中表示已包含)。

解决步骤

  1. 确认问题存在:检查 api/core/plugin/impl/model.py 文件,确认模型插件分发数据是否缺少 app_id
  2. 应用 Dify 主仓库修复:等待或手动合入 PR langgenius/dify#35859,该 PR 在 model.py 的模型插件分发数据中添加 app_id 字段(当模型在应用上下文外被调用时,app_idnull)。
  3. 应用插件 SDK 修复:等待或手动合入 PR langgenius/dify-plugin-sdks#313,该 PR 在 SDK 侧将 session 转发给模型插件实例,并暴露 get_current_session() 方法供插件作者获取 app_id
  4. 处理 null app_id 场景:在模型插件中处理 app_idnull 的情况(例如 RAG 路由、标题生成、建议问题等内部调用)。推荐使用哨兵值 "dify_system" 将这些调用单独归类,以区分外部业务应用流量。
  5. 更新插件逻辑:在自定义模型插件中,通过 get_current_session() 获取当前 session,并从中提取 app_id,用于在提供商 API 请求中设置标签(如 Bedrock 的 requestMetadata、OpenAI 的 metadata、Anthropic 的 metadata 等)。

验证方法

在应用修复后,在模型插件中通过 get_current_session() 获取 app_id 字段,并在提供商 API 请求中设置对应标签。然后查看提供商的成本归因仪表板(如 AWS CloudWatch Logs、Azure Usage Dashboard、Google Cloud Billing 等)确认请求已被正确标注应用 ID。对于内部系统调用(不包含 app_id 的请求),确认其被标记为预设的哨兵值(如 dify_system)而非缺失或错误。

参考来源

原始 Issue:langgenius/dify #35772

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 16166

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注