保险Agent开发实战:从意图识别到合规控制的全流程架构设计
1. 从一张白板到跑通全流程这个保险Agent到底在做什么去年年底某业务团队找到我说他们有一批保险咨询的线上流量人工客服根本接不过来想做一个能自动应答、能引导用户、还能把复杂条款讲明白的对话助手。我当时第一反应是保险这个领域做对话Agent难度不在模型本身而在“怎么把非结构化的条款和话术变成Agent能稳定执行的结构化流程”。市面上通用的对话框架直接拿来用十有八九会在“用户问了一个条款边缘问题”的时候翻车。这个项目我前后迭代了三个大版本从最初用纯提示词硬扛到后来引入意图路由加知识检索再到最后做成可配置的流程引擎中间踩的坑足够写一本小册子。今天这篇记录就是把这几个月做保险Agent开发的核心思路、关键实现和踩坑经验完整梳理一遍。不管你是刚接触对话系统的新手还是已经做过几个Agent想看看别人怎么处理复杂业务场景的老手应该都能从里面找到一些可以直接抄作业的东西。先说清楚这个Agent的定位它不是一个“万能保险百科”而是一个有明确业务边界的引导型对话助手。核心能力包括三块——第一识别用户意图判断他是想咨询产品、对比方案、还是已经准备投保第二根据意图走不同的对话分支该问的问清楚该给的资料给到位第三在关键节点做风险提示和合规话术兜底。听起来简单但每一块拆开都有大量细节要处理。我见过不少团队做类似项目上来就堆大模型能力结果对话是流畅了但业务逻辑完全不可控用户问“这个产品保不保某某病”Agent张口就来一个答案跟实际条款对不上这种在保险场景里是致命的。所以我的核心设计原则从一开始就很明确模型负责理解和表达业务逻辑必须由结构化流程来控制。这个原则贯穿了整个开发过程后面所有的技术选型和架构设计都是围绕它展开的。2. 整体架构设计为什么我没有一上来就全用大模型2.1 三层架构的取舍逻辑最开始我试过纯提示词方案把产品条款和话术全部塞进系统提示里让模型自己判断该说什么。实测下来简单问题还行一旦对话轮次超过五轮模型就开始“自由发挥”要么把不同产品的条款混在一起要么在用户没提供足够信息的时候就给出具体建议。这个方案被我果断放弃了。后来确定的架构是三层意图识别层、流程控制层、内容生成层。意图识别层负责判断用户当前这句话属于哪个业务意图比如“产品咨询”“条款询问”“价格对比”“投保意向”“售后问题”等。流程控制层是一个状态机根据当前意图和对话历史决定下一步该走哪个分支、该收集哪些信息、该输出什么类型的内容。内容生成层才是大模型发挥作用的地方它根据流程控制层给出的指令结合检索到的知识片段生成自然流畅的回复。为什么这么设计因为保险对话有一个特点用户的问题往往不是孤立的而是有业务阶段属性的。一个用户可能先问“你们有什么医疗险”然后问“这个跟某某产品比怎么样”接着问“投保需要什么条件”最后说“那我先看看”。这四个问题分别属于不同的业务阶段如果Agent不能识别这种阶段变化就会在用户已经进入投保意向阶段的时候还在给他推产品介绍体验非常割裂。三层架构的好处是每一层只做自己最擅长的事。意图识别可以用小模型或者规则引擎快速跑流程控制用状态机保证确定性内容生成用大模型保证表达质量。三层之间通过明确定义的接口通信任何一层出问题都可以单独排查和替换。2.2 状态机的设计细节流程控制层我用的是一个有限状态机状态节点大概有二十多个覆盖了从“初次接触”到“投保完成”再到“售后跟进”的完整链路。每个状态节点定义了四样东西进入条件、需要收集的槽位、可执行的行动、退出条件。举个例子“产品推荐”这个状态节点进入条件是用户表达了“想了解某类保险”的意图需要收集的槽位包括“被保人年龄”“保障需求类型”“预算范围”可执行的行动包括“检索匹配产品”“生成对比说明”“询问补充信息”退出条件是“用户明确表示对某个产品感兴趣”或者“用户表示暂时不需要”。槽位收集这块我踩过一个坑最开始设计的时候我要求所有槽位必须收集完整才能进入下一步结果用户经常在只说了年龄之后就不耐烦了。后来改成渐进式收集先根据已有信息给出初步建议在对话过程中自然地把缺失信息补上。比如用户说“我三十岁”Agent可以先推荐几款适合三十岁的产品然后顺带问一句“您主要是想给自己配置还是给家人”这样用户就不会觉得在被审问。状态机的另一个关键设计是异常兜底。用户随时可能说一些跟当前流程无关的话比如突然问“你们公司靠谱吗”或者“我朋友说某某产品更好”。这时候状态机需要有一个“通用应答”的兜底状态先接住用户的话再尝试把对话拉回主流程。这个兜底状态的话术我打磨了很久核心原则是“先共情再引导”不要生硬地忽略用户的问题。2.3 知识检索的粒度控制保险产品的条款文档动辄几十页直接全部塞给模型肯定不行。我的做法是把条款拆成最小可回答单元每个单元对应一个具体的用户问题类型。比如“等待期是多久”“既往症怎么定义”“报销比例是多少”“免赔额怎么算”每个问题类型对应一段结构化的知识片段。检索的时候不是简单做向量相似度匹配而是意图加实体双重过滤。先根据意图识别结果缩小范围比如用户问的是“等待期”就只在等待期相关的知识片段里检索再根据实体过滤比如用户问的是“某某医疗险的等待期”就只匹配这个产品的片段。这样检索准确率比纯向量检索高出一大截。知识片段的格式我也做了统一每条包含产品标识、问题类型、标准答案、补充说明、风险提示。标准答案是直接可以用的回复内容补充说明是给模型参考的背景信息风险提示是必须附带在回复里的合规话术。这样内容生成层拿到的就是一份“半成品”模型只需要做语言润色和上下文衔接不需要自己组织业务逻辑。3. 意图识别与槽位抽取怎么让Agent听懂人话3.1 意图分类体系的搭建意图分类是整个Agent的入口分错了后面全错。我最初设计了三十多个意图后来发现太细了很多意图之间的边界模糊模型经常混淆。经过几轮合并和调整最终稳定在十二个一级意图和若干二级意图的结构。一级意图包括产品咨询、条款询问、价格对比、投保意向、投保操作、售后咨询、投诉建议、闲聊、无效输入、转人工、结束对话、其他。每个一级意图下面根据业务需要再分二级比如“产品咨询”下面分“医疗险咨询”“重疾险咨询”“意外险咨询”“寿险咨询”等。分类模型我用的是微调后的小型文本分类模型不是大模型。原因很简单意图分类需要的是快和稳不需要创造性。小模型在这个任务上准确率能做到百分之九十五以上而且响应时间在几十毫秒级别比调大模型快一个数量级。训练数据来自历史客服对话记录人工标注了大概五千条覆盖了各种表达方式。这里有个经验意图分类一定要留一个“其他”类别并且给这个类别足够的训练样本。很多团队做分类的时候只关注主要意图结果用户说了一句稍微偏一点的话模型就强行归类到某个主要意图里导致后续流程完全跑偏。我专门收集了大量“其他”类别的样本让模型学会在不确定的时候说“不确定”这样流程控制层可以走兜底逻辑而不是被错误分类带偏。3.2 槽位抽取的规则与模型结合槽位抽取我采用的是规则加模型的混合方案。规则负责处理格式固定的信息比如年龄、金额、日期、产品名称模型负责处理表达多样的信息比如“我想给刚出生的宝宝买”这种需要推理才能提取出“被保人年龄为零岁”的情况。规则部分用正则表达式和词典匹配就能覆盖大部分场景。比如年龄用户可能说“三十岁”“30”“三十”“今年三十了”这些都可以用规则处理。金额也是用户说“预算五千左右”“大概五千块”“不超过五千”规则都能提取出来。产品名称用词典匹配维护一个产品名称和别名的映射表。模型部分我用了一个序列标注模型专门处理那些规则搞不定的情况。比如用户说“我孩子刚上幼儿园”模型需要推理出“被保人是学龄前儿童”用户说“我老公是家里的顶梁柱”模型需要推理出“用户想给配偶配置保险且可能关注寿险或重疾险”。这些推理规则很难穷举交给模型更合适。槽位抽取的准确率直接影响后续流程所以我在这个环节加了置信度阈值。规则匹配的置信度设为高模型抽取的置信度根据概率值判断。如果某个槽位的置信度低于阈值流程控制层会主动追问确认而不是直接使用。比如模型从“我孩子刚上幼儿园”推理出年龄是三到六岁置信度中等Agent就会追问一句“请问宝宝具体几岁了”确保信息准确。3.3 多轮对话中的上下文管理保险对话经常需要多轮才能收集齐信息上下文管理就变得很重要。我的做法是维护一个对话状态对象里面包含当前意图、已收集槽位、对话历史摘要、当前流程节点、待确认信息等。每次用户输入进来先更新对话状态再根据新状态决定下一步动作。对话历史摘要这块我做了特殊处理。不是简单地把所有历史消息拼在一起而是按轮次提取关键信息。比如用户第一轮说“我想了解医疗险”第二轮说“我三十岁”第三轮说“预算五千”摘要就是“用户咨询医疗险三十岁预算五千”。这样即使对话轮次很多状态对象也不会膨胀模型处理起来也更快。还有一个细节用户可能在对话过程中改变主意。比如一开始说想了解医疗险聊到一半突然问“你们重疾险怎么样”。这时候状态机需要能够识别意图切换把当前流程挂起先处理新的意图处理完再决定是回到原流程还是开启新流程。这个逻辑我调试了很久核心是要区分“用户是在补充信息”还是“用户是在切换话题”。我的判断依据是意图分类的置信度和槽位的相关性如果新意图跟当前流程的槽位高度相关就当作补充信息处理如果完全不相关就当作话题切换。4. 内容生成与合规控制让Agent说对话、说好话4.1 回复模板与模型生成的结合内容生成层我没有完全交给大模型而是采用模板加生成的混合模式。对于标准问题比如“等待期是多久”“报销比例是多少”直接用预置的回复模板模板里留出变量位置由流程控制层填充具体数值。这样做的原因是保险条款的表述必须精确模型生成的内容哪怕意思对了用词不准确也可能引发合规风险。对于需要解释和引导的场景比如“为什么推荐这款产品”“这个条款是什么意思”才用大模型生成。生成的时候也不是让模型自由发挥而是给它一个结构化的生成指令包含回复目标、必须包含的信息点、必须避免的表述、语气要求、长度限制。模型在这个框架内组织语言既保证了表达的自然度又保证了内容的可控性。举个例子用户问“这个医疗险的免赔额是什么意思”生成指令会告诉模型需要解释免赔额的定义需要说明这款产品的免赔额具体是多少需要用生活化的例子帮助理解不能使用“绝对”“保证”等绝对化表述长度控制在两百字以内。模型拿到这个指令结合检索到的知识片段生成一段既准确又易懂的回复。4.2 合规话术的强制嵌入保险行业的合规要求非常严格有些话必须说有些话绝对不能说。我在内容生成层做了一个合规检查模块所有生成的回复在输出之前都要过一遍这个模块。必须说的话比如“具体保障内容以保险合同为准”“投保前请仔细阅读条款”“本回复仅供参考不构成投保建议”这些是强制嵌入的不管模型生成了什么最后都会把这些话附上。绝对不能说的情况比如“保证赔付”“百分百报销”“没有任何限制”这些用规则加模型双重检测一旦发现就拦截并重新生成。合规检查模块还有一个功能是敏感词替换。有些表述虽然不是绝对禁止但在特定场景下不合适比如“最便宜”“最好”“第一”这类比较级词汇会被替换成“性价比较高”“较受欢迎”“市场反馈较好”等更稳妥的表述。这个替换表是动态维护的根据业务反馈不断补充。4.3 多轮对话中的一致性保证多轮对话最容易出的问题是前后不一致。比如第一轮说“这款产品等待期是三十天”第三轮用户再问等待期Agent回答“九十天”这种错误在保险场景里是致命的。为了保证一致性我在对话状态对象里维护了一个已确认信息表所有已经输出过的关键信息都会记录在里面后续生成回复的时候会先查这个表确保不会出现矛盾。还有一个一致性问题是推荐逻辑的一致性。如果Agent在第一轮推荐了某款产品后面用户补充了新的信息比如“我其实有既往症”Agent需要重新评估推荐是否仍然合适。我的做法是在槽位更新的时候触发推荐重评估如果新信息导致原推荐不再合适Agent会主动说明“根据您补充的信息之前推荐的产品可能不太适合我重新为您筛选一下”。这种主动纠偏的体验比用户自己发现不对再问要好得多。5. 实操过程中的典型问题与排查记录5.1 意图识别准确率上不去的排查过程项目初期意图识别准确率一直在百分之八十五左右徘徊怎么调都上不去。我花了两天时间做错误分析发现主要问题出在短文本和口语化表达上。用户经常只说“多少钱”“保什么”“怎么样”这些短文本缺乏上下文模型很难判断意图。解决方案有两个第一在意图分类的时候拼接最近两轮对话作为上下文而不是只看当前这一句。比如用户上一句问“这个医疗险”当前句问“多少钱”拼接起来就是“这个医疗险多少钱”意图就很明确了。第二针对高频短文本建立映射表把“多少钱”映射到“价格询问”“保什么”映射到“保障范围询问”“怎么样”映射到“产品评价询问”。映射表覆盖了大概两百个高频短句准确率直接提升了五个百分点。还有一个问题是多意图混合。用户一句话里可能包含多个意图比如“这个医疗险多少钱跟那个重疾险比哪个划算”既有价格询问又有产品对比。我的处理方式是按优先级拆分先处理最明确的意图在回复中覆盖其他意图。上面这句话先回答价格再简要对比最后问用户想深入了解哪个。5.2 槽位抽取的边界情况处理槽位抽取遇到的边界情况比预想的多得多。举几个典型的例子用户说“我三十岁”这个好处理。用户说“我九零年的”需要计算年龄而且要考虑当前年份。用户说“我孩子上小学”需要推理出孩子大概六到十二岁。用户说“我跟我老婆都买”需要识别出两个被保人。用户说“预算的话一年万把块吧”需要把“万把块”解析成“一万元左右”。这些边界情况我整理了一个测试用例集大概三百多条每次修改槽位抽取逻辑都跑一遍确保没有回归。这个测试集是逐步积累的每次线上发现新的边界情况就补充进去。现在这个测试集已经成了项目最宝贵的资产之一新来的同事接手的时候跑一遍测试集就能快速了解系统能处理哪些情况、不能处理哪些情况。还有一个经验槽位抽取不要追求一次到位。用户说“我三十岁想买医疗险”能抽到年龄和产品类型就够了不要试图从这一句话里推断出预算、保障期限、缴费方式。这些信息在后续对话中自然收集就好。贪多求全反而容易出错而且会让用户觉得在被审问。5.3 对话流程卡死的修复上线初期遇到过一个典型问题对话流程卡死。用户说了一句话Agent回复之后用户又说了一句Agent的回复跟上一轮一模一样陷入死循环。排查发现是状态机在某个状态下没有正确处理用户输入导致状态没有迁移下一轮又回到同一个状态。修复方案是给状态机加了最大停留轮次限制。任何一个状态如果连续三轮没有迁移就强制进入兜底流程由兜底流程判断是继续当前话题还是转人工。这个机制上线之后对话卡死的问题基本消失了。还有一个类似的问题是槽位收集死循环。Agent问“请问您的预算是多少”用户回答“你推荐就行”Agent又追问“请问您的预算是多少”用户又回答“你看着办”如此反复。修复方案是给每个槽位设置最大追问次数超过两次就跳过这个槽位用默认值或者范围值代替并在后续推荐中说明“由于预算信息不明确以下推荐覆盖了不同价位段”。5.4 常见问题速查表问题现象可能原因排查方法解决方案意图识别准确率低短文本缺乏上下文查看错误分类的样本拼接上下文、建立短文本映射表槽位抽取遗漏表达方式超出规则覆盖检查测试用例集补充规则或训练样本对话流程卡死状态机未处理某类输入查看对话日志中的状态迁移增加最大停留轮次限制回复前后矛盾已确认信息未记录检查对话状态对象维护已确认信息表合规话术遗漏生成指令未包含检查生成指令模板强制嵌入合规话术推荐结果不合适槽位更新未触发重评估检查槽位更新逻辑增加推荐重评估触发用户频繁转人工兜底话术不够共情分析转人工前的对话优化兜底话术先共情再引导响应速度慢模型调用链路过长检查各层耗时意图识别用小模型知识检索加缓存6. 几个让我印象深刻的踩坑经历6.1 那个把“等待期”说成“观察期”的下午有一次测试的时候发现Agent在解释等待期的时候有时候说“等待期”有时候说“观察期”。这两个词在保险行业里意思相近但不完全一样不同产品的条款用词也不同。用户如果较真可能会觉得Agent不专业。排查发现是知识片段里两个词都有出现模型在生成的时候随机选了一个。修复方案是在知识片段里统一术语并且在生成指令里明确指定使用哪个词。这个坑让我意识到保险领域的术语标准化比想象中重要。后来我专门做了一份术语对照表把所有同义词、近义词都统一到一个标准表述上模型生成的时候只能使用标准表述。6.2 用户说“我再想想”之后Agent做了什么用户说“我再想想”这是一个很常见的对话结束信号。最开始Agent的处理是直接回复“好的有需要随时联系”然后结束对话。后来分析数据发现这类用户中有相当一部分在几天后又会回来咨询但回来的时候Agent完全不记得之前的对话用户需要重新说一遍需求。于是我加了一个对话暂存与恢复机制。用户说“我再想想”的时候Agent会把当前对话状态保存下来并给用户一个简短的摘要比如“您刚才咨询的是三十岁男性的医疗险预算五千左右我给您推荐了两款产品”。用户下次回来的时候Agent可以恢复之前的对话状态直接接着聊。这个改动之后回访用户的转化率有明显提升。6.3 那个被用户骂“机器人”的回复有一次收到用户反馈说Agent回复太机械了像机器人。我翻了一下对话记录发现用户问“我这种情况能买吗”Agent回复“根据您提供的信息您符合投保条件可以购买”。这个回复本身没错但确实太生硬了。后来我调整了生成指令要求模型在回复中加入共情表达。比如上面那个场景改成“您的情况我了解了从目前的信息来看是符合投保条件的您可以放心。不过投保的时候记得如实告知健康状况这样后续理赔会更顺利”。加了共情和提醒之后用户反馈明显好了很多。这个经历让我明白保险Agent不只是回答问题还要管理用户的情绪。用户咨询保险的时候往往带着焦虑和不确定Agent的回复需要让用户感到被理解和被帮助而不是冷冰冰的信息输出。7. 后续可以继续打磨的方向这个Agent目前已经稳定运行了一段时间日均处理对话量在几千次左右意图识别准确率稳定在百分之九十三以上用户满意度评分在四点五分左右。但我觉得还有不少可以继续优化的地方。第一个方向是个性化推荐。目前推荐逻辑主要基于用户主动提供的信息后续可以结合用户的历史咨询记录、浏览行为等数据做更精准的推荐。当然这涉及到数据隐私和合规问题需要谨慎处理。第二个方向是多模态交互。现在用户只能打字后续可以考虑支持语音输入甚至图片识别比如用户拍一张保单照片Agent自动识别关键信息并解答相关问题。第三个方向是主动服务。目前Agent是被动应答用户问什么答什么。后续可以在关键节点主动提醒比如用户咨询完医疗险之后过几天主动问一句“之前您咨询的医疗险现在考虑得怎么样了有什么我可以帮您的”。这种主动触达需要把握好频率和时机不然容易变成骚扰。第四个方向是知识库的自动化更新。目前知识片段是人工维护的产品条款更新的时候需要手动同步。后续可以做一个半自动化的流程产品文档更新后自动抽取关键信息人工审核后入库减少维护成本。做保险Agent这几个月最大的体会是这个领域技术不是最难的难的是对业务的理解和对细节的把控。模型能力再强如果不懂保险业务的逻辑不懂合规的边界不懂用户的心理做出来的东西就是花架子。反过来只要把业务逻辑理清楚了把流程控制做扎实了模型的能力才能真正发挥出来。这个项目我还会继续迭代后面有新的经验和踩坑记录再接着写。