diff --git a/zh_CN/.gitbook/assets/8000.png b/zh_CN/.gitbook/assets/8000.png
new file mode 100644
index 0000000..aa78090
Binary files /dev/null and b/zh_CN/.gitbook/assets/8000.png differ
diff --git a/zh_CN/.gitbook/assets/download.png b/zh_CN/.gitbook/assets/download.png
new file mode 100644
index 0000000..9eede15
Binary files /dev/null and b/zh_CN/.gitbook/assets/download.png differ
diff --git a/zh_CN/.gitbook/assets/ngrock.png b/zh_CN/.gitbook/assets/ngrock.png
new file mode 100644
index 0000000..379d712
Binary files /dev/null and b/zh_CN/.gitbook/assets/ngrock.png differ
diff --git a/zh_CN/.gitbook/assets/红框.png b/zh_CN/.gitbook/assets/红框.png
new file mode 100644
index 0000000..dffe7d1
Binary files /dev/null and b/zh_CN/.gitbook/assets/红框.png differ
diff --git a/zh_CN/SUMMARY.md b/zh_CN/SUMMARY.md
index 226c931..5bc47b0 100644
--- a/zh_CN/SUMMARY.md
+++ b/zh_CN/SUMMARY.md
@@ -55,10 +55,12 @@
* [接入 LocalAI 部署的本地模型](advanced/model-configuration/localai.md)
* [更多集成](advanced/more-integration.md)
* [扩展](advanced/extension/README.md)
- * [API-based 扩展](advanced/extension/api\_based\_extension/README.md)
- * [外部数据工具扩展](advanced/extension/api\_based\_extension/external\_data\_tool.md)
- * [敏感内容审查扩展](advanced/extension/api\_based\_extension/moderation.md)
- * [Code-based 扩展](advanced/extension/code\_based\_extension.md)
+ * [API 扩展](advanced/extension/api\_based\_extension/README.md)
+ * [外部数据工具](advanced/extension/api\_based\_extension/external\_data\_tool.md)
+ * [敏感内容审查](advanced/extension/api\_based\_extension/moderation.md)
+ * [代码扩展](advanced/extension/code\_based\_extension/README.md)
+ * [外部数据工具](advanced/extension/code\_based\_extension/external\_data\_tool.md)
+ * [敏感内容审查](advanced/extension/code\_based\_extension/moderation.md)
## 使用案例
diff --git a/zh_CN/advanced/extension/README.md b/zh_CN/advanced/extension/README.md
index fbb5b45..48be1b2 100644
--- a/zh_CN/advanced/extension/README.md
+++ b/zh_CN/advanced/extension/README.md
@@ -4,4 +4,4 @@
[api\_based\_extension](api\_based\_extension/ "mention")
-[code\_based\_extension.md](code\_based\_extension.md "mention")
+[code\_based\_extension](code\_based\_extension/ "mention")
diff --git a/zh_CN/advanced/extension/api_based_extension/README.md b/zh_CN/advanced/extension/api_based_extension/README.md
index a3e0f2e..8812e2a 100644
--- a/zh_CN/advanced/extension/api_based_extension/README.md
+++ b/zh_CN/advanced/extension/api_based_extension/README.md
@@ -1,4 +1,4 @@
-# API-based 扩展
+# API 扩展
开发者可通过 API 扩展模块能力,当前支持以下模块扩展:
@@ -11,7 +11,7 @@

基于 API 扩展
-### [API 规范](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#api-%E8%A7%84%E8%8C%83)
+### API 规范
Dify 将会以以下规范调用您的接口:
@@ -19,14 +19,14 @@ Dify 将会以以下规范调用您的接口:
POST {Your-API-Endpoint}
```
-#### [Header](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#header)
+#### Header
| Header | Value | Desc |
| --------------- | ----------------- | --------------------------------------------------------------------- |
| `Content-Type` | application/json | 请求内容为 JSON 格式。 |
| `Authorization` | Bearer {api\_key} | API Key 以 Token 令牌的方式传输,您需要解析该 `api_key` 并确认是否和提供的 API Key 一致,保证接口安全。 |
-#### [Request Body](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#request-body)
+#### Request Body
```
{
@@ -37,7 +37,7 @@ POST {Your-API-Endpoint}
}
```
-#### [API 返回](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#api-%E8%BF%94%E5%9B%9E)
+#### API 返回
```
{
@@ -45,20 +45,20 @@ POST {Your-API-Endpoint}
}
```
-### [校验](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#%E6%A0%A1%E9%AA%8C)
+### 校验
在 Dify 配置 API-based Extension 时,Dify 将会发送一个请求至 API Endpoint,以检验 API 的可用性。
当 API Endpoint 接收到 `point=ping` 时,接口应返回 `result=pong`,具体如下:
-#### [Header](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#header-1)
+#### Header
```
Content-Type: application/json
Authorization: Bearer {api_key}
```
-#### [Request Body](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#request-body-1)
+#### Request Body
```
{
@@ -66,7 +66,7 @@ Authorization: Bearer {api_key}
}
```
-#### [API 期望返回](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#api-%E6%9C%9F%E6%9C%9B%E8%BF%94%E5%9B%9E)
+#### API 期望返回
```
{
@@ -74,24 +74,24 @@ Authorization: Bearer {api_key}
}
```
-### [范例](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#%E8%8C%83%E4%BE%8B)
+### 范例
此处以外部数据工具为例,场景为根据地区获取外部天气信息作为上下文。
-#### [API 范例](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#api-%E8%8C%83%E4%BE%8B)
+#### API 范例
```
POST https://fake-domain.com/api/dify/receive
```
-[**Header**](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#header-2)
+**Header**
```
Content-Type: application/json
Authorization: Bearer 123456
```
-[**Request Body**](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#request-body-2)
+**Request Body**
```
{
@@ -107,7 +107,7 @@ Authorization: Bearer 123456
}
```
-[**API 返回**](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#api-%E8%BF%94%E5%9B%9E-1)
+**API 返回**
```
{
@@ -115,7 +115,7 @@ Authorization: Bearer 123456
}
```
-#### [代码范例](https://github.com/langgenius/dify-docs/diffs/2?branch=main\&name=main\&qualified\_name=refs%2Fheads%2Fmain\&sha1=fb07d2bea301bd6388c393d5f3d8a80386c4dfdb\&sha2=a72d056812efe42f153d649085811e5b49ee131e\&short\_path=e2d7adb\&unchanged=expanded\&w=false#%E4%BB%A3%E7%A0%81%E8%8C%83%E4%BE%8B)
+#### 代码范例
代码基于 Python FastAPI 框架。
@@ -190,16 +190,15 @@ Authorization: Bearer 123456
```
3. 启动 API 服务,默认端口为 8000,API 完整地址为:`http://127.0.0.1:8000/api/dify/receive`,配置的 API Key 为 `123456`。
- ```
- uvicorn main:app --reload
- ```
+
uvicorn main:app --reload
+
4. 在 Dify 配置该 API。
-[](../../../.gitbook/assets/api\_based\_01.png)
+
配置 API
5. 在 App 中选择该 API 扩展。
-[](../../../.gitbook/assets/api\_based\_02.png)
+
选择扩展
App 调试时,Dify 将请求配置的 API,并发送以下内容(范例):
@@ -224,3 +223,37 @@ API 返回为:
"result": "City: London\nTemperature: 10°C\nRealFeel®: 8°C\nAir Quality: Poor\nWind Direction: ENE\nWind Speed: 8 km/h\nWind Gusts: 14 km/h\nPrecipitation: Light rain"
}
```
+
+### 本地调试
+
+由于 Dify 云端版无法访问内网 API 服务,为了方便本地调试 API 服务,可以使用 [Ngrok](https://ngrok.com) 将 API 服务的端点暴露到公网,实现云端调试本地代码。操作步骤:
+
+1. 进入 [https://ngrok.com](https://ngrok.com) 官网,注册并下载 Ngrok 文件。
+
+
+
+ 
Download
+2. 下载完成后,进入下载目录,根据下方说明解压压缩包,并执行说明中的初始化脚本。
+ * ```Shell
+ $ unzip /path/to/ngrok.zip
+ $ ./ngrok config add-authtoken 你的Token
+ ```
+3. 查看本地 API 服务的端口:
+
+
查看端口
+
+并运行以下命令启动:
+
+* ```Shell
+ $ ./ngrok http 端口号
+ ```
+
+ 启动成功的样例如下:
+
+
Ngrok 启动
+
+4. 我们找到 Forwarding 中,如上图:`https://177e-159-223-41-52.ngrok-free.app`(此为示例域名,请替换为自己的)即为公网域名。
+
+* 按照上述的范例,我们把本地已经启动的服务端点暴露出去,将代码范例接口:`http://127.0.0.1:8000/api/dify/receive` 替换为 `https://177e-159-223-41-52.ngrok-free.app/api/dify/receive`
+
+此 API 端点即可公网访问。至此,我们即可在 Dify 配置该 API 端点进行本地调试代码,配置步骤请参考 [external\_data\_tool.md](../../../application/prompt-engineering/external\_data\_tool.md "mention")。
diff --git a/zh_CN/advanced/extension/code_based_extension.md b/zh_CN/advanced/extension/code_based_extension.md
deleted file mode 100644
index d3dc622..0000000
--- a/zh_CN/advanced/extension/code_based_extension.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Code-based 扩展
-
-对于本地部署 Dify 的开发者,如果想实现扩展能力,无需重新写一个 API 服务,可以使用 Code-based Extension 即在 Dify 功能的基础上,以代码形式扩展或增强程序的能力(即插件能力),而不破坏 Dify 原有代码逻辑。它遵循一定的接口或规范,以实现与主程序的兼容和可插拔性。 目前,Dify 开放了两种 Code-based Extension,分别为:
-
-* 新增一种新的外部数据工具类型[external\_data\_tool.md](api\_based\_extension/external\_data\_tool.md "mention")
-* 扩展敏感内容审查策略[moderation.md](api\_based\_extension/moderation.md "mention")
-
-可在上述功能的基础上,遵循代码层 interface 的规范,来实现横向扩展的目的。
diff --git a/zh_CN/advanced/extension/code_based_extension/README.md b/zh_CN/advanced/extension/code_based_extension/README.md
new file mode 100644
index 0000000..d51caa7
--- /dev/null
+++ b/zh_CN/advanced/extension/code_based_extension/README.md
@@ -0,0 +1,28 @@
+# 代码扩展
+
+对于本地部署 Dify 的开发者,如果想实现扩展能力,无需重新写一个 API 服务,可以使用代码扩展,即在 Dify 功能的基础上,以代码形式扩展或增强程序的能力(即插件能力),而不破坏 Dify 原有代码逻辑。它遵循一定的接口或规范,以实现与主程序的兼容和可插拔性。 目前,Dify 开放了两种代码扩展,分别为:
+
+* 新增一种新的外部数据工具类型 [external\_data\_tool.md](external\_data\_tool.md "mention")
+* 扩展敏感内容审查策略 [moderation.md](moderation.md "mention")
+
+可在上述功能的基础上,遵循代码层 interface 的规范,来实现横向扩展的目的。
+
+### schema.json 规范定义
+
+Code-based Extension 前端样式通过 `schema.json` 定义,以下是定义规范。
+
+* label:自定义类型名称,支持系统语言切换
+* form\_schema:表单内容列表
+ * type:组件类型
+ * select:下拉选项
+ * text-input:文本
+ * paragraph:段落
+ * label:组件名称,支持系统语言切换
+ * variable:变量名称
+ * required:是否必填
+ * default:默认值
+ * placeholder:组件提示内容
+ * options:组件「select」专有属性,定义下拉内容
+ * label:下拉名称,支持系统语言切换
+ * value:下拉选项值
+ * max\_length:组件「text-input」专有属性,最大长度
diff --git a/zh_CN/advanced/extension/code_based_extension/external_data_tool.md b/zh_CN/advanced/extension/code_based_extension/external_data_tool.md
new file mode 100644
index 0000000..0dc3e53
--- /dev/null
+++ b/zh_CN/advanced/extension/code_based_extension/external_data_tool.md
@@ -0,0 +1,85 @@
+# 外部数据工具
+
+外部数据工具用于在终端用户提交数据后,利用外部工具获取额外数据组装至提示词中作为 LLM 额外上下文信息。Dify 默认提供了外部 API 调用的工具,具体参见 [api\_based\_extension](../api\_based\_extension/ "mention")。
+
+而对于本地部署 Dify 的开发者,为了满足更加定制化的需求,或者不希望额外开发一个 API Server,可以直接在 Dify 服务的基础上,以插件的形式插入定制的外部数据工具实现逻辑。扩展自定义工具后,将会在工具类型的下拉列表中增加您的自定义工具选项,团队成员即可使用自定义的工具来获取外部数据。
+
+## 如何开发扩展
+
+开发新的外部数据工具需要准备下面几个文件:
+
+* `{your_tool_name}.py` 工具扩展实现代码
+
+ * `your_tool_name` 为您定义的工具唯一标识,唯一标识不可与其他工具重复,建议以 `custom_` 为开头,目录结构示例如下:
+
+
+
+ ```Python
+ .
+ └── external_data_tool
+ └── custom_db_search
+ ├── custom_db_search.py
+ └── schema.json
+ ```
+
+ PS. Python 文件名称必须与文件夹名称保持一致。
+* `schema.json` 前端表单结构规范
+
+
+
+ 
Front-end Form Structure
+
+ 红框上的为固定表单项,红框中的表单项可在 schema.json 中的 form\_schema 自定义,规范见:[.](./ "mention")
+
+### 实现代码
+
+```python
+from typing import Optional
+
+from core.external_data_tool.base import ExternalDataTool
+
+
+class YourToolNameTool(ExternalDataTool):
+ name: str = "{your_tool_name}"
+
+ @classmethod
+ def validate_config(cls, tenant_id: str, config: dict) -> None:
+ """
+ Validate the incoming form config data.
+
+ :param tenant_id: the id of workspace
+ :param config: the form config data
+ :return:
+ """
+
+ # implement your own validate logic here
+
+ def query(self, inputs: dict, query: Optional[str] = None) -> str:
+ """
+ Query the external data tool.
+
+ :param inputs: user inputs
+ :param query: the query of chat app
+ :return: the tool query result
+ """
+ # TODO implement your own query logic here
+
+ return ''
+```
+
+代码需要放置在 `api/core/external_data_tool`中,目录结构如下:
+
+```python
+.
+└── api
+ └── core
+ └── external_data_tool
+ ├── base.py
+ ├── external_data_tool_factory.py
+ ├── api
+ │ ├── api.py
+ │ └── schema.json
+ ├── {your_tool_name}
+ │ ├── {your_tool_name}.py
+ │ └── schema.json
+```
diff --git a/zh_CN/advanced/extension/code_based_extension/moderation.md b/zh_CN/advanced/extension/code_based_extension/moderation.md
new file mode 100644
index 0000000..129a6cf
--- /dev/null
+++ b/zh_CN/advanced/extension/code_based_extension/moderation.md
@@ -0,0 +1,318 @@
+# 敏感内容审查
+
+## **内容审查扩展**
+
+除了系统内置的内容审查类型,Dify 也支持用户扩展自定义实现,该方法适用于私有部署的用户定制开发,如果您愿意将扩展功能贡献给我们的话,非常欢迎给 Dify 提交 PR。
+
+## 快速开始
+
+这里以一个 `Cloud Service` 内容审查扩展为例:大致步骤如下:
+
+1. 初始化目录
+2. 添加前端组件定义文件
+3. 添加实现类
+4. 预览前端界面
+5. 调试扩展
+6. ### 初始化目录
+
+新增自定义类型 `Cloud Service`,需要在 `api/core/moderation` 目录下新建相关的目录和文件。
+
+```Plain
+.
+└── api
+ └── core
+ └── moderation
+ └── cloud_service
+ ├── __init__.py
+ ├── cloud_service.py
+ └── schema.json
+```
+
+2. ### 添加前端组件规范
+
+* `schema.json`,这里定义了前端组件规范,详细见 [.](./ "mention")
+
+```JSON
+{
+ "label": {
+ "en-US": "Cloud Service",
+ "zh-Hans": "云服务"
+ },
+ "form_schema": [
+ {
+ "type": "select",
+ "label": {
+ "en-US": "Cloud Provider",
+ "zh-Hans": "云厂商"
+ },
+ "variable": "cloud_provider",
+ "required": true,
+ "options": [
+ {
+ "label": {
+ "en-US": "AWS",
+ "zh-Hans": "亚马逊"
+ },
+ "value": "AWS"
+ },
+ {
+ "label": {
+ "en-US": "Google Cloud",
+ "zh-Hans": "谷歌云"
+ },
+ "value": "GoogleCloud"
+ },
+ {
+ "label": {
+ "en-US": "Azure Cloud",
+ "zh-Hans": "微软云"
+ },
+ "value": "Azure"
+ }
+ ],
+ "default": "GoogleCloud",
+ "placeholder": ""
+ },
+ {
+ "type": "text-input",
+ "label": {
+ "en-US": "API Endpoint",
+ "zh-Hans": "API Endpoint"
+ },
+ "variable": "api_endpoint",
+ "required": true,
+ "max_length": 100,
+ "default": "",
+ "placeholder": "https://api.example.com"
+ },
+ {
+ "type": "paragraph",
+ "label": {
+ "en-US": "API Key",
+ "zh-Hans": "API Key"
+ },
+ "variable": "api_keys",
+ "required": true,
+ "default": "",
+ "placeholder": "Paste your API key here"
+ }
+ ]
+}
+```
+
+3. ### 添加实现类
+
+`cloud_service.py` 代码模版,你可以在这里实现具体的业务逻辑。
+
+> 注意:类变量 name 为自定义类型名称,需要跟目录和文件名保持一致,而且唯一。
+
+```Python
+from core.moderation.base import Moderation, ModerationAction, ModerationInputsResult, ModerationOutputsResult
+
+class CloudServiceModeration(Moderation):
+ """
+ The name of custom type must be unique, keep the same with directory and file name.
+ """
+ name: str = "cloud_service"
+
+ @classmethod
+ def validate_config(cls, tenant_id: str, config: dict) -> None:
+ """
+ schema.json validation. It will be called when user save the config.
+
+ Example:
+ .. code-block:: python
+ config = {
+ "cloud_provider": "GoogleCloud",
+ "api_endpoint": "https://api.example.com",
+ "api_keys": "123456",
+ "inputs_config": {
+ "enabled": True,
+ "preset_response": "Your content violates our usage policy. Please revise and try again."
+ },
+ "outputs_config": {
+ "enabled": True,
+ "preset_response": "Your content violates our usage policy. Please revise and try again."
+ }
+ }
+
+ :param tenant_id: the id of workspace
+ :param config: the variables of form config
+ :return:
+ """
+
+ cls._validate_inputs_and_outputs_config(config, True)
+
+ if not config.get("cloud_provider"):
+ raise ValueError("cloud_provider is required")
+
+ if not config.get("api_endpoint"):
+ raise ValueError("api_endpoint is required")
+
+ if not config.get("api_keys"):
+ raise ValueError("api_keys is required")
+
+ def moderation_for_inputs(self, inputs: dict, query: str = "") -> ModerationInputsResult:
+ """
+ Moderation for inputs.
+
+ :param inputs: user inputs
+ :param query: the query of chat app, there is empty if is completion app
+ :return: the moderation result
+ """
+ flagged = False
+ preset_response = ""
+
+ if self.config['inputs_config']['enabled']:
+ preset_response = self.config['inputs_config']['preset_response']
+
+ if query:
+ inputs['query__'] = query
+ flagged = self._is_violated(inputs)
+
+ # return ModerationInputsResult(flagged=flagged, action=ModerationAction.OVERRIDED, inputs=inputs, query=query)
+ return ModerationInputsResult(flagged=flagged, action=ModerationAction.DIRECT_OUTPUT, preset_response=preset_response)
+
+ def moderation_for_outputs(self, text: str) -> ModerationOutputsResult:
+ """
+ Moderation for outputs.
+
+ :param text: the text of LLM response
+ :return: the moderation result
+ """
+ flagged = False
+ preset_response = ""
+
+ if self.config['outputs_config']['enabled']:
+ preset_response = self.config['outputs_config']['preset_response']
+
+ flagged = self._is_violated({'text': text})
+
+ # return ModerationOutputsResult(flagged=flagged, action=ModerationAction.OVERRIDED, text=text)
+ return ModerationOutputsResult(flagged=flagged, action=ModerationAction.DIRECT_OUTPUT, preset_response=preset_response)
+
+ def _is_violated(self, inputs: dict):
+ """
+ The main logic of moderation.
+
+ :param inputs:
+ :return: the moderation result
+ """
+ return False
+```
+
+4. ### 预览前端界面
+
+按照上面步骤执行,运行服务即可见新增的自定义类型。
+
+5. #### 调试扩展
+
+至此,即可在 Dify 应用编排界面选择自定义的 `Cloud Service` 内容审查扩展类型进行调试。\
+
+
+## 前端组件规范
+
+* 请参考 [.](./ "mention")
+
+## 实现类模版
+
+```Python
+from core.moderation.base import Moderation, ModerationAction, ModerationInputsResult, ModerationOutputsResult
+
+class CloudServiceModeration(Moderation):
+ """
+ The name of custom type must be unique, keep the same with directory and file name.
+ """
+ name: str = "cloud_service"
+
+ @classmethod
+ def validate_config(cls, tenant_id: str, config: dict) -> None:
+ """
+ schema.json validation. It will be called when user save the config.
+
+ :param tenant_id: the id of workspace
+ :param config: the variables of form config
+ :return:
+ """
+ cls._validate_inputs_and_outputs_config(config, True)
+
+ # implement your own logic here
+
+ def moderation_for_inputs(self, inputs: dict, query: str = "") -> ModerationInputsResult:
+ """
+ Moderation for inputs.
+
+ :param inputs: user inputs
+ :param query: the query of chat app, there is empty if is completion app
+ :return: the moderation result
+ """
+ flagged = False
+ preset_response = ""
+
+ # implement your own logic here
+
+ # return ModerationInputsResult(flagged=flagged, action=ModerationAction.OVERRIDED, inputs=inputs, query=query)
+ return ModerationInputsResult(flagged=flagged, action=ModerationAction.DIRECT_OUTPUT, preset_response=preset_response)
+
+ def moderation_for_outputs(self, text: str) -> ModerationOutputsResult:
+ """
+ Moderation for outputs.
+
+ :param text: the text of LLM response
+ :return: the moderation result
+ """
+ flagged = False
+ preset_response = ""
+
+ # implement your own logic here
+
+ # return ModerationOutputsResult(flagged=flagged, action=ModerationAction.OVERRIDED, text=text)
+ return ModerationOutputsResult(flagged=flagged, action=ModerationAction.DIRECT_OUTPUT, preset_response=preset_response)
+```
+
+## 实现类开发详细介绍
+
+### def validate\_config
+
+`schema.json` 表单校验方法,当用户点击「发布」保存配置时调用
+
+* `config` 表单参数
+ * `{{variable}}` 表单自定义变量
+ * `inputs_config` 输入审查预设回复
+ * `enabled` 是否开启
+ * `preset_response` 输入预设回复
+ * `outputs_config`输出审查预设回复
+ * `enabled` 是否开启
+ * `preset_respons` 输出预设回复
+
+### def moderation\_for\_inputs
+
+输入校验函数
+
+* `inputs` :终端用户传入变量值
+* `query` :终端用户当前对话输入内容,对话型应用固定参数。
+* `ModerationInputsResult`
+ * `flagged` 是否违反校验规则
+ * `action` 执行动作
+ * `direct_output` 直接输出预设回复
+ * `overrided` 覆写传入变量值
+ * `preset_response` 预设回复(仅当 action=direct\_output 返回)
+ * `inputs` 终端用户传入变量值,key 为变量名,value 为变量值(仅当 action=overrided 返回)
+ * `query` 覆写的终端用户当前对话输入内容,对话型应用固定参数。(仅当 action=overrided 返回)
+
+### def moderation\_for\_outputs
+
+输出校验函数
+
+* `text` :模型输出内容
+* `moderation_for_outputs` :输出校验函数
+ * `text` :LLM 回答内容。当 LLM 输出为流式时,此处为 100 字为一个分段的内容。
+ * `ModerationOutputsResult`
+ * `flagged` 是否违反校验规则
+ * `action` 执行动作
+ * `direct_output`直接输出预设回复
+ * `overrided`覆写传入变量值
+ * `preset_response` 预设回复(仅当 action=direct\_output 返回)
+ * `text` 覆写的 LLM 回答内容。(仅当 action=overrided 返回)
+
+\
diff --git a/zh_CN/application/prompt-engineering/external_data_tool.md b/zh_CN/application/prompt-engineering/external_data_tool.md
index 89bb137..40cd91e 100644
--- a/zh_CN/application/prompt-engineering/external_data_tool.md
+++ b/zh_CN/application/prompt-engineering/external_data_tool.md
@@ -4,11 +4,11 @@
此前 [datasets](../../advanced/datasets/ "mention") 功能允许开发者可以直接上传各类格式的长文本、结构化数据来构建数据集,使 AI 应用基于用户上传的最新上下文进行对话。
-而本次更新的**外部数据工具**赋能开发者可以使用自有的搜索能力或内部知识库等外部数据作为 LLM 的上下文,通过 API 扩展的方式实现外部数据的获取并嵌入 Prompt。相比在云端上传数据集,使用**外部数据工具**可以在保障私有数据安全,自定义搜索,获取实时数据等方面有显著优势。
+而本次更新的**外部数据工具**赋能开发者可以使用自有的搜索能力或内部知识库等外部数据作为 LLM 的上下文,通过 API 扩展的方式实现外部数据的获取并嵌入提示词。相比在云端上传数据集,使用**外部数据工具**可以在保障私有数据安全,自定义搜索,获取实时数据等方面有显著优势。
## 具体实现
-当终端用户向对话系统提出请求时,平台后端会触发外部数据工具(即调用自己的 API),它会查询用户问题相关的外部信息,如员工资料、实时记录等,通过 API 返回与当前请求相关的部分。平台后端会将返回的结果组装成文本作为上下文注入到 Prompt 中,以输出更加个性化和符合用户需求的回复内容。
+当终端用户向对话系统提出请求时,平台后端会触发外部数据工具(即调用自己的 API),它会查询用户问题相关的外部信息,如员工资料、实时记录等,通过 API 返回与当前请求相关的部分。平台后端会将返回的结果组装成文本作为上下文注入到提示词中,以输出更加个性化和符合用户需求的回复内容。
## 操作说明
@@ -21,11 +21,11 @@

Weather Inquiry
-4. 在提示词编排页面,点击“工具”右侧的“+添加”按钮,在打开的“添加 工具”对话框,填写名称和变量名称(变量名称会被引用到 Prompt 中,请填写英文),以及选择第 2 步中已经添加的基于 API 的扩展。
+4. 在提示词编排页面,点击“工具”右侧的“+添加”按钮,在打开的“添加 工具”对话框,填写名称和变量名称(变量名称会被引用到提示词中,请填写英文),以及选择第 2 步中已经添加的基于 API 的扩展。

External_data_tool
-5. 这样,我们在提示词编排框就可以把查询到的外部数据拼装到 Prompt 中。比如我们要查询今天的伦敦天气,可以添加`location` 变量,输入"London",结合外部数据工具的扩展变量名称`weather_data`,调试输出如下:
+5. 这样,我们在提示词编排框就可以把查询到的外部数据拼装到提示词中。比如我们要查询今天的伦敦天气,可以添加`location` 变量,输入"London",结合外部数据工具的扩展变量名称`weather_data`,调试输出如下:

Weather_search_tool