【实战】Dify从0到100进阶--插件开发(1)Github爬取插件

发布于:2025-08-02 ⋅ 阅读:(8) ⋅ 点赞:(0)

在这里插入图片描述

基础配置

1. 安装插件CLI

  • macOS / Linux(Homebrew)

    brew tap langgenius/dify
    brew install dify
    

    安装完成后执行 dify version,应能看到类似 v0.0.1‑beta.15 的版本号。
    若需升级:

    brew upgrade dify
    
  • Windows / Linux / macOS(二进制文件)

    1. 从 GitHub Releases(https://github.com/langgenius/homebrew-difyhttps://github.com/langgenius/dify-plugin-daemon/releases)下载对应平台与架构的可执行文件(如 dify-plugin-darwin-arm64)。

    2. 赋予执行权限并重命名:

      chmod +x ./dify-plugin-darwin-arm64
      mv ./dify-plugin-darwin-arm64 dify
      
    3. (可选)复制到系统路径以便全局调用:

      sudo mv dify /usr/local/bin/
      
    4. 运行 dify version 检查是否安装成功。

  • 常见问题

    • macOS 若出现 “无法验证” 提示,前往「系统偏好 → 隐私与安全性」允许打开即可。
    • 确保最终能在任意终端使用 dify version 查看输出。

2. Python 环境准备

  • 插件开发要求 Python 版本 ≥ 3.12。
  • 可参考官方安装教程或社区文档完成安装:
  • 建议使用 pyenvconda 或 venv 创建独立环境,以免与系统默认 Python 冲突。

3. 后续开发指引

  • 环境准备完毕后,可参考官方插件开发入门文档,了解:
    • 插件项目结构
    • dify plugin init 快速生成模板
    • 开发、调试与打包流程
    • 插件能力分类(Data Source、Tool、LLM Extension 等)
  • 根据业务需求,选择对应的插件类型,并参阅示例仓库中的标准实践。

项目创建

1.前置准备

  1. 安装 Dify 插件 CLI

    • Homebrew(macOS/Linux)

      brew tap langgenius/dify
      brew install dify
      

      验证:dify version 应输出类似 v0.0.1‑beta.xx
      升级:brew upgrade dify

    • 二进制方式(Windows/macOS/Linux)

      1. 从 GitHub Releases 下载对应平台的可执行文件(如 dify-plugin-darwin-arm64)。

      2. 赋予可执行权限并重命名:

        chmod +x dify-plugin-darwin-arm64
        mv dify-plugin-darwin-arm64 dify
        
      3. (可选)拷贝至系统路径:sudo mv dify /usr/local/bin/

      4. 验证:dify version

  2. Python 环境

    • 版本要求:≥ 3.12
    • 建议使用 pyenvcondavenv 创建独立虚拟环境,避免与系统 Python 冲突。

2.初始化

# 若二进制已放至 PATH,可直接使用 dify
dify plugin init

  1. 选择项目类型
    • 在交互式菜单中选择 Tool
  2. 配置资源权限
    • 勾选:Tools、Apps、Storage(持久化存储)、Endpoint 注册权限。
  3. 完成后,脚手架会在当前目录生成一个包含基础结构的插件模板。

3.配置Provider

  1. 在项目根目录下的 /provider 目录,github_llm.yaml示例内容:

identity:
author: “yplz”
name: “github_llm”
label:
en_US: “github_llm”
zh_Hans: “github_llm”
pt_BR: “github_llm”
description:
en_US: “github_to_llm”
zh_Hans: “github_to_llm”
pt_BR: “github_to_llm”
icon: “icon.svg”
tools:

  • tools/github_llm.yaml
    extra:
    python:
    source: provider/github_llm.py

### 四、定义单个工具(Tool)

在 `/tools` 目录下`github_llm.yaml`,示例:

```yaml
identity:
name: "github_llm"
author: "yplz"
label:
 en_US: "github_llm"
 zh_Hans: "github_llm"
 pt_BR: "github_llm"
description:
human:
 en_US: "github_to_llm"
 zh_Hans: "github_to_llm"
 pt_BR: "github_to_llm"
llm: "github_to_llm"
parameters:
- name: input
 type: string
 required: true
 label:
   en_US: Query string
   zh_Hans: 输入内容
   pt_BR: Query string
 human_description:
   en_US: "github_to_llm"
   zh_Hans: "输入内容"
   pt_BR: "github_to_llm"
 llm_description: "github_to_llm"
 form: llm
extra:
python:
 source: tools/github_llm.py

  • identity:工具的唯一标识与展示信息。
  • parameters:定义输入参数,支持多语言描述和 LLM 推理模式。

4.实现工具逻辑

  1. 工具代码 /tools/github_llm.py

import asyncio
from collections.abc import Generator
from typing import Any
from dify_plugin import Tool
from dify_plugin.entities.tool import ToolInvokeMessage
import re
from datetime import datetime
import json
from playwright.async_api import async_playwright

async def fetch_github_trending():
“”“抓取 GitHub Trending,并返回项目列表”“”
# 启动 Playwright
playwright = await async_playwright().start()
browser = await playwright.chromium.launch(headless=True)
context = await browser.new_context()
page = await context.new_page()

# 访问 Trending 页面并等待加载完成
await page.goto("https://github.com/trending")
await page.wait_for_load_state('networkidle')

project_list = []
articles = await page.query_selector_all('article.Box-row')
for element in articles:
    try:
        pdict = {}

        # 项目名称及链接
        link = await element.query_selector('h2 a')
        href = await link.get_attribute("href")  # e.g. "/owner/repo"
        pdict['项目名称'] = href.split("/")[-1]
        pdict['url'] = f"https://github.com{href}"

        # 编程语言
        lang_ele = await element.query_selector("span[itemprop='programmingLanguage']")
        pdict['编程语言'] = (await lang_ele.text_content()).strip() if lang_ele else ""

        # 历史 star 数
        star_ele = await element.query_selector('a.Link--muted[href$="/stargazers"]')
        stars = await star_ele.text_content()
        pdict['历史star数'] = ''.join(re.findall(r'\d+', stars))

        # 今日 star 数
        today_ele = await element.query_selector('span.d-inline-block.float-sm-right')
        today = await today_ele.text_content()
        pdict['今日star数'] = ''.join(re.findall(r'\d+', today))

        # 创作者(仓库所有者)
        owner = href.split("/")[1]
        pdict['创作者'] = owner

        # 简介
        desc_ele = await element.query_selector('p.col-9')
        pdict['简介'] = (await desc_ele.text_content()).strip() if desc_ele else ""

        project_list.append(pdict)
    except Exception:
        # 遇到单条解析错误时忽略,继续下一个
        continue

# 清理并返回结果
await browser.close()
await playwright.stop()
return project_list

class GithubLlmTool(Tool):
def _invoke(self, tool_parameters: dict[str, Any]) -> Generator[ToolInvokeMessage]:
res=“未能查询到结果”
if tool_parameters[‘input’]:
res=asyncio.run(fetch_github_trending())
res = json.dumps(res, ensure_ascii=False)
else:
pass

    yield self.create_text_message(res)

2. **Provider 验证代码** `/provider/github_llm.py`:

```python
from typing import Any

from dify_plugin import ToolProvider
from dify_plugin.errors.tool import ToolProviderCredentialValidationError


class GithubLlmProvider(ToolProvider):
 def _validate_credentials(self, credentials: dict[str, Any]) -> None:
     try:
         """
         IMPLEMENT YOUR VALIDATION HERE
         """
     except Exception as e:
         raise ToolProviderCredentialValidationError(str(e))

5.调试与打包

  1. 远程调试

    • 在 Dify 控制台 “插件管理” 获取远程调试地址和 Key,填入项目根目录 .env

      INSTALL_METHOD=remote
      REMOTE_INSTALL_URL=debug.dify.ai:5003
      REMOTE_INSTALL_KEY=<your_key>
      
    • 启动:python -m main;登录 Dify Workspace,确认插件已安装并可调用。

  2. 打包发布

    dify plugin package ./github_llm
    

    生成 github_llm.difypkg,即可上传或发布至 Dify Marketplace。


网站公告

今日签到

点亮在社区的每一天
去签到