Dify中的工具

Dify中的工具分为内置工具(硬编码)和第三方工具(OpenAPI Swagger/ChatGPT Plugin)。工具可被Workflow(工作流)和Agent使用,当然Workflow也可被发布为工具,这样Workflow(工作流)中又可以使用Workflow(工具)。

一.Dify内置工具

下面以Google为例介绍。从前端看只要输入SerpApi API key即可,接下来重点分析后端实现。

源码位置:dify-0.6.9/api/core/tools/provider/builtin/google

1.准备工具供应商 yaml

源码位置:dify-0.6.9/api/core/tools/provider/builtin/google/google.yaml

identity:  # 工具供应商的基本信息
  author: Dify  # 作者
  name: google  # 工具供应商的名称,名称是唯一的,不允许和其它供应商重名
  label:  # 标签用于前端展示
    en_US: Google  # 英文标签
    zh_Hans: Google  # 简体中文标签
    pt_BR: Google  # 葡萄牙语标签
  description:  # 描述用于前端展示
    en_US: Google  # 英文描述
    zh_Hans: GoogleSearch  # 简体中文描述
    pt_BR: Google  # 葡萄牙语描述
  icon: icon.svg  # 图标文件名,图标文件需要放在当前模块的_assets目录下

2.准备供应商凭据

源码位置:dify-0.6.9/api/core/tools/provider/builtin/google/google.yaml

Google使用了SerpApi提供的API,而SerpApi需要一个API Key才能使用,即该工具需要一个凭证才能使用,也是前端需要输入SerpApi API key的原因。

credentials_for_provider:  # 凭据字段
  serpapi_api_key:  # 凭据字段的唯一标识
    type: secret-input  # 凭据字段的类型
    required: true  # 是否必填
    label:  # 标签用于前端展示
      en_US: SerpApi API key  # 英文标签
      zh_Hans: SerpApi API key  # 简体中文标签
      pt_BR: SerpApi API key  # 葡萄牙语标签
    placeholder:  # 提示用于前端展示
      en_US: Please input your SerpApi API key  # 英文提示
      zh_Hans: 请输入你的 SerpApi API key  # 简体中文提示
      pt_BR: Please input your SerpApi API key  # 葡萄牙语提示
    help:  # 凭据字段帮助文本
      en_US: Get your SerpApi API key from SerpApi  # 英文帮助文本
      zh_Hans: 从 SerpApi 获取您的 SerpApi API key  # 简体中文帮助文本
      pt_BR: Get your SerpApi API key from SerpApi  # 葡萄牙语帮助文本
    url: https://serpapi.com/manage-api-key  # 凭据字段帮助链接

type:凭据字段类型,目前支持secret-input、text-input、select 三种类型,分别对应密码输入框、文本输入框、下拉框,如果为secret-input,则会在前端隐藏输入内容,并且后端会对输入内容进行加密。

3.准备工具 yaml

源码位置:dify-0.6.9\api\core\tools\provider\builtin\google\tools\google_search.yaml

一个供应商底下可以有多个工具,每个工具都需要一个 yaml 文件来描述,这个文件包含了工具的基本信息、参数、输出等。

identity:  # 工具的基本信息
  name: google_search  # 工具的唯一名称
  author: Dify  # 工具的作者
  label:  # 工具的标签,用于前端展示
    en_US: GoogleSearch  # 英文标签
    zh_Hans: 谷歌搜索  # 简体中文标签
    pt_BR: GoogleSearch  # 葡萄牙语标签
description:  # 工具的描述
  human:  # 人类可读的描述
    en_US: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
    zh_Hans: 一个用于执行 Google SERP 搜索并提取片段和网页的工具。输入应该是一个搜索查询。
    pt_BR: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
  # 传递给 LLM 的介绍,为了使得LLM更好理解这个工具,我们建议在这里写上关于这个工具尽可能详细的信息,让 LLM 能够理解并使用这个工具
  llm: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.
parameters:  # 参数列表
  - name: query  # 参数名称
    type: string  # 参数类型
    required: true  # 是否必填
    label:  # 参数标签
      en_US: Query string  # 英文标签
      zh_Hans: 查询语句  # 简体中文标签
      pt_BR: Query string  # 葡萄牙语标签
    human_description:  # 参数描述,用于前端展示
      en_US: used for searching  # 英文描述
      zh_Hans: 用于搜索网页内容  # 简体中文描述
      pt_BR: used for searching  # 葡萄牙语描述
    # 传递给LLM的介绍,同上,为了使得LLM更好理解这个参数,我们建议在这里写上关于这个参数尽可能详细的信息,让LLM能够理解这个参数
    llm_description: key words for searching
    form: llm  # 参数的表单类型,llm表示这个参数需要由Agent自行推理出来,前端将不会展示这个参数
  - name: result_type  # 参数名称
    type: select  # 参数类型
    required: true  # 是否必填
    options:  # 参数的选项
      - value: text
        label:
          en_US: text
          zh_Hans: 文本
          pt_BR: texto
      - value: link
        label:
          en_US: link
          zh_Hans: 链接
          pt_BR: link
    default: link  # 默认值为链接
    label:
      en_US: Result type
      zh_Hans: 结果类型
      pt_BR: Result type
    human_description:
      en_US: used for selecting the result type, text or link
      zh_Hans: 用于选择结果类型,使用文本还是链接进行展示
      pt_BR: used for selecting the result type, text or link
    form: form  # 参数的表单类型,form表示这个参数需要由用户在对话开始前在前端填写
  • identity 字段是必须的,它包含了工具的基本信息,包括名称、作者、标签、描述等

  • parameters 参数列表

    • name 参数名称,唯一,不允许和其他参数重名

    • type 参数类型,目前支持stringnumberbooleanselect 四种类型,分别对应字符串、数字、布尔值、下拉框

    • required 是否必填

      • llm模式下,如果参数为必填,则会要求 Agent 必须要推理出这个参数

      • form模式下,如果参数为必填,则会要求用户在对话开始前在前端填写这个参数

    • options 参数选项

      • llm模式下,Dify 会将所有选项传递给 LLM,LLM 可以根据这些选项进行推理

      • form模式下,typeselect时,前端会展示这些选项

    • default 默认值

    • label 参数标签,用于前端展示

    • human_description 用于前端展示的介绍,支持多语言

    • llm_description 传递给 LLM 的介绍,为了使得 LLM 更好理解这个参数,我们建议在这里写上关于这个参数尽可能详细的信息,让 LLM 能够理解这个参数

    • form 表单类型,目前支持llmform两种类型,分别对应 Agent 自行推理和前端填写

4.准备工具代码

源码位置:dify-0.6.9\api\core\tools\provider\builtin\google\tools\google_search.py

class GoogleSearchTool(BuiltinTool):
    def _invoke(self, 
                user_id: str,  # 表示用户ID
               tool_parameters: dict[str, Any],  # 表示工具参数
        ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:  # 表示工具调用消息
        """
            invoke tools
        """
        query = tool_parameters['query']  # 表示查询
        result_type = tool_parameters['result_type']  # 表示结果类型
        api_key = self.runtime.credentials['serpapi_api_key']  # 表示API密钥
        result = SerpAPI(api_key).run(query, result_type=result_type)  # 表示运行查询
        if result_type == 'text':  # 表示结果类型为文本
            return self.create_text_message(text=result)  # 返回文本消息
        return self.create_link_message(link=result)  # 返回链接消息

5.准备供应商代码

源码位置:dify-0.6.9\api\core\tools\provider\builtin\google\google.py

class GoogleSearchTool(BuiltinTool):
    def _invoke(self, 
                user_id: str,  # 表示用户ID
               tool_parameters: dict[str, Any],  # 表示工具参数
        ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:  # 表示工具调用消息
        """
            invoke tools
        """
        query = tool_parameters['query']  # 表示查询
        result_type = tool_parameters['result_type']  # 表示结果类型
        api_key = self.runtime.credentials['serpapi_api_key']  # 表示API密钥
        result = SerpAPI(api_key).run(query, result_type=result_type)  # 表示运行查询
        if result_type == 'text':  # 表示结果类型为文本
            return self.create_text_message(text=result)  # 返回文本消息
        return self.create_link_message(link=result)  # 返回链接消息

二.工具接口中的消息返回

1.返回消息类型

源码位置:dify-0.6.9\api\core\tools\tool\tool.py

Dify支持文本 链接 图片 文件BLOB 等多种消息类型,可通过以下几个接口返回不同类型的消息给 LLM 和用户。

def create_image_message(self, image: str, save_as: str = '') -> ToolInvokeMessage:
    """
        create an image message

        :param image: the url of the image
        :return: the image message
    """
    return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.IMAGE, 
                             message=image, 
                             save_as=save_as)

def create_file_var_message(self, file_var: FileVar) -> ToolInvokeMessage:
    return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.FILE_VAR,
                             message='',
                             meta={
                                 'file_var': file_var
                             },
                             save_as='')

def create_link_message(self, link: str, save_as: str = '') -> ToolInvokeMessage:
    """
        create a link message

        :param link: the url of the link
        :return: the link message
    """
    return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.LINK, 
                             message=link, 
                             save_as=save_as)

def create_text_message(self, text: str, save_as: str = '') -> ToolInvokeMessage:
    """
        create a text message

        :param text: the text
        :return: the text message
    """
    return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.TEXT, 
                             message=text,
                             save_as=save_as
                             )

def create_blob_message(self, blob: bytes, meta: dict = None, save_as: str = '') -> ToolInvokeMessage:
    """
        create a blob message

        :param blob: the blob
        :return: the blob message
    """
    return ToolInvokeMessage(type=ToolInvokeMessage.MessageType.BLOB, 
                             message=blob, meta=meta,
                             save_as=save_as
                             )

如果要返回文件的原始数据,如图片、音频、视频、PPT、Word、Excel 等,可以使用文件 BLOB。

  • blob 文件的原始数据,bytes 类型。

  • meta 文件的元数据,如果知道该文件的类型,最好传递一个mime_type,否则Dify将使用octet/stream作为默认类型。比如:

# b64decode函数的作用是将一个Base64编码的字符串解码为原始的字节数据
self.create_blob_message(blob=b64decode(image.b64_json), meta={ 'mime_type': 'image/png' }, save_as=self.VARIABLE_KEY.IMAGE.value)

self.create_blob_message(blob=response.content, meta={'mime_type': 'image/svg+xml'})

application/octet-stream 是一种通用的二进制数据的 MIME 类型。“Octet” 是一个八位字节,“stream” 指的是数据流。这种类型通常用于表示未知的、二进制的数据。当下载或上传文件时,如果服务器或客户端不能确定文件的具体类型,就可能会使用 application/octet-stream。例如,当下载一个 .exe 文件或者 .zip 文件时,HTTP 响应的 Content-Type 头部字段可能就会被设置为 application/octet-stream

2.总结和爬虫

还有2个常用的文本总结工具和网络爬虫工具如下:

源码位置:dify-0.6.9\api\core\tools\tool\builtin_tool.py

def summary(self, user_id: str, content: str) -> str:
    max_tokens = self.get_max_tokens()

    if self.get_prompt_tokens(prompt_messages=[
        UserPromptMessage(content=content)
    ]) < max_tokens * 0.6:
        return content
    
    def get_prompt_tokens(content: str) -> int:
        return self.get_prompt_tokens(prompt_messages=[
            SystemPromptMessage(content=_SUMMARY_PROMPT),
            UserPromptMessage(content=content)
        ])
    
    def summarize(content: str) -> str:
        summary = self.invoke_model(user_id=user_id, prompt_messages=[
            SystemPromptMessage(content=_SUMMARY_PROMPT),
            UserPromptMessage(content=content)
        ], stop=[])

        return summary.message.content

    lines = content.split('\n')
    new_lines = []
    # split long line into multiple lines
    for i in range(len(lines)):
        line = lines[i]
        if not line.strip():
            continue
        if len(line) < max_tokens * 0.5:
            new_lines.append(line)
        elif get_prompt_tokens(line) > max_tokens * 0.7:
            while get_prompt_tokens(line) > max_tokens * 0.7:
                new_lines.append(line[:int(max_tokens * 0.5)])
                line = line[int(max_tokens * 0.5):]
            new_lines.append(line)
        else:
            new_lines.append(line)

    # merge lines into messages with max tokens
    messages: list[str] = []
    for i in new_lines:
        if len(messages) == 0:
            messages.append(i)
        else:
            if len(messages[-1]) + len(i) < max_tokens * 0.5:
                messages[-1] += i
            if get_prompt_tokens(messages[-1] + i) > max_tokens * 0.7:
                messages.append(i)
            else:
                messages[-1] += i

    summaries = []
    for i in range(len(messages)):
        message = messages[i]
        summary = summarize(message)
        summaries.append(summary)

    result = '\n'.join(summaries)

    if self.get_prompt_tokens(prompt_messages=[
        UserPromptMessage(content=result)
    ]) > max_tokens * 0.7:
        return self.summary(user_id=user_id, content=result)
    
    return result

def get_url(self, url: str, user_agent: str = None) -> str:
    """
        get url
    """
    return get_url(url, user_agent=user_agent)

3.变量池

简单理解变量池用于存储工具运行过程中产生的变量、文件等,这些变量可以在工具运行过程中被其它工具使用。以DallE3Vectorizer.AI为例,介绍如何使用变量池。

  • DallE3是一个图片生成工具,它可以根据文本生成图片,将让DallE3生成一个咖啡厅的 Logo。

  • Vectorizer.AI是一个矢量图转换工具,它可以将图片转换为矢量图,将DallE3生成的PNG图标转换为矢量图,从而可真正被设计师使用。

# DallE 消息返回
self.create_blob_message(blob=b64decode(image.b64_json), meta={ 'mime_type': 'image/png' }, save_as=self.VARIABLE_KEY.IMAGE.value)

# 从变量池中获取到之前 DallE 生成的图片
image_binary = self.get_variable_file(self.VARIABLE_KEY.IMAGE)

三.Dify第三方工具

创建自定义工具,目前支持 OpenAPI Swagger 和 ChatGPT Plugin 规范。可将 OpenAPI schema 内容直接粘贴或从 URL 内导入。工具目前支持两种鉴权方式:无鉴权 和 API Key。

1.天气(JSON)

{
      "openapi": "3.1.0",
      "info": {
        "title": "Get weather data",
        "description": "Retrieves current weather data for a location.",
        "version": "v1.0.0"
      },
      "servers": [
        {
          "url": "https://weather.example.com"
        }
      ],
      "paths": {
        "/location": {
          "get": {
            "description": "Get temperature for a specific location",
            "operationId": "GetCurrentWeather",
            "parameters": [
              {
                "name": "location",
                "in": "query",
                "description": "The city and state to retrieve the weather for",
                "required": true,
                "schema": {
                  "type": "string"
                }
              }
            ],
            "deprecated": false
          }
        }
      },
      "components": {
        "schemas": {}
      }
}

2.宠物商店(YAML)

# Taken from https://github.com/OAI/OpenAPI-Specification/blob/main/examples/v3.0/petstore.yaml

    openapi: "3.0.0"
    info:
      version: 1.0.0
      title: Swagger Petstore
      license:
        name: MIT
    servers:
      - url: https://petstore.swagger.io/v1
    paths:
      /pets:
        get:
          summary: List all pets
          operationId: listPets
          tags:
            - pets
          parameters:
            - name: limit
              in: query
              description: How many items to return at one time (max 100)
              required: false
              schema:
                type: integer
                maximum: 100
                format: int32
          responses:
            '200':
              description: A paged array of pets
              headers:
                x-next:
                  description: A link to the next page of responses
                  schema:
                    type: string
              content:
                application/json:    
                  schema:
                    $ref: "#/components/schemas/Pets"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
        post:
          summary: Create a pet
          operationId: createPets
          tags:
            - pets
          responses:
            '201':
              description: Null response
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
      /pets/{petId}:
        get:
          summary: Info for a specific pet
          operationId: showPetById
          tags:
            - pets
          parameters:
            - name: petId
              in: path
              required: true
              description: The id of the pet to retrieve
              schema:
                type: string
          responses:
            '200':
              description: Expected response to a valid request
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Pet"
            default:
              description: unexpected error
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Error"
    components:
      schemas:
        Pet:
          type: object
          required:
            - id
            - name
          properties:
            id:
              type: integer
              format: int64
            name:
              type: string
            tag:
              type: string
        Pets:
          type: array
          maxItems: 100
          items:
            $ref: "#/components/schemas/Pet"
        Error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: integer
              format: int32
            message:
              type: string

3.空模板(JSON)

{
      "openapi": "3.1.0",
      "info": {
        "title": "Untitled",
        "description": "Your OpenAPI specification",
        "version": "v1.0.0"
      },
      "servers": [
        {
          "url": ""
        }
      ],
      "paths": {},
      "components": {
        "schemas": {}
      }
}

四.Cloudflare Workers

一个函数调用工具可以部署到Cloudflare Workers,并使用OpenAPI模式。其中,Cloudflare Workers是Cloudflare提供的一种在边缘网络运行JavaScript函数的服务。简单理解这是一个用于为dify应用创建工具的Cloudflare Worker。

# 克隆代码
git clone https://github.com/crazywoola/dify-tools-worker

# 开发模式
cp .wrangler.toml.example .wrangler.toml
npm install
npm run dev
# You will get a url like this: http://localhost:8787

# 部署模式
npm run deploy 
# You will get a url like this: https://difytoolsworker.yourname.workers.dev

填写URL从URL中导入,如下所示:

参考文献

[1] Tools:https://github.com/langgenius/dify/blob/main/api/core/tools/README_CN.md

[2] 快速接入Tool:https://github.com/langgenius/dify/blob/main/api/core/tools/docs/zh_Hans/tool_scale_out.md

[3] 高级接入Tool:https://github.com/langgenius/dify/blob/main/api/core/tools/docs/zh_Hans/advanced_scale_out.md

[4] OpenAPI Specification:https://swagger.io/specification/

[5] https://github.com/crazywoola/dify-tools-worker

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/799696.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

git批量删除本地包含某字符串的特定分支

git批量删除本地包含某字符串的特定分支 git branch -a | grep 分支中包含的字符串 | xargs git branch -D git删除本地分支_git查看删除本地分支-CSDN博客文章浏览阅读989次。git branch -d <分支名>可以通过: git branch 查看所有本地分支及其名字&#xff0c;然后删…

PHP中的函数与调用:深入解析与应用

目录 一、函数基础 1.1 函数的概念 1.2 函数的定义 1.3 函数的调用 二、PHP函数的分类 2.1 内置函数 2.2 用户自定义函数 2.3 匿名函数 2.4 递归函数 2.5 回调函数 2.6 魔术方法 三、函数的参数与返回值 3.1 参数传递 3.2 返回值 四、函数的高级特性 4.1 可变函…

搭建调用链监控Zipkin和Sleuth

项目环境: win7、jdk8 1、添加依赖&#xff0c;添加了spring-cloud-starter-zipkin会自动导入Sleuth <!--Sleuth&#xff0c;zipkin--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zipkin</…

路径规划 | 基于蚁群算法的三维无人机航迹规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 基于蚁群算法的三维无人机航迹规划&#xff08;Matlab&#xff09;。 蚁群算法&#xff08;Ant Colony Optimization&#xff0c;ACO&#xff09;是一种模拟蚂蚁觅食行为的启发式算法。该算法通过模拟蚂蚁在寻找食物时…

记录一次渗透实战

收集目标域名信息 用到的知识&#xff1a;16-5 信息收集 - 域名-CSDN博客 目标域名为&#xff1a;h****e.cc 使用一些在线网站可以查询目标域名信息如&#xff1a;站长工具-百度权重排名查询-站长seo查询 - 爱站网 收集子域名 这里使用在线工具进行爆破&#xff1a;http:/…

MySQL学习记录 —— 이십일 MySQL服务器配置与管理(1)

文章目录 1、配置和默认值2、系统变量和选项1、介绍2、常用选项3、使用系统变量 3、常用服务器配置4、查看状态变量5、MySQL数据目录 mysql的服务端就是mysqld&#xff0c;d就是daemon&#xff0c;守护进程的意思。 配置文件中[mysqld]部分时服务器支持的启动选项。服务器的部…

MySQl高级篇 -索引优化篇

索引 InnoDB采用了一个B数来存储索引&#xff0c;使得在千万级数据量的一个情况下&#xff0c;树的高度可以控制在3层以内&#xff0c;而层高代表磁盘IO的一个次数&#xff0c;因此基于索引查找可以减少磁盘IO的次数 MySQL的索引是在存储引擎层实现的&#xff0c;不同的存储引…

浅聊授权-spring security和oauth2

文章目录 前言自定义授权spring security授权oauth2授权概述 前言 通常说到授权&#xff0c;就会想到登录授权、token令牌、JWT等概念&#xff0c;授权。顾名思义就是服务器授予了客户端访问资源的权益&#xff0c;那么要实现授权有几种方案呢&#xff0c;三种授权方式在公司项…

【java】力扣 买卖股票的最佳时机II

文章目录 题目链接题目描述思路代码 题目链接 122.买卖股票的最佳时机II 题目描述 思路 这道题和121.买卖股票的最佳时机 有所不同&#xff0c;不同点在于&#xff0c;这道题的股票可以多次买卖(但是要在买之前先卖掉) 详细思路请看链接的文章【java】力扣 买卖股票的最佳时…

KALI使用MSF攻击安卓设备

这期是kali使用MSF进行安卓渗透的保姆级别教程&#xff0c;话不多说&#xff0c;直接开始。 准备材料&#xff1a; 1.装有kali的实体机或虚拟机&#xff08;这里用实体机进行演示&#xff09; 2.一台安卓10.0以下的手机 打开kali&#xff0c;先用ifconfig查看自己的kali IP地址…

RABBITMQ的本地测试证书生成脚本

由于小程序要求必须访问wss的接口&#xff0c;因此需要将测试环境也切换到https&#xff0c;看了下官方的文档 RabbitMQ Web STOMP Plugin | RabbitMQ里面有这个信息 然后敲打GPT一阵子&#xff0c;把要求输入几个来回&#xff0c;得到这样一个脚本&#xff1a; generate_cer…

Redis 中String类型操作命令(命令演示,时间复杂度,返回值,注意事项)

String 类型 文章目录 String 类型set 命令get 命令mset 命令mget 命令get 和 mget 的区别incr 命令incrby 命令decr 命令decrby 命令incrbyfloat 命令append 命令getrange 命令setrange 命令 字符串类型是 Redis 中最基础的数据类型&#xff0c;在讲解命令之前&#xff0c;我们…

论文分享|Arxiv2024‘麦吉尔大学|LLM2Vec—将LLM转换为文本编码器

LLM本身的表征直接用于Embedding&#xff0c;比如用于检索/聚类/STS等任务&#xff0c;效果其实不太好。因此才需要将Embedding模型和大模型区分开来。本文介绍一篇将LLM转换为Embedding模型的工作&#xff0c;代码全开源&#xff0c;值得好好学习。 论文题目&#xff1a;LLM2…

Qt Mqtt客户端 + Emqx

环境 Qt 5.14.2 qtmqtt mqttx 功能 QT Mqtt客户端 qtmqtt 下载 qtmqtt (注意下载与QT版本相符的库)并使用QT 编译 编译完成后需要的文件: emqx 1.虚拟机中安装emqx,并启动 curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash sudo apt-get inst…

【详解】Spring Cloud概述

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;Spring学习之路&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 1. 认识微服务 1.1 单体架构 1.2 集群和分布式架构 1.3 集群和分布式…

【全面介绍Pip换源】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 🦁Pip换源.⛅ 🦁当使用Pip安装Python软件包时,默认情况下会…

BayesPrism(贝叶斯棱镜法)可提取单细胞数据去卷积后将信息映射至bulkRNA数据

贝叶斯棱镜法作为一种工具可以根据scRNA数据(作为先验模型)去推断bulkRNA数据中肿瘤微环境组成(不同免疫细胞组分/不同细胞群)和基因表达情况。 开发者展示的图片就很形象了&#xff0c;左边图展示了把标注了不同细胞类型的单细胞数据作为先验信息(prior info)的基因信息和bul…

力扣144题:二叉树的先序遍历

给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a;root [1] 输出&am…

【云岚到家】-day05-6-项目迁移-门户-CMS

【云岚到家】-day05-6-项目迁移-门户-CMS 4 项目迁移-门户4.1 迁移目标4.2 能力基础4.2.1 缓存方案设计与应用能力4.2.2 静态化技术应用能力 4.3 需求分析4.3.1 界面原型 4.4 系统设计4.4.1 表设计4.4.2 接口与方案4.4.2.1 首页信息查询接口4.4.3.1 数据缓存方案4.4.3.2 页面静…

【绝命Coding助力秋招】Python实现<实习僧>海投脚本

hello hello~ &#xff0c;这里是绝命Coding——老白~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff1a;绝命Coding-CSDN博客 &a…