Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs/api-based-extension #419

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion zh_CN/guides/extension/api-based-extension/cloudflare-workers.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,43 @@ const result = await fetch(url).then(res => res.text())
这个仓库简化了除了业务逻辑之外所有的配置,你可以直接使用 `npm` 命令来部署你的 API 扩展。

```bash
npm install
npm run deploy
```

部署成功之后,你会得到一个公网地址,你可以在 Dify 中添加这个地址作为 API Endpoint。请注意不要遗漏 `endpoint` 这个路径。
部署成功之后,你会得到一个公网地址,你可以在 Dify 中添加这个地址作为 API Endpoint。请注意不要遗漏 `endpoint` 这个路径,此路径的具体定义在 `src/index.ts` 中可以查看

<figure><img src="../../../.gitbook/assets/api_extension_edit.png" alt=""><figcaption><p>在 Dify 中添加 API Endpoint</p></figcaption></figure>

<figure><img src="../../../.gitbook/assets/app_tools_edit.png" alt=""><figcaption><p>在 App 编辑页面中添加上 API Tool</p></figcaption></figure>


另外,也可以直接使用 `npm run dev` 命令来部署到本地进行测试。

```bash
npm install
npm run dev
```

相关输出:

```bash
$ npm run dev
> dev
> wrangler dev src/index.ts

⛅️ wrangler 3.99.0
-------------------

Your worker has access to the following bindings:
- Vars:
- TOKEN: "ban****ool"
⎔ Starting local server...
[wrangler:inf] Ready on http://localhost:58445
```

之后就可以使用 Postman 等工具进行本地接口调试。

## 其他逻辑 TL;DR

### 关于 Bearer Auth
Expand Down
117 changes: 114 additions & 3 deletions zh_CN/guides/extension/api-based-extension/moderation.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

### app.moderation.input 扩展点 <a href="#usercontentappmoderationinput-kuo-zhan-dian" id="usercontentappmoderationinput-kuo-zhan-dian"></a>

当在 Chatflow、Agent、聊天助手等应用下开启**内容审查>审查输入内容**时,Dify 会给相应的 API 扩展发送下列 HTTP POST 请求:

#### Request Body <a href="#user-content-request-body" id="user-content-request-body"></a>

```
Expand Down Expand Up @@ -44,7 +46,7 @@
}
```

#### API 返回 <a href="#usercontentapi-fan-hui" id="usercontentapi-fan-hui"></a>
#### API 返回规范 <a href="#usercontentapi-fan-hui" id="usercontentapi-fan-hui"></a>

```
{
Expand All @@ -61,7 +63,7 @@
```

* Example
* `action=``direct_output`
* `action=direct_output`
* ```
{
"flagged": true,
Expand All @@ -84,6 +86,8 @@

### app.moderation.output 扩展点 <a href="#usercontentappmoderationoutput-kuo-zhan-dian" id="usercontentappmoderationoutput-kuo-zhan-dian"></a>

当在 Chatflow、Agent、聊天助手等应用下开启**内容审查>审查输出内容**时,Dify 会给相应的 API 扩展发送下列 HTTP POST 请求:

#### Request Body <a href="#user-content-request-body-1" id="user-content-request-body-1"></a>

```
Expand All @@ -107,7 +111,7 @@
}
```

#### API 返回 <a href="#usercontentapi-fan-hui-1" id="usercontentapi-fan-hui-1"></a>
#### API 返回规范 <a href="#usercontentapi-fan-hui-1" id="usercontentapi-fan-hui-1"></a>

```
{
Expand Down Expand Up @@ -135,3 +139,110 @@
"text": "I will *** you."
}
```
## 代码示例
下面展示一段可部署在 Cloudflare 的 `src/index.ts` 代码。(Cloudflare 完整的使用方法参见[此文档](https://docs.dify.ai/zh-hans/guides/extension/api-based-extension/cloudflare-workers))

代码工作原理是进行关键词匹配,实现对 Input (用户输入的内容)以及输出(大模型返回的内容)进行过滤。用户可以按照需求自行修改匹配逻辑。
```
import { Hono } from "hono";
import { bearerAuth } from "hono/bearer-auth";
import { z } from "zod";
import { zValidator } from "@hono/zod-validator";
import { generateSchema } from '@anatine/zod-openapi';

type Bindings = {
TOKEN: string;
};

const app = new Hono<{ Bindings: Bindings }>();

// API 格式校验 ⬇️
const schema = z.object({
point: z.union([
z.literal("ping"),
z.literal("app.external_data_tool.query"),
z.literal("app.moderation.input"),
z.literal("app.moderation.output"),
]), // Restricts 'point' to two specific values
params: z
.object({
app_id: z.string().optional(),
tool_variable: z.string().optional(),
inputs: z.record(z.any()).optional(),
query: z.any(),
text: z.any()
})
.optional(),
});


// Generate OpenAPI schema
app.get("/", (c) => {
return c.json(generateSchema(schema));
});

app.post(
"/",
(c, next) => {
const auth = bearerAuth({ token: c.env.TOKEN });
return auth(c, next);
},
zValidator("json", schema),
async (c) => {
const { point, params } = c.req.valid("json");
if (point === "ping") {
return c.json({
result: "pong",
});
}
// ⬇️ impliment your logic here ⬇️
// point === "app.external_data_tool.query"
else if (point === "app.moderation.input"){
// 输入检查 ⬇️
const inputkeywords = ["输入过滤测试1", "输入过滤测试2", "输入过滤测试3"];

if (inputkeywords.some(keyword => params.query.includes(keyword)))
{
return c.json({
"flagged": true,
"action": "direct_output",
"preset_response": "输入存在违法内容,请换个问题再试!"
});
} else {
return c.json({
"flagged": false,
"action": "direct_output",
"preset_response": "输入无异常"
});
}
// 输入检查完毕
}

else {
// 输出检查 ⬇️
const outputkeywords = ["输出过滤测试1", "输出过滤测试2", "输出过滤测试3"];

if (outputkeywords.some(keyword => params.text.includes(keyword)))
{
return c.json({
"flagged": true,
"action": "direct_output",
"preset_response": "输出存在敏感内容,已被系统过滤,请换个问题再问!"
});
}

else {
return c.json({
"flagged": false,
"action": "direct_output",
"preset_response": "输出无异常"
});
};
}
// 输出检查完毕
}
);

export default app;

```