前言

在上一篇Dify私有化部署实战(四):进阶之通过 Workflow (工作流) 编排复杂业务逻辑中,我们已经把内置的网络搜索工具加进了工作流,解决了大模型联网获取实时信息的问题。

内置工具虽然好用,但大模型真正要在企业生产环境中落地,必须打破业务系统的“数据孤岛”。这篇笔记主要记录两个核心扩展场景:一是出于合规与安全考量,通过 API 扩展接入自定义的敏感词检测机制;二是通过 OpenAPI 规范,把内部系统(以工单查询为例)封装成自定义工具,让 AI 具备直接调用企业内部数据的能力。

一、 API 扩展实战:智能聊天接入敏感词检测 API

大模型生成的内容具有不可控性,在对外的智能聊天应用中,内容合规是红线。Dify 提供了 API 扩展(API-based Extension)功能,非常适合用来做前置/后置的内容审查(Moderation)。

1. 敏感词检测 API 接口开发

这里我用 NodeJS 快速写了一个敏感词检测接口。为了配合 Dify 的 API 扩展规范,接口需要接收特定的 JSON payload,并返回 Dify 约定的结构。

服务端代码(部署在云服务器某端口,例如 3000):

const express = require('express');
const fs = require('fs');
const path = require('path');

const app = express();
const port = 3000;

// Dify 敏感词过滤 API 扩展接口
// 敏感词列表(示例)
const SENSITIVE_WORDS = ['暴力', '色情', '违禁品', '政治敏感'];

app.post('/api/dify/moderation', (req, res) => {
    const { point, params } = req.body;

    // 1. 验证接口端点可用性 (Ping/Pong)
    if (point === 'ping') {
        return res.json({ result: 'pong' });
    }

    // 2. 处理内容审查逻辑
    if (point === 'app.moderation.input' || point === 'app.moderation.output') {
        const query = params.query || '';
        const inputs = params.inputs || {};

        // 拼接所有可能包含文字的字段进行统计
        let textToCheck = query;
        for (const key in inputs) {
            if (typeof inputs[key] === 'string') {
                textToCheck += ' ' + inputs[key];
            }
        }

        // 检查敏感词
        const foundWords = SENSITIVE_WORDS.filter(word => textToCheck.includes(word));

        if (foundWords.length > 0) {
            // 发现敏感词,触发拦截
            return res.json({
                flagged: true,
                action: 'direct_output',
                preset_response: '您的输入或输出内容中包含敏感内容,已被系统拦截。'
            });
        }

        // 未发现敏感词
        return res.json({
            flagged: false
        });
    }

    // 未知的扩展点
    res.status(400).json({ error: 'Unsupported point: ' + point });
});

app.listen(port, () => {
    console.log(`Server is running at http://localhost:${port}`);
});
2. 在 Dify 中配置 API 扩展

接口跑起来之后,需要去 Dify 平台进行注册挂载。

  1. 点击右上角头像部分,打开设置页面,打开API扩展。

  2. 添加一个新的 API 扩展,填写接口的 Endpoint。

  3. 坑点注意: 因为 Dify 跑在 Docker 容器里,如果你的 API 脚本和 Dify 部署在同一台云服务器的宿主机上,Endpoint 不能写 http://127.0.0.1:8081 或 http://localhost:8081。需要写云服务器的公网 IP。

3. 智能聊天应用中挂载审查功能

进入你之前创建的“智能聊天”应用 -> 提示词/编排 (Orchestrate) 页面 -> 找到 内容审查 (Moderation) 模块。
开启审查后,选择我们刚刚挂载的“API 扩展”,将其作用于“输入/输出”阶段。

二、 自定义工具 (Tools) 开发:基于 OpenAPI 接入工单查询系统

第二个场景是业务痛点:业务员需要通过自然语言直接查询自己的报修或审批工单状态。这就需要给 Dify 挂载自定义工具 (Custom Tool)。Dify 支持标准 OpenAPI (Swagger) 格式的接口解析。

1. 编写工单查询 API 并生成 OpenAPI 规范

我依旧用 NodeJS 模拟一个内部的 CRM 工单接口。并使用AI生成了一个OpenAPI JSON规范。

工单接口代码(运行在云服务器 3000 端口):

// GET 接口:根据 ID 查询工单详情(示例)
app.get('/api/orders/:id', (req, res) => {
    const orderId = req.params.id;

    // 这里是示例硬编码数据,实际开发中通常从数据库查询
    const mockOrder = {
        id: orderId,
        title: "示例工单 - 服务器连接异常",
        description: "在进行例行检查时发现,部分节点出现 SSH 连接超时,需要排查网络配置或硬件状态。",
        status: "processing",
        priority: "high",
        creator: "Admin",
        createdAt: "2024-02-13T08:00:00Z",
        updatedAt: "2024-02-13T10:30:00Z",
        assignee: "运维工程师-王五",
        category: "网络故障",
        history: [
            { action: "工单创建", operator: "Admin", time: "2024-02-13T08:00:00Z" },
            { action: "状态变更为处理中", operator: "王五", time: "2024-02-13T09:15:00Z" },
            { action: "添加备注:正在排查交换机配置", operator: "王五", time: "2024-02-13T10:30:00Z" }
        ]
    };

    // 假设 ID 不存在的情况(可选示例)
    if (orderId === '404') {
        return res.status(404).json({ error: 'Order not found' });
    }

    res.json(mockOrder);
});
2. Dify 接入自定义工具

进入 Dify 顶部的 工具 (Tools) -> 自定义 (Custom) -> 创建自定义工具

将刚才AI生成的 openapi.json 贴入 Schema 输入框中。Dify 会自动解析出包含 apiordersid_get 的可用方法,并提取出入参(id)。

配置项修改建议:
由于自动生成的 JSON 里 Server URL 可能是 http://0.0.0.0:8082,这里需要手动把 Schema 里面的 servers 字段下的 URL 替换为你云服务器真实的内网/公网 IP,否则 Dify 容器无法正确发起调用。

3. 工具在智能体/工作流中的调用

工具创建好以后,就可以把它拉入之前篇章写过的 Workflow 或者 Agent 中使用了。

在 Agent 的测试面板,当输入“帮我查一下工单 T1001 的进度”时,观察右侧的调试日志 (Logs),可以看到清晰的执行流:

  1. 模型理解意图,提取出工单号 T1001。

  2. 模型命中并调用 apiordersid_get 工具,传入参数 id: T1001。

  3. 获取到 JSON 响应。

  4. 模型将 JSON 转化为自然语言输出:“工单 T1001(标题:示例工单 - 服务器连接异常)的当前进度如下”

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐