第 2.8.3 节:用条件边、循环和人工中断控制复杂流程
条件边、循环和人工中断只有拆成可执行步骤,才容易复核、排错和交接。完成本节后,你应该能够按顺序说明条件边、循环和人工中断的触发、处理、复核、记录和兜底步骤。
实现步骤或决策流程
读图重点:按优先级读:缺字段先暂停;工具失败只能在上限内回环;高风险写入必须经过人工中断点,同意才执行,修改会再次确认,拒绝则安全结束。
推荐技术流
把已设计的客服状态迁移表落成 LangGraph(智能体状态图框架)状态图,推荐按下面顺序做。
| 步骤 | 做什么 | 为什么 |
|---|---|---|
| 1 | 选定一条业务主线 | 先做“退款投诉处理”,不要一开始覆盖所有客服场景。 |
| 2 | 复用已验收的状态迁移表 | 状态图不是凭空画,必须来自已验收的状态迁移。 |
| 3 | 定义运行状态字段 | 明确哪些字段决定分支、恢复、权限和日志。 |
| 4 | 拆分节点 | 每个节点对应一个可测试业务动作。 |
| 5 | 定义固定边 | 表达稳定顺序,例如校验通过后查订单。 |
| 6 | 定义条件边 | 表达缺信息、无权限、工具失败、需要人工、完成或转人工。 |
| 7 | 加入循环上限 | 工具重试、用户补充、草稿修改都要有退出条件。 |
| 8 | 加入人工中断点 | 写入动作、高风险动作和争议判断必须可暂停确认。 |
| 9 | 设计检查点和恢复 | 用户离开、服务重启、人工延迟后能从正确位置继续。 |
| 10 | 设计日志和可视化 | 每个节点、边和状态变化都能被复盘。 |
| 11 | 用路径样例验收 | 不只验收成功路径,也验收失败、越权、重试和人工拒绝路径。 |
这条技术流的核心理由是:LangGraph(智能体状态图框架)应该服务业务流程,不应该从框架示例反推业务。
字段契约
本章不写代码,但状态图一定需要字段契约。字段契约是图能否稳定运行的核心。
运行状态字段
| 字段 | 含义 | 来源 | 用途 | 验收要求 |
|---|---|---|---|---|
| trace_id(追踪编号) | 串联一次用户请求和图运行 | 系统生成 | 日志、排障、面试复盘 | 每次图运行必须有。 |
| session_id(会话编号) | 串联多轮对话 | 用户入口或会话系统 | 恢复上下文 | 用户补充信息能接上旧任务。 |
| task_id(任务编号) | 串联一次业务任务 | 任务状态管理器 | 区分同一会话内多个诉求 | 退款和物流咨询不能混在一起。 |
| current_node(当前节点) | 状态图当前执行到哪里 | 编排层更新 | 前端展示、恢复执行 | 暂停后能展示正确节点。 |
| current_step(当前业务步骤) | 业务层当前阶段 | 节点输出 | 给产品和客服理解流程 | 不依赖框架内部名称也能看懂。 |
| intent(意图) | 用户诉求类型 | 分流层 | 决定初始路径 | 可追溯到用户输入或分类结果。 |
| risk_level(风险等级) | 当前任务风险 | 分流层和规则 | 决定是否人工确认 | 高风险不能自动执行写入或资金动作。 |
| missing_fields(缺失字段) | 当前还缺哪些信息 | 节点输出 | 决定是否追问 | 补齐后必须移除对应字段。 |
| order_id(订单号) | 当前处理订单 | 用户选择或订单系统 | 查订单、查政策、建工单 | 必须做归属校验。 |
| tool_results(工具结果摘要) | 工具返回的关键事实 | 工具节点 | 后续分支和回答 | 不保存不必要敏感字段。 |
| approval_required(需要审批) | 是否需要人工确认 | 规则或政策节点 | 路由到人工确认 | 高风险路径必须为 true。 |
| approval_status(审批状态) | 待确认、同意、拒绝、修改 | 人工确认模块 | 决定继续或回退 | 每次确认要有确认人和时间。 |
| retry_count(重试次数) | 当前失败重试次数 | 循环与重试模块 | 防止无限循环 | 超过上限必须停止或转人工。 |
| stop_reason(停止原因) | 本次运行为什么结束 | 最终节点 | 质检、监控、面试说明 | 必须覆盖完成、缺信息、转人工、失败、拒绝。 |
节点契约
每个节点都要有清晰契约。下面用客服退款投诉流程举例。
| 节点 | 输入状态 | 输出状态 | 可调用能力 | 失败处理 |
|---|---|---|---|---|
| classify_intent(识别意图) | 用户输入、会话摘要 | intent(意图)、risk_level(风险等级) | 模型分类、规则校验 | 输出无效时重试一次,仍无效转人工或安全兜底。 |
| ask_for_order_id(追问订单号) | missing_fields(缺失字段)包含 order_id(订单号) | stop_reason(停止原因)为 need_info(需要补充信息) | 前端追问 | 暂停并保存检查点,不继续查订单。 |
| validate_order_scope(校验订单归属) | user_id(用户编号)、order_id(订单号) | permission_status(权限状态) | 订单归属校验工具 | 无权限时拒绝并记录。 |
| check_order_status(查订单状态) | 已校验订单号 | tool_results(工具结果)里的订单摘要 | 查订单工具 | 超时可重试,超过上限转人工。 |
| search_after_sales_policy(查售后政策) | 订单摘要、问题类型 | policy_result(政策结果)、approval_required(需要审批) | RAG(检索增强生成)或政策工具 | 无匹配政策时转人工,不让模型硬判。 |
| prepare_ticket_draft(准备工单草稿) | 用户诉求、订单摘要、政策结果 | ticket_draft(工单草稿) | 模型摘要、规则模板 | 草稿缺字段时回到补信息。 |
| human_confirm(人工确认) | ticket_draft(工单草稿)、风险提示 | approval_status(审批状态) | 用户确认或客服审核 | 等待期间暂停,拒绝则结束或回改。 |
| create_ticket(创建工单) | 已确认草稿、幂等键 | ticket_id(工单编号)、ticket_status(工单状态) | 创建工单工具 | 失败转人工;疑似重复时查询已有工单。 |
| final_response(最终答复) | 工具结果、工单结果、停止原因 | final_summary(最终摘要) | 模型组织回复 | 不能编造未返回的工单编号或审批结果。 |
条件边契约
| 条件边 | 判断依据 | 目标节点 | 默认兜底 |
|---|---|---|---|
| 是否缺信息 | missing_fields(缺失字段)是否为空 | ask_for_order_id(追问订单号)或 validate_order_scope(校验订单归属) | 字段不确定时追问,不调用工具。 |
| 是否有权限 | permission_status(权限状态) | check_order_status(查订单状态)或 reject_request(拒绝请求) | 无法确认归属时拒绝或转人工。 |
| 工具是否成功 | tool_status(工具状态)和 error_type(错误类型) | 下一业务节点、重试节点或转人工节点 | 未知错误不让模型猜结果。 |
| 是否需要人工 | risk_level(风险等级)、policy_result(政策结果)、approval_required(需要审批) | human_confirm(人工确认)或 final_response(最终答复) | 高风险默认人工确认。 |
| 是否继续循环 | retry_count(重试次数)、max_retry(最大重试次数) | 原节点或 handoff_to_human(转人工) | 超过上限必须退出。 |
| 确认结果如何 | approval_status(审批状态) | create_ticket(创建工单)、prepare_ticket_draft(准备工单草稿)或结束 | 未确认不能执行写入。 |
制作步骤
第 1 步:从状态迁移表出发
不要先打开框架文档照抄示例。先拿客服任务迁移表:
| 当前状态 | 触发事件 | 下一个状态 | 系统动作 |
|---|---|---|---|
| new_task(新任务) | 用户提交退款投诉 | waiting_for_order_id(等待订单号) | 追问订单号,记录高风险。 |
| waiting_for_order_id(等待订单号) | 用户补充订单号 | ready_to_check_order(可查订单) | 校验订单号格式和归属。 |
| ready_to_check_order(可查订单) | 权限通过 | checking_order(正在查订单) | 调用查订单工具。 |
| checking_order(正在查订单) | 工具成功 | ready_to_search_policy(可查政策) | 保存订单结果摘要。 |
| ready_to_search_policy(可查政策) | 政策要求人工 | waiting_approval(等待审批) | 准备工单草稿并等待确认。 |
| waiting_approval(等待审批) | 用户确认 | creating_ticket(创建工单中) | 调用创建工单工具。 |
| creating_ticket(创建工单中) | 工单创建成功 | completed(完成) | 返回工单编号和处理摘要。 |
然后问三个问题:
- 哪些状态适合变成节点?
- 哪些触发事件适合变成条件边?
- 哪些地方需要暂停、恢复、重试或人工确认?
第 2 步:确定图的边界
一张图不要包办整个客服系统。建议起步版本只覆盖“退款投诉处理”这条主线。
图内负责:
- 读取和更新任务状态。
- 编排节点顺序。
- 控制条件分支。
- 控制重试、暂停、恢复和结束。
图外负责:
- 用户登录和身份系统。
- 订单系统真实查询。
- 售后政策资料维护。
- 工单系统真实写入。
- 权限规则配置。
- 日志存储和监控平台。
边界越清楚,状态图越容易维护。
第 3 步:把业务动作拆成节点
节点不要按“模型调用一次”来拆,而要按“业务上可验收的一步”来拆。
| 业务动作 | 是否适合成为节点 | 理由 |
|---|---|---|
| 识别退款投诉意图 | 适合 | 输出会影响后续路径。 |
| 追问订单号 | 适合 | 会暂停并等待用户输入。 |
| 校验订单归属 | 适合 | 权限边界,不能省略。 |
| 查订单状态 | 适合 | 独立工具动作,可重试。 |
| 查售后政策 | 适合 | 影响是否人工确认。 |
| 准备工单草稿 | 适合 | 写入前需要用户确认。 |
| 创建工单 | 适合 | 写入动作,需要幂等和审计。 |
| 调整一个临时变量 | 不适合 | 太细,会让节点膨胀。 |
第 4 步:定义条件边
条件边要优先根据结构化状态判断。
| 判断问题 | 使用字段 | 分支 |
|---|---|---|
| 信息是否完整? | missing_fields(缺失字段) | 缺字段则追问,完整则校验权限。 |
| 订单是否属于当前用户? | permission_status(权限状态) | 通过则查订单,不通过则拒绝。 |
| 工具是否成功? | tool_status(工具状态) | 成功进入下一步,失败进入重试或转人工。 |
| 是否高风险? | risk_level(风险等级)和 policy_result(政策结果) | 高风险进入人工确认。 |
| 用户是否确认? | approval_status(审批状态) | 同意创建工单,修改回草稿,拒绝结束。 |
如果一个条件边的判断依据说不清,它就不应该自动执行。
第 5 步:加入暂停点
客服流程至少有两个暂停点:
- 缺少订单号时,暂停等待用户补充。
- 创建工单前,暂停等待用户确认或客服审核。
暂停点需要展示给用户或审核人的信息包括:
| 字段 | 含义 |
|---|---|
| pending_node(等待节点) | 当前停在哪个节点。 |
| pending_reason(等待原因) | 为什么暂停。 |
| requested_input(需要输入) | 需要用户补充什么。 |
| action_preview(动作预览) | 如果确认,系统将执行什么动作。 |
| risk_notice(风险提示) | 这一步有什么风险或限制。 |
| expires_at(过期时间) | 多久不处理会超时。 |
第 6 步:加入恢复策略
恢复时不要只说“继续执行”。要先校验:
- 当前用户是否仍有权限访问这个任务。
- 任务是否仍处于可恢复状态。
- 检查点状态字段是否完整。
- 之前是否已经执行过写入动作。
- 如果状态版本变化,是否需要迁移或转人工。
恢复路径可以这样设计:
| 恢复来源 | 恢复动作 | 风险控制 |
|---|---|---|
| 用户补充订单号 | 从 waiting_for_order_id(等待订单号)继续到校验订单归属 | 先校验订单属于当前用户。 |
| 人工同意工单草稿 | 从 waiting_approval(等待审批)继续到创建工单 | 确认审批状态和幂等键。 |
| 工具超时后重试 | 从失败节点回到原工具节点 | 检查 retry_count(重试次数)。 |
| 系统重启后恢复 | 读取最新检查点和状态日志 | 不重复执行已成功写入动作。 |
第 7 步:设计可视化和验收路径
状态图至少要能展示:
- 当前节点。
- 已执行节点。
- 下一步候选节点。
- 暂停原因。
- 失败节点和错误原因。
- 人工确认状态。
- 最终停止原因。
验收时不要只跑“用户信息完整、工具全成功”的路径。还要跑缺订单号、越权、工具超时、人工拒绝、重复确认和恢复失败。
和后续章节的关系
| 后续章节或主题 | 和本章的关系 |
|---|---|
| 多智能体协作 | 多个 Agent(智能体)之间的转交,本质上也需要状态图和交接条件。 |
| 前端界面 | 前端要展示当前节点、等待确认、失败原因和处理进度。 |
| 安全、权限与审批 | 本章的人工确认节点会在安全章节继续扩展成审批流和风控策略。 |
| 测试与可观测性 | 节点日志、状态迁移日志和路径验收会成为监控与测试基础。 |
| 商业交付 | 客户更关心“哪些路径能稳定走完、失败怎么处理”,状态图能变成验收材料。 |
| 部署与运维 | 检查点、恢复、超时和重试会影响生产部署策略。 |
本章是工具治理到多智能体协作之间的桥梁。没有状态图思维,多智能体很容易变成多个模型互相转述;有了状态图,转交、复核和监督才有可控边界。
岗位 JD(职位描述) 能力映射
LangGraph(智能体状态图框架)相关岗位要求通常不会只写框架名,而会写“复杂 Agent 流程编排”“人工确认”“可恢复工作流”和“可观测性”。
| JD(职位描述)常见要求 | 本章对应能力 | 面试证据 |
|---|---|---|
| 设计复杂 Agent 工作流 | 能把退款投诉处理拆成 State(状态)、Node(节点)、Edge(边)和 Conditional Edge(条件边) | 展示退款投诉状态图和节点契约表。 |
| 支撑人工确认和审批流程 | 能设置暂停点、确认内容、恢复入口和审批状态 | 说明创建工单前为什么必须保存检查点。 |
| 保障任务恢复和幂等 | 能避免系统重启、用户刷新或重复确认导致重复写入 | 用 task_id(任务编号)、action_key(动作键)和 retry_count(重试次数)解释。 |
| 建设可观测 Agent 链路 | 能记录节点日志、状态迁移日志、工具日志和人工确认日志 | 用 trace_id(追踪编号)还原一次完整路径。 |
版本与资料来源
本节聚焦 LangGraph(智能体状态图框架)的状态图设计、业务编排、人工确认、恢复、日志和面试表达。
主要资料入口:
- LangGraph(智能体状态图框架)总览:https://docs.langchain.com/oss/python/langgraph/overview
- LangGraph(智能体状态图框架) Graph API(应用程序接口)说明:https://docs.langchain.com/oss/python/langgraph/graph-api
- LangGraph(智能体状态图框架) Persistence(持久化)说明:https://docs.langchain.com/oss/python/langgraph/persistence
- LangGraph(智能体状态图框架) Interrupts(中断)说明:https://docs.langchain.com/oss/python/langgraph/interrupts
- LangGraph(智能体状态图框架) Workflows and agents(工作流与智能体)说明:https://docs.langchain.com/oss/python/langgraph/workflows-agents
- OpenAI(模型服务商) Agents SDK(智能体软件开发工具包)文档:https://openai.github.io/openai-agents-python/
过时风险:LangGraph(智能体状态图框架)、LangChain(大模型应用框架)和 OpenAI(模型服务商) Agents SDK(智能体软件开发工具包)会持续更新。进入真实项目开发前,必须重新核对当前官方文档、版本说明和团队使用的运行时能力。