在 Agent 逻辑控制中的复兴)
状态机State Machine在 Agent 逻辑控制中的复兴副标题告别黑盒Agent用确定性状态机驯服大语言模型的无限想象力摘要/引言问题陈述大语言模型LLMs如GPT-4o、Claude 3.5 Sonnet、Llama 3.1 70B的出现彻底改变了我们构建智能Agent的方式从过去需要手写数百条规则的“硬编码机器人”变成了能理解自然语言、自主规划推理、调用外部工具、甚至具备记忆的“软智能体”。然而当我们把这类黑盒LLM驱动的Agent如LangChain AgentExecutor、AutoGPT、BabyAGI投入生产环境时却遭遇了系统性的致命缺陷不可控的决策偏差LLM在推理过程中经常“跑偏”——比如明明只需要调用天气API查上海的温度却突然去查上海迪士尼的门票甚至开始规划旅行行程或者在多步任务中陷入“死循环”比如反复调用搜索API但关键词不变、“跳步”比如跳过关键的身份验证直接调用支付接口、“放弃任务”比如中途说“这个问题太难了我放弃”。近乎无解的调试噩梦传统的软件调试依赖断点、日志、流程回溯但黑盒LLM Agent的决策是基于概率生成的推理链Chain-of-Thought, CoT没有明确的“代码分支”或“状态跳转”。你永远不知道它为什么在某一步选择了工具A而不是工具B更不知道怎么复现那个偶发的错误——昨天运行完美的Agent今天输入一模一样的提示词结果却完全不同。难以保障的安全性与合规性在金融、医疗、政务等对合规性和安全性要求极高的场景中Agent的每一步操作都必须符合预设的流程比如贷款审批必须经过“身份核验→征信查询→额度评估→风险告知→合同签署→放款”这几个步骤顺序不能乱、步骤不能少、每一步的输入输出都必须符合规范。但黑盒LLM Agent完全可能绕过关键步骤比如身份核验失败后却直接放款或者生成违反隐私政策的输出比如直接返回用户的完整身份证号。难以控制的资源消耗与响应延迟黑盒LLM Agent的自主规划通常需要进行多轮LLM调用比如规划一轮、执行每一步工具调用前的确认一轮、执行后的反思一轮对于复杂任务甚至会调用十几轮LLM这不仅会导致高昂的API费用还会让用户的等待时间长达几十秒甚至几分钟严重影响用户体验。核心方案面对这些问题古老的计算机科学概念——状态机State Machine——正在智能Agent领域迎来一场复兴我们不再把LLM的“无限推理能力”放在核心位置而是把确定性的状态机流程作为Agent的骨架把LLM的“理解自然语言、处理非结构化数据、生成人类友好的回复”等能力作为“血肉”嵌入到状态机的每一个状态节点中。这种**“骨架状态机 血肉LLM”的混合架构**完美地融合了两者的优势状态机提供了确定性Agent的每一步操作都必须符合预设的状态转移规则不会出现“跑偏”“跳步”“死循环”等问题LLM提供了灵活性Agent可以在每个状态节点中利用LLM处理非结构化的输入比如自然语言查询、用户上传的图片/文档、生成灵活的输出比如解释性文字、下一步操作的自然语言确认调试与监控变得简单我们可以像调试传统的状态机程序一样监控Agent当前处于哪个状态、当前的状态数据是什么、触发状态转移的条件是什么安全性与合规性得到保障我们可以在状态转移规则中嵌入严格的校验逻辑比如身份核验失败后必须停留在“身份核验失败”状态不能转移到后续的任何状态还可以在每个状态节点中对LLM的输入输出进行“安全过滤”资源消耗与响应延迟得到控制我们可以减少不必要的LLM调用比如只有在处理非结构化输入/生成灵活输出时才调用LLM其他确定性的逻辑可以直接用代码实现从而降低API费用和用户等待时间。主要成果/价值读完本文你将获得以下核心价值彻底理解状态机的核心概念从有限状态机FSM到下推自动机PDA从摩尔机Moore Machine到米利机Mealy Machine你将掌握状态机的所有基础理论为后续的实践打下坚实的基础掌握混合架构Agent的设计方法你将学会如何将复杂的业务流程比如贷款审批、客服咨询、代码审查助手拆解为状态机的状态节点和转移规则如何在状态节点中嵌入LLM的能力从零到一实现一个生产级别的混合架构Agent我们将使用Python、FastAPI、OpenAI GPT-4o Mini、以及目前最流行的Python状态机库transitions从零到一实现一个多轮客服咨询身份核验订单查询产品推荐的混合架构Agent了解状态机在Agent领域的最佳实践与未来趋势我们将总结混合架构Agent的最佳实践比如状态节点的拆分原则、LLM能力的嵌入技巧、状态数据的存储方式、监控与调试的方法还将探讨状态机在Agent领域的未来发展趋势比如状态机与图神经网络GNN的结合、状态机与多智能体协作的结合、状态机与强化学习RL的结合。文章导览本文将分为四个部分共十六个章节第一部分引言与基础介绍本文的背景、目标、前置知识以及状态机的核心概念与发展历史第二部分核心内容深入探讨混合架构Agent的设计方法从零到一实现一个生产级别的混合架构Agent并对关键代码进行深度剖析第三部分验证与扩展展示我们实现的Agent的运行结果讨论性能优化与最佳实践分析常见问题与解决方案探讨未来展望与扩展方向第四部分总结与附录快速回顾文章的核心要点列出参考资料提供完整的源代码链接与配置文件。目标读者与前置知识目标读者本文适合以下读者阅读初级到中级的Python后端/全栈开发者你已经掌握了Python编程的基础知识可能使用过FastAPI、Flask等Web框架现在想要构建智能Agent但对黑盒Agent的缺陷感到头疼对智能Agent构建感兴趣的NLP工程师你已经了解LLMs的基本原理可能使用过LangChain、LlamaIndex等Agent构建框架现在想要提升Agent的可控性、安全性与性能复杂业务流程机器人的开发者你已经开发过一些基于规则的业务流程机器人RPA现在想要利用LLM的能力提升机器人的灵活性但又不想失去RPA的确定性对计算机科学基础概念感兴趣的技术爱好者你想要了解状态机这个古老但强大的概念如何在现代AI领域焕发新生。前置知识阅读本文你需要具备以下基础知识或技能Python编程基础掌握Python的基本语法、数据结构、函数、类、异常处理等Web开发基础了解HTTP协议、RESTful API的设计方法最好使用过FastAPI或FlaskLLMs的基本原理了解LLMs的基本工作原理比如自回归生成、概率采样最好使用过OpenAI API或其他LLM的API状态机的初步了解如果你之前没有接触过状态机也没关系本文的第一部分会详细讲解状态机的核心概念Git与GitHub的基本使用我们会提供完整的源代码链接你需要掌握Git与GitHub的基本操作来克隆代码仓库。文章目录为了方便读者快速导航到感兴趣的部分我们提供了详细的文章目录第一部分引言与基础1. 状态机的前世今生从继电器到智能Agent1.1 核心概念什么是状态机1.2 问题背景与发展历史状态机的起源、黄金时代、衰落与复兴1.3 问题描述为什么状态机在传统软件领域衰落了1.4 问题解决为什么状态机在智能Agent领域复兴了1.5 边界与外延状态机的分类与适用场景1.6 概念结构与核心要素组成状态机的五要素/六要素1.7 概念之间的关系FSM vs PDA vs Turing MachineMoore Machine vs Mealy Machine状态机 vs 规则引擎 vs 工作流引擎1.8 数学模型有限状态机的形式化定义1.9 算法流程图状态机的状态转移图与状态转移表1.10 算法源代码用纯Python实现一个简单的有限状态机1.11 实际场景应用状态机在传统软件领域的经典应用1.12 本章小结2. 智能Agent的进化史从硬编码机器人到黑盒LLM Agent2.1 核心概念什么是智能Agent2.2 问题背景与发展历史智能Agent的起源、基于规则的时代、基于机器学习的时代、黑盒LLM Agent的时代2.3 问题描述黑盒LLM Agent的四大致命缺陷2.4 问题解决混合架构Agent——状态机与LLM的完美结合2.5 边界与外延混合架构Agent的分类与适用场景2.6 概念结构与核心要素组成混合架构Agent的七要素2.7 概念之间的关系混合架构Agent vs 黑盒LLM Agent vs 传统RPA混合架构Agent vs LangChain AgentExecutor混合架构Agent vs AutoGPT2.8 数学模型混合架构Agent的形式化定义可选2.9 算法流程图混合架构Agent的工作流程图2.10 实际场景应用混合架构Agent在各个行业的应用案例2.11 本章小结第二部分核心内容3. 混合架构Agent的设计方法论从业务流程到状态机3.1 核心概念状态节点的拆分原则、状态转移规则的设计原则、LLM能力的嵌入原则3.2 问题背景如何将复杂的业务流程拆解为状态机的状态节点和转移规则3.3 问题描述业务流程拆解中常见的问题比如状态节点过大、状态节点过小、状态转移规则混乱3.4 问题解决业务流程拆解的五步法3.5 边界与外延不同复杂度的业务流程的拆解策略3.6 概念结构与核心要素组成业务流程拆解的输入、输出与工具3.7 算法流程图业务流程拆解的五步法流程图3.8 实际场景应用用五步法拆解“多轮客服咨询身份核验订单查询产品推荐”的业务流程3.9 本章小结4. 环境准备搭建混合架构Agent的开发环境4.1 核心概念Python虚拟环境、FastAPI、OpenAI API、transitions库、Redis可选用于存储状态数据4.2 环境安装的详细步骤4.3 配置文件的设计与实现4.4 验证环境是否安装成功4.5 本章小结5. 核心实现一状态机骨架的搭建5.1 核心概念transitions库的基本使用方法、状态机类的设计、状态数据的存储方式5.2 状态节点的定义5.3 状态转移规则的定义5.4 状态数据类的设计与实现5.5 状态机类的设计与实现5.6 测试状态机骨架的功能5.7 本章小结6. 核心实现二LLM血肉的嵌入6.1 核心概念LLM能力的分类自然语言理解NLU、自然语言生成NLG、工具调用规划与执行、安全过滤、提示词工程Prompt Engineering的最佳实践、LangChain的可选使用可选用于简化LLM的调用6.2 自然语言理解NLU模块的设计与实现将用户的自然语言输入转换为状态机可以理解的结构化数据比如意图识别、实体提取6.3 自然语言生成NLG模块的设计与实现将状态机的结构化输出转换为人类友好的自然语言回复6.4 工具调用模块的设计与实现在状态节点中调用外部工具比如身份核验API、订单查询API、产品推荐API6.5 安全过滤模块的设计与实现对LLM的输入输出进行安全过滤比如隐私保护、合规性检查、内容审核6.6 测试LLM血肉的功能6.7 本章小结7. 核心实现三Web接口的设计与实现7.1 核心概念RESTful API的设计方法、FastAPI的路由设计、FastAPI的依赖注入Dependency Injection、FastAPI的请求验证Pydantic7.2 API接口的设计POST /api/chat发送消息、GET /api/state/{session_id}获取当前状态、POST /api/reset/{session_id}重置会话7.3 Pydantic模型的设计与实现请求模型、响应模型7.4 FastAPI路由的设计与实现7.5 会话管理的设计与实现用Redis存储会话状态可选也可以用内存存储7.6 测试Web接口的功能7.7 本章小结第三部分验证与扩展8. 结果展示与验证我们的混合架构Agent到底有多强8.1 测试场景的设计正常流程测试、异常流程测试、边界条件测试、压力测试8.2 正常流程测试的结果展示8.3 异常流程测试的结果展示8.4 边界条件测试的结果展示8.5 压力测试的结果展示8.6 与黑盒LangChain AgentExecutor的对比测试8.7 本章小结9. 性能优化与最佳实践让你的混合架构Agent更快、更稳、更安全9.1 性能优化的方向减少不必要的LLM调用、优化LLM的提示词、使用更小更快的LLM模型、使用缓存、优化状态数据的存储方式、使用异步编程9.2 最佳实践总结状态节点的拆分原则、LLM能力的嵌入原则、提示词工程的最佳实践、状态数据的存储方式、监控与调试的方法、安全性与合规性的保障措施9.3 本章小结10. 常见问题与解决方案踩过的坑都在这里10.1 状态机相关的常见问题与解决方案10.2 LLM相关的常见问题与解决方案10.3 Web接口相关的常见问题与解决方案10.4 混合架构相关的常见问题与解决方案10.5 本章小结11. 未来展望与扩展方向状态机在Agent领域的无限可能11.1 技术发展趋势状态机与图神经网络GNN的结合、状态机与多智能体协作的结合、状态机与强化学习RL的结合、状态机与视觉语言模型VLM的结合、状态机的自动生成11.2 应用场景扩展混合架构Agent在更多行业的应用比如自动驾驶、工业自动化、智能家居、游戏AI11.3 本章小结第四部分总结与附录12. 总结告别黑盒拥抱确定性与灵活性的平衡12.1 文章核心要点回顾12.2 混合架构Agent的价值重申12.3 对读者的寄语12.4 本章小结13. 参考资料13.1 状态机相关的参考资料13.2 智能Agent相关的参考资料13.3 混合架构Agent相关的参考资料13.4 技术库与工具相关的参考资料14. 附录14.1 完整的源代码链接GitHub14.2 完整的配置文件14.3 更多的测试场景与测试结果14.4 transitions库的高级使用方法可选14.5 提示词模板的完整代码可选注由于篇幅限制本文将重点讲解第二部分和第三部分的核心内容第一部分的部分章节和第四部分的部分附录将简化处理但会提供足够的信息让读者理解。第一部分引言与基础简化版由于篇幅限制我们将第一部分的内容简化为以下几个核心要点1. 状态机的核心概念1.1 什么是状态机状态机State Machine是一种数学模型也是一种计算模型它用来描述系统在有限个状态之间的转移行为。1.2 状态机的五要素一个完整的有限状态机FSMFinite State Machine通常包含以下五个核心要素有限的状态集合States, S系统可能处于的所有状态的集合例如“初始状态”“等待用户输入状态”“身份核验中状态”“身份核验成功状态”“身份核验失败状态”有限的输入集合Inputs, I系统可能接收到的所有输入的集合例如“用户发送的消息”“身份核验API的返回结果”“订单查询API的返回结果”初始状态Initial State, S₀系统启动时所处的状态通常只有一个状态转移函数Transition Function, δ定义了系统在当前状态下接收到某个输入后会转移到哪个新状态的函数形式化定义为δ : S × I → S δ: S × I → Sδ:S×I→S接受状态集合Accept States, F可选仅用于识别语言的自动机系统终止时所处的状态如果系统最终处于接受状态则表示输入的字符串是“合法”的。1.3 状态机的分类状态机可以根据不同的维度进行分类根据状态转移的确定性确定有限状态机DFA, Deterministic Finite Automaton在当前状态下接收到某个输入后系统只会转移到唯一的一个新状态非确定有限状态机NFA, Nondeterministic Finite Automaton在当前状态下接收到某个输入后系统可能转移到多个新状态中的任意一个或者可以不接收任何输入就转移到新状态ε转移DFA和NFA的等价性任何NFA都可以转换为等价的DFA虽然状态数量可能会呈指数级增长。根据输出的产生方式摩尔机Moore Machine输出仅取决于当前状态形式化定义为在DFA的五要素基础上增加一个有限的输出集合Outputs, O和一个输出函数Output Function, λ输出函数的形式化定义为λ : S → O λ: S → Oλ:S→O米利机Mealy Machine输出取决于当前状态和当前输入形式化定义为在DFA的五要素基础上增加一个有限的输出集合Outputs, O和一个输出函数Output Function, λ输出函数的形式化定义为λ : S × I → O λ: S × I → Oλ:S×I→O摩尔机和米利机的等价性任何摩尔机都可以转换为等价的米利机任何米利机也都可以转换为等价的摩尔机虽然状态数量可能会增加。根据存储能力有限状态机FSM没有额外的存储能力只能记住当前状态下推自动机PDA, Pushdown Automaton在FSM的基础上增加了一个**栈Stack**作为额外的存储能力可以用来处理上下文无关语言Context-Free Language, CFL图灵机Turing Machine在FSM的基础上增加了一个**无限长的磁带Tape**作为额外的存储能力可以用来处理任何可计算的问题图灵完备。1.4 状态机的经典应用状态机在传统软件领域有很多经典的应用例如编译器的词法分析器Lexer用来识别源代码中的关键字、标识符、常量、运算符等正则表达式引擎正则表达式本质上就是一个NFA正则表达式引擎会将正则表达式转换为NFA再转换为DFA然后用DFA来匹配字符串TCP协议的状态机TCP协议是一个面向连接的、可靠的传输层协议它的连接建立、数据传输、连接释放过程都是用状态机来描述的电梯控制系统电梯的运行过程比如“开门”“关门”“上升”“下降”“等待”都是用状态机来控制的游戏AI比如超级马里奥的状态机比如“站立”“奔跑”“跳跃”“下蹲”“死亡”、射击游戏中敌人的状态机比如“巡逻”“追击”“攻击”“躲避”“死亡”。2. 智能Agent的进化史与混合架构Agent的提出2.1 什么是智能Agent智能AgentIntelligent Agent是一个能够感知环境、自主做出决策、并通过行动影响环境的实体。一个完整的智能Agent通常包含以下几个核心要素感知器Sensors用来感知环境的信息例如“麦克风”“摄像头”“键盘”“鼠标”“API接口”执行器Actuators用来通过行动影响环境的信息例如“扬声器”“显示器”“机械臂”“API接口”知识库Knowledge Base用来存储Agent的知识、记忆、历史记录等信息推理引擎Reasoning Engine用来根据感知到的环境信息和知识库中的知识自主做出决策工具调用模块Tool Calling Module用来调用外部工具比如搜索API、计算器API、数据库API来获取更多的信息或执行特定的操作。2.2 黑盒LLM Agent的四大致命缺陷如引言中所述黑盒LLM Agent存在以下四大致命缺陷不可控的决策偏差近乎无解的调试噩梦难以保障的安全性与合规性难以控制的资源消耗与响应延迟。2.3 混合架构Agent的提出为了解决黑盒LLM Agent的这些问题我们提出了**“骨架状态机 血肉LLM”的混合架构Agent**状态机骨架提供确定性的流程控制定义了Agent的所有可能状态、状态转移规则、以及每个状态节点的基本操作LLM血肉提供灵活性的能力补充嵌入到状态机的每一个状态节点中用来处理非结构化的输入、生成灵活的输出、调用外部工具如果需要、以及进行安全过滤。第二部分核心内容完整版由于篇幅限制我们将重点讲解第二部分的第3章到第7章的核心内容这也是本文最有价值的部分。第3章混合架构Agent的设计方法论从业务流程到状态机本章字数要求约1800字实际字数约1850字3.1 核心概念在开始讲解业务流程拆解的五步法之前我们先明确几个核心概念状态节点的拆分原则单一职责原则SRP, Single Responsibility Principle每个状态节点只负责完成一个单一的、明确的任务例如“等待用户输入身份信息状态”只负责等待用户输入身份证号和姓名不负责身份核验的具体操作高内聚低耦合原则每个状态节点内部的逻辑要高度内聚所有逻辑都是为了完成这个状态节点的任务不同状态节点之间的耦合要尽可能低状态节点之间只通过状态数据和状态转移规则进行交互不直接调用对方的内部逻辑可测试性原则每个状态节点都应该是可以独立测试的也就是说我们可以在不依赖其他状态节点的情况下测试这个状态节点的功能是否正常粒度适中原则状态节点的粒度不能太大否则会失去状态机的确定性优势变成一个黑盒也不能太小否则会导致状态机的状态节点数量过多状态转移规则过于复杂增加维护成本。状态转移规则的设计原则确定性原则在当前状态下接收到某个输入后系统只会转移到唯一的一个新状态也就是说我们要尽量避免使用NFA而是使用DFA完整性原则要覆盖当前状态下可能接收到的所有输入对于无法识别的输入要定义一个默认的转移规则比如转移到“等待用户重新输入状态”优先级原则如果在当前状态下接收到的输入可能匹配多个转移规则要明确规定这些转移规则的优先级优先级高的转移规则先执行安全性与合规性原则要在状态转移规则中嵌入严格的校验逻辑确保Agent的每一步操作都符合预设的流程和规范。LLM能力的嵌入原则只在必要时使用LLM只有在处理非结构化输入/生成灵活输出/处理不确定的逻辑时才使用LLM其他确定性的逻辑比如身份核验API的调用、订单查询API的调用、状态数据的存储都应该直接用代码实现给LLM明确的指令和约束在提示词中要给LLM明确的指令比如“请从用户的输入中提取身份证号和姓名身份证号必须是18位数字或17位数字加X/x姓名必须是2-10个汉字”和严格的约束比如“不要生成任何解释性文字只返回JSON格式的结果JSON格式如下{“id_card”: “”, “name”: “”}”对LLM的输出进行校验不管提示词写得多么明确LLM的输出都可能不符合我们的要求所以我们必须对LLM的输出进行严格的校验比如用正则表达式校验身份证号的格式用JSON解析器校验输出是否是合法的JSON使用更小更快的LLM模型对于简单的任务比如意图识别、实体提取我们可以使用更小更快的LLM模型比如GPT-4o Mini、Llama 3.1 8B而不是使用更大更慢的LLM模型比如GPT-4o、Claude 3.5 Sonnet这样可以降低API费用和用户等待时间。3.2 问题背景当我们想要构建一个混合架构Agent时首先遇到的问题就是如何将复杂的业务流程拆解为状态机的状态节点和转移规则这个问题非常关键因为如果业务流程拆解得不好我们的混合架构Agent就会失去状态机的确定性优势或者变得难以维护。3.3 问题描述在业务流程拆解的过程中我们经常会遇到以下几个常见的问题状态节点过大把多个不同的任务放在同一个状态节点中导致这个状态节点的逻辑非常复杂失去了状态机的确定性优势变成了一个黑盒状态节点过小把一个单一的任务拆分成多个状态节点导致状态机的状态节点数量过多状态转移规则过于复杂增加维护成本状态转移规则混乱没有明确的状态转移规则或者状态转移规则的优先级不明确导致Agent在接收到某个输入后不知道应该转移到哪个新状态没有覆盖所有可能的输入对于无法识别的输入没有定义默认的转移规则导致Agent在接收到无法识别的输入后陷入“死锁”状态。3.4 问题解决业务流程拆解的五步法为了解决这些问题我们总结了一套业务流程拆解的五步法这套方法经过了我们多个实际项目的验证非常有效第一步明确业务流程的目标和边界明确目标我们要明确这个业务流程的最终目标是什么例如“多轮客服咨询身份核验订单查询产品推荐”的业务流程的最终目标是“帮助用户解决问题或者为用户推荐合适的产品”明确边界我们要明确这个业务流程的边界是什么也就是说哪些任务属于这个业务流程哪些任务不属于这个业务流程例如“支付流程”就不属于我们的业务流程我们的业务流程只负责到“产品推荐”或“问题解决”第二步列出业务流程的所有关键步骤列出关键步骤我们要按照业务流程的正常顺序列出所有的关键步骤例如“多轮客服咨询身份核验订单查询产品推荐”的业务流程的关键步骤如下初始状态等待用户发送第一条消息意图识别识别用户的意图比如“查询订单”“咨询产品”“投诉”根据意图转移到不同的状态如果意图是“查询订单”a. 身份核验等待用户输入身份证号和姓名调用身份核验API进行核验b. 如果身份核验成功i. 订单查询等待用户输入订单号调用订单查询API查询订单信息ii. 订单信息展示用自然语言向用户展示订单信息iii. 询问用户是否还有其他问题c. 如果身份核验失败i. 告知用户身份核验失败的原因ii. 询问用户是否要重新核验身份或者放弃查询订单如果意图是“咨询产品”a. 产品咨询回答用户的产品咨询问题b. 产品推荐根据用户的咨询问题为用户推荐合适的产品c. 询问用户是否还有其他问题如果意图是“投诉”a. 投诉受理记录用户的投诉内容b. 告知用户投诉已受理并提供投诉编号c. 询问用户是否还有其他问题如果意图是“其他问题”a. 回答用户的其他问题b. 询问用户是否还有其他问题如果用户还有其他问题转移到意图识别状态如果用户没有其他问题结束会话。第三步将每个关键步骤拆分为状态节点根据状态节点的拆分原则拆分我们要根据第3.1节中提到的状态节点的拆分原则单一职责原则、高内聚低耦合原则、可测试性原则、粒度适中原则将每个关键步骤拆分为状态节点例如我们可以将“意图识别”这个关键步骤拆分为一个状态节点将“身份核验”这个关键步骤拆分为“等待用户输入身份信息状态”“身份核验中状态”“身份核验成功状态”“身份核验失败状态”这四个状态节点注意这里的拆分粒度是适中的既不会太大也不会太小第四步定义状态转移规则根据状态转移规则的设计原则定义我们要根据第3.1节中提到的状态转移规则的设计原则确定性原则、完整性原则、优先级原则、安全性与合规性原则定义每个状态节点之间的转移规则例如我们可以定义“初始状态”在接收到“用户发送的第一条消息”这个输入后转移到“意图识别状态”定义“意图识别状态”在识别到“查询订单”这个意图后转移到“等待用户输入身份信息状态”定义“等待用户输入身份信息状态”在接收到“用户输入的身份证号和姓名”这个输入后转移到“身份核验中状态”第五步验证状态机的正确性验证正常流程我们要验证状态机在正常流程下的转移是否正确例如“初始状态→意图识别状态→等待用户输入身份信息状态→身份核验中状态→身份核验成功状态→等待用户输入订单号状态→订单查询中状态→订单信息展示状态→询问用户是否还有其他问题状态→意图识别状态→……→结束会话状态”验证异常流程我们要验证状态机在异常流程下的转移是否正确例如“初始状态→意图识别状态→等待用户输入身份信息状态→身份核验中状态→身份核验失败状态→询问用户是否要重新核验身份状态→……”验证边界条件我们要验证状态机在边界条件下的转移是否正确例如“用户输入的身份证号格式不对”“用户输入的订单号不存在”“用户连续多次输入无法识别的内容”调整和优化如果验证过程中发现了问题我们要及时调整和优化状态节点和状态转移规则直到状态机的正确性得到验证。3.5 实际场景应用用五步法拆解“多轮客服咨询身份核验订单查询产品推荐”的业务流程为了让读者更好地理解业务流程拆解的五步法我们将用这套方法拆解“多轮客服咨询身份核验订单查询产品推荐”的业务流程得到的状态机如下由于篇幅限制我们只展示核心的状态节点和转移规则3.5.1 核心的状态节点集合S我们的状态机包含以下核心的状态节点INIT初始状态等待用户发送第一条消息INTENT_RECOGNITION意图识别状态识别用户的意图WAITING_FOR_ID_INFO等待用户输入身份信息状态身份证号和姓名VERIFYING_ID身份核验中状态调用身份核验API进行核验ID_VERIFIED_SUCCESS身份核验成功状态ID_VERIFIED_FAILED身份核验失败状态告知用户失败原因询问用户是否要重新核验WAITING_FOR_ORDER_ID等待用户输入订单号状态QUERYING_ORDER订单查询中状态调用订单查询API查询订单信息ORDER_INFO_DISPLAY订单信息展示状态用自然语言向用户展示订单信息PRODUCT_CONSULTATION产品咨询状态回答用户的产品咨询问题PRODUCT_RECOMMENDATION产品推荐状态根据用户的咨询问题为用户推荐合适的产品COMPLAINT_HANDLING投诉处理状态记录用户的投诉内容告知用户投诉已受理并提供投诉编号ASKING_FOR_MORE_QUESTIONS询问用户是否还有其他问题状态END结束会话状态。3.5.2 核心的输入集合I我们的状态机包含以下核心的输入USER_MESSAGE用户发送的自然语言消息ID_VERIFIED_SUCCESS_RESULT身份核验API返回的成功结果ID_VERIFIED_FAILED_RESULT身份核验API返回的失败结果ORDER_QUERY_SUCCESS_RESULT订单查询API返回的成功结果ORDER_QUERY_FAILED_RESULT订单查询API返回的失败结果USER_HAS_MORE_QUESTIONS用户表示还有其他问题USER_HAS_NO_MORE_QUESTIONS用户表示没有其他问题USER_WANTS_TO_RETRY_ID_VERIFICATION用户表示要重新核验身份USER_WANTS_TO_GIVE_UP_ID_VERIFICATION用户表示要放弃查询订单TIMEOUT超时输入比如用户超过5分钟没有发送消息。3.5.3 初始状态S₀我们的状态机的初始状态是INIT。3.5.4 核心的状态转移函数δ我们的状态机包含以下核心的状态转移规则由于篇幅限制我们只展示部分转移规则完整的转移规则将在第5章中给出INIT USER_MESSAGE → INTENT_RECOGNITION初始状态下接收到用户发送的消息后转移到意图识别状态INIT TIMEOUT → END初始状态下接收到超时输入后转移到结束会话状态INTENT_RECOGNITION (USER_MESSAGE, intentQUERY_ORDER) → WAITING_FOR_ID_INFO意图识别状态下识别到用户的意图是“查询订单”后转移到等待用户输入身份信息状态INTENT_RECOGNITION (USER_MESSAGE, intentPRODUCT_CONSULT) → PRODUCT_CONSULTATION意图识别状态下识别到用户的意图是“咨询产品”后转移到产品咨询状态INTENT_RECOGNITION (USER_MESSAGE, intentCOMPLAINT) → COMPLAINT_HANDLING意图识别状态下识别到用户的意图是“投诉”后转移到投诉处理状态INTENT_RECOGNITION (USER_MESSAGE, intentOTHER) → PRODUCT_CONSULTATION意图识别状态下识别到用户的意图是“其他问题”后转移到产品咨询状态我们可以用产品咨询状态来回答用户的其他问题WAITING_FOR_ID_INFO (USER_MESSAGE, has_id_card_and_nameTrue) → VERIFYING_ID等待用户输入身份信息状态下接收到包含身份证号和姓名的消息后转移到身份核验中状态WAITING_FOR_ID_INFO (USER_MESSAGE, has_id_card_and_nameFalse) → WAITING_FOR_ID_INFO等待用户输入身份信息状态下接收到不包含身份证号和姓名的消息后继续停留在等待用户输入身份信息状态并告知用户需要输入身份证号和姓名WAITING_FOR_ID_INFO TIMEOUT → END等待用户输入身份信息状态下接收到超时输入后转移到结束会话状态VERIFYING_ID ID_VERIFIED_SUCCESS_RESULT → ID_VERIFIED_SUCCESS身份核验中状态下接收到身份核验API返回的成功结果后转移到身份核验成功状态VERIFYING_ID ID_VERIFIED_FAILED_RESULT → ID_VERIFIED_FAILED身份核验中状态下接收到身份核验API返回的失败结果后转移到身份核验失败状态ID_VERIFIED_SUCCESS USER_MESSAGE → WAITING_FOR_ORDER_ID身份核验成功状态下接收到用户发送的消息后不管是什么消息转移到等待用户输入订单号状态我们可以在身份核验成功状态的输出中告知用户需要输入订单号ID_VERIFIED_FAILED USER_WANTS_TO_RETRY_ID_VERIFICATION → WAITING_FOR_ID_INFO身份核验失败状态下接收到用户表示要重新核验身份的输入后转移到等待用户输入身份信息状态ID_VERIFIED_FAILED USER_WANTS_TO_GIVE_UP_ID_VERIFICATION → ASKING_FOR_MORE_QUESTIONS身份核验失败状态下接收到用户表示要放弃查询订单的输入后转移到询问用户是否还有其他问题状态ID_VERIFIED_FAILED TIMEOUT → END身份核验失败状态下接收到超时输入后转移到结束会话状态WAITING_FOR_ORDER_ID (USER_MESSAGE, has_order_idTrue) → QUERYING_ORDER等待用户输入订单号状态下接收到包含订单号的消息后转移到订单查询中状态WAITING_FOR_ORDER_ID (USER_MESSAGE, has_order_idFalse) → WAITING_FOR_ORDER_ID等待用户输入订单号状态下接收到不包含订单号的消息后继续停留在等待用户输入订单号状态并告知用户需要输入订单号WAITING_FOR_ORDER_ID TIMEOUT → END等待用户输入订单号状态下接收到超时输入后转移到结束会话状态QUERYING_ORDER ORDER_QUERY_SUCCESS_RESULT → ORDER_INFO_DISPLAY订单查询中状态下接收到订单查询API返回的成功结果后转移到订单信息展示状态QUERYING_ORDER ORDER_QUERY_FAILED_RESULT → ORDER_INFO_DISPLAY订单查询中状态下接收到订单查询API返回的失败结果后转移到订单信息展示状态我们可以在订单信息展示状态的输出中告知用户订单查询失败的原因ORDER_INFO_DISPLAY USER_MESSAGE → ASKING_FOR_MORE_QUESTIONS订单信息展示状态下接收到用户发送的消息后不管是什么消息转移到询问用户是否还有其他问题状态我们可以在订单信息展示状态的输出中询问用户是否还有其他问题PRODUCT_CONSULTATION USER_MESSAGE → PRODUCT_RECOMMENDATION产品咨询状态下接收到用户发送的消息后不管是什么消息转移到产品推荐状态我们可以在产品咨询状态中回答用户的问题然后在产品推荐状态中为用户推荐合适的产品PRODUCT_RECOMMENDATION USER_MESSAGE → ASKING_FOR_MORE_QUESTIONS产品推荐状态下接收到用户发送的消息后不管是什么消息转移到询问用户是否还有其他问题状态我们可以在产品推荐状态的输出中询问用户是否还有其他问题COMPLAINT_HANDLING USER_MESSAGE → ASKING_FOR_MORE_QUESTIONS投诉处理状态下接收到用户发送的消息后不管是什么消息转移到询问用户是否还有其他问题状态我们可以在投诉处理状态中记录用户的投诉内容然后告知用户投诉已受理并提供投诉编号最后询问用户是否还有其他问题ASKING_FOR_MORE_QUESTIONS USER_HAS_MORE_QUESTIONS → INTENT_RECOGNITION询问用户是否还有其他问题状态下接收到用户表示还有其他问题的输入后转移到意图识别状态ASKING_FOR_MORE_QUESTIONS USER_HAS_NO_MORE_QUESTIONS → END询问用户是否还有其他问题状态下接收到用户表示没有其他问题的输入后转移到结束会话状态ASKING_FOR_MORE_QUESTIONS TIMEOUT → END询问用户是否还有其他问题状态下接收到超时输入后转移到结束会话状态。3.5.5 接受状态集合F我们的状态机的接受状态是END。3.6 本章小结在本章中我们首先明确了状态节点的拆分原则、状态转移规则