Dify
简体中文
简体中文
  • 入门
    • 欢迎使用 Dify
      • 特性与技术规格
      • 模型供应商列表
    • 云服务
    • 社区版
      • Docker Compose 部署
      • 本地源码启动
      • 宝塔面板部署
      • 单独启动前端 Docker 容器
      • 环境变量说明
      • 常见问题
    • Dify Premium
    • Dify 教育版
  • 手册
    • 接入大模型
      • 增加新供应商
      • 预定义模型接入
      • 自定义模型接入
      • 接口方法
      • 配置规则
      • 负载均衡
    • 构建应用
      • 创建应用
      • 聊天助手
        • 多模型调试
      • Agent
      • 应用工具箱
        • 敏感内容审查
    • 工作流
      • 关键概念
      • 变量
      • 节点说明
        • 开始
        • LLM
        • 知识检索
        • 问题分类
        • 条件分支
        • 代码执行
        • 模板转换
        • 文档提取器
        • 列表操作
        • 变量聚合
        • 变量赋值
        • 迭代
        • 参数提取
        • HTTP 请求
        • Agent
        • 工具
        • 结束
        • 直接回复
        • 循环
      • 快捷键
      • 编排节点
      • 文件上传
      • 异常处理
        • 预定义异常处理逻辑
        • 错误类型
      • 附加功能
      • 预览与调试
        • 预览与运行
        • 单步调试
        • 对话/运行日志
        • 检查清单
        • 运行历史
      • 应用发布
      • 结构化输出
      • 变更公告:图片上传被替换为文件上传
    • 知识库
      • 创建知识库
        • 1. 导入文本数据
          • 1.1 从 Notion 导入数据
          • 1.2 从网页导入数据
        • 2. 指定分段模式
        • 3. 设定索引方法与检索设置
      • 管理知识库
        • 维护知识库内文档
        • 通过 API 维护知识库
      • 元数据
      • 在应用内集成知识库
      • 召回测试/引用归属
      • 知识库请求频率限制
      • 连接外部知识库
      • 外部知识库 API
    • 工具
      • 快速接入工具
      • 高级接入工具
      • 工具配置
        • Google
        • Bing
        • SearchApi
        • StableDiffusion
        • Dall-e
        • Perplexity Search
        • AlphaVantage 股票分析
        • Youtube
        • SearXNG
        • Serper
        • SiliconFlow (支持 Flux 绘图)
        • ComfyUI
    • 发布
      • 发布为公开 Web 站点
        • Web 应用的设置
        • 文本生成型应用
        • 对话型应用
      • 嵌入网站
      • 基于 APIs 开发
      • 基于前端组件再开发
    • 标注
      • 日志与标注
      • 标注回复
    • 监测
      • 集成外部 Ops 工具
        • 集成 LangSmith
        • 集成 Langfuse
        • 集成 Opik
      • 数据分析
    • 扩展
      • API 扩展
        • 使用 Cloudflare Workers 部署 API Tools
        • 敏感内容审查
      • 代码扩展
        • 外部数据工具
        • 敏感内容审查
    • 协同
      • 发现
      • 邀请与管理成员
    • 管理
      • 应用管理
      • 团队成员管理
      • 个人账号管理
      • 订阅管理
      • 版本管理
  • 动手实验室
    • 初级
      • 如何搭建 AI 图片生成应用
      • AI Agent 实战:搭建个人在线旅游助手
    • 中级
      • 使用文件上传搭建文章理解助手
      • 使用知识库搭建智能客服机器人
      • ChatFlow 实战:搭建 Twitter 账号分析助手
  • 社区
    • 寻求支持
    • 成为贡献者
    • 为 Dify 文档做出贡献
  • 插件
    • 功能简介
    • 快速开始
      • 安装与使用插件
      • 插件开发
        • 初始化开发工具
        • Tool 插件
        • Model 插件
          • 创建模型供应商
          • 接入预定义模型
          • 接入自定义模型
        • Agent 策略插件
        • Extension 插件
        • Bundle 插件包
      • 插件调试
    • 插件管理
    • 接口定义
      • Manifest
      • Endpoint
      • Tool
      • Agent
      • Model
        • 模型设计规则
        • 模型接口
      • 通用规范定义
      • 持久化存储
      • 反向调用 Dify 服务
        • App
        • Model
        • Tool
        • Node
    • 最佳实践
      • 开发 Slack Bot 插件
      • Dify MCP 插件指南:一键连接 Zapier 并自动发送邮件
    • 发布插件
      • 自动发布插件
      • 发布至 Dify Marketplace
        • 插件开发者准则
        • 插件隐私政策准则
      • 发布至个人 GitHub 仓库
      • 本地发布与分享
      • 第三方签名验证
    • 常见问题
  • 研发
    • 后端
      • DifySandbox
        • 贡献指南
    • 模型接入
      • 接入 Hugging Face 上的开源模型
      • 接入 Replicate 上的开源模型
      • 接入 Xinference 部署的本地模型
      • 接入 OpenLLM 部署的本地模型
      • 接入 LocalAI 部署的本地模型
      • 接入 Ollama 部署的本地模型
      • 接入 LiteLLM 代理的模型
      • 接入 GPUStack 进行本地模型部署
      • 接入 AWS Bedrock 上的模型(DeepSeek)
    • 迁移
      • 将社区版迁移至 v1.0.0
  • 阅读更多
    • 应用案例
      • DeepSeek 与 Dify 集成指南:打造具备多轮思考的 AI 应用
      • 本地私有化部署 DeepSeek + Dify,构建你的专属私人 AI 助手
      • 如何训练出专属于“你”的问答机器人?
      • 教你十几分钟不用代码创建 Midjourney 提示词机器人
      • 构建一个 Notion AI 助手
      • 如何在几分钟内创建一个带有业务数据的官网 AI 智能客服
      • 使用全套开源工具构建 LLM 应用实战:在 Dify 调用 Baichuan 开源模型能力
      • 手把手教你把 Dify 接入微信生态
      • 使用 Dify 和 Twilio 构建 WhatsApp 机器人
      • 将 Dify 应用与钉钉机器人集成
      • 使用 Dify 和 Azure Bot Framework 构建 Microsoft Teams 机器人
      • 如何让 LLM 应用提供循序渐进的聊天体验?
      • 如何将 Dify Chatbot 集成至 Wix 网站?
      • 如何连接 AWS Bedrock 知识库?
      • 构建 Dify 应用定时任务助手
      • 如何在 Dify 内体验大模型“竞技场”?以 DeepSeek R1 VS o1 为例
      • 在 Dify 云端构建 AI Thesis Slack Bot
      • 将 Dify 快速接入 QQ、微信、飞书、钉钉、Telegram、Discord 等平台
    • 扩展阅读
      • 什么是 LLMOps?
      • 什么是数组变量?
      • 检索增强生成(RAG)
        • 混合检索
        • 重排序
        • 召回模式
      • 提示词编排
      • 如何使用 JSON Schema 让 LLM 输出遵循结构化格式的内容?
    • 常见问题
      • 本地部署
      • LLM 配置与使用
      • 插件
  • 政策
    • 开源许可证
    • 用户协议
      • 服务条款
      • 隐私政策
      • 获取合规报告
Powered by GitBook
On this page
  • 接入自定义模型插件
  • 1. 创建模型供应商文件
  • 2. 编写模型代码
  • 3. 调试插件
  • 4. 发布插件
  • 探索更多
  1. 插件
  2. 快速开始
  3. 插件开发
  4. Model 插件

接入自定义模型

Previous接入预定义模型NextAgent 策略插件

Last updated 2 months ago

自定义模型指的是需要自行部署或配置的 LLM。本文将以 为例,演示如何在模型插件内接入自定义模型。

自定义模型默认包含模型类型和模型名称两个参数,无需在供应商 yaml 文件定义。

供应商配置文件无需实现 validate_provider_credential。Runtime 会根据用户选择的模型类型或模型名称,自动调用对应模型层的 validate_credentials 方法进行验证。

接入自定义模型插件

接入自定义模型分为以下步骤:

  1. 创建模型供应商文件

    明确自定义模型中所包含的模型类型。

  2. 根据模型类型创建代码文件

    根据模型的类型(如 llm 或 text_embedding)创建代码文件。确保每种模型类型有独立的逻辑分层,便于维护和扩展。

  3. 根据不同的模型模块,编写模型调用代码

    在对应的模型类型模块下,创建一个与模型类型同名的 Python 文件(例如 llm.py)。在文件中定义实现具体模型逻辑的类,该类应符合系统的模型接口规范。

  4. 调试插件

    为新增的供应商功能编写单元测试和集成测试,确保所有功能模块符合预期,并能够正常运行。


1. 创建模型供应商文件

在插件项目的 /provider 路径下,新建 xinference.yaml 文件。

Xinference 家族模型支持 LLM``,Text Embedding 和 Rerank 模型类型,因此需要在 xinference.yaml 文件中包含上述模型类型。

示例代码:

provider: xinference # 确定供应商标识
label: # 供应商展示名称,可设置 en_US 英文、zh_Hans 中文两种语言,zh_Hans 不设置将默认使用 en_US。
  en_US: Xorbits Inference
icon_small: # 小图标,可以参考其他供应商的图标,存储在对应供应商实现目录下的 _assets 目录,中英文策略同 label
  en_US: icon_s_en.svg
icon_large: # 大图标
  en_US: icon_l_en.svg
help: # 帮助
  title:
    en_US: How to deploy Xinference
    zh_Hans: 如何部署 Xinference
  url:
    en_US: https://github.com/xorbitsai/inference
supported_model_types: # 支持的模型类型,Xinference 同时支持 LLM/Text Embedding/Rerank
- llm
- text-embedding
- rerank
configurate_methods: # Xinference 为本地部署的供应商,并且没有预定义模型,需要用什么模型需要根据 Xinference 的文档进行部署,因此此处的方法为自定义模型。
- customizable-model
provider_credential_schema:
  credential_form_schemas:

接着需要定义 provider_credential_schema 字段。Xinference 支持 text-generation,embeddings 和 reranking 模型,示例代码如下:

provider_credential_schema:
  credential_form_schemas:
  - variable: model_type
    type: select
    label:
      en_US: Model type
      zh_Hans: 模型类型
    required: true
    options:
    - value: text-generation
      label:
        en_US: Language Model
        zh_Hans: 语言模型
    - value: embeddings
      label:
        en_US: Text Embedding
    - value: reranking
      label:
        en_US: Rerank

Xinference 中的每个模型都需要定义名称 model_name。

  - variable: model_name
    type: text-input
    label:
      en_US: Model name
      zh_Hans: 模型名称
    required: true
    placeholder:
      zh_Hans: 填写模型名称
      en_US: Input model name

Xinference 模型需要使用者输入模型的本地部署地址,插件内需要提供允许填写 Xinference 模型的本地部署地址(server_url)和模型 UID 的位置,示例代码如下:

  - variable: server_url
    label:
      zh_Hans: 服务器 URL
      en_US: Server url
    type: text-input
    required: true
    placeholder:
      zh_Hans: 在此输入 Xinference 的服务器地址,如 https://example.com/xxx
      en_US: Enter the url of your Xinference, for example https://example.com/xxx
  - variable: model_uid
    label:
      zh_Hans: 模型 UID
      en_US: Model uid
    type: text-input
    required: true
    placeholder:
      zh_Hans: 在此输入您的 Model UID
      en_US: Enter the model uid

填写所有参数后即可完成自定义模型供应商 yaml 配置文件的创建。接下来需为配置文件内定义的模型添加具体的功能代码文件。

2. 编写模型代码

Xinference 模型供应商的模型类型包含 llm、rerank、speech2text、tts 类型,因此需要在 /models 路径下为每个模型类型创建独立的分组,并创建对应的功能代码文件。

下文将以 llm 类型为例,说明如何创建 llm.py 代码文件。创建代码时需创建一个 Xinference LLM 类,可以取名为 XinferenceAILargeLanguageModel,继承 __base.large_language_model.LargeLanguageModel 基类,实现以下几个方法:

  • LLM 调用

LLM 调用的核心方法,同时支持流式和同步返回。

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]:
    """
    Invoke large language model

    :param model: model name
    :param credentials: model credentials
    :param prompt_messages: prompt messages
    :param model_parameters: model parameters
    :param tools: tools for tool calling
    :param stop: stop words
    :param stream: is stream response
    :param user: unique user id
    :return: full response or stream response chunk generator result
    """

实现代码时,需要注意使用两个函数来返回数据,分别用于处理同步返回和流式返回。

Python 会将函数中包含 yield 的关键字函数识别为生成器函数,返回的数据类型固定为 Generator,因此需要分别实现同步和流式返回,例如以下示例代码:

该示例使用了简化参数,实际编写代码时需参考上文中的参数列表。

def _invoke(self, stream: bool, **kwargs) \
        -> Union[LLMResult, Generator]:
    if stream:
          return self._handle_stream_response(**kwargs)
    return self._handle_sync_response(**kwargs)

def _handle_stream_response(self, **kwargs) -> Generator:
    for chunk in response:
          yield chunk
def _handle_sync_response(self, **kwargs) -> LLMResult:
    return LLMResult(**response)
  • 预计算输入 Tokens

如果模型未提供预计算 tokens 的接口,可以直接返回 0。

def get_num_tokens(self, model: str, credentials: dict, prompt_messages: list[PromptMessage],
                 tools: Optional[list[PromptMessageTool]] = None) -> int:
  """
  Get number of tokens for given prompt messages

  :param model: model name
  :param credentials: model credentials
  :param prompt_messages: prompt messages
  :param tools: tools for tool calling
  :return:
  """

在某些情况下,如果不想直接返回 0,可以使用 self._get_num_tokens_by_gpt2(text: str) 方法计算 tokens。该方法位于 AIModel 基类中,使用 GPT-2 的 Tokenizer 进行计算。但请注意,这是一个替代方案,计算结果可能存在一定误差。

  • 模型凭据校验

与供应商凭据校验类似,这里针对单个模型进行校验。

def validate_credentials(self, model: str, credentials: dict) -> None:
    """
    Validate model credentials

    :param model: model name
    :param credentials: model credentials
    :return:
    """
  • 模型参数 Schema

例如,Xinference 支持 max_tokens、temperature 和 top_p 三种模型参数。然而一些供应商(例如 OpenLLM)会根据具体模型支持不同的参数。

举例来说,供应商 OpenLLM 的 A 模型支持 top_k 参数,而 B 模型则不支持 top_k。在该情况下,需要动态生成每个模型对应的参数 Schema,示例代码如下:

  def get_customizable_model_schema(self, model: str, credentials: dict) -> AIModelEntity | None:
      """
          used to define customizable model schema
      """
      rules = [
          ParameterRule(
              name='temperature', type=ParameterType.FLOAT,
              use_template='temperature',
              label=I18nObject(
                  zh_Hans='温度', en_US='Temperature'
              )
          ),
          ParameterRule(
              name='top_p', type=ParameterType.FLOAT,
              use_template='top_p',
              label=I18nObject(
                  zh_Hans='Top P', en_US='Top P'
              )
          ),
          ParameterRule(
              name='max_tokens', type=ParameterType.INT,
              use_template='max_tokens',
              min=1,
              default=512,
              label=I18nObject(
                  zh_Hans='最大生成长度', en_US='Max Tokens'
              )
          )
      ]

      # if model is A, add top_k to rules
      if model == 'A':
          rules.append(
              ParameterRule(
                  name='top_k', type=ParameterType.INT,
                  use_template='top_k',
                  min=1,
                  default=50,
                  label=I18nObject(
                      zh_Hans='Top K', en_US='Top K'
                  )
              )
          )

      """
          some NOT IMPORTANT code here
      """

      entity = AIModelEntity(
          model=model,
          label=I18nObject(
              en_US=model
          ),
          fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
          model_type=model_type,
          model_properties={
              ModelPropertyKey.MODE:  ModelType.LLM,
          },
          parameter_rules=rules
      )

      return entity
  • 调用异常错误映射表

当模型调用异常时需要映射到 Runtime 指定的 InvokeError 类型,方便 Dify 针对不同错误做不同后续处理。

Runtime Errors:

  • InvokeConnectionError 调用连接错误

  • InvokeServerUnavailableError 调用服务方不可用

  • InvokeRateLimitError 调用达到限额

  • InvokeAuthorizationError 调用鉴权失败

  • InvokeBadRequestError 调用传参有误

@property
def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]:
    """
    Map model invoke error to unified error
    The key is the error type thrown to the caller
    The value is the error type thrown by the model,
    which needs to be converted into a unified error type for the caller.

    :return: Invoke error mapping
    """

3. 调试插件

插件开发完成后,接下来需测试插件是否可以正常运行。详细说明请参考:

4. 发布插件

如果想要将插件发布至 Dify Marketplace,请参考以下内容:

探索更多

快速开始:

插件接口文档:

与不同,由于未在 YAML 文件中预设模型所支持的参数,因此需要动态生成模型参数的 Schema。

如需了解更多接口方法,请参考。

如需获取本文所涉及的完整代码文件,请访问 。

结构

详细定义

Xinference 模型
预定义模型类型
接口文档:Model
GitHub 代码仓库
插件调试
发布至 Dify Marketplace
开发 Extension 插件
开发 Tool 插件
Bundle 插件:将多个插件打包
Manifest
Endpoint
反向调用 Dify 能力
工具
模型