ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

开源AI Agent Runtime客服知识问答卡片拆解实战指南

开源AI Agent Runtime客服知识问答卡片拆解实战指南 1. 客服知识为什么需要“问答卡片”这种形态做过客服系统的人都有一个共同感受知识库里的文档写得再全一线客服在跟用户对话的那几分钟里根本没时间翻。用户问“我这个订单为什么还没发货”客服需要的不是一篇三千字的售后政策说明而是一张能直接命中问题、给出标准回复口径的卡片。这就是问答卡片存在的意义。我最早接触这个需求是在给一个电商团队做 AI Agent 客服助手的时候。当时他们的知识库是一堆 Word 文档和飞书文档里面有产品参数、退换货规则、物流时效说明、活动细则内容很全但结构极差。AI Agent 接进去之后回答质量惨不忍睹——要么答非所问要么把三段不相关的政策拼在一起要么直接说“我无法回答这个问题”。后来我们花了大概两周时间把那些文档拆成了结构化的问答卡片Agent 的命中率和回答准确率才有了质的提升。所以这篇文章要聊的就是开源 AI Agent Runtime 场景下客服知识怎么整理成问答卡片这件事。它不是单纯的知识管理问题也不是单纯的 AI 工程问题而是两者的交叉地带。你既要想清楚“知识怎么拆”也要想清楚“Runtime 怎么用这些卡片”。适合读这篇内容的人大概有三类一是正在从零搭建 AI Agent 客服系统的开发者二是手里有一堆客服文档但不知道怎么喂给 AI 的运营或产品同学三是已经在用开源 Runtime 但效果不理想的工程师。我会尽量把原理讲透同时给出可以直接抄的操作步骤。2. 先搞清楚 Runtime 到底在问答卡片里扮演什么角色2.1 Runtime 不是知识库它是“调度器”很多人一开始会把 Runtime 和知识库混为一谈觉得把文档丢进去Runtime 就能自动回答问题了。这个理解偏差会导致后面所有设计都跑偏。Runtime 的本质是一个执行调度层。它负责的是接收用户输入、决定要不要检索知识、检索到什么、怎么组织上下文、调用哪个模型、怎么生成最终回复。它不负责“知识长什么样”那是知识库和问答卡片的事。打个比方Runtime 像是餐厅的前厅经理问答卡片像是后厨备好的半成品菜。前厅经理负责接单、传菜、协调出餐顺序但菜本身得后厨提前备好。你不能指望前厅经理现场去种菜。在开源 AI Agent Runtime 里这个调度逻辑通常体现在几个环节意图识别判断用户这句话是在问物流、问退款、还是问产品功能知识检索根据意图去问答卡片库里捞对应的卡片上下文组装把捞到的卡片内容拼成模型能理解的 prompt回复生成让模型基于卡片内容生成自然语言回复问答卡片的质量直接决定了第三步和第四步的上限。卡片拆得烂Runtime 再强也救不回来。2.2 问答卡片和普通文档的本质区别普通客服文档是给人读的问答卡片是给 Runtime 检索和模型消费的。这个区别决定了它们的结构完全不同。普通文档可以有大段叙述、可以有前后文依赖、可以靠标题层级来组织信息。但问答卡片不行它必须是自包含的——每一张卡片单独拿出来都要能完整回答一个问题不依赖其他卡片。我见过一个典型的反面案例某团队把退换货政策拆成了“退货条件”“退货流程”“退款时效”三张卡片但“退货条件”那张卡片里写的是“满足上述条件的用户可申请退货”这个“上述条件”在卡片里根本找不到因为它在上一个文档段落里。Runtime 检索到这张卡片模型看到“上述条件”四个字直接懵了。所以问答卡片的第一原则是一张卡片 一个独立问题 一个完整答案 必要的边界条件。2.3 卡片粒度怎么定太粗和太细都是坑粒度是问答卡片设计里最难拿捏的部分。我踩过的坑基本都在这。粒度太粗一张卡片覆盖了退换货的所有情况答案写了八百字。Runtime 检索到这张卡片模型要么截断要么把不相关的部分也塞进回复里。用户问“七天无理由怎么退”模型回了一大段包括质量问题退货、换货、维修的内容体验很差。粒度太细把“七天无理由退货”拆成“七天从哪天算起”“无理由包括哪些理由”“退货要不要包装”三张卡片。用户问一句“我想退货”Runtime 检索到三张卡片模型不知道该用哪张或者把三张拼在一起回复变得啰嗦。我的经验是以用户的一个完整意图为粒度。用户问“七天无理由怎么退”这是一个完整意图对应一张卡片。用户问“退货要多久到账”这是另一个完整意图对应另一张卡片。判断标准很简单——如果两个问题用户不会在同一句话里问出来就拆成两张卡片。3. 问答卡片的结构设计字段怎么定3.1 最小可用字段集一张能用的问答卡片至少需要这几个字段字段名作用是否必填card_id卡片唯一标识用于检索和追踪必填question标准问题用于意图匹配必填answer标准答案用于生成回复必填category分类标签用于粗筛建议填keywords关键词列表用于召回建议填conditions适用条件/边界用于精确匹配选填source知识来源用于追溯选填这个字段集是我试过好几版之后稳定下来的。card_id 用 UUID 或者业务编号都行关键是唯一。question 不一定要跟用户原话一模一样但要是用户可能问的标准表述。answer 是核心后面会专门讲怎么写。3.2 question 字段怎么写才能被检索到question 字段的作用是让 Runtime 能把用户输入匹配到这张卡片。匹配方式通常有两种向量相似度匹配和关键词匹配。开源 Runtime 里两种都很常见有的还会做混合检索。如果是向量匹配question 的表述要尽量覆盖用户可能的问法。比如“七天无理由退货”这张卡片question 可以写成“七天无理由退货怎么操作”但用户可能问“我想退货”“买了不想要了能退吗”“七天包退是什么意思”。这时候有两个做法一是把 question 写成多个变体的数组Runtime 检索时取最高相似度。二是把变体放到 keywords 字段里做关键词召回兜底。我一般两个都做。question 主字段写最标准的那个问法keywords 里塞五到十个变体。实测下来混合检索的召回率比单用向量高不少尤其是用户用了口语化表达的时候。3.3 answer 字段的写法给模型看的不是给人读的这是最容易被忽视的一点。answer 字段的内容最终是要被塞进 prompt 让模型消费的。所以它的写法要符合模型的“阅读习惯”。第一结论前置。模型在生成回复时倾向于优先使用上下文里靠前的内容。所以 answer 的第一句就要给出核心结论。比如“七天无理由退货的时效是签收后七天内从签收次日零点开始计算。”而不是先铺垫“根据我们的售后政策规定……”第二分点但不啰嗦。模型对结构化内容的处理能力比大段文字强。可以用短句分点但每点不要太长。我一般控制在每点不超过两行。第三明确边界。如果这个答案有例外情况一定要写清楚。比如“定制类商品不支持七天无理由退货”这句话必须出现在 answer 里否则模型可能会给出错误承诺。第四避免指代。不要出现“如上所述”“参见前文”“该政策”这种指代每张卡片都要自包含。3.4 conditions 字段处理“看情况”的问题客服场景里大量问题是“看情况”的。退货时效看商品类型运费承担看退货原因活动优惠看用户等级。这些“看情况”的部分如果全塞进 answer 里卡片会变得很臃肿。我的做法是单独设一个 conditions 字段用结构化的方式写清楚适用条件。比如{ conditions: [ {field: 商品类型, operator: in, value: [普通商品], result: 支持七天无理由}, {field: 商品类型, operator: in, value: [定制商品, 生鲜], result: 不支持七天无理由} ] }Runtime 在检索到这张卡片后可以结合用户订单信息做二次过滤把不相关的条件剔除只把命中的那部分塞进 prompt。这样模型拿到的上下文更干净回复也更准确。4. 从原始文档到问答卡片的完整拆解流程4.1 第一步文档清洗和去重原始客服文档通常有几个问题格式混乱、内容重复、版本不一致。直接拆卡片会把这些毛病带进去。我一般会先做一轮清洗统一格式把 Word、PDF、飞书文档都转成纯文本或 Markdown去掉页眉页脚、水印、无关的排版符号合并重复同一个政策在不同文档里出现多次的合并成一份以最新版本为准标注来源每段内容标注它来自哪个文档、哪个版本方便后续追溯剔除无效内容内部通知、会议纪要、临时公告这些不属于客服知识的内容先拿出去这一步看起来简单但实际很耗时间。我做过一个项目原始文档有四十多份清洗完只剩十二份是真正有用的客服知识。如果不做这一步后面拆出来的卡片会有一大半是噪音。4.2 第二步按用户意图聚类清洗完之后不要急着按文档结构拆卡片。文档结构是写文档的人的逻辑不是用户的逻辑。正确的做法是按用户意图聚类。具体操作是把清洗后的内容通读一遍然后问自己“用户会在什么场景下问这个问题”把属于同一个场景的内容归到一起。比如退换货政策文档里可能分散在“售后服务”“物流说明”“活动规则”三个章节。但用户问“我要退货”的时候他关心的是能不能退、怎么退、运费谁出、多久到账。这四个问题应该聚成一个意图簇然后再拆成四张卡片。我一般会用一张表格来做这个聚类意图簇包含的原始内容来源文档退货申请退货条件、退货入口、申请流程售后服务v2.1退货运费运费承担规则、运费险说明售后服务v2.1、活动规则v1.3退款时效退款到账时间、支付方式差异物流说明v3.0这张表做完卡片的骨架就出来了。4.3 第三步逐张卡片填充字段聚类完成后就是逐张卡片填字段。这个过程我建议用表格工具或者 JSON 文件来做不要直接在文档里写方便后续导入 Runtime。填字段的顺序建议是先写 question再写 answer然后补 keywords 和 conditions最后填 category 和 source。写 answer 的时候有个技巧先写一版给用户看的自然语言答案再改写成给模型看的结构化答案。第一版帮你理清逻辑第二版才是最终入库的版本。4.4 第四步卡片质量校验卡片写完不能直接用必须校验。我一般会做三轮第一轮自包含校验。随机抽十张卡片单独拿出来看能不能不依赖其他卡片就回答清楚一个问题。如果有指代、有缺失、有歧义打回去重写。第二轮冲突校验。检查不同卡片之间有没有矛盾。比如一张卡片说“退货包运费”另一张说“退货运费自理”这种冲突会让模型精神分裂。发现冲突要回到原始文档确认哪个是最新政策。第三轮覆盖度校验。拿真实的用户问题日志随机抽一百条看有多少条能被现有卡片覆盖。覆盖率低于百分之八十说明卡片拆得不够全要补。这三轮做完卡片库才算能上线。5. 卡片入库 Runtime 后的检索与生成调优5.1 检索策略向量加关键词的混合召回卡片入库之后Runtime 怎么把它们捞出来是决定效果的关键。我试过纯向量、纯关键词、混合三种方案最后稳定用的是混合召回。纯向量的问题是用户问“七天无理由”向量可能匹配到“七天发货”“无理由换货”这些语义相近但意图不同的卡片。纯关键词的问题是用户换个说法就匹配不到了。混合召回的做法是先用关键词做一轮粗筛把包含核心词的卡片捞出来再用向量做精排取相似度最高的前几张。这样既保证了召回率又保证了准确率。在开源 Runtime 里这个逻辑通常可以通过配置检索器的 pipeline 来实现。有的 Runtime 支持自定义检索器那就更灵活可以按业务特点调权重。5.2 上下文组装给模型喂几张卡片合适检索到卡片之后塞几张进 prompt也是个需要调的参数。塞太少模型信息不够回答不完整。塞太多模型注意力被分散容易把不相关的卡片内容也编进回复里。我的经验值是三到五张。具体看卡片的内容长度如果每张卡片答案都很短可以塞五张如果卡片答案比较长塞三张就够了。另外塞进去的顺序也有讲究。相似度最高的卡片放最前面因为模型对靠前的内容更敏感。如果卡片之间有逻辑顺序比如“退货条件”在“退货流程”前面那就按逻辑顺序排。5.3 生成约束怎么让模型别乱编即使卡片内容是对的模型也可能生成出卡片里没有的信息。这在客服场景里是致命的因为可能给出错误承诺。我一般会在 prompt 里加几条硬约束只使用提供的卡片内容回答不要添加卡片之外的信息如果卡片内容不足以回答问题明确告知用户“这个问题我需要帮您转接人工”不要对卡片内容做推断和延伸这几条约束写进 system prompt 里能挡掉大部分幻觉。但也不是万能的模型有时候还是会“自作聪明”。所以上线前一定要做一轮对抗测试专门问一些卡片里没有的问题看模型会不会乱答。5.4 效果评估怎么知道卡片拆得好不好卡片拆得好不好不能靠感觉要有指标。我一般看四个指标指标含义目标值召回率用户问题能检索到相关卡片的比例大于85%准确率检索到的卡片确实相关的比例大于90%回答采纳率模型生成的回复被客服直接采用的比例大于70%转人工率模型无法回答转人工的比例小于15%这四个指标里召回率和准确率反映卡片库的质量回答采纳率和转人工率反映整体效果。如果召回率低说明卡片不够全或者 question 写得不好如果准确率高但采纳率低说明 answer 写得不好模型没法直接用。6. 实操中踩过的坑和排查技巧6.1 卡片答案太长导致模型截断这是最常见的坑。一张卡片的 answer 写了五百字Runtime 检索到三张prompt 直接超长模型要么截断要么忽略后面的内容。排查方法统计所有卡片 answer 的长度分布超过两百字的卡片重点检查看能不能拆成两张。解决思路answer 控制在两百字以内超出的部分要么拆卡片要么放到 conditions 里做条件分支。6.2 同义问题匹配不到用户问“我不想买了能退吗”卡片里写的是“七天无理由退货”向量相似度不够匹配不到。排查方法拿用户问题日志跑一遍检索把没匹配到的问题捞出来人工看应该匹配哪张卡片。解决思路把这些问法加到对应卡片的 keywords 里。如果量很大可以考虑用模型做一轮问法扩展自动生成变体。6.3 多张卡片内容冲突两张卡片对同一个问题给出了不同答案模型随机选一个回复不稳定。排查方法用聚类算法把语义相近的卡片找出来人工检查有没有冲突。解决思路回到原始文档确认最新政策把旧卡片下线或者标注失效。6.4 模型忽略卡片内容自己编卡片里明明写了“不支持退货”模型回复“可以为您办理退货”。排查方法做对抗测试专门问卡片里有明确否定答案的问题看模型是否遵守。解决思路加强 prompt 约束把关键结论用更醒目的方式标注比如加粗或者用特殊符号包裹。如果还是不行考虑在生成后加一层校验检查回复里有没有出现卡片里没有的关键承诺。6.5 卡片更新后 Runtime 没生效改了卡片内容但 Runtime 检索到的还是旧内容。排查方法检查 Runtime 的缓存机制和索引更新策略。解决思路大部分开源 Runtime 都有索引重建的接口卡片更新后要触发重建。有的还支持增量更新但增量更新有时候会有延迟重要更新建议直接全量重建。7. 一个完整的卡片示例和它的设计思路说了这么多理论来看一张实际的卡片长什么样。{ card_id: return_007, question: 七天无理由退货的时效怎么算, answer: 七天无理由退货的时效从签收次日零点开始计算共七天。例如1月1日签收1月2日零点开始计算1月8日二十四点截止。超过时效后无法申请七天无理由退货但质量问题退货不受此限制。, keywords: [七天无理由, 退货时效, 退货时间, 几天内退货, 签收后多久], conditions: [ {field: 商品类型, operator: in, value: [普通商品], result: 适用}, {field: 商品类型, operator: in, value: [定制商品, 生鲜, 虚拟商品], result: 不适用} ], category: 售后服务-退货, source: 售后服务政策v2.1-第三章 }这张卡片的设计思路是这样的question 写的是最标准的问法但 keywords 里塞了五个变体覆盖了用户可能的口语化表达。answer 第一句直接给结论第二句用例子说明第三句补充例外情况。conditions 把商品类型的差异单独拎出来Runtime 可以结合订单信息做过滤。source 标注了来源方便后续追溯和更新。这张卡片 answer 长度控制在一百字出头塞三张进 prompt 也不会超长。conditions 结构化之后Runtime 可以做精确匹配不会把定制商品的政策错误地用在普通商品上。8. 卡片库的长期维护别让它烂掉卡片库不是建完就完事的它会随着业务变化而腐烂。政策改了、活动结束了、产品下架了对应的卡片如果不同步更新就会变成错误知识的来源。我的做法是建立一套维护机制定期审计每个月抽一天把卡片库过一遍检查有没有过期内容。重点看活动相关的卡片活动结束就要下线。变更联动业务侧的政策文档更新时要同步触发卡片更新。这个最好做成流程而不是靠人记得。效果监控持续监控前面说的四个指标指标下滑就说明卡片库有问题要及时排查。用户反馈闭环客服在使用过程中发现卡片有问题要有一个方便的反馈入口反馈要能直接触达卡片维护人。这套机制跑起来之后卡片库的维护成本会低很多。最怕的是建完就不管半年后回头看一半卡片都是错的。9. 关于开源 Runtime 选型的一点个人看法最后聊几句 Runtime 选型。现在开源 AI Agent Runtime 的选择不少有偏重工作流编排的有偏重对话管理的有偏重知识检索的。我的建议是如果你的核心场景是客服问答优先选知识检索能力强、支持自定义检索器、支持结构化知识入库的 Runtime。工作流编排能力反而是次要的因为客服问答的流程相对固定不需要太复杂的编排。另外要看 Runtime 的卡片管理能力。有的 Runtime 自带知识库管理界面可以直接导入结构化卡片有的需要自己写接口对接。如果卡片量大自带管理界面的会省很多事。还有一点是社区活跃度。开源项目最怕的是停更遇到问题没人管。选之前看看最近的提交记录和 issue 响应速度这个比功能列表更能反映项目的真实状态。我在实际使用中的体会是Runtime 本身的能力差距其实没有想象中那么大真正拉开效果差距的是卡片库的质量。同样的 Runtime卡片拆得好效果能到八十分卡片拆得烂效果可能只有四十分。所以与其花时间纠结选哪个 Runtime不如先把卡片拆好。
返回列表