diff --git a/zh_CN/.gitbook/assets/Feb 4, 2024.png b/zh_CN/.gitbook/assets/Feb 4, 2024.png
new file mode 100644
index 0000000..6a4446b
Binary files /dev/null and b/zh_CN/.gitbook/assets/Feb 4, 2024.png differ
diff --git a/zh_CN/SUMMARY.md b/zh_CN/SUMMARY.md
index 8558d24..2c2b1ce 100644
--- a/zh_CN/SUMMARY.md
+++ b/zh_CN/SUMMARY.md
@@ -50,7 +50,8 @@
* [从 Notion 导入数据](guides/knowledge-base/sync-from-notion.md)
* [通过 API 维护数据集](guides/knowledge-base/maintain-dataset-via-api.md)
* [外部数据工具](guides/knowledge-base/external\_data\_tool.md)
-* [工具](guides/tools.md)
+* [工具](guides/tools/README.md)
+ * [快速接入工具](guides/tools/kuai-su-jie-ru-gong-ju.md)
* [日志与标注](guides/logs.md)
* [团队协同](guides/workspace/README.md)
* [邀请与管理成员](guides/workspace/invite-and-manage-members.md)
diff --git a/zh_CN/guides/tools.md b/zh_CN/guides/tools/README.md
similarity index 77%
rename from zh_CN/guides/tools.md
rename to zh_CN/guides/tools/README.md
index fbe6a2e..fa6d4e1 100644
--- a/zh_CN/guides/tools.md
+++ b/zh_CN/guides/tools/README.md
@@ -13,7 +13,7 @@
### 如何配置第一方工具
-.png)
第一方工具列表
+.png)
第一方工具列表
Dify 目前已支持:
@@ -27,11 +27,11 @@ Dify 目前已支持:
若你需要直接使用 Dify 生态提供的第一方内置工具,你需要在使用前配置相应的凭据。
-.png)
配置第一方工具凭据
+.png)
配置第一方工具凭据
凭据校验成功后工具会显示“已授权”状态。配置凭据后,工作区中的所有成员都可以在编排应用程序时使用此工具。
-.png)
第一方工具已授权
+.png)
第一方工具已授权
### 如何创建自定义工具
@@ -39,32 +39,29 @@ Dify 目前已支持:
工具目前支持两种鉴权方式:无鉴权 和 API Key。
-.png)
创建自定义工具
+.png)
创建自定义工具
在导入 Schema 内容后系统会主动解析文件内的参数,并可预览工具具体的参数、 方法、路径。您也可以在此对工具参数进行测试。
-.png)
自定义工具参数测试
+.png)
自定义工具参数测试
完成自定义工具创建之后,工作区中的所有成员都可以在“工作室”内编排应用程序时使用此工具。
-.png)
已添加自定义工具
+.png)
已添加自定义工具
#### Cloudflare Workers
您也可以使用 [dify-tools-worker](https://github.com/crazywoola/dify-tools-worker) 来快速部署自定义工具。该工具提供了:
-- 可以导入 Dify 的路由 `https://difytoolsworker.yourname.workers.dev/doc`, 提供了 OpenAPI 兼容的接口文档
-- API 的实现代码,可以直接部署到 Cloudflare Workers
+* 可以导入 Dify 的路由 `https://difytoolsworker.yourname.workers.dev/doc`, 提供了 OpenAPI 兼容的接口文档
+* API 的实现代码,可以直接部署到 Cloudflare Workers
### 如何在应用内使用工具
目前,您可以在“工作室”中创建**智能助手型应用**时,将已配置好凭据的工具在其中使用。
-.png)
创建智能助手型应用时添加工具
+.png)
创建智能助手型应用时添加工具
以下图为例,在财务分析应用内添加工具后,智能助手将在需要时自主调用工具,从工具中查询财务报告数据,并将数据分析后完成与用户之间的对话。
-.png)
智能助手在对话中完成工具调用回复问题
-
-
-
+.png)
智能助手在对话中完成工具调用回复问题
diff --git a/zh_CN/guides/tools/kuai-su-jie-ru-gong-ju.md b/zh_CN/guides/tools/kuai-su-jie-ru-gong-ju.md
new file mode 100644
index 0000000..757861e
--- /dev/null
+++ b/zh_CN/guides/tools/kuai-su-jie-ru-gong-ju.md
@@ -0,0 +1,246 @@
+# 快速接入工具
+
+这里我们以 GoogleSearch 为例,介绍如何快速接入一个工具。
+
+### 1. 准备工具供应商 yaml
+
+#### 介绍
+
+这个 yaml 将包含工具供应商的信息,包括供应商名称、图标、作者等详细信息,以帮助前端灵活展示。
+
+#### 示例
+
+我们需要在 `core/tools/provider/builtin`下创建一个`google`模块(文件夹),并创建`google.yaml`,名称必须与模块名称一致。
+
+后续,我们关于这个工具的所有操作都将在这个模块下进行。
+
+```yaml
+identity: # 工具供应商的基本信息
+ author: Dify # 作者
+ name: google # 名称,唯一,不允许和其他供应商重名
+ label: # 标签,用于前端展示
+ en_US: Google # 英文标签
+ zh_Hans: Google # 中文标签
+ description: # 描述,用于前端展示
+ en_US: Google # 英文描述
+ zh_Hans: Google # 中文描述
+ icon: icon.svg # 图标,需要放置在当前模块的_assets文件夹下
+
+```
+
+* `identity` 字段是必须的,它包含了工具供应商的基本信息,包括作者、名称、标签、描述、图标等
+ * 图标需要放置在当前模块的`_assets`文件夹下,可以参考这里:api/core/tools/provider/builtin/google/\_assets/icon.svg
+
+ ```xml
+
+ ```
+
+### 2. 准备供应商凭据
+
+Google 作为一个第三方工具,使用了 SerpApi 提供的 API,而 SerpApi 需要一个 API Key 才能使用,那么就意味着这个工具需要一个凭据才可以使用,而像`wikipedia`这样的工具,就不需要填写凭据字段,可以参考这里:api/core/tools/provider/builtin/wikipedia/wikipedia.yaml
+
+```yaml
+identity:
+ author: Dify
+ name: wikipedia
+ label:
+ en_US: Wikipedia
+ zh_Hans: 维基百科
+ pt_BR: Wikipedia
+ description:
+ en_US: Wikipedia is a free online encyclopedia, created and edited by volunteers around the world.
+ zh_Hans: 维基百科是一个由全世界的志愿者创建和编辑的免费在线百科全书。
+ pt_BR: Wikipedia is a free online encyclopedia, created and edited by volunteers around the world.
+ icon: icon.svg
+credentials_for_provider:
+```
+
+配置好凭据字段后效果如下:
+
+```yaml
+identity:
+ author: Dify
+ name: google
+ label:
+ en_US: Google
+ zh_Hans: Google
+ description:
+ en_US: Google
+ zh_Hans: Google
+ icon: icon.svg
+credentials_for_provider: # 凭据字段
+ serpapi_api_key: # 凭据字段名称
+ type: secret-input # 凭据字段类型
+ required: true # 是否必填
+ label: # 凭据字段标签
+ en_US: SerpApi API key # 英文标签
+ zh_Hans: SerpApi API key # 中文标签
+ placeholder: # 凭据字段占位符
+ en_US: Please input your SerpApi API key # 英文占位符
+ zh_Hans: 请输入你的 SerpApi API key # 中文占位符
+ help: # 凭据字段帮助文本
+ en_US: Get your SerpApi API key from SerpApi # 英文帮助文本
+ zh_Hans: 从 SerpApi 获取您的 SerpApi API key # 中文帮助文本
+ url: https://serpapi.com/manage-api-key # 凭据字段帮助链接
+
+```
+
+* `type`:凭据字段类型,目前支持`secret-input`、`text-input`、`select` 三种类型,分别对应密码输入框、文本输入框、下拉框,如果为`secret-input`,则会在前端隐藏输入内容,并且后端会对输入内容进行加密。
+
+### 3. 准备工具 yaml
+
+一个供应商底下可以有多个工具,每个工具都需要一个 yaml 文件来描述,这个文件包含了工具的基本信息、参数、输出等。
+
+仍然以 GoogleSearch 为例,我们需要在`google`模块下创建一个`tools`模块,并创建`tools/google_search.yaml`,内容如下。
+
+```yaml
+identity: # 工具的基本信息
+ name: google_search # 工具名称,唯一,不允许和其他工具重名
+ author: Dify # 作者
+ label: # 标签,用于前端展示
+ en_US: GoogleSearch # 英文标签
+ zh_Hans: 谷歌搜索 # 中文标签
+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 搜索并提取片段和网页的工具。输入应该是一个搜索查询。
+ llm: A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query. # 传递给 LLM 的介绍,为了使得LLM更好理解这个工具,我们建议在这里写上关于这个工具尽可能详细的信息,让 LLM 能够理解并使用这个工具
+parameters: # 参数列表
+ - name: query # 参数名称
+ type: string # 参数类型
+ required: true # 是否必填
+ label: # 参数标签
+ en_US: Query string # 英文标签
+ zh_Hans: 查询语句 # 中文标签
+ human_description: # 用于前端展示的介绍,支持多语言
+ en_US: used for searching
+ zh_Hans: 用于搜索网页内容
+ llm_description: key words for searching # 传递给LLM的介绍,同上,为了使得LLM更好理解这个参数,我们建议在这里写上关于这个参数尽可能详细的信息,让LLM能够理解这个参数
+ form: llm # 表单类型,llm表示这个参数需要由Agent自行推理出来,前端将不会展示这个参数
+ - name: result_type
+ type: select # 参数类型
+ required: true
+ options: # 下拉框选项
+ - value: text
+ label:
+ en_US: text
+ zh_Hans: 文本
+ - value: link
+ label:
+ en_US: link
+ zh_Hans: 链接
+ default: link
+ label:
+ en_US: Result type
+ zh_Hans: 结果类型
+ human_description:
+ en_US: used for selecting the result type, text or link
+ zh_Hans: 用于选择结果类型,使用文本还是链接进行展示
+ form: form # 表单类型,form表示这个参数需要由用户在对话开始前在前端填写
+
+```
+
+* `identity` 字段是必须的,它包含了工具的基本信息,包括名称、作者、标签、描述等
+* `parameters` 参数列表
+ * `name` 参数名称,唯一,不允许和其他参数重名
+ * `type` 参数类型,目前支持`string`、`number`、`boolean`、`select` 四种类型,分别对应字符串、数字、布尔值、下拉框
+ * `required` 是否必填
+ * 在`llm`模式下,如果参数为必填,则会要求 Agent 必须要推理出这个参数
+ * 在`form`模式下,如果参数为必填,则会要求用户在对话开始前在前端填写这个参数
+ * `options` 参数选项
+ * 在`llm`模式下,Dify 会将所有选项传递给 LLM,LLM 可以根据这些选项进行推理
+ * 在`form`模式下,`type`为`select`时,前端会展示这些选项
+ * `default` 默认值
+ * `label` 参数标签,用于前端展示
+ * `human_description` 用于前端展示的介绍,支持多语言
+ * `llm_description` 传递给 LLM 的介绍,为了使得 LLM 更好理解这个参数,我们建议在这里写上关于这个参数尽可能详细的信息,让 LLM 能够理解这个参数
+ * `form` 表单类型,目前支持`llm`、`form`两种类型,分别对应 Agent 自行推理和前端填写
+
+### 4. 准备工具代码
+
+当完成工具的配置以后,我们就可以开始编写工具代码了,主要用于实现工具的逻辑。
+
+在`google/tools`模块下创建`google_search.py`,内容如下。
+
+```python
+from core.tools.tool.builtin_tool import BuiltinTool
+from core.tools.entities.tool_entities import ToolInvokeMessage
+
+from typing import Any, Dict, List, Union
+
+class GoogleSearchTool(BuiltinTool):
+ def _invoke(self,
+ user_id: str,
+ tool_paramters: Dict[str, Any],
+ ) -> Union[ToolInvokeMessage, List[ToolInvokeMessage]]:
+ """
+ invoke tools
+ """
+ query = tool_paramters['query']
+ result_type = tool_paramters['result_type']
+ api_key = self.runtime.credentials['serpapi_api_key']
+ # TODO: search with serpapi
+ 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)
+```
+
+#### 参数
+
+工具的整体逻辑都在`_invoke`方法中,这个方法接收两个参数:`user_id`和`tool_paramters`,分别表示用户 ID 和工具参数
+
+#### 返回数据
+
+在工具返回时,你可以选择返回一个消息或者多个消息,这里我们返回一个消息,使用`create_text_message`和`create_link_message`可以创建一个文本消息或者一个链接消息。
+
+### 5. 准备供应商代码
+
+最后,我们需要在供应商模块下创建一个供应商类,用于实现供应商的凭据验证逻辑,如果凭据验证失败,将会抛出`ToolProviderCredentialValidationError`异常。
+
+在`google`模块下创建`google.py`,内容如下。
+
+```python
+from core.tools.entities.tool_entities import ToolInvokeMessage, ToolProviderType
+from core.tools.tool.tool import Tool
+from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
+from core.tools.errors import ToolProviderCredentialValidationError
+
+from core.tools.provider.builtin.google.tools.google_search import GoogleSearchTool
+
+from typing import Any, Dict
+
+class GoogleProvider(BuiltinToolProviderController):
+ def _validate_credentials(self, credentials: Dict[str, Any]) -> None:
+ try:
+ # 1. 此处需要使用 GoogleSearchTool()实例化一个 GoogleSearchTool,它会自动加载 GoogleSearchTool 的 yaml 配置,但是此时它内部没有凭据信息
+ # 2. 随后需要使用 fork_tool_runtime 方法,将当前的凭据信息传递给 GoogleSearchTool
+ # 3. 最后 invoke 即可,参数需要根据 GoogleSearchTool 的 yaml 中配置的参数规则进行传递
+ GoogleSearchTool().fork_tool_runtime(
+ meta={
+ "credentials": credentials,
+ }
+ ).invoke(
+ user_id='',
+ tool_paramters={
+ "query": "test",
+ "result_type": "link"
+ },
+ )
+ except Exception as e:
+ raise ToolProviderCredentialValidationError(str(e))
+```
+
+### 完成
+
+当上述步骤完成以后,我们就可以在前端看到这个工具了,并且可以在 Agent 中使用这个工具。
+
+当然,因为 google\_search 需要一个凭据,在使用之前,还需要在前端配置它的凭据。
+
+