简介:本资源是一份面向AI应用开发者的实战指南,聚焦Dify开源平台的完整落地实践,帮助研发人员快速构建生产级生成式AI应用,尤其适合希望降低LLM开发门槛、提升RAG与Agent应用开发效率的中高级开发者。资源为单文件PDF文档(217KB),内容涵盖Dify核心架构解析、多模型接入(GPT/Mistral/Llama3等)、可视化Prompt编排、RAG引擎调优、Agent工作流设计,以及电商客服、新媒体内容生成、办公自动化等真实场景案例详解,并对比FastGPT突出其BaaS+LLMOps一体化优势。已有455人学习下载,文档结构清晰,从安装部署到高阶优化层层递进,附带可直接复用的配置逻辑、组件选型建议与运营监控要点,助力读者快速掌握AI应用全生命周期管理能力。
1. 为什么中小团队在没 GPU 服务器、没算法工程师的情况下,也能用 Dify 快速上线一个能查制度、能答条款、能自动归档的 LLM 应用?
这不是“又一个大模型玩具”。我去年在一家 30 人规模的制造业合规部门做技术顾问,他们连一台带显卡的服务器都没有,但急需把 200+ 份 PDF 版《安全生产责任制》《危化品管理细则》《外包单位准入标准》变成可检索、可问答、可嵌入 OA 审批流的智能助手。试过 LangChain 自搭、RAGFlow 本地部署、甚至让实习生硬啃 LlamaIndex 文档——全卡在向量入库慢、提示词调不稳、权限控制漏缝、升级后知识库失效这四道坎上。直到把 Dify 社区版 1.10 部署到一台 8C16G 的 CentOS 7 老服务器(没 GPU),用它自带的「知识库流水线」+「DSL 编排」+「变量赋值节点」,三天内上线了制度条例学习助手:HR 新员工培训时扫码提问“试用期解除合同要走几步”,系统直接返回条款原文+审批路径图+关联表单链接。关键不是“它能跑”,而是它把 LLM 应用开发里最耗人力的 70% 黑匣子操作——文档解析策略、chunk 切分逻辑、embedding 模型绑定、检索重排序规则、会话状态隔离——全封装进可视化界面和 YAML 流水线定义里。适合谁?不是冲着 SOTA 指标去的算法团队,而是法务、HR、IT 运维组成的三人小组,需要两周内交付一个能写进年度数字化 KPI 的 LLM 应用。标题里的“从安装到实战案例详解”,本质是拆解:怎么绕过 Docker 网络玄学、怎么让 unstructured API 在 CentOS 7 上不报错、怎么用变量节点把用户工号自动注入检索上下文、怎么让知识库更新不触发全量重索引——这些才是真实项目里卡住进度的血泪经验。
2. 在无 GPU 的 CentOS 7 服务器上完成 Dify 社区版 1.10 部署:避开 SSL 错误、too many incorrect password、unstructured API URL 未配置三大翻车点
Dify 不是“一键安装”就能跑的玩具。它的部署链路像一条精密流水线:前端 Nginx 反向代理 → 后端 Flask 服务 → Celery 异步任务队列 → PostgreSQL 存元数据 → Redis 缓存会话 → 向量数据库(默认 Weaviate)存 embedding → unstructured 服务解析文档。任何一个环节参数错位,就会出现标题里高频热词对应的错误:dify ssl error、dify too many incorrect password attempts、unstructured api url is not configured for doc file processing。下面按真实生产环境顺序,逐层落地。
2.1 基础环境准备:CentOS 7 的 Python 3.11 + pip 23.3.1 是唯一稳定组合
CentOS 7 默认 Python 2.7,强行升级到 3.9+ 极易破坏 yum。必须用 pyenv 独立管理 Python 版本,且只认准 3.11.9(Dify 1.10 官方测试矩阵唯一覆盖的 3.11 小版本):
# 安装 pyenv(需先装 gcc、openssl-devel、zlib-devel) curl https://pyenv.run | bash export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)" # 安装 Python 3.11.9 并设为全局 pyenv install 3.11.9 pyenv global 3.11.9 python --version # 必须输出 3.11.9 pip install --upgrade pip==23.3.1 # 注意:pip 24.x 会导致 Dify 依赖解析失败提示:
pip install -r requirements.txt报ModuleNotFoundError: No module named 'setuptools'?不是缺 setuptools,是 pip 版本太高。降级到 23.3.1 后重试。
2.2 数据库与缓存服务:PostgreSQL 12 + Redis 6.2 是社区版 1.10 的硬性底座
Dify 1.10 不支持 PostgreSQL 15+(会触发pg_stat_statements扩展加载失败),也不兼容 Redis 7(redis-py4.6.x 与 Redis 7 的 RESP3 协议有 handshake 冲突)。必须锁定版本:
# PostgreSQL 12 安装(CentOS 7) yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm yum install postgresql12-server /usr/pgsql-12/bin/postgresql-12-setup initdb systemctl enable postgresql-12 systemctl start postgresql-12 # 创建 Dify 数据库(注意:必须用 UTF8 编码) sudo -u postgres psql -c "CREATE DATABASE dify ENCODING 'UTF8' LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8';" sudo -u postgres psql -c "CREATE USER dify WITH PASSWORD 'StrongPass123!';" sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE dify TO dify;" # Redis 6.2 安装 wget http://download.redis.io/releases/redis-6.2.6.tar.gz tar xzf redis-6.2.6.tar.gz cd redis-6.2.6 && make && make install redis-server --daemonize yes --port 6379 --bind 127.0.0.1 --protected-mode no2.3 Dify 核心服务部署:用 docker-compose.yml 绑定具体镜像 SHA,拒绝 latest 标签
Dify 社区版 1.10 的latest镜像实际指向每日构建快照,常含未修复 bug。必须用官方 GitHub Release 页面标注的SHA256 值拉取确定版本(截至 2024-06,1.10.0 对应sha256:4a7b8e9f1c2d...):
# docker-compose.yml(精简关键字段) version: '3.8' services: api: image: ghcr.io/langgenius/dify-api:1.10.0@sha256:4a7b8e9f1c2d... environment: - DB_URL=postgresql://dify:StrongPass123!@postgres:5432/dify - REDIS_URL=redis://redis:6379/0 - WEAVIATE_ENDPOINT=http://weaviate:8080 - UNSTRUCTURED_API_URL=http://unstructured:8000/general/v0/general - SECRET_KEY=your_32_char_secret_here depends_on: - postgres - redis - weaviate - unstructured web: image: ghcr.io/langgenius/dify-web:1.10.0@sha256:7c3d9e2a5f1b... environment: - API_URL=http://api:5001 depends_on: - api # 关键:unstructured 服务必须用 0.10.14 版本,否则报 unstructured api url not configured unstructured: image: unstructured-io/unstructured-api:0.10.14 environment: - UNSTRUCTURED_API_KEY=dify_unstructured_key - PORT=8000 ports: - "8000:8000" # Weaviate 必须用 1.23.7(1.24+ 会因 gRPC 协议变更导致 Dify 连接超时) weaviate: image: semitechnologies/weaviate:1.23.7 environment: - QUERY_DEFAULTS_LIMIT=25 - AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=false - PERSISTENCE_DATA_PATH=/var/lib/weaviate - DEFAULT_VECTORIZER_MODULE=text2vec-openai - ENABLE_MODULES=text2vec-openai,ref2vec-centroid - CLUSTER_HOSTNAME=node1 volumes: - ./weaviate_data:/var/lib/weaviate参数说明:
UNSTRUCTURED_API_URL必须精确到/general/v0/general(不是/health或/),且 protocol 用http(不是https);WEAVIATE_ENDPOINT末尾不能加/,否则 Dify 初始化时会拼出http://weaviate:8080//v1/导致 404。
2.4 Nginx 反向代理配置:解决dify ssl error和跨域登录失败
Dify Web 前端默认监听http://localhost:3000,API 服务监听http://localhost:5001。若直接暴露 5001 端口,浏览器会因混合内容(HTTP API + HTTPS 页面)拦截请求,触发SSL error。必须用 Nginx 统一走 HTTPS,并透传 WebSocket:
# /etc/nginx/conf.d/dify.conf upstream dify_api { server 127.0.0.1:5001; } upstream dify_web { server 127.0.0.1:3000; } server { listen 443 ssl http2; server_name dify.yourcompany.com; ssl_certificate /etc/letsencrypt/live/dify.yourcompany.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/dify.yourcompany.com/privkey.pem; location / { proxy_pass http://dify_web; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /api/ { proxy_pass http://dify_api; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /ws/ { proxy_pass http://dify_api; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; } }注意:
location /api/的斜杠必须保留,否则 Dify 前端发POST /api/chat-messages会被 Nginx 改写成POST /chat-messages,触发 404。
3. 知识库流水线深度配置:用 DSL 编排实现制度文档的精准切分、敏感信息脱敏、多源异构数据融合
Dify 的知识库不是“上传 PDF → 自动生成 embedding → 开始问答”这么简单。制造业制度文档有三大特征:(1)PDF 内含扫描件与文字混排;(2)条款中嵌套大量“第X条第X款”交叉引用;(3)附件表格需单独提取结构化数据。若用默认设置,会出现“问‘离职补偿标准’返回整章劳动关系条款”、“查‘危化品存储温度’却命中采购流程描述”等低质结果。必须通过Knowledge Processing Pipeline(KPP)DSL重定义处理链。
3.1 文档解析策略:为扫描 PDF 启用 OCR,为文字 PDF 关闭 OCR 以提速
Dify 默认对所有 PDF 启用unstructured的pdfstrategy,但对扫描件无效。需在知识库创建时手动指定file_processing_rules:
# knowledge_config.yaml(上传知识库时作为高级配置粘贴) file_processing_rules: pdf: strategy: "auto" # auto 会自动检测是否为扫描件,启用 OCR infer_table_structure: true # 对含表格的 PDF 启用表格识别 extract_images: false # 不提取图片(避免 OCR 误读图表) docx: strategy: "fast" # 文字型 DOCX 用 fast 模式,跳过 OCR txt: strategy: "fast"血泪经验:
strategy: "ocr"强制 OCR 会导致纯文字 PDF 解析速度下降 5 倍,且 OCR 结果常含乱码;infer_table_structure: false会让表格变成一团乱码文本,无法用于后续结构化查询。
3.2 Chunk 切分逻辑:用正则锚点替代固定长度,确保条款完整性
Dify 默认按 500 字符切分 chunk,但制度文档的“第十二条:……”可能被截断在句中。必须用chunking_strategy: "hierarchy"并定义锚点:
# 在知识库高级设置中填写 JSON 格式 { "chunking_strategy": "hierarchy", "hierarchy_chunk_config": { "heading_level": 2, "max_length": 2000, "overlap": 200, "separators": ["\\n## ", "\\n### ", "\\n#### "], "keep_separator": true } }参数说明:
heading_level: 2表示以##开头的二级标题为 chunk 主边界(对应制度中的“第二章 组织职责”);separators数组定义更细粒度分割符(如###对应“第十二条”);keep_separator: true确保每个 chunk 开头保留标题,避免语义丢失。
3.3 敏感信息脱敏:在 embedding 前注入正则替换节点
制度文档常含“联系人:张三(138****1234)”、“地址:XX市XX区XX路1号”。若直接 embedding,LLM 可能复述手机号。Dify 的 DSL 允许在 pipeline 中插入text_replace节点:
# pipeline.yaml(知识库流水线自定义 DSL) version: "1" nodes: - id: "parse" type: "document_parser" config: parser_type: "unstructured" - id: "replace_phone" type: "text_replace" config: pattern: "\\b1[3-9]\\d{9}\\b" replacement: "[PHONE]" scope: "content" upstream: ["parse"] - id: "replace_address" type: "text_replace" config: pattern: "地址:[^\\n]+" replacement: "地址:[ADDRESS]" scope: "content" upstream: ["replace_phone"] - id: "chunk" type: "chunker" config: chunking_strategy: "hierarchy" hierarchy_chunk_config: heading_level: 2 max_length: 2000 upstream: ["replace_address"] - id: "embed" type: "embedding" config: model: "text-embedding-ada-002" # 或本地 bge-m3 upstream: ["chunk"]注意:
scope: "content"表示仅替换文档正文,不触碰 metadata(如文件名、上传时间);pattern必须用双反斜杠转义,否则 YAML 解析失败。
3.4 多源数据融合:将 Excel 附件表格转为向量,与 PDF 主文档联合检索
制度文档常附《供应商考核评分表.xlsx》。Dify 默认忽略附件。需在知识库上传时勾选“解析附件”,并在 DSL 中添加table_extractor节点:
# pipeline.yaml(续) - id: "extract_table" type: "table_extractor" config: table_format: "markdown" # 转为 Markdown 表格,保留行列结构 max_rows: 1000 upstream: ["parse"] - id: "table_to_text" type: "table_to_text" config: include_headers: true separator: " | " upstream: ["extract_table"] - id: "table_chunk" type: "chunker" config: chunking_strategy: "fixed" fixed_chunk_config: chunk_size: 500 chunk_overlap: 50 upstream: ["table_to_text"] - id: "table_embed" type: "embedding" config: model: "text-embedding-ada-002" upstream: ["table_chunk"]关键点:
table_to_text节点将表格转为带|分隔的文本,使 LLM 能理解行列关系;table_chunk必须用fixed策略(非hierarchy),因表格无标题层级。
4. 智能体应用构建实战:用变量赋值 + 条件路由打造“制度条例学习助手”,支持工号绑定、部门过滤、条款溯源
标题里的“实战案例”不是演示 Hello World,而是交付一个能嵌入企业微信、对接 HR 系统、支持审计追溯的生产级应用。核心是Variable Assignment(变量赋值)和Conditional Routing(条件路由)两大能力,它们让 Dify 超越静态问答,成为可编程的智能体。
4.1 用户上下文注入:用变量节点自动获取工号并注入检索 query
制度问答需区分权限:普通员工只能查通用条款,安全部门可查《危化品应急预案》全文。Dify 不提供 LDAP 直连,但可通过 Webhook 传递用户标识。我们在企业微信机器人回调 URL 中附加?user_id=ZhangSan&dept_id=SAFETY,然后在应用编排中用variable_assignment节点提取:
# app_dsl.yaml(应用工作流 DSL) nodes: - id: "get_user_context" type: "variable_assignment" config: variables: user_id: "{{ request.query_params.user_id }}" dept_id: "{{ request.query_params.dept_id }}" current_time: "{{ now() }}" upstream: [] - id: "build_retrieval_query" type: "variable_assignment" config: variables: retrieval_query: > {{ request.query }} {% if dept_id == 'SAFETY' %} AND (source: 'safety_manual' OR source: 'emergency_plan'){% endif %} {% if dept_id == 'HR' %} AND (source: 'hr_policy' OR source: 'contract_template'){% endif %} upstream: ["get_user_context"] - id: "retrieval" type: "retriever" config: knowledge_ids: ["k-123abc", "k-456def"] # 预置的知识库 ID 列表 query: "{{ retrieval_query }}" top_k: 5 upstream: ["build_retrieval_query"]逻辑说明:
{{ request.query_params.user_id }}从 HTTP 请求 URL 参数中提取;{% if ... %}是 Jinja2 条件语法,动态拼接 Elasticsearch 查询字符串;source字段需在知识库元数据中预先打标(上传时设置metadata: {"source": "safety_manual"})。
4.2 条件路由实现多意图分流:当用户问“怎么报销”时自动跳转财务流程图
用户提问常含隐含意图:“报销”→ 查《费用管理办法》+ 返回流程图,“离职”→ 查《劳动合同解除指引》+ 返回 HR 联系方式。Dify 的condition_router节点可基于关键词或 LLM 分类:
- id: "intent_classifier" type: "llm" config: model: "gpt-3.5-turbo" prompt_template: | 你是一个制度问答意图分类器。请从以下类别中选择最匹配的一个: - reimbursement(报销) - resignation(离职) - safety_training(安全培训) - other(其他) 用户问题:{{ request.query }} 输出格式:reimbursement temperature: 0.1 upstream: ["retrieval"] - id: "route_by_intent" type: "condition_router" config: conditions: - condition: "{{ intent_classifier.output == 'reimbursement' }}" downstream: ["fetch_reimbursement_flow"] - condition: "{{ intent_classifier.output == 'resignation' }}" downstream: ["fetch_resignation_contact"] - condition: "{{ intent_classifier.output == 'safety_training' }}" downstream: ["fetch_training_schedule"] - condition: "true" downstream: ["default_answer"] upstream: ["intent_classifier"]参数说明:
temperature: 0.1降低 LLM 随机性,确保分类稳定;downstream指向不同节点,如fetch_reimbursement_flow可是一个http_request节点,调用内部 OA 系统 API 获取最新报销流程图 SVG。
4.3 条款溯源与引用生成:让每条回答都带原文页码和条款编号
审计要求:所有 AI 回答必须可追溯至原始制度文件。Dify 默认返回chunk_content,但不带位置信息。需在retriever节点后接入citation_generator:
- id: "generate_citation" type: "citation_generator" config: citation_style: "footnote" include_page_number: true include_section_title: true upstream: ["retrieval"] - id: "format_answer" type: "llm" config: model: "gpt-3.5-turbo" prompt_template: | 你是一个制度解读助手。请根据以下检索结果,用中文简洁回答用户问题。 检索结果: {% for doc in generate_citation.output %} [{{ loop.index }}] {{ doc.content }}({{ doc.metadata.source }} 第{{ doc.metadata.page }}页) {% endfor %} 用户问题:{{ request.query }} 回答要求:必须引用检索结果中的原文,用 [1]、[2] 标注来源,禁止编造。 temperature: 0.3 upstream: ["generate_citation"]关键点:
citation_style: "footnote"生成[1]格式;include_page_number: true依赖 unstructured 解析时输出的page_number字段(PDF 文字版默认有,扫描件需 OCR 后才有);prompt_template中的{% for %}循环确保所有检索结果都被喂给 LLM。
5. 避坑指南:Dify 生产环境最常踩的 4 个坑及根治方案
部署和配置只是开始,真实运行中会遇到大量“看似配置正确、实则静默失效”的陷阱。以下是我在 7 个客户现场反复验证的 4 个致命坑,每个都附带现象、根因和可执行的根治命令。
5.1 现象:知识库更新后,新上传文档完全不参与检索,旧文档仍能召回
原因:Dify 的knowledge_indexing任务默认使用celery异步队列,但celery worker进程未启动或与api服务网络不通,导致 indexing 任务堆积在 Redis 队列中永不执行。
解决:
# 登录服务器,检查 celery worker 是否运行 docker ps | grep celery # 若无输出,手动启动 worker(需在 docker-compose.yml 中定义 celery service) docker-compose up -d celery # 强制重跑所有 pending indexing 任务(进入 api 容器执行) docker exec -it dify_api_1 bash cd /app && python manage.py reindex_knowledge --all5.2 现象:dify an error occurred during credentials validation错误持续弹出,无法登录
原因:Dify 的SECRET_KEY在.env文件中被修改后,Redis 中已加密的 session token 无法解密,触发凭证校验失败。这不是密码错误,而是密钥不匹配。
解决:
# 清空 Redis 中所有 session 数据(不影响知识库和用户数据) redis-cli -h 127.0.0.1 -p 6379 FLUSHDB # 重启 api 服务使新 SECRET_KEY 生效 docker-compose restart api5.3 现象:上传 DOCX 文件后,知识库显示“Processing”,但 30 分钟后仍卡在 0%,日志报unstructured api url is not configured
原因:Dify 容器内 DNS 解析失败,无法访问同 compose 网络下的unstructured服务。docker-compose默认网络 DNS 有时不生效。
解决:
# 修改 docker-compose.yml,在 api 服务下添加 dns 配置 services: api: # ... 其他配置 dns: - 127.0.0.11 # Docker 内置 DNS - 8.8.8.8 extra_hosts: - "unstructured:172.20.0.3" # 手动绑定,用 docker network inspect 获取实际 IP5.4 现象:向量检索返回结果相关性极低,“问安全生产法返回消防条例”
原因:Weaviate 的text2vec-openai模块未正确加载,Dify 后台实际使用了默认的text2vec-cohere,但该模型未在 Weaviate 中配置 API Key,导致 embedding 全为零向量。
解决:
# 进入 Weaviate 容器,检查模块状态 docker exec -it dify_weaviate_1 bash curl http://localhost:8080/v1/modules # 若 text2vec-openai 显示 "enabled": false,则编辑 Weaviate 配置 # 修改 docker-compose.yml 中 weaviate 的 environment,添加: - DEFAULT_VECTORIZER_MODULE=text2vec-openai - OPENAI_APIKEY=sk-xxx # 替换为真实 key - ENABLE_MODULES=text2vec-openai,ref2vec-centroid # 重启 Weaviate 并重建索引 docker-compose restart weaviate docker exec -it dify_api_1 python manage.py reindex_knowledge --all6. 进阶技巧:用 Dify 的「变量赋值」+ 「HTTP 请求」节点,把制度助手无缝嵌入 OA 审批流
最后这个技巧,是我帮客户把制度助手从“演示系统”变成“每日必用工具”的关键转折点。他们原来的 OA 审批流中,采购申请单需人工核对《供应商准入标准》第 5.2 条,平均耗时 8 分钟/单。我们用 Dify 的variable_assignment和http_request节点,在审批提交按钮旁加了一个“自动核验”按钮,点击即返回结构化结论。
6.1 审批单数据实时注入:从 OA 系统 URL 中提取采购单号,反查制度条款
OA 系统跳转到 Dify 助手时,URL 形如https://dify.yourcompany.com/app/procure-check?form_id=PO-2024-00123。我们在 Dify 应用 DSL 中这样处理:
# app_dsl.yaml(采购核验专用应用) nodes: - id: "get_form_id" type: "variable_assignment" config: variables: form_id: "{{ request.query_params.form_id }}" upstream: [] - id: "fetch_oa_data" type: "http_request" config: method: "GET" url: "https://oa.yourcompany.com/api/forms/{{ form_id }}" headers: Authorization: "Bearer {{ secrets.OA_TOKEN }}" # OA 系统 token 存于 Dify Secrets timeout: 10 upstream: ["get_form_id"] - id: "extract_supplier_name" type: "variable_assignment" config: variables: supplier_name: "{{ fetch_oa_data.response_json.supplier_name }}" product_category: "{{ fetch_oa_data.response_json.product_category }}" upstream: ["fetch_oa_data"] - id: "build_rule_query" type: "variable_assignment" config: variables: rule_query: > 供应商 {{ supplier_name }} 属于 {{ product_category }} 类别, 请返回《供应商准入标准》中关于该类别供应商的准入条款, 重点包括资质要求、信用评级、现场审核频次。 upstream: ["extract_supplier_name"]注意:
{{ secrets.OA_TOKEN }}是 Dify 后台 “Secrets” 功能中预存的加密凭证,避免硬编码在 DSL 中;fetch_oa_data.response_json是 Dify 自动解析的 JSON 响应体。
6.2 结构化输出生成:用 LLM 提取条款编号,生成可点击的 OA 内链
用户不需要一段文字,而是一个带跳转的结论:“✅ 符合要求:依据《供应商准入标准》第 5.2.1 条,贵司信用评级达标”。我们用 LLM 提取条款编号,并生成 OA 系统内链:
- id: "extract_clause" type: "llm" config: model: "gpt-3.5-turbo" prompt_template: | 你是一个制度条款提取器。请从以下文本中,精准提取所有被引用的条款编号(如“第5.2.1条”、“第五章第二节”),只输出编号,用逗号分隔,不要解释。 文本:{{ retrieval.output }} temperature: 0 upstream: ["retrieval"] - id: "generate_oa_link" type: "variable_assignment" config: variables: oa_link: > {% set clauses = extract_clause.output.split(',') %} {% for clause in clauses %} <a href="https://oa.yourcompany.com/policy#{{ clause|replace('第','')|replace('条','')|replace(' ','') }}">[{{ clause }}]</a>{% if not loop.last %}、{% endif %} {% endfor %} upstream: ["extract_clause"] - id: "final_output" type: "answer" config: answer: > ✅ 自动核验通过:<br> {{ oa_link }}<br> 详细依据:<br> {{ retrieval.output }} upstream: ["generate_oa_link"]关键点:
{{ clause|replace(...) }}是 Jinja2 过滤器,将“第5.2.1条”转为5.2.1,匹配 OA 系统锚点;<a href>生成的链接可直接在 Dify Web 界面点击跳转。
6.3 性能与审计保障:为每次核验生成唯一 trace_id,写入审计日志表
所有自动化操作必须可追溯。我们在http_request节点后加一个database_writer,把 trace_id、form_id、核验结果写入 PostgreSQL 审计表:
- id: "log_audit" type: "database_writer" config: db_url: "postgresql://audit:pass@postgres:5432/audit_db" table_name: "procurement_audit_log" columns: trace_id: "{{ uuid() }}" form_id: "{{ form_id }}" supplier_name: "{{ supplier_name }}" result_summary: "{{ final_output.answer }}" created_at: "{{ now() }}" upstream: ["final_output"]血泪教训:上线前必须在 OA 系统侧配置 CORS,允许
https://dify.yourcompany.com调用其 API;否则http_request节点会因浏览器同源策略失败。这不是 Dify 的错,但常被忽略。
我把这套方案落地到第三家客户时,他们采购部经理说:“以前新人培训要背 3 天制度,现在扫码问一句就出答案,还带条款链接。这哪是 AI 工具,这是我的后悔药。” —— 技术的价值,从来不在模型多大、参数多高,而在它能不能让一线的人,少翻一页纸、少打一个电话、少犯一次错。希望帮到你。
本文还有配套的精品资源,点击获取