
银行做智能客服最难的不是把大模型接进来而是让它在几十个产品线、几百篇制度文档、上千条话术里每次都答得准、答得合规、答得像一个训练有素的坐席。我最近在做的这个项目就是用 Dify 从零搭了一套银行智能客服核心链路就是两件事先把用户意图识别做扎实再用多 RAG 架构把分散的知识源管起来。这篇文章把我整个选型、搭建、踩坑的过程完整记录下来给正在用 Dify 做知识库问答、智能客服或者金融行业 AI 落地的朋友一个可参考的路线图。1. 为什么是 Dify为什么是多 RAG先回答一个很多人会问的问题银行项目为什么不用 LangChain 直接写而是选 Dify我的答案很简单因为银行的智能客服从来不只是“技术问题”它是产品、风控、客服运营和研发多方协作的业务系统。Dify 的可视化工作流让非技术同事也能看得懂调用链甚至能一起调提示词、调知识库配置这一点在跨部门项目里比什么都重要。1.1 银行客服场景的隐性需求很多人以为银行客服就是“用户问余额机器人答余额”真做起来才发现隐性需求比显性需求多得多。第一是知识域极度分散。存款、贷款、信用卡、理财、网银、ATM、费率、网点信息每个业务线都有自己的文档体系产品参数还经常变。如果所有文档都塞进一个知识库里检索时彼此干扰极其严重。第二是合规要求极高。客服话术不能乱承诺收益不能代替法律条款不能泄露他人隐私高危操作比如挂失、投诉必须能一键转人工。这意味着系统不能只追求“答得对”还要能追溯、能审计、能兜底。第三是知识更新节奏快。银行每隔一段时间就有新的活动、新的利率、新的产品上线知识库如果更新不及时AI 就会拿旧话术去糊弄客户后果很麻烦。所以知识库的更新流程必须设计成可持续运转的而不是上线那天人工导一次就完事。第四是知识召回的质量要求高。银行术语重叠严重同样是“提前支取”活期、定期、大额存单、理财产品的规则完全不同同样是“利息”存款和贷款是天壤之别。这种场景下语义相似的文档越多召回阶段的噪声就越大。这些需求叠加在一起基本就回答了一个问题为什么不能只做一个“把所有文档灌进去的 RAG”。因为单库 RAG 在知识量大、领域分叉多的场景下精度会快速下降。后续我会专门讲多 RAG 怎么解决这个问题。1.2 Dify 的选型逻辑我在选型阶段对比过 LangChain、Langflow、Dify 和一些商业客服平台最终选择 Dify 社区版核心是下面这几条理由。第一可视化工作流与提示词编排能力。Dify 把大模型应用拆成了“工作流画布”意图识别、知识检索、答案生成、条件分支都可以用节点拖出来不需要写几百行编排代码。对银行这种需要反复评审和调整话术的场景改动成本低很多。第二模型接入自由度高。项目早期我可以用 Ollama 拉本地模型做开发和演示后期换成在线模型 API 只需要改模型配置不用动业务逻辑。Dify 对 Embedding 模型、Rerank 模型也都支持这一点在做多 RAG 架构时是刚需。第三知识库管理能力强。Dify 支持多知识库、分段、清洗、父子分块、混合检索等多种配置还支持通过 API 或工作流往知识库里写入结构化数据。热词里提到的“知识库流水线”在 Dify 1.17.1 版本里变得更完整可以把文档解析、分段、索引、更新做成自动化流程。第四多租户与会话隔离。Dify 社区版 1.10 版本以后引入了多租户能力对银行这种不同部门、不同业务线需要隔离知识库和权限的场景很实用。加上数据是存在自己的服务器上的方便内部审计。第五部署相对轻量。Docker Compose 一键拉起整个系统包含 API 服务、Worker、Web 前端、PostgreSQL、Redis、向量数据库对中小型项目来说完全能撑得住。1.3 整体架构总览项目整体架构我按数据流向分为四层这里用文字把关键链路描述清楚方便后面理解每一节的定位。渠道层负责接入来自 App、微信公众号、网页客服的消息Dify 应用层承担核心对话编排用户消息进入后会先做意图识别识别结果决定走哪条知识检索分支模型层统一管理 LLM、Embedding、Rerank 三套模型数据层则分为结构化业务数据库、文件型知识库和向量索引库三层。关键调用路径是这样的用户提问 → 预处理与变量提取 → 意图识别 → 定位知识域 → 多路 RAG 检索 → 结果合并与重排 → 答案生成 → 合规检查 → 输出或转人工。整条链路全部在 Dify 的一个工作流里完成这样每步都可以单独调试上线后也方便定位问题是出在意图识别还是检索环节。2. 意图识别AI 客服的第一道闸门意图识别是整个客服系统的入口直接决定后续走哪条知识管道。这里我采用了一种“AI 意图识别架构”不靠传统 NLU 小模型而是让 LLM 基于预设的意图分类规则做判断配合条件分支完成路由。2.1 传统 NLU 与 LLM 意图识别的取舍在做 Dify 方案之前我们尝试过传统的 NLU 方案也就是训练一个轻量的意图分类模型把用户问题分到十几个预设槽位里。这个方案的问题是显而易见的银行业务话术翻新太快每上一个新产品就要重新标注、重新训练用户表达太随意“我钱怎么少了”和“请查询我的账户余额”在语义上是同一件事但在传统 NLU 里就是两个不同的问题。LLM 意图识别的优势在于只需要在提示词里把意图类别枚举清楚再给几个示例就能处理绝大多数情况。对没见过的表达方式也有一定的泛化能力。Dify 有内置的意图分类节点也可以用 LLM 节点配合结构化输出来实现灵活度更高。我对意图识别的一个核心理解是意图分类和后续知识域路由要解耦。意图回答的是“用户想干什么”知识域回答的是“该去哪找答案”。两者相关但不能混为一谈。比如用户说“我想查定期存款利率”意图是“利率查询”知识域是“存款产品库”用户说“信用卡逾期了怎么办”意图是“逾期处理”知识域是“信用卡制度库”。如果意图直接对应知识域分类体系的维护成本会急剧膨胀不划算。2.2 意图分类的落地配置我在 Dify 里用的是自定义 LLM 节点来做意图分类而不是直接套用内置的简单分类器因为银行场景需要更精细的控制。意图类别我会按照业务域划分并用代码编号命名方便后续分支条件精确匹配intent_balance余额查询、交易明细查询intent_transfer转账、汇款相关问题intent_card信用卡申请、额度、还款、账单intent_deposit存款业务定期、活期、大额存单intent_loan贷款业务利率、还款、提前还款intent_account开户、销户、资料变更、密码重置intent_report挂失、冻结、高风险操作intent_complaint投诉、建议、人工客服intent_greeting寒暄、开场白intent_unknown无法归类的开放问题在提示词里我会给出每一个类别的详细定义和典型示例并明确要求模型输出严格的 JSON 格式比如 {intent: intent_deposit, confidence: 0.9, entities: {...}}这样后续分支条件可以直接读取变量不用再解析自然语言。Temperature 我设置为 0.2保证分类结果稳定避免同一句话两次问得到不同意图。这里有个很关键的坑意图识别节点不能只输出意图名称还要输出一个“意图外的自由文本描述”。比如用户说“我昨天在 ATM 上取钱卡被吞了怎么拿回来”意图是 report但后续知识检索时如果只拿“intent_report”去做 query召回效果会很差。我会把用户原始问题完整保留作为知识库检索的 query 变量。2.3 意图识别之后的路由策略意图识别完成后我用 Dify 的条件分支节点做路由。分支逻辑并不只是根据意图字段简单分流还要配合置信度和业务风险等级一起判断。正常路径中查询类意图查余额、查利率直接走对应知识库的检索分支高风险意图挂失、投诉、账户冻结不直接给最终答复而是先输出安抚话术同时把会话标记为“转人工优先”让系统在答案末尾附带人工坐席入口。低置信度意图也就是模型输出 confidence 低于阈值的情况走兜底分支回复标准话术并询问用户是否转人工。这里还有一个业务上的细节银行的高风险意图不能全自动闭环。比如信用卡挂失即使 AI 能从知识库找到挂失流程也一定要让用户确认“是否转人工办理”因为挂失涉及身份核验和法律责任不能由模型凭记忆操作。这是合规红线务必提前跟业务方确认清楚。3. 多 RAG 架构把“一个知识库”拆成“一组知识管道”多 RAG 架构是整个项目的核心也是“检索效果差”这类问题最有效的解法。简单说就是把一个臃肿的知识库拆成多个有边界的知识库再通过意图识别、路由、多路召回和重排来保证质量。3.1 单库 RAG 为什么在银行业不够用我相信很多人一开始的做法是把所有文档一股脑丢进 Dify建一个巨大的知识库然后发现检索效果时好时坏。这在知识量小的时候没问题但一旦文档数量上去问题就非常明显。核心矛盾在于TopK 检索是在全部文档里找语义相似的片段而不是在“当前问题所属的领域”里找。银行文档里“利息”“支取”“风险”这类词到处都是用户问的是“大额存单提前支取有什么损失”结果向量检索同时返回了理财产品的风险提示、贷款的提前还款条款、定期的部分支取规则。这些内容不能说完全无关但它们混在一起LLM 在生成答案时很容易被带偏。单库 RAG 的第二个问题是知识权限没法隔离。银行的内部制度和面向客户的话术严格来说不应该放在同一个检索空间里。一旦内部制度被检索出来生成的回复就可能包含不该说的内容。多知识库配合路由天然就解决了这个问题。3.2 多 RAG 的三种落地形态在实际项目里我根据不同的业务需求做了三种多 RAG 形态这里分别说明一下。形态一是基于路由的 RAG也就是“意图或知识域路由 → 只去对应的子知识库检索”。这是最常见、最稳的做法。用户问信用卡就只检索信用卡知识库问存款就只检索存款知识库。路由条件可以是意图输出也可以是对用户问题再做一次知识域分类。优点是精度高、速度快、成本低缺点是如果路由错了后续所有检索都是白费。形态二是多路召回合并的 RAG适合用户问题本身横跨多个知识域的情况。比如用户问“我理财到期了想转成定期哪个划算”这个问题既涉及理财库又涉及存款库。我会用“多条知识检索节点并行”的方式同时从两个知识库里检索把结果合并后再交给 Rerank 和 LLM 做综合判断。形态三是知识库流水线适合更深度的问答场景。先在一个“索引知识库”里检索定位到用户问题属于哪本制度文档再根据文档路径或元数据去对应的知识库做精确检索。这个很像图书馆先查目录再进书库取书的流程适合银行这种文档体系非常严格的场景。Dify 的知识检索节点天然支持挂多个知识库也支持配置多路召回所以这三种形态都能在一个工作流里实现。关键是把“路由变量”和“检索条件”设计清楚。3.3 知识准备从原始文档到可检索的分块一个多 RAG 系统的好坏一半取决于知识库本身的数据质量。文档解析、分段、索引这三步每一步都会直接影响检索效果。第一步是解析。银行给过来的文档经常是 PDF 扫描件、Excel 台账、Word 制度文直接扔给 Dify 处理往往效果很差。我们引入 MinerU 这类文档解析工具把 PDF 转成结构清晰的 Markdown表格转成 Markdown 表格再导入知识库。这个预处理非常关键很多“检索效果差”其实是文档解析阶段就丢了信息。第二步是分块。Dify 支持父子分块策略就是父块保留较大上下文子块做精细匹配。我的经验是父块按章节切大概 800 到 1200 字子块按段落切大概 200 到 300 字相邻块之间保留少量重叠避免关键信息被切断。区分“检索命中”和“上下文供给”两个角色子块负责命中父块负责给 LLM 提供完整上下文。第三步是索引和元数据管理。每个知识库我都要求业务方按照预设字段维护元数据比如文档类型、所属业务线、更新日期、适用渠道。Dify 知识库可以设置元数据过滤条件这样在多路召回时可以只检索“当前渠道生效”的规则。这在银行场景里很实用因为柜面、网银、手机银行的政策不完全相同。3.4 混合检索与 Rerank 的实操细节Dify 里的知识检索节点支持三种模式向量检索、全文检索、混合检索。刚开始我们只开向量检索结果一些包含精确产品或制度编号的查询召回效果很差。后来把检索模式切到混合检索也就是向量 全文关键词双双召回再合并去重召回率明显提升。这里的原理不复杂向量检索擅长处理语义相似但遇到精确编号和合规条款时关键词匹配往往更可靠。接着就是 Rerank。多路召回后结果列表里会有大量候选片段直接交给 LLM 会出现两个问题一是超出上下文窗口二是“淹没在无关信息里”。我的做法是在 Dify 的知识检索节点上开启 Rerank 配置接入一个 bge-reranker 模型。Rerank 会对候选片段重新计算与查询的相关性把最相关的内容排到最前面这样答案生成的输入质量会高一大截。关于 Score 阈值我最终定在 0.35 左右。阈值设太高比如 0.6很多本来是正确答案的片段会被过滤掉导致知识库“答不上来”阈值设太低比如 0.1检索结果会混入大量噪声。0.35 这个值是我们跑了几百条真实问题后找到的一个平衡点。不同业务的知识库可以单独调没有一刀切的万能值。4. 用 Dify 工作流串起整个客服链路前面讲了架构和原理这一节我完整地走一遍实操流程从部署开始到工作流编排给你一套可以直接抄作业的步骤。4.1 部署与基础准备Dify 的本地部署其实不难但有几个细节常坑人。Dify 官方提供 Docker Compose 方式我是这样做的从官网下载社区版源码包解压后进入 dify-main 的 docker 文件夹在该路径下打开命令行先执行cp .env.example .env生成环境变量文件然后按需修改 .env 里的配置比如部署端口、密钥、向量库类型等。最后执行docker compose up -d启动所有服务。拉取镜像失败是新手最容易卡住的地方。常见原因是终端环境与 Docker Hub 的连接不稳定。我的建议是配置 Docker 镜像加速地址再重新拉取如果仍然不行可以考虑在有网络条件的环境下载镜像后导出导入也可以改用国内能访问的镜像源。这个环节不用急慢一点能避免后面一堆问题。模型接入方面我用了两套方案并存。开发环境用 Ollama 拉取本地大模型比如 qwen2.5:14b配置到 Dify 的模型供应商里即可生产环境则切换到在线模型 API。Embedding 和 Rerank 模型我同样通过 Ollama 或模型供应商接入。Dify 里配置模型的路径在“设置→模型供应商”把 API 地址和模型名称填对然后做一次测试连通即可。热词里有人问“LM Studio 接入 Dify”“离线安装 Ollama 插件”这类问题其实路径是一样的。Dify 支持 OpenAI 兼容的 API 协议LM Studio 和 Ollama 都兼容这个协议只要在自定义模型配置里把 Base URL 指到本地服务的地址就行。4.2 知识库创建与文档导入知识库层面我拆了五个库分别是产品知识库、流程制度库、话术规范库、应急预案库和公共 FAQ 库。每一个库对应一个业务域设置独立的检索配置和描述信息这样在后续知识检索节点里选择知识库时能清楚地知道“这个库是干嘛的”。文档导入我分了两条路径。一条是离线文档直接在 Dify 后台上传 PDF、Markdown 或 Word配置好分段规则和索引方式让系统自动建立索引。另一条是外部结构化数据比如业务系统里的产品参数表、利率表我先用工作流或脚本把数据从数据库读取出来转换成规范格式再通过 Dify 的知识库 API 写入这样能实现定时更新。上传文档之后尤其要注意“重新索引”这一步。Dify 在你修改知识库内容后需要触发重新索引否则检索用的还是旧向量。我在上线初期吃过这个亏文档更新了但线上回答没变化排查了半天才发现是没重新索引。4.3 对话型应用与工作流编排核心工作流我是在“对话型应用”里编排的。起始节点接收用户输入同时可以定义一些会话变量比如用户 ID、渠道来源、是否命中转人工等。紧接着是意图识别节点把用户原始问题和会话变量传进去得到意图分类结果。然后是条件分支节点。根据意图分类结果分别进入不同的知识检索链路。比如 intent_deposit 进入存款产品知识库检索intent_loan 进入贷款制度库检索每个知识检索节点独立配置 query、TopK、Score 阈值和 Rerank 开关。如果是多路召回我会同时启用多个知识检索节点再把结果用变量聚合器拼成一个“候选上下文”列表统一传给后续节点。答案生成节点是最终的话术出口。这里提示词编排比较讲究我给它的指令是基于“候选上下文”回答严格遵循上下文中的业务规则当上下文不足以支撑答案时明确回复“该问题需要人工确认”不得自行编造利率、期限、费用等数据回答风格要贴近银行客服话术。同时我会在提示词里强调“只输出对客户说的话不要输出检索过程”避免模型说出类似“根据我的知识库检索结果”这样的话。人工接管逻辑我放在答案生成之后。满足以下任一条件时系统会拼接一段“转人工提示”并输出用户明确要求人工服务、意图分类属于高风险的挂失或投诉类、RAG 检索结果为空且得分低于阈值、模型置信度过低。这段逻辑用条件分支节点实现非常直观。4.4 提示词编排怎么做热词里有人问“Dify 提示词编排怎么做”我简单说下我的方法。Dify 的提示词分为系统提示词和用户提示词两块。系统提示词里放角色设定、知识库检索结果、回答规则用户提示词就是当前用户的输入和变量。我习惯把提示词拆成三层。第一层是角色层定义它是银行智能客服助手服务规范是什么第二层是规则层列出硬性禁忌比如不能承诺收益、不能用绝对化表述、不能泄露隐私第三层是数据层引用知识检索结果并明确以它为唯一事实来源。每一层用分隔符隔开让模型清晰地区分“指令”和“内容”。实际测试中我发现提示词里“不要做什么”比“要做什么”更能影响模型行为。比如“不要编造数据”效果远好于“请你准确回答”。银行场景里宁可让 AI 说不知道也不能让它瞎猜这条规则要写在提示词最前面。5. 常见问题与排查技巧实录这一节把我实际遇到的高频问题整理成速查表再挑几个重点详细说。问题现象常见原因解决方案知识库检索效果差答案相关度低或答非所问文档分段不合理、未开混合检索、没配 Rerank检查分段策略、开混合检索、接入 Rerank 模型拉取镜像失败docker compose up 卡住无加速或镜像仓库不稳定配置镜像加速或离线导入镜像本地模型无法调用Ollama 报了 404Base URL 或模型名填错核对 OpenAI 兼容 API 地址与模型名称文档更新后回答不变线上仍是旧知识未重新索引知识库修改后触发重新索引意图识别不稳定相同问题不同分类Temperature 过高或示例不足降低温度、增加 few-shot 示例无法读取本地文件上传失败或解析失败文档格式非标准、扫描版 PDF先用 MinerU 转换再导入对接飞书失败授权凭证无效飞书应用权限未开通按文档申请云文档权限并获取凭证升级 Dify 后功能异常页面报错或任务卡死环境变量不兼容、数据库迁移失败升级前备份数据、按官方升级流程操作5.1 知识库检索效果差的排查思路检索效果差是最常见也最让人头疼的问题。我的排查顺序是这样先看“查得到吗”再看“排序对吗”。“查得到吗”是检查召回阶段。先在 Dify 知识库的“召回测试”里输入一条测试问题看返回的片段是否包含正确答案。如果完全不相关优先检查分段是否合理比如一个段落里塞了太多主题或者关键信息被分割到了两个块里。如果相关但得分很低优先检查是否开了混合检索以及 Embedding 模型对银行业术语的理解是否足够。“排序对吗”就是看 Rerank 做得怎么样。如果召回结果里正确答案排在十几名开外LLM 很容易忽略它。我碰到的情况是开启 Rerank 之后正确答案被大幅提前整体回答质量立马上来了。如果 Rerank 已经开了还是不行就检查 Rerank 模型本身的能力换一个更强的 reranker 试试。最后还有一个容易忽略的点提示词里的“候选上下文”是否完整传给了 LLM。有时候知识检索节点返回的结果很多但不代表答案生成节点都看到了要看变量传递有没有遗漏。5.2 模型与镜像相关问题热词里大量涉及“dify 拉取镜像失败”“dify 离线安装 ollama 插件”“lmstudio 接入 dify”这类问题我统一讲一下。Dify 本身是基于 Docker 部署的所以“拉取镜像失败”本质上就是 Docker 镜像拉不动。优先检查的一是加速地址有没有配置二是本地磁盘空间是否不足三是 Docker Desktop 是否正常启动。如果是离线环境那就需要在一台能上网的机器上把镜像拉下来导出再导入目标服务器。这个过程比较繁琐但确实是离线部署的常规做法。把 Ollama 或 LM Studio 作为本地大模型接入 Dify 时填写的 Base URL 很重要。Ollama 一般是http://localhost:11434/v1LM Studio 一般是http://localhost:1234/v1。很多 404 或连接失败问题就出在 Base URL 少了个/v1后缀。如果 Dify 和模型服务不在同一台机器记得把 localhost 换成实际 IP并确认防火墙放行了端口。5.3 升级 Dify 和去掉 Powered by Dify热词里有人问“dify 在线升级 windows”“dify 1.17.1 与 1.15.0”的区别还有“嵌入式如何把左下角 powered by dify 去掉”。我分别说下我的经验。Dify 升级确实要小心。我一般会先备份 docker 挂载的数据目录和数据库再拉取新版本镜像按官方文档执行数据库迁移。升级后我会重点测试工作流是否正常、知识库索引是否还在、模型配置是否失效。建议不要在业务高峰期动升级选在维护窗口做。关于去品牌标识我建议这种做法如果用的是社区版通常可以在系统设置里修改应用名称和品牌信息但底部的“Powered by Dify”是否允许移除取决于你用的版本和授权协议。如果是商业版本或企业授权可以放心自定义如果是社区版最好先确认许可要求避免合规风险。用开源软件时这种细节值得留心。5.4 飞书对接与外部数据导入银行项目里飞书是常见办公协作平台热词里也提到“dify 如何对接飞书”“首次使用飞书云文档的授权凭证如何取得”。Dify 支持把飞书云文档作为知识库数据源前提是要创建一个飞书应用开通云文档相关权限然后拿到 App ID、App Secret 等凭证填入 Dify 的飞书数据源配置里。权限要在飞书开放平台的后台逐项勾选少了任何一项授权都会失败。外部结构化数据的导入我走的路径是业务系统数据 → 定时任务或工作流读取 → 转成 Markdown/文本 → 调用 Dify 知识库 API 或直接写入数据库。有段时间我尝试把利率表也直接灌进向量库效果一般后来发现结构化数据更适合先用代码查询再把查询结果拼进提示词上下文。这个思路简单说就是动态数据查库静态知识走 RAG两者各自发挥长处。6. 最后再分享一点个人体会项目上线三个月我最大的体会是意图识别和多 RAG 架构的真正难点不在于模型参数而在于对业务边界的划分。你用什么类别去分意图你按什么维度去拆知识库这些决策直接决定了系统的上限。我后来复盘时发现当时把“意图”和“知识域”解耦是做得最正确的决定之一。意图类别跟着用户体验走知识域跟着文档体系走中间通过路由逻辑连接。这样无论业务方改意图还是改文档影响范围都是可控的。还有一个建议是银行类客服上线前一定要把“答不上来”当成一种正常状态来设计而不是羞耻。让 AI 在不确定时主动说需要人工确认比硬答安全得多。从成本角度看多一个转人工按钮的代价很低但一次错误回复可能引发的投诉和合规风险却很大。后续如果有精力我准备在这套系统上继续做两件事一是把多智能体协同引进来比如用 Agent 节点自动调用业务查询工具实现“查余额”这类实时数据的闭环二是做一个知识库流水线的定期巡检机制自动发现失效文档和过期内容。Dify 这个平台迭代很快社区版 1.17.1 已经带来不少新能力值得持续跟进。