实现标准的模型集成
本文档面向需要编写Python代码以添加或增强Dify模型支持的开发者,详细指导如何创建目录结构、编写模型配置、实现模型调用逻辑、调试和发布插件的完整流程,包含了核心方法实现和错误处理的细节。
本文档是为需要通过编写 Python 代码来为 Dify 添加或增强模型支持的开发者准备的标准指南。当你需要添加的模型涉及新的 API 调用逻辑、特殊参数处理或 Dify 需要显式支持的新功能(如 Vision, Tool Calling)时,就需要遵循本指南的步骤。
阅读本文前,建议你:
- 具备 Python 编程基础和面向对象编程的基本理解。
- 熟悉你想要集成的模型供应商提供的 API 文档和认证方式。
- 已安装并配置好 Dify 插件开发工具包 (参考 初始化开发工具)。
- (可选)阅读 模型插件介绍 文档,了解模型插件的基本概念和架构。
本指南将引导你完成创建目录结构、编写模型配置 (YAML)、实现模型调用逻辑 (Python) 以及调试和发布插件的全过程。
第 1 步: 创建目录结构
一个组织良好的目录结构是开发可维护插件的基础。你需要为你的模型供应商插件创建特定的目录和文件。
- 定位或创建供应商目录: 在你的插件项目(通常是
dify-official-plugins
的本地克隆)的models/
目录下,找到或创建以模型供应商命名的文件夹(例如models/my_new_provider
)。 - 创建
models
子目录: 在供应商目录下,创建models
子目录。 - 按模型类型创建子目录: 在
models/models/
目录下,为你需要支持的每种模型类型创建一个子目录。常见的类型包括:llm
: 文本生成模型text_embedding
: 文本 Embedding 模型rerank
: Rerank 模型speech2text
: 语音转文字模型tts
: 文字转语音模型moderation
: 内容审查模型
- 准备实现文件:
- 在每个模型类型目录下(例如
models/models/llm/
),你需要创建一个 Python 文件来实现该类型模型的调用逻辑(例如llm.py
)。 - 同样在该目录下,你需要为该类型下的每个具体模型创建一个 YAML 配置文件(例如
my-model-v1.yaml
)。 - (可选)可以创建一个
_position.yaml
文件来控制该类型下模型在 Dify UI 中的显示顺序。
- 在每个模型类型目录下(例如
示例结构 (假设供应商 my_provider
支持 LLM 和 Embedding):
第 2 步: 定义模型配置 (YAML)
对于每个具体模型,你需要创建一个 YAML 文件来描述其属性、参数和功能,以便 Dify 能够正确地理解和使用它。
- 创建 YAML 文件: 在对应的模型类型目录下(例如
models/models/llm/
),为你要添加的模型创建一个 YAML 文件,文件名通常与模型 ID 保持一致或具有描述性(例如my-llm-model-v1.yaml
)。 - 编写配置内容: 遵循 AIModelEntity Schema Definition 规范编写内容。关键字段包括:
model
: (必需) 模型的官方 API 标识符。label
: (必需) 在 Dify UI 中显示的名称 (支持多语言)。model_type
: (必需) 必须与所在目录类型一致 (如llm
)。features
: (可选) 声明模型支持的特殊功能 (如vision
,tool-call
,stream-tool-call
等)。model_properties
: (必需) 定义模型固有属性,如mode
(chat
或completion
),context_size
。parameter_rules
: (必需) 定义用户可调参数及其规则 (名称name
, 类型type
, 是否必须required
, 默认值default
, 范围min
/max
, 选项options
等)。可以使用use_template
引用预定义模板简化常见参数(如temperature
,max_tokens
)的配置。pricing
: (可选) 定义模型的计费信息。
示例 (claude-3-5-sonnet-20240620.yaml
):
第 3 步: 编写模型调用代码 (Python)
这是实现模型功能的和核心步骤。你需要在对应模型类型的 Python 文件中(例如 llm.py
)编写代码来处理 API 调用、参数转换和结果返回。
-
创建/编辑 Python 文件: 在模型类型目录下(例如
models/models/llm/
)创建或打开相应的 Python 文件(例如llm.py
)。 -
定义实现类:
- 定义一个类,例如
MyProviderLargeLanguageModel
。 - 该类必须继承自 Dify 插件 SDK 中对应的模型类型基类。例如,对于 LLM,需要继承
dify_plugin.provider_kits.llm.LargeLanguageModel
。
- 定义一个类,例如
-
实现关键方法: (具体需要实现的方法取决于继承的基类,以下以 LLM 为例)
-
_invoke(...)
: 核心调用方法。- 签名:
def _invoke(self, model: str, credentials: dict, prompt_messages: List[PromptMessage], model_parameters: dict, tools: Optional[List[PromptMessageTool]] = None, stop: Optional[List[str]] = None, stream: bool = True, user: Optional[str] = None) -> Union[LLMResult, Generator[LLMResultChunk, None, None]]:
- 职责:
- 使用
credentials
和model_parameters
准备 API 请求。 - 将 Dify 的
prompt_messages
格式转换为供应商 API 所需的格式。 - 处理
tools
参数以支持 Function Calling / Tool Use (如果模型支持)。 - 根据
stream
参数决定是进行流式调用还是同步调用。 - 流式返回: 如果
stream=True
,此方法必须返回一个生成器 (Generator
),通过yield
逐块返回LLMResultChunk
对象。每个 chunk 包含部分结果(文本、工具调用块等)和可选的用量信息。 - 同步返回: 如果
stream=False
,此方法必须返回一个完整的LLMResult
对象,包含最终的文本结果、完整的工具调用列表以及总的用量信息 (LLMUsage
)。
- 使用
- 实现模式: 强烈建议将同步和流式逻辑拆分到内部帮助方法中。
- 签名:
-
validate_credentials(self, model: str, credentials: dict) -> None
: (必需) 用于在用户添加或修改凭证时验证其有效性。通常通过调用一个简单的、低成本的 API 端点(如列出可用模型、检查余额等)来实现。如果验证失败,应抛出CredentialsValidateFailedError
或其子类。 -
get_num_tokens(self, model: str, credentials: dict, prompt_messages: List[PromptMessage], tools: Optional[List[PromptMessageTool]] = None) -> int
: (可选但推荐) 用于预估给定输入的 Token 数量。如果无法准确计算或 API 不支持,可以返回 0。 -
@property _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]
: (必需) 定义一个错误映射字典。键是 Dify 的标准InvokeError
子类,值是供应商 SDK 可能抛出的需要被映射到该标准错误的异常类型列表。这对于 Dify 统一处理不同供应商的错误至关重要。
-
第 4 步: 调试插件
在将插件贡献给社区之前,充分的测试和调试是必不可少的。Dify 提供了远程调试功能,让你可以在本地修改代码并实时在 Dify 实例中测试效果。
-
获取调试信息:
- 在你的 Dify 实例中,进入 “插件管理” 页面 (可能需要管理员权限)。
- 点击页面右上角的 “调试插件”,获取你的
调试 Key
和远程服务器地址
(例如http://<your-dify-domain>:5003
)。
-
配置本地环境:
-
在你的本地插件项目根目录下,找到或创建
.env
文件 (可从.env.example
复制)。 -
编辑
.env
文件,填入调试信息:
-
-
启动本地插件服务:
-
在插件项目根目录下,确保你的 Python 环境已激活(如果使用虚拟环境)。
-
运行主程序:
-
观察终端输出,如果连接成功,通常会有相应的日志提示。
-
-
在 Dify 中测试:
- 刷新 Dify 的 “插件” 或 “模型供应商” 页面,你应该能看到你的本地插件实例,可能带有 “调试中” 标识。
- 前往 “设置” -> “模型供应商”,找到你的插件,配置有效的 API 凭证。
- 在 Dify 应用中选择并使用你的模型进行测试。你在本地对 Python 代码的修改(保存后通常会自动重新加载服务)会直接影响 Dify 中的调用行为。使用 Dify 的调试预览功能可以帮助你检查输入输出和错误信息。
第 5 步: 打包与发布
当你完成了开发和调试,并对插件的功能满意后,就可以将其打包并贡献给 Dify 社区了。
- 打包插件:
-
停止本地调试服务 (
Ctrl+C
)。 -
在插件项目根目录下运行打包命令:
-
这将在项目根目录下生成一个
<provider_name>.difypkg
文件。
-
- 提交 Pull Request:
- 确保你的代码风格良好,并遵循 Dify 的插件发布规范。
- 将你的本地 Git 提交推送到你 Fork 的
dify-official-plugins
仓库。 - 在 GitHub 上向
langgenius/dify-official-plugins
主仓库发起 Pull Request。在 PR 描述中清晰说明你所做的更改、添加的模型或功能,以及任何必要的测试说明。 - 等待 Dify 团队审核。审核通过并合并后,你的贡献将包含在官方插件中,并在 Dify Marketplace 上可用。
探索更多
- 模型 Schema 定义 (模型 YAML 规范)
- 插件 Manifest 结构 (
manifest.yaml
规范) - Dify Plugin SDK 参考 (查找基类、数据结构和错误类型)
- Dify 官方插件仓库 (查看现有插件的实现)