👁 75 次阅读

配图

为什么客服机器人必须可回溯
客服场景与普通知识问答不同。答案经常涉及退款条件、服务范围、责任边界、操作步骤和承诺口径。一旦机器人给出错误回答,用户可能截图传播,客服团队也很难判断问题出在知识源、切片、检索还是模型生成。可回溯不是给答案加一个来源链接就结束,而是能从最终回答倒查到当时使用的文档版本、具体片段、检索分数、会话上下文和人工修正记录。Dify 提供了知识库、检索、Chatflow 和应用日志等能力,但要达到可回溯,需要在入库规范、检索链路和展示层做一套约束。本文给出一条可以直接照做的路径,重点不是把机器人做得更会说话,而是让每句话都有依据、有版本、有责任人。

配图

先定义可回溯的四个对象
在动手前,先把可回溯拆成四个对象。对象定义清楚,后面的 Dify 配置才不会散。下面的表格是建议的最小记录集,字段名可以按团队习惯调整,但不要省略版本和定位信息。
| 对象 | 至少记录 | 用途 |
|---|---|---|
| 文档版本 | doc_id、标题、版本、负责人、生效状态、校验值 | 判断答案依据是否过期 |
| 切片 | chunk_id、doc_id、小节标题、片段位置、文本摘要 | 定位答案来自哪一段 |
| 检索 | 查询词、知识库、分数、重排结果、命中片段列表 | 复盘为什么召回或漏召回 |
| 会话 | conversation_id、message_id、用户问题、答案、引用、反馈、转人工标记 | 回放完整服务过程并追责改进 |
准备知识源与元数据规范
客服知识库通常来自政策文档、FAQ、操作手册、工单摘要。不要直接把共享盘文件夹拖进 Dify。先做三件事:去重、分版本、加元数据。每个文档应该有稳定 doc_id,标题不要频繁改;版本用可排序的规则;负责人写岗位而不是个人昵称;生效状态用草稿、生效、停用三类。文档正文尽量用清晰标题分层,标题要能独立表达含义。例如不要写「其他说明」,而要写「跨渠道退换货的适用条件」。这样切片后仍然保留语义。
doc_id: cs-refund-policy title: 退款政策 version: vYYYY.MM owner: 客服运营组 status: active effective_date: YYYY-MM-DD product_line: 通用 region: 中国大陆 source_url: internal://policy/refund
这些字段一部分可以写入 Dify 知识库元数据,一部分写入文档首部并在切片时保留。若当前 Dify 版本对元数据过滤支持有限,就把不同产品线、不同地区拆成独立知识库,用知识库边界代替过滤条件。不要依赖文件名承担全部语义,因为文件名在切片和引用中不一定稳定展示。
在 Dify 中创建知识库与分段策略
在 Dify 中新建知识库,命名采用「业务域-文档类型-版本范围」的结构,例如「客服-退款政策-当前生效」。上传前确认文档已经脱敏,工单摘要中的手机号、地址、订单号等敏感信息要替换。分段策略不要一套参数走到底,按文档类型分开建库或至少分开目录。
| 文档类型 | 分段依据 | 建议保留的上下文 | 检索注意 |
|---|---|---|---|
| 政策条款 | 按条款或二级标题 | 条款编号、适用范围、生效版本 | 先过滤生效状态,再检索 |
| FAQ | 一问一答为一段 | 问题原文与答案同片 | 避免答案与问题被切开 |
| 操作手册 | 按步骤或章节 | 前置条件、步骤序号、注意事项 | 保留步骤编号方便引用 |
| 工单摘要 | 按工单或问题类型 | 现象、处理结论、适用产品 | 必须脱敏并标注不可对外承诺 |
分段长度以能覆盖一条完整规则为准。太短会把条件与结论拆开,太长会降低检索精度。重叠只用于衔接上下文,不要用大重叠掩盖结构问题。上传后随机抽几条切片检查:标题是否还在、条件是否完整、表格是否被拆散。发现跨条款就回到原文改标题或改用自定义分段。
用 Chatflow 固定检索与回答链路
建议用 Chatflow 而不是只靠默认对话。链路可以固定为:开始节点接收问题,必要时做问题改写,知识检索节点召回片段,条件分支判断是否有足够依据,LLM 节点按模板生成答案,最后输出引用和转人工标记。问题改写只做指代消解和术语归一,不要让模型扩展出知识库里没有的条件。检索节点要明确选择知识库,开启可用的重排能力,设置分数阈值。阈值不要凭感觉,先用一批真实问题跑出分布,再选一个能平衡召回与噪声的值。
你是客服知识库问答助手。只根据检索片段回答。 回答结构: 结论:用一句话回答用户问题。 适用条件:列出必须满足的条件。 操作步骤:如问题涉及操作,按顺序列出。 引用:文档标题 + 小节标题 + 版本。 限制:不得补充片段中没有的政策、金额、时限和承诺。 如果片段不足或相互冲突,输出:当前知识库没有足够依据,请转人工。
这段提示词的关键是强制引用和拒答。很多机器人出问题,不是检索不到,而是模型在片段不足时仍然补全。条件分支里可以把「无命中」或「低分命中」直接转到人工,并把检索结果写入日志。若业务允许,也可以让模型输出结构化字段,再由结束节点拼装给前端。结构化字段包括结论、条件、引用列表、置信度和转人工标记。这样前端不必解析自然语言,日志也更容易统计。
让答案显示引用:前端与 API 两种做法
可回溯的最后一公里是展示。只在后台记录引用不够,用户和客服都需要看到答案依据。使用 Dify 的对话 API 时,响应元数据中通常包含检索资源列表,可以取出文档名、片段标识、分数和内容摘要。下面的 Python 示例演示如何调用对话接口并打印引用,实际字段以当前 Dify 版本返回为准。
import requests
resp = requests.post(
'https://your-dify-host/v1/chat-messages
headers={'Authorization': 'Bearer ' + API_KEY},
json={
'inputs': {},
'query': user_query,
'response_mode': 'blocking',
'conversation_id': conversation_id,
'user': user_id,
},
timeout=30,
)
data = resp.json()
resources = data.get('metadata', {}).get('retriever_resources', [])
for item in resources:
print(item.get('document_name'), item.get('segment_id'), item.get('score'))
前端渲染时,把引用做成可展开列表:标题显示文档名和小节名,展开后显示命中片段摘要和版本。不要只显示一个「来源」图标,用户无法判断依据是否适用。若使用嵌入窗口,先确认当前版本是否支持引用展示;若不支持,就在外层页面调用 API 自行渲染。无论哪种方式,都要把 message_id 和引用列表一起保存。这样用户点踩时,客服可以看到当时答案引用了哪一段,而不是重新问一遍问题。
配置日志、审计与人工修正闭环
日志不是把聊天记录全存下来就完事。建议至少记录:会话标识、消息标识、渠道、用户标识、原始问题、改写后问题、命中的知识库、引用片段、最终答案、耗时、是否转人工、用户反馈。Dify 自带日志能力可以满足基础查看,但要做长期审计,最好在应用外层加一个轻量网关,把请求和响应同步到自己的日志表。网关只记录必要字段,敏感信息脱敏后再落库。每周抽查低分回答和点踩回答,按三类归因:知识缺失、切片错误、生成越界。知识缺失就补文档;切片错误就改标题或分段;生成越界就收紧提示词和拒答条件。每次修正都要留下变更记录,方便下次回放。
- 为每条答案保存引用片段列表,而不是只保存文档名。
- 为每个文档保存版本和生效状态,停用文档不要直接删除。
- 为每次人工修正记录原因和处理人岗位。
- 为转人工会话保留检索结果,便于判断是否漏召回。
评测与回归:每次知识更新都要跑一遍
可回溯系统需要可评测。准备一组覆盖高频问题、边界问题、过期政策问题、跨产品问题的测试集。每个问题标注期望文档、期望小节和是否应该拒答。每次知识库更新后跑一遍,重点看四个指标:检索是否命中期望文档,答案要点是否能在引用片段中找到,无依据问题是否正确转人工,用户反馈是否进入复核队列。不要只看答案像不像,要看依据是否对得上。
| 指标 | 观察方法 | 不达标时的动作 |
|---|---|---|
| 检索命中 | 期望文档是否出现在引用中 | 调整分段、补充同义问法、检查元数据过滤 |
| 引用一致 | 答案要点能否在引用片段找到 | 收紧提示词,要求逐条对应 |
| 拒答正确 | 边界问题是否转人工 | 增加无依据示例,调整阈值 |
| 反馈闭环 | 点踩问题是否被复核 | 建立每周清理队列 |
测试集不要一次性写很多然后长期不用。每次线上发现新问题,就把它补进测试集。知识库版本变化时,先跑回归,再发布。对于政策类问题,要专门测试旧版本是否会被召回;如果旧版本仍能被检索到,说明知识库隔离或元数据过滤没有做好。
常见坑与排查清单
- 切片跨条款:答案把两个条件的结论拼在一起。处理方法是按标题切,保留条款编号。
- 旧版本混入:用户看到已停用政策。处理方法是独立知识库或元数据过滤,停用文档移出检索范围。
- 只做向量检索:专有名词和编号召回不稳定。处理方法是使用可用的混合检索与重排能力,补充同义问法。
- 提示词允许自由发挥:片段不足仍然给承诺。处理方法是强制引用和拒答,并设置条件分支。
- 引用不可见:客服无法判断答案依据。处理方法是前端展示文档名、小节名、版本和片段摘要。
- 日志缺 message_id:无法回放某次回答。处理方法是网关统一记录请求、响应和引用列表。
- 工单未脱敏:知识库入库带来隐私风险。处理方法是入库前替换敏感字段,权限按业务域隔离。
一套可执行的落地顺序
- 选一个高频、低风险、答案边界清晰的客服场景,先不要覆盖全部业务。
- 整理该场景的文档,统一 doc_id、版本、负责人和生效状态。
- 在 Dify 创建独立知识库,按文档类型设置分段,上传后抽查切片。
- 用 Chatflow 固定检索、条件分支、回答模板和转人工节点。
- 通过 API 或嵌入页面展示引用,保存 message_id 与引用列表。
- 建立测试集和每周复核队列,按知识缺失、切片错误、生成越界归因。
- 稳定后再扩展到相邻场景,每扩展一个场景就新增一组回归问题。
今天就能开始的执行建议
如果今天就要动手,先不要追求大而全。选一个客服团队最常被问到、且答案有明确文档依据的场景,建立一个小知识库;为每篇文档补上版本、负责人和生效状态;用 Chatflow 把检索、引用和拒答固定下来;在前端把引用做成可展开列表;最后用一个表格记录每次点踩和人工修正。坚持两周,你会得到一套能回放、能追责、能迭代的问答链路。等这条链路跑顺,再扩展产品线和渠道,比一开始堆很多文档更可靠。