【Agent智能体】39TurnPlanner实现
章节三十九TurnPlanner实现1. 概述TurnPlanner负责根据用户当前输入和对话状态生成本轮对话计划 TurnPlan。整体流程第一步DialogueEngine 收到文本消息调用 TurnPlanner.predict。第二步构建 prompt_inputs把当前状态整理成提示词变量。第三步渲染 planning/turn_plan_v1 提示词。第四步调用 LLM 生成 TurnPlan。第五步TurnPlanValidator 校验是否可直接执行。第六步如果校验通过DialogueEngine 分发到对应 Handler如果校验不通过ClarifyResponder 生成澄清回复。重要边界TurnPlanner负责真实识别用户意图可以识别出多个轨道TurnPlanValidator负责判断当前执行引擎是否能直接处理DialogueEngine只在校验通过后分发到一个具体 Handler当前系统支持三个轨道task任务型流程例如查订单、查物流、申请退款knowledge知识问答例如商品信息、退款政策、配送规则chitchat闲聊例如打招呼、询问助手身份2. TurnPlan JSON 格式LLM 输出的 TurnPlan 是一个 JSON 对象顶层固定包含三个字段task、knowledge、chitchat。如果用户是在办理业务填写 task// 功能说明Task 类型的 TurnPlan 示例// task.commands 包含要执行的命令列表如 start_flow、set_slots 等如果用户是在咨询知识填写 knowledge// 功能说明Knowledge 类型的 TurnPlan 示例// knowledge.intents 包含命中知识意图ID列表如果用户是在闲聊填写 chitchat// 功能说明Chitchat 类型的 TurnPlan 示例// chitchat 为空对象即可如果用户一句话同时表达多个意图LLM 也可以同时填写多个轨道。但这种多意图 TurnPlan 会被 TurnPlanValidator 认定为当前引擎不能直接执行然后引导用户澄清先处理哪一个。3. TurnPlan 模型与 JSON 对应的 Python 模型模型说明TaskTurnPlan对应 task 字段内部保存 commandsKnowledgeTurnPlan对应 knowledge 字段内部保存 intentsChitchatTurnPlan对应 chitchat 字段当前不需要额外参数TurnPlan顶层模型包含 task、knowledge、chitchat 三个可选字段from_dict() 负责把 LLM 输出的 JSON 字典转换成对应模型。# 功能说明TurnPlan 数据模型# 将 LLM 输出的 JSON 解析为 Python 对象# 支持 task/knowledge/chitchat 三种轨道的组合4. TurnPlanner 入口TurnPlanner.predict() 是本组件的入口方法。接收三类信息state当前对话状态flows系统支持的任务流程knowledge_intents系统支持的知识意图入口方法内部调用两个方法build_prompt_inputs()把当前状态、可用 flow、知识意图整理成提示词变量_predict_from_prompt_inputs()使用提示词变量调用 LLM并把输出转换成 TurnPlan# 功能说明TurnPlanner.predict() 入口方法# 1. 构建提示词输入变量# 2. 调用 LLM 生成 TurnPlan# 3. 返回 TurnPlan 对象5. 提示词设计提示词的核心要求TurnPlan 顶层只允许 task、knowledge、chitchat 三个字段这三个字段的值必须是 JSON 对象或 null如果用户同时表达多个意图可以同时填写多个轨道后续执行引擎一次只能处理一个轨道如果输出多个轨道系统会向用户澄清先处理哪一个只输出合法 JSON不要输出 markdown 代码块提示词中使用的参数参数说明available_flows_json系统当前支持的任务流程列表。LLM 根据它判断用户是否要启动某个业务流程knowledge_intents_json系统当前支持的知识意图列表。LLM 根据它选择要查询哪类知识active_task_json当前正在执行的任务。如果用户继续补充信息LLM 可据此生成 set_slots 等命令interrupted_tasks_json当前被暂停的任务列表。如果用户表达继续之前的任务LLM 可据此生成 resume_flowfocused_object_json当前聚焦的业务对象商品或订单。帮助 LLM 判断用户是要办理对象相关业务还是咨询对象相关知识current_conversation最近对话历史。让 LLM 判断当前意图时能参考上下文user_message用户本轮输入的原始文本。TurnPlan 的预测主要围绕这句话展开6. 构造提示词输入build_prompt_inputs() 负责把当前对话状态转换成提示词需要的变量。这一步不会调用 LLM也不会修改状态只是做数据整理。返回的变量包括current_conversation最近对话历史并追加当前用户消息available_flows_json系统支持哪些任务流程去掉 steps 细节active_task_json当前是否有正在执行的任务interrupted_tasks_json当前被暂停的任务列表focused_object_json当前聚焦的商品或订单knowledge_intents_json系统支持哪些知识意图# 功能说明build_prompt_inputs() 提示词输入构建# 将 DialogueState 中的各种状态信息格式化为提示词模板变量# 使用 json.dumps 将对象序列化为 JSON 字符串7. 调用 LLM_predict_from_prompt_inputs() 负责真正调用 LLM。使用 LangChain 的链式写法prompt - llm - JsonOutputParser。执行结果是 JSON 字符串先用 json.loads() 转成字典再通过 TurnPlan.from_dict() 转成 TurnPlan 对象。# 功能说明_predict_from_prompt_inputs() LLM 调用# 加载 turn_plan 提示词模板Jinja2 格式# 组装 LangChain 调用链prompt | llm | JsonOutputParser# 异步调用大模型解析输出为 TurnPlan 对象8. TurnPlanValidator8.1 校验结果定义TurnPlanValidator 的返回值是 TurnPlanValidationResult表达当前 TurnPlan 是否可以执行以及校验失败的原因。ClarifyReason 枚举定义了各种失败原因原因说明MISSING_TRACKTurnPlan 没有命中任何轨道系统无法判断本轮应该做什么MULTIPLE_TRACKSTurnPlan 同时命中了多个轨道执行引擎一次只能处理一个MISSING_TASK_COMMANDS命中了 task 轨道但 commands 为空不知道具体执行什么命令MISSING_KNOWLEDGE_INTENT命中了 knowledge 轨道但 intents 为空不知道查询哪类知识MISSING_FOCUSED_OBJECT知识意图需要聚焦对象但当前状态中没有合适的 focused_objectOBJECT_REQUIRES_INTENT用户只发送了对象但没有说明想做什么8.2 校验逻辑整体流程第一步获取活跃轨道列表_active_tracks。第二步如果没有活跃轨道返回 MISSING_TRACK。第三步如果有多个活跃轨道返回 MULTIPLE_TRACKS。第四步取唯一轨道根据轨道类型分别校验task 轨道校验 commands 是否为空knowledge 轨道校验 intents 是否为空以及是否需要聚焦对象chitchat 轨道直接通过# 功能说明TurnPlanValidator.validate() 校验入口# 1. 检查活跃轨道数量# 2. 根据轨道类型调用对应校验方法# 3. 返回 TurnPlanValidationResultvalid reasontask 校验检查 commands 是否为空。具体 command 是否能执行由后续 TaskHandler 和 CommandProcessor 处理。knowledge 校验检查两件事intents 不能为空如果某个 intent 要求聚焦对象则当前状态中必须有对应类型的 focused_object。例如product_info 需要当前聚焦商品order_info 需要当前聚焦订单refund_policy 这类规则咨询不一定需要聚焦对象。9. ClarifyResponder9.1 概述ClarifyResponder 负责把澄清原因转换成最终的 BotMessage。接收两类信息state当前对话状态和 reason澄清原因。整体处理思路第一步根据 reason 和 state 生成一条基础澄清话术build_clarify_message。第二步读取当前对话历史和聚焦对象。第三步调用 clarify/rewrite 提示词把基础话术改写成自然的客服回复。第四步返回 BotMessage。职责分离TurnPlanValidator 只负责判断失败原因ClarifyResponder 负责生成基础澄清话术并改写成自然回复。9.2 澄清提示词提示词要点角色中文电商客服助手语气自然、友好、简洁任务把系统澄清提示改写成更自然的一句话要求不要扩写不要新增信息不要改变澄清意图提示词变量变量说明reason澄清原因枚举值clarify_message基础澄清话术focused_object当前聚焦对象描述history当前会话历史user_message用户本轮输入文本9.3 基础话术生成build_clarify_message() 根据 reason 生成基础澄清话术原因基础话术MULTIPLE_TRACKS你这次同时提到了多个方向。我们先处理一个你想先办业务还是先咨询信息呢MISSING_FOCUSED_OBJECT请先发送你想咨询的商品或订单我再继续帮你看。MISSING_KNOWLEDGE_INTENT你是想了解商品信息、订单信息还是售后配送规则呢MISSING_TRACK你是想先处理业务问题还是先咨询信息呢MISSING_TASK_COMMANDS你这次是想办理什么业务呢比如查订单、查物流或者申请退款。OBJECT_REQUIRES_INTENT我已经收到这个订单/商品了。你想查状态、查物流还是申请退款/了解信息呢# 功能说明ClarifyResponder 澄清回复生成器# 1. 根据 reason 生成基础澄清话术# 2. 加载对话历史和聚焦对象# 3. 调用 clarify_respond 提示词让 LLM 改写为自然回复# 4. 返回 BotMessage