指南 04 · 交互式对话(暂停 / 恢复)¶
让 Agent 流程跑到一半停下来问用户要信息(选一项、填一段),拿到答复后再接着跑。这是「多轮交互式办理」(如让用户确认业务类型、补充手机号)的实现基础。
对应两个节点:
UserSelect:给用户一组选项选一个。UserInput:让用户自由输入一段。
0. 前提:必须带 checkpointer¶
交互式暂停/恢复依赖断点:暂停时把现场存起来,用户答复后凭同一 chatId 恢复。wf.compile() 不带 store 就无法跨请求恢复。至少用内存断点:
from agentframework.state.checkpoint import MemoryCheckpointStore
app = wf.compile(store=MemoryCheckpointStore()) # 内存:同进程跨请求可恢复
生产要进程重启不丢,接持久化 saver(见指南 06)。
1. UserSelect — 让用户选¶
from agentframework.nodes import UserSelect
wf.add_node(
UserSelect(
name="choose",
description="请选择业务类型", # 给用户的问题
options=[
{"key": "a", "value": "贷款"}, # 选项:key + value
{"key": "b", "value": "还款"},
],
)
)
- 输入:
description(必填,问题)、options(必填,[{key, value}, ...])。 - 输出:
selected——用户选中的value。 - 行为:暂停时向客户端发
interactive载荷(type="userSelect");恢复时校验提交值必须属于选项value,否则抛ValueError。
执行到这一步,网关会发 SSE interactive 事件,前端据此渲染选项;用户提交后流程恢复,selected 存进状态供下游 wf.ref("choose.selected") 读取。
2. UserInput — 让用户输入¶
from agentframework.nodes import UserInput
wf.add_node(UserInput(name="ask", description="请输入您的手机号"))
- 输入:
description(必填,问题)。 - 输出:
input——用户输入内容。
3. 组合:判断 → 交互 → 分支¶
典型客服流:先让模型判断要不要转人工,需要就让用户选,再按选择分流。
from agentframework import Workflow
from agentframework.nodes import Answer, ChatLLM, IfElse, UserSelect
wf = Workflow(name="interactive_cs")
wf.add_node(ChatLLM(name="llm", chat_model=model, output=False))
wf.add_node(
IfElse(
name="judge", left=wf.ref("llm.reply"), condition=lambda i, ctx: "转人工" in str(i["left"])
)
)
wf.add_node(
UserSelect(
name="select",
description="请问需要办理什么业务?",
options=[{"key": "loan", "value": "贷款"}, {"key": "repay", "value": "还款"}],
)
)
wf.add_node(Answer(name="auto", text="已为您自动处理"))
wf.add_node(Answer(name="loan", text="为您办理贷款业务"))
wf.add_node(Answer(name="repay", text="为您办理还款业务"))
wf.add_edge("llm", "judge")
wf.add_conditional_edge("judge", {True: "select", False: "auto"})
wf.add_conditional_edge("select", {"贷款": "loan", "还款": "repay"})
4. 客户端视角¶
对客户端而言,一次交互式请求分两段:
- 第一段请求:跑流程到
UserSelect/UserInput→ 收到interactive事件,流程暂停。 - 恢复请求:客户端带上用户答复(
Command(resume=...)语义,chatId不变)再发一次 → 流程从断点续跑,最终回到[DONE]。
事件/恢复载荷的精确字段(
interactive的params、恢复用的Command)以仓库doc/Agent接口契约.md为准。
5. 完整可运行示例¶
- interactive_flow 示例:ChatLLM + IfElse + UserSelect 最小交互流(内存断点)。
- sqlite_persistence 示例:交互 + SQLite 持久化,演示进程重启后交互仍可恢复。
- postgres_persistence / mongodb_persistence / mysql_persistence:各库持久化下的
UserSelect恢复。 - withdrawal_customer_service 示例:用
UserInput在阶段中让用户补充信息,恢复后写入变量回传。