📎 配套脚本附件正文未内嵌 · 共 5 个 · 点开可在线查看
📂 查看全部 126 个脚本附件 →
⚠️ 脚本内含明文凭据(与本页正文一致),请勿在公网环境直接运行。
场景 · 智能体与工作流

用智能体和工作流把客服、工单、监控和自愈走一遍

在已有的 Dify 上把场景跑一遍:六条智能体(工单分流、监控检查、故障自愈、智能客服、合同问答、运维巡检)与三条工作流(工单分流、监控检查、客服检索)。含 Prometheus 与 vLLM 的只读工具、max_tokens 与 {{#context#}} 两处踩坑记录,以及沙箱代理 NO_PROXY 的 DNS 排查。

用智能体和工作流把客服、工单、监控和自愈走一遍

目录

  1. 一、两条用法,一条请求路径
  2. 二、智能体
  3. 三、工作流
  4. 四、沙箱写配置时碰到的 DNS
  5. 五、文件

本文记录 2026-10-13 在现有 Dify 1.17 上跑过的场景。智能体六条:工单分流、监控检查、故障自愈、智能客服,加上原来的合同问答和运维巡检。工作流三条:工单分流、监控检查、客服检索。本章目录是 场景。机器是 prod102,地址 10.0.1.47。合同知识库的安装写在同级目录 dify 的《用 Dify 做合同知识库:Qwen 对话、bge 重排和 Langfuse 工具追踪.md》。流程对照页是同目录的《走一遍客服、工单、监控和自愈.html》。

页面是 http://10.0.1.47:8088,登录 admin@example.com / Dify-rag-2026。对话模型是 qwen3.6-27b,请求从 Dify 到 New-API,再到 vLLM。向量是 bge-m3,重排是 bge-reranker-v2-m3,由 Xinference 提供。

scripts/10-试用主流场景.py 和 scripts/11-试用工作流.py 已经在现网执行过。同名应用会复用或覆盖草稿。复习时看本文即可。不要重新初始化「阿里云合同条款」,那会再索引一份。不要为了对照文档重启 vLLM 或 New-API。

登录口令沿用现网值。Vault 根令牌、Langfuse 的 NEXTAUTH_SECRET、SALT、ENCRYPTION_KEY、Redis 口令、MinIO 口令、kubeadm 加入令牌,以及 Argo CD 仓库 Secret 里的个人访问令牌,不写进本文。不要把本文发到公网。

一、两条用法,一条请求路径

浏览器打开 Dify。需要生成文字时,路径仍是:

text
Dify → New-API → vLLM qwen3.6-27b → GPU

知识库检索走 Xinference。监控数字走 Prometheus http://10.0.1.47:9090。

智能体由模型决定下一步:要不要查知识库,要不要调工具,要不要再查一次。工作流的模式是 workflow。节点和连线写在图里,分类之后只进入一个出口,监控按固定顺序发三次 HTTP。监控那条工作流不调用对话模型。

nvidia-smi 里大约 86GB 是 vLLM 启动参数 gpu-memory-utilization 0.70 预先划出的 KV 缓存。短对话使用这块已经划出的显存。全部跑完时占用约 86323 MiB,/health 为 200。

二、智能体

脚本 scripts/10-试用主流场景.py。新注册的工具:

工具地址作用
queryPrometheushttp://10.0.1.47:9090/api/v1/query只读 PromQL,OpenAPI 在 config/prometheus-openapi.yaml
checkVllmHealthhttp://10.0.1.47:8000/health只读健康检查,OpenAPI 在 config/vllm-health-openapi.yaml

客服说明知识库的名字是「平台客服说明」,编号 b2dd0af3-d73c-4983-9348-8b25ca502ef2。里面是平台入口:Dify、GitLab、Argo CD、模型名和导航页。索引状态是 completed。口令没有写进这份说明,客服被要求不要编造口令。

1. 工单分流

不挂工具。提示词要求分成咨询、投诉、故障、账号之一,并给出紧急程度高或低,输出三行:类别、紧急程度、摘要。

来话是合同发票三天未收到、语气急、要求今天答复。结果:

text
类别:投诉
紧急程度:高
摘要:客户称合同发票已等待三天仍未收到,语气急切并要求今日内答复

应用编号 3155e433-60f0-496b-bd48-d055a6cca385。

2. 监控检查

必须调用 queryPrometheus,依次查询:

text
DCGM_FI_DEV_GPU_TEMP
DCGM_FI_DEV_FB_USED
sum(vllm:num_requests_waiting{model_name="qwen3.6-27b"})

结果:温度 37°C,显存 86092 MB,排队 0。这是 Prometheus 里这张 H20 的数。应用编号 a747a108-8520-4358-9900-ed792d20ca90。

3. 故障自愈

只读。必须调用 checkVllmHealth 和 queryPrometheus。结论只允许三个词:无需处理、观察、人工处理。排队大于 10 时写观察,并说明 KEDA 会把 Dify worker 扩到最多 3 个。提示词禁止输出重启、删除 Pod、kubectl 或改镜像的命令。没有给它这些工具。

vLLM 的 /health 在正常时返回 200,响应体是空的。第一次模型把空响应当成故障,写成了「人工处理」。提示词改为「没有报错、空响应也算健康」,重新发布后再判断,结论是无需处理,排队仍是 0。应用编号 31154f0a-0fa3-4a85-9e00-809b29bc2c11。

4. 智能客服

只根据「平台客服说明」回答。问题是 GitLab 的网页地址。回答是 http://10.0.1.47:8929。应用编号 8db6337b-efc6-4554-a51a-2950de4b66c0。

5. 合同问答

这是原来的应用,知识库「阿里云合同条款」,编号 71042108-5f9a-4856-a0db-4359e8e7fa98,高质量索引,混合检索,重排模型 bge-reranker-v2-m3。问题是这份合同的客户是谁。回答是甲方抖爸爸(杭州)电子商务服务有限公司。应用编号 d2e3f57b-3901-45de-bd9a-d51feb849f6e。

6. 运维巡检

调用原来的 getServerStatus,地址 http://172.17.0.1:8777。问的是 gpu-server-01。返回的是演示接口里的固定数:CPU 45%,内存 62%,GPU 利用率 78%,显存 18.2/24 GB。这组数和监控检查里的温度、显存不是同一路数据。应用编号 e4d614f6-de22-4f4c-b58e-caeb0504b121。接口程序是 server-status/app.py,不要为了这次场景重启它。

三、工作流

脚本 scripts/11-试用工作流.py。三条都已发布。模型节点的 max_tokens 是 2048,温度 0.2。分类和客服检索会调用 qwen3.6-27b。监控这条只有 HTTP 和代码节点。

1. 工单分流工作流

编号 4e30ef60-44ee-40a6-928a-a1f4bd76da7d。

text
开始(工单文本)
  → 问题分类(投诉 / 咨询)
      → 投诉出口:类别、紧急程度高、今日内答复
      → 咨询出口:类别、紧急程度普通、按平台说明答复

「合同发票已经三天没收到,请今天给一个答复」进入投诉出口。「GitLab 的网页地址在哪里」进入咨询出口。

分类节点第一次失败,错误是 could not find json block in the output。模型把当时 256 的回答预算花在思考上,正文是空的,后面的出口没有类别可以接。预算改成 2048 之后,两个出口都走到结束。

2. 监控检查工作流

编号 f0b6357e-e9fe-43c4-ba16-a9b23cfdf78f。

text
开始
  → HTTP 查 DCGM_FI_DEV_GPU_TEMP
  → HTTP 查 DCGM_FI_DEV_FB_USED
  → HTTP 查 sum(vllm:num_requests_waiting{model_name="qwen3.6-27b"})
  → 代码节点抽出每条结果里的数值
  → 结束

三次请求都打到 http://10.0.1.47:9090/api/v1/query。SSRF 允许 10.0.0.0/8,这个地址可以通。跑完的输出:

text
温度 53 C
显存 86322 MiB
排队 0

53°C 高于前面智能体监控时的 37°C,是中间几次生成把卡带起来了。显存仍在预先划出的那一块附近。排队是 0,KEDA 不会因此去加 worker。

3. 客服检索工作流

编号 8b6dbeff-0d83-434a-b16e-b0cd5e460cac。

text
开始(问题)
  → 知识检索「平台客服说明」,top_k 3,重排 bge-reranker-v2-m3
  → 对话模型,系统提示里放 {{#context#}}
  → 结束

问题是 GitLab 的网页地址是什么。检索节点已经拿到含有 http://10.0.1.47:8929 的片段。第一次回答是「不知道」,因为提示词只写了「根据检索内容回答」,图里没有把检索结果放进提示。系统提示加上 {{#context#}} 并重新发布之后,回答是:GitLab 的网页地址是 http://10.0.1.47:8929。

四、沙箱写配置时碰到的 DNS

在页面里让监控智能体整理结果时,queryPrometheus 能返回三条数据。同一页红框写的是 agent_backend:5050 DNS 解析失败,笔记和配置写不进去。

agent-backend 的 Deployment 和 Service 都在,ClusterIP 10.107.0.77,端口 5050,Pod 1/1。CoreDNS 有一条改写,把 agent_backend.dify.svc.cluster.local 指到 agent-backend.dify.svc.cluster.local。从 Pod 里解析这个短名字是通的。

写配置的进程跑在 local-sandbox。它的 HTTP_PROXY 是 http://agent_ssrf_proxy:3128,NO_PROXY 原来只有 localhost,127.0.0.1。于是 http://agent_backend:5050 被交给 Squid。Squid 不做 Kubernetes 的搜索域补全,短名字在访问日志里是 TCP_MISS_ABORTED/503,HIER_NONE。带完整后缀的 agent-backend.dify.svc.cluster.local 可以从代理直连到 Service。

现网已经把 local-sandbox 的 NO_PROXY 补成:

text
localhost,127.0.0.1,agent_backend,agent-backend,agent_backend.dify.svc.cluster.local,agent-backend.dify.svc.cluster.local,local_sandbox,local-sandbox,api,api.dify.svc.cluster.local,agent_ssrf_proxy,agent-ssrf-proxy,.cluster.local

这个值在 Vault 路径 apps/dify/local-sandbox-env,由 ExternalSecret local-sandbox-env 同步到同名 Secret。改完后只删掉了 local-sandbox 的 Pod,让它读到新环境变量。不带令牌再访问 http://agent_backend:5050/agent-stub/config/manifest,后端返回 401。401 说明请求已经到达 agent-backend,空请求没有登录信息。vLLM 的 /health 在这次重启之后仍是 200。

代码执行用的另一个沙箱 sandbox 走的是 ssrf_proxy:3128,NO_PROXY 仍是空的。这次三条工作流里的代码节点已经成功抽出监控数字,没有改那一份环境变量。

五、文件

文件作用
scripts/10-试用主流场景.py注册两个只读工具,准备客服说明,发布四条新智能体并各问一次
scripts/11-试用工作流.py发布三条工作流并各跑一次
config/prometheus-openapi.yamlPrometheus 即时查询
config/vllm-health-openapi.yamlvLLM /health
走一遍客服、工单、监控和自愈.html本阶段的流程对照页

原来的合同脚本和巡检脚本仍在 dify/scripts,分别是 05-合同知识库.py 和 08-注册服务器状态工具.py。这次场景没有重跑它们。