当前位置: 首页 > news >正文

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 searchingform: llm  # 参数的表单类型,llm表示这个参数需要由Agent自行推理出来,前端将不会展示这个参数- name: result_type  # 参数名称type: select  # 参数类型required: true  # 是否必填options:  # 参数的选项- value: textlabel:en_US: textzh_Hans: 文本pt_BR: texto- value: linklabel:en_US: linkzh_Hans: 链接pt_BR: linkdefault: link  # 默认值为链接label:en_US: Result typezh_Hans: 结果类型pt_BR: Result typehuman_description:en_US: used for selecting the result type, text or linkzh_Hans: 用于选择结果类型,使用文本还是链接进行展示pt_BR: used for selecting the result type, text or linkform: 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,  # 表示用户IDtool_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,  # 表示用户IDtool_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 contentdef 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.contentlines = content.split('\n')new_lines = []# split long line into multiple linesfor i in range(len(lines)):line = lines[i]if not line.strip():continueif 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 tokensmessages: 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] += iif get_prompt_tokens(messages[-1] + i) > max_tokens * 0.7:messages.append(i)else:messages[-1] += isummaries = []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 resultdef 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.yamlopenapi: "3.0.0"info:version: 1.0.0title: Swagger Petstorelicense:name: MITservers:- url: https://petstore.swagger.io/v1paths:/pets:get:summary: List all petsoperationId: listPetstags:- petsparameters:- name: limitin: querydescription: How many items to return at one time (max 100)required: falseschema:type: integermaximum: 100format: int32responses:'200':description: A paged array of petsheaders:x-next:description: A link to the next page of responsesschema:type: stringcontent:application/json:    schema:$ref: "#/components/schemas/Pets"default:description: unexpected errorcontent:application/json:schema:$ref: "#/components/schemas/Error"post:summary: Create a petoperationId: createPetstags:- petsresponses:'201':description: Null responsedefault:description: unexpected errorcontent:application/json:schema:$ref: "#/components/schemas/Error"/pets/{petId}:get:summary: Info for a specific petoperationId: showPetByIdtags:- petsparameters:- name: petIdin: pathrequired: truedescription: The id of the pet to retrieveschema:type: stringresponses:'200':description: Expected response to a valid requestcontent:application/json:schema:$ref: "#/components/schemas/Pet"default:description: unexpected errorcontent:application/json:schema:$ref: "#/components/schemas/Error"components:schemas:Pet:type: objectrequired:- id- nameproperties:id:type: integerformat: int64name:type: stringtag:type: stringPets:type: arraymaxItems: 100items:$ref: "#/components/schemas/Pet"Error:type: objectrequired:- code- messageproperties:code:type: integerformat: int32message: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

相关文章:

Dify中的工具

Dify中的工具分为内置工具&#xff08;硬编码&#xff09;和第三方工具&#xff08;OpenAPI Swagger/ChatGPT Plugin&#xff09;。工具可被Workflow&#xff08;工作流&#xff09;和Agent使用&#xff0c;当然Workflow也可被发布为工具&#xff0c;这样Workflow&#xff08;工…...

在Visutal Studio 2022中完成D3D12初始化

在Visutal Studio 2022中完成DirectX设备初始化 1 DirectX121.1 DirectX 简介1.2 DirectX SDK安装2 D3D12初始化2.1 创建Windwos桌面项目2.2 修改符合模式2.3 下载d3dx12.h文件2.4 创建一个异常类D3DException,定义抛出异常实例的宏ThrowIfFailed3 D3D12的初始化步骤3.1 初始化…...

MobaXterm工具

MobaXterm 是一个增强型的 Windows 终端。其为 Windows 桌面提供所有重要的远程网络终端工具&#xff08;如 SSH、X11、RDP、VNC、FTP、SFTP、Telnet、Serial、Mosh、WSL 等&#xff09;&#xff0c;和 Unix 命令&#xff08;如 bash、ls、cat、sed、grep、awk、rsync 等&#…...

二分图练习

对于二分图我们可以用染色法 #include<bits/stdc.h> using namespace std;#define int long long const int N 2e65; int e[N],ne[N],h[N],idx 0; int colo[N]; int num 0;void add(int x,int y){e[idx] y;ne[idx] h[x];h[x] idx; } void dfs(int nod,int c){colo…...

创新设计策略:提升大屏幕可视化设计效果的关键方法

随着科技的不断发展和数据量的快速增长&#xff0c;数据可视化大屏在各个行业中的应用越来越广泛&#xff0c;可以帮助人们更好地理解和分析数据&#xff0c;可视化大屏设计也因此成了众多企业的需求。但很多设计师对可视化大屏设计并不了解&#xff0c;也不知道如何制作可视化…...

论文 | Chain-of-Thought Prompting Elicits Reasoningin Large Language Models 思维链

这篇论文研究了如何通过生成一系列中间推理步骤&#xff08;即思维链&#xff09;来显著提高大型语言模型进行复杂推理的能力。论文展示了一种简单的方法&#xff0c;称为思维链提示&#xff0c;通过在提示中提供几个思维链示例来自然地激发这种推理能力。 主要发现&#xff1…...

[机器学习]-人工智能对程序员的深远影响——案例分析

机器学习和人工智能对未来程序员的深远影响 目录 机器学习和人工智能对未来程序员的深远影响1. **自动化编码任务**1.1 代码生成1.2 自动调试1.3 测试自动化 2. **提升开发效率**2.1 智能建议2.2 项目管理 3. **改变编程范式**3.1 数据驱动开发 4. **职业发展的新机遇**4.1 AI工…...

AI学习环境 没有更好的替代 - (Google)Drive + Colab

在开始正题前&#xff0c;请容许我做一番回顾&#xff0c;并夹带一点点私货&#xff08;谷歌扛旗的开源精神还没有死&#xff0c;并且会是未来的举足轻重的力量&#xff09; 卧龙凤雏&#xff0c;一时瑜亮。一切的缘起应该是世纪初的门户网站乱战。 彼时&#xff0c;谷歌是从…...

【观成科技】Websocket协议代理隧道加密流量分析与检测

Websocket协议代理隧道加密流量简介 攻防场景下&#xff0c;Websocket协议常被用于代理隧道的搭建&#xff0c;攻击者企图通过Websocket协议来绕过网络限制&#xff0c;搭建一个低延迟、双向实时数据传输的隧道。当前&#xff0c;主流的支持Websocket通信代理的工具有&#xf…...

DangerWind-RPC-framework---三、服务端下机

当一台机器下线时&#xff0c;面临很多问题&#xff1a;如何将其从注册中心下线&#xff1f;如何清理释放资源&#xff1f;客户端拉取服务列表时也使用了本地缓存&#xff0c;如何及时更新本地缓存&#xff1f; 服务端机器的优雅下线需要使用ShutdownHook&#xff0c;这相当于添…...

基于Make的c工程No compilation commands found报错

由于安装gcc时只安装了build-essential&#xff0c;没有将其添加到环境变量中&#xff0c;因此打开Make工程时&#xff0c;CLion会产生如下错误&#xff1a; 要解决这个问题&#xff0c;一个方法是将GCC添加到环境变量中&#xff0c;但是这个方法需要修改至少两个配置文件&…...

c++:面向对象的继承特性

什么是继承 (1)继承是C源生支持的一种语法特性&#xff0c;是C面向对象的一种表现 (2)继承特性可以让派生类“瞬间”拥有基类的所有&#xff08;当然还得考虑权限&#xff09;属性和方法 (3)继承特性本质上是为了代码复用 (4)类在C编译器的内部可以理解为结构体&#xff0c;派…...

skywalking-2-客户端-php的安装与使用

skywalking的客户端支持php&#xff0c;真的很棒。 官方安装文档&#xff1a;https://skywalking.apache.org/docs/skywalking-php/next/en/setup/service-agent/php-agent/readme/ 前置准备 本次使用的php版本是8.2.13: php -v PHP 8.2.13 (cli) (built: Nov 21 2023 09:5…...

图文讲解IDEA如何导入JDBC驱动包

前言 学习JDBC编程,势必要学会如何导入驱动包,这里笔者用图文的方式来介绍 视频版本在这里 50秒教你怎么导入驱动包然后进行JDBC编程的学习_哔哩哔哩_bilibili 忘记录音频了,大伙凑合着看 下载驱动包 https://mvnrepository.com/artifact/mysql/mysql-connector-java 去中…...

java.lang.NullPointerException: null cannot be cast to non-null type kotlin.Int

java.lang.NullPointerException: null cannot be cast to non-null type kotlin.Int fun main(args: Array<String>) {var any1: Any?any1 nullval n1 any1 as? Int ?: -2024println(n1)kotlin.runCatching {var any2: Any?any2 nullval n2 any2 as Intprintln(…...

scrapy写爬虫

Scrapy是一个用于爬取网站数据并提取结构化信息的Python框架 一、Scrapy介绍 1.引擎&#xff08;Engine&#xff09; – Scrapy的引擎是控制数据流和触发事件的核心。它管理着Spider发送的请求和接收的响应&#xff0c;以及处理Spider生成的Item。引擎是Scrapy运行的驱动力。…...

Mybatis study

一、Mybatis Plus mybatis-plus指定实体类字段不查询 加标签 TableField(exist false) Spring Data Jpa学习 干我们这行&#xff0c;啥时候懈怠&#xff0c;就意味着长进的停止&#xff0c;长进的停止就意味着被淘汰&#xff0c;只能往前冲&#xff0c;直到凤凰涅槃的一天&am…...

【论文速读】《面向深度学习的联合消息传递与自编码器》

这篇文章来自华为的渥太华无线先进系统能力中心和无线技术实验室&#xff0c;作者中有大名鼎鼎的童文。 一、自编码架构的全局收发机面临的主要问题 文章对我比较有启发的地方&#xff0c;是提到自编码架构的全局收发机面临的主要问题&#xff1a; 问题一&#xff1a;基于随…...

防御---001

一、实验拓扑二、要求 1&#xff0c;DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00 - 18:00)可以访问&#xff0c;生产区的的设备全天可以访问. 2&#xff0c;生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网 3,办公区设备10.0.2.10不允许访问DMZ…...

DNS 杂谈

一、定义 DNS&#xff08;Domain Name System&#xff09;&#xff0c;域名系统&#xff0c;该系统记录域名和Ip地址的相互映射关系。用户访问互联网时&#xff0c;通过域名地址得到对应的IP地址&#xff0c;这个过程称为域名解析。DNS运行于UDP协议之上&#xff0c;使用的端口…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...