GITBOOK-21: change request with no subject merged in GitBook

pull/25/head
zorroj 2023-11-07 15:48:44 +00:00 committed by gitbook-bot
parent d423693bf2
commit 841a05bade
No known key found for this signature in database
GPG Key ID: 07D2180C7B12D0FF
12 changed files with 495 additions and 37 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

View File

@ -55,10 +55,12 @@
* [接入 LocalAI 部署的本地模型](advanced/model-configuration/localai.md) * [接入 LocalAI 部署的本地模型](advanced/model-configuration/localai.md)
* [更多集成](advanced/more-integration.md) * [更多集成](advanced/more-integration.md)
* [扩展](advanced/extension/README.md) * [扩展](advanced/extension/README.md)
* [API-based 扩展](advanced/extension/api\_based\_extension/README.md) * [API 扩展](advanced/extension/api\_based\_extension/README.md)
* [外部数据工具扩展](advanced/extension/api\_based\_extension/external\_data\_tool.md) * [外部数据工具](advanced/extension/api\_based\_extension/external\_data\_tool.md)
* [敏感内容审查扩展](advanced/extension/api\_based\_extension/moderation.md) * [敏感内容审查](advanced/extension/api\_based\_extension/moderation.md)
* [Code-based 扩展](advanced/extension/code\_based\_extension.md) * [代码扩展](advanced/extension/code\_based\_extension/README.md)
* [外部数据工具](advanced/extension/code\_based\_extension/external\_data\_tool.md)
* [敏感内容审查](advanced/extension/code\_based\_extension/moderation.md)
## 使用案例 <a href="#use-cases" id="use-cases"></a> ## 使用案例 <a href="#use-cases" id="use-cases"></a>

View File

@ -4,4 +4,4 @@
[api\_based\_extension](api\_based\_extension/ "mention") [api\_based\_extension](api\_based\_extension/ "mention")
[code\_based\_extension.md](code\_based\_extension.md "mention") [code\_based\_extension](code\_based\_extension/ "mention")

View File

@ -1,4 +1,4 @@
# API-based 扩展 # API 扩展
开发者可通过 API 扩展模块能力,当前支持以下模块扩展: 开发者可通过 API 扩展模块能力,当前支持以下模块扩展:
@ -11,7 +11,7 @@
<figure><img src="../../../.gitbook/assets/api_based_01.png" alt=""><figcaption><p>基于 API 扩展</p></figcaption></figure> <figure><img src="../../../.gitbook/assets/api_based_01.png" alt=""><figcaption><p>基于 API 扩展</p></figcaption></figure>
### [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) <a href="#usercontentapi-gui-fan" id="usercontentapi-gui-fan"></a> ### API 规范 <a href="#usercontentapi-gui-fan" id="usercontentapi-gui-fan"></a>
Dify 将会以以下规范调用您的接口: Dify 将会以以下规范调用您的接口:
@ -19,14 +19,14 @@ Dify 将会以以下规范调用您的接口:
POST {Your-API-Endpoint} 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) <a href="#user-content-header" id="user-content-header"></a> #### Header <a href="#user-content-header" id="user-content-header"></a>
| Header | Value | Desc | | Header | Value | Desc |
| --------------- | ----------------- | --------------------------------------------------------------------- | | --------------- | ----------------- | --------------------------------------------------------------------- |
| `Content-Type` | application/json | 请求内容为 JSON 格式。 | | `Content-Type` | application/json | 请求内容为 JSON 格式。 |
| `Authorization` | Bearer {api\_key} | API Key 以 Token 令牌的方式传输,您需要解析该 `api_key` 并确认是否和提供的 API Key 一致,保证接口安全。 | | `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) <a href="#user-content-request-body" id="user-content-request-body"></a> #### Request Body <a href="#user-content-request-body" id="user-content-request-body"></a>
``` ```
{ {
@ -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) <a href="#usercontentapi-fan-hui" id="usercontentapi-fan-hui"></a> #### API 返回 <a href="#usercontentapi-fan-hui" id="usercontentapi-fan-hui"></a>
``` ```
{ {
@ -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) <a href="#usercontent-xiao-yan" id="usercontent-xiao-yan"></a> ### 校验 <a href="#usercontent-xiao-yan" id="usercontent-xiao-yan"></a>
在 Dify 配置 API-based Extension 时Dify 将会发送一个请求至 API Endpoint以检验 API 的可用性。 在 Dify 配置 API-based Extension 时Dify 将会发送一个请求至 API Endpoint以检验 API 的可用性。
当 API Endpoint 接收到 `point=ping` 时,接口应返回 `result=pong`,具体如下: 当 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) <a href="#user-content-header-1" id="user-content-header-1"></a> #### Header <a href="#user-content-header-1" id="user-content-header-1"></a>
``` ```
Content-Type: application/json Content-Type: application/json
Authorization: Bearer {api_key} 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) <a href="#user-content-request-body-1" id="user-content-request-body-1"></a> #### Request Body <a href="#user-content-request-body-1" id="user-content-request-body-1"></a>
``` ```
{ {
@ -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) <a href="#usercontentapi-qi-wang-fan-hui" id="usercontentapi-qi-wang-fan-hui"></a> #### API 期望返回 <a href="#usercontentapi-qi-wang-fan-hui" id="usercontentapi-qi-wang-fan-hui"></a>
``` ```
{ {
@ -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) <a href="#usercontent-fan-li" id="usercontent-fan-li"></a> ### 范例 <a href="#usercontent-fan-li" id="usercontent-fan-li"></a>
此处以外部数据工具为例,场景为根据地区获取外部天气信息作为上下文。 此处以外部数据工具为例,场景为根据地区获取外部天气信息作为上下文。
#### [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) <a href="#usercontentapi-fan-li" id="usercontentapi-fan-li"></a> #### API 范例 <a href="#usercontentapi-fan-li" id="usercontentapi-fan-li"></a>
``` ```
POST https://fake-domain.com/api/dify/receive 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 Content-Type: application/json
Authorization: Bearer 123456 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) <a href="#usercontent-dai-ma-fan-li" id="usercontent-dai-ma-fan-li"></a> #### 代码范例 <a href="#usercontent-dai-ma-fan-li" id="usercontent-dai-ma-fan-li"></a>
代码基于 Python FastAPI 框架。 代码基于 Python FastAPI 框架。
@ -190,16 +190,15 @@ Authorization: Bearer 123456
``` ```
3. 启动 API 服务,默认端口为 8000API 完整地址为:`http://127.0.0.1:8000/api/dify/receive`,配置的 API Key 为 `123456` 3. 启动 API 服务,默认端口为 8000API 完整地址为:`http://127.0.0.1:8000/api/dify/receive`,配置的 API Key 为 `123456`
``` <pre><code><strong>uvicorn main:app --reload
uvicorn main:app --reload </strong></code></pre>
```
4. 在 Dify 配置该 API。 4. 在 Dify 配置该 API。
[![](https://github.com/langgenius/dify-docs/raw/main/zh\_CN/.gitbook/assets/api\_based\_01.png)](../../../.gitbook/assets/api\_based\_01.png) <figure><img src="https://github.com/langgenius/dify-docs/raw/main/zh_CN/.gitbook/assets/api_based_01.png" alt=""><figcaption><p>配置 API </p></figcaption></figure>
5. 在 App 中选择该 API 扩展。 5. 在 App 中选择该 API 扩展。
[![](https://github.com/langgenius/dify-docs/raw/main/zh\_CN/.gitbook/assets/api\_based\_02.png)](../../../.gitbook/assets/api\_based\_02.png) <figure><img src="https://github.com/langgenius/dify-docs/raw/main/zh_CN/.gitbook/assets/api_based_02.png" alt=""><figcaption><p>选择扩展</p></figcaption></figure>
App 调试时Dify 将请求配置的 API并发送以下内容范例 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" "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 文件。
<figure><img src="../../../.gitbook/assets/download.png" alt=""><figcaption><p>Download</p></figcaption></figure>
2. 下载完成后,进入下载目录,根据下方说明解压压缩包,并执行说明中的初始化脚本。
* ```Shell
$ unzip /path/to/ngrok.zip
$ ./ngrok config add-authtoken 你的Token
```
3. 查看本地 API 服务的端口:
<figure><img src="../../../.gitbook/assets/8000.png" alt=""><figcaption><p>查看端口</p></figcaption></figure>
并运行以下命令启动:
* ```Shell
$ ./ngrok http 端口号
```
启动成功的样例如下:
<figure><img src="../../../.gitbook/assets/ngrock.png" alt=""><figcaption><p>Ngrok 启动</p></figcaption></figure>
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")。

View File

@ -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 的规范,来实现横向扩展的目的。

View File

@ -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」专有属性最大长度

View File

@ -0,0 +1,85 @@
# 外部数据工具
外部数据工具用于在终端用户提交数据后,利用外部工具获取额外数据组装至提示词中作为 LLM 额外上下文信息。Dify 默认提供了外部 API 调用的工具,具体参见 [api\_based\_extension](../api\_based\_extension/ "mention")。
而对于本地部署 Dify 的开发者,为了满足更加定制化的需求,或者不希望额外开发一个 API Server可以直接在 Dify 服务的基础上,以插件的形式插入定制的外部数据工具实现逻辑。扩展自定义工具后,将会在工具类型的下拉列表中增加您的自定义工具选项,团队成员即可使用自定义的工具来获取外部数据。
## 如何开发扩展
开发新的外部数据工具需要准备下面几个文件:
* `{your_tool_name}.py` 工具扩展实现代码
* &#x20; `your_tool_name` 为您定义的工具唯一标识,唯一标识不可与其他工具重复,建议以 `custom_` 为开头,目录结构示例如下:
```Python
.
└── external_data_tool
└── custom_db_search
├── custom_db_search.py
└── schema.json
```
PS. Python 文件名称必须与文件夹名称保持一致。
* `schema.json` 前端表单结构规范
<figure><img src="../../../.gitbook/assets/红框.png" alt=""><figcaption><p>Front-end Form Structure</p></figcaption></figure>
红框上的为固定表单项,红框中的表单项可在 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
```

View File

@ -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. ### 预览前端界面
按照上面步骤执行,运行服务即可见新增的自定义类型。![](https://langgenius.feishu.cn/space/api/box/stream/download/asynccode/?code=OTcxZjhjYWQ0Y2FhODI4NmU3ZGQ5NmY1OWE3M2UzMmJfMFJ1M1dzbG5semNQcjA5NjgyWjhUcGdPdDlYREtBWUxfVG9rZW46Q1JPS2I3bFU0b0NQY2l4YVlhUGNVSTNNblJkXzE2OTkzNjQ1MzQ6MTY5OTM2ODEzNF9WNA)
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 返回)
\

View File

@ -4,11 +4,11 @@
此前 [datasets](../../advanced/datasets/ "mention") 功能允许开发者可以直接上传各类格式的长文本、结构化数据来构建数据集,使 AI 应用基于用户上传的最新上下文进行对话。 此前 [datasets](../../advanced/datasets/ "mention") 功能允许开发者可以直接上传各类格式的长文本、结构化数据来构建数据集,使 AI 应用基于用户上传的最新上下文进行对话。
而本次更新的**外部数据工具**赋能开发者可以使用自有的搜索能力或内部知识库等外部数据作为 LLM 的上下文,通过 API 扩展的方式实现外部数据的获取并嵌入 Prompt。相比在云端上传数据集,使用**外部数据工具**可以在保障私有数据安全,自定义搜索,获取实时数据等方面有显著优势。 而本次更新的**外部数据工具**赋能开发者可以使用自有的搜索能力或内部知识库等外部数据作为 LLM 的上下文,通过 API 扩展的方式实现外部数据的获取并嵌入提示词。相比在云端上传数据集,使用**外部数据工具**可以在保障私有数据安全,自定义搜索,获取实时数据等方面有显著优势。
## 具体实现 ## 具体实现
当终端用户向对话系统提出请求时,平台后端会触发外部数据工具(即调用自己的 API它会查询用户问题相关的外部信息如员工资料、实时记录等通过 API 返回与当前请求相关的部分。平台后端会将返回的结果组装成文本作为上下文注入到 Prompt 中,以输出更加个性化和符合用户需求的回复内容。 当终端用户向对话系统提出请求时,平台后端会触发外部数据工具(即调用自己的 API它会查询用户问题相关的外部信息如员工资料、实时记录等通过 API 返回与当前请求相关的部分。平台后端会将返回的结果组装成文本作为上下文注入到提示词中,以输出更加个性化和符合用户需求的回复内容。
## 操作说明 ## 操作说明
@ -21,11 +21,11 @@
<figure><img src="../../.gitbook/assets/weather inquiry.png" alt=""><figcaption><p>Weather Inquiry</p></figcaption></figure> <figure><img src="../../.gitbook/assets/weather inquiry.png" alt=""><figcaption><p>Weather Inquiry</p></figcaption></figure>
4. 在提示词编排页面,点击“工具”右侧的“+添加”按钮,在打开的“添加 工具”对话框,填写名称和变量名称(变量名称会被引用到 Prompt 中,请填写英文),以及选择第 2 步中已经添加的基于 API 的扩展。 4. 在提示词编排页面,点击“工具”右侧的“+添加”按钮,在打开的“添加 工具”对话框,填写名称和变量名称(变量名称会被引用到提示词中,请填写英文),以及选择第 2 步中已经添加的基于 API 的扩展。
<figure><img src="../../.gitbook/assets/api_based_extension1.png" alt=""><figcaption><p>External_data_tool</p></figcaption></figure> <figure><img src="../../.gitbook/assets/api_based_extension1.png" alt=""><figcaption><p>External_data_tool</p></figcaption></figure>
5. 这样,我们在提示词编排框就可以把查询到的外部数据拼装到 Prompt 中。比如我们要查询今天的伦敦天气,可以添加`location` 变量,输入"London",结合外部数据工具的扩展变量名称`weather_data`,调试输出如下: 5. 这样,我们在提示词编排框就可以把查询到的外部数据拼装到提示词中。比如我们要查询今天的伦敦天气,可以添加`location` 变量,输入"London",结合外部数据工具的扩展变量名称`weather_data`,调试输出如下:
<figure><img src="../../.gitbook/assets/Weather_search_tool.jpeg" alt=""><figcaption><p>Weather_search_tool</p></figcaption></figure> <figure><img src="../../.gitbook/assets/Weather_search_tool.jpeg" alt=""><figcaption><p>Weather_search_tool</p></figcaption></figure>