管理会话、运行和中断
完成第一次调用后,把智能体开发服务平台(AgentWorks)的会话、运行状态和工具处理接入你的业务系统:让用户继续对话、看到任务进度,并在需要时批准、取消或恢复任务。
区分会话和单次运行
一段会话可以包含多条输入和多次运行。chat_id 表示你的业务会话,服务端返回 context_key 用于订阅;每条输入的 msg_id 与事件的 mid 对应。不要用模型消息 ID 或事件到达顺序猜测事件属于哪条输入。
保存业务进度和调用记录
以工单 INC-1024 的“问题分类”为例,你的应用要记住这是哪张工单、向智能体发了哪条消息,以及现在能否继续分派。可以像下表这样保存;工单状态由你的应用定义,chat_id 等字段用于和 AgentWorks 对接。
| 保存的信息 | 示例 | 来源和用途 |
|---|---|---|
| 业务任务和步骤 | INC-1024 / 问题分类 | 应用定义,用于找到本次调用所属的步骤 |
chat_id | ticket-session-42 | 应用生成的 API 请求字段,继续同一会话时复用 |
context_key | account-1_ticket-session-42 | 从 HTTP 响应保存,用于订阅和核对事件 sid |
msg_id | 本次提交生成的 UUID | API 请求标识,用于匹配事件 mid |
| 业务步骤状态 | 等待分类、待人工处理、分类已校验 | 应用根据运行终态和结果校验情况保存 |
| 步骤输出 | 账号 | 应用从回复中选出并检查过的分类值 |
| 续传游标 | 184715 | 已处理并持久保存的事件外层 seq |
| 待处理中断 | 中断 ID、原 mid、处理记录 | 从 pending.id 和事件关联信息保存,用于恢复和去重 |
同时记下发起请求的登录用户。订阅会话或执行业务工具前,检查该用户是否有权访问;同一账号的 Token 不会自动替你的应用区分不同用户。先保存收到的事件和处理进度,再更新续传游标,刷新页面或重启应用后才能接着处理。
智能体这次处理返回 success,而且分类符合要求后,可以用同一次事务保存分类结果和一条待分派任务。以工单编号和“问题分类”步骤作为唯一键,避免重连后重复安排分派。
真正调用工单分派接口时,给这次操作一个固定编号(幂等键),如 INC-1024:assign-team。如果调用超时,先用这个编号查询是否已经分派,再决定要不要重试。msg_id 和续传游标只能帮你找到原请求和漏掉的事件,不能代替工单处理记录。
如何从回复中确定分类、检查是否符合要求,见确认结果后再执行下一步。
识别运行生命周期
用事件更新界面状态,而不是在 HTTP 提交成功时立即显示“任务成功”:
| 收到的信号 | 应用中的处理 |
|---|---|
| HTTP 接收成功 | 显示“已提交”,继续等待输出 |
graph_start | 显示“运行中” |
retry | 显示自动重试提示,继续等待;不重新提交原消息 |
has_pending_interrupt 或新建 pending | 显示“等待处理”,保留待审批或待执行的工具 |
pending_phase: resolved | 移除对应待处理项,继续等待后续事件 |
主智能体的 success、error 或 cancelled | 记录本轮运行终态;成功后继续校验业务步骤输出 |
先匹配目标会话的 sid 和本轮 mid。带 sub 的事件属于子代理,不要用子代理的终态提前结束主任务。字段定义和事件示例见运行事件和完成条件。
处理重试和失败后的上下文
平台自动重试与应用重新提交消息是两件事。收到 retry 时继续等待原请求:单步重试只处理某次模型或工具调用;任务级重试重新尝试当前任务,不另发 graph_start。应用可显示范围和次数,但不要因此再次调用 SendMessage。字段说明见自动重试与错误信息。
任务最终失败后,同一会话仍保留这次运行的上下文。先检查错误、工具结果和外部业务记录,再决定继续追问、修正问题或重新尝试。需要不沿用失败尝试的新对话时,使用新的业务 chat_id。
注意
自动重试不会撤销业务操作
写入工单、发送通知等操作可能已经完成,只是回复没有正常返回。即使平台正在自动重试,应用也要按工具执行记录和业务幂等键避免重复写入。任务失败或取消后,停用原任务的审批和提问入口;重新尝试时处理新任务产生的中断。
创建和继续会话
需要让后续输入沿用当前对话上下文时,保存并复用会话标识,同时为每条新输入建立独立关联。
- 为新的业务会话生成唯一
chat_id,使用字母、数字和连字符。 - 以
chat_type: "group"调用SendMessage,传入可信user_id、新msg_id和content。 - 保存响应
context_key,用它作为sub.d.session_id,首次订阅设置since_seq: 0。 - 检查
subd.d.ok,并只处理属于目标会话和请求的事件。 - 继续会话时复用
chat_id,新输入使用新msg_id;新主题使用新的业务会话标识。
group 在这里是 API 的会话模式,不要求你有一个实际群聊。context_key 是服务端返回的会话标识,不要把它作为 chat_id 再次提交。
规划上下文和保存周期
业务服务自行决定何时开始新会话、保留用户界面状态和清理外部文件。事件回放窗口不是永久历史存储;长期业务记录和审计由你的系统保存。
分开会话不等于分开沙箱、记忆库或业务凭证。需要按用户隔离资源时,结合资源配置方式设计,不要仅依靠 user_id 或不同会话编号。
同一会话按顺序发送请求
同一会话发往 AgentWorks 的请求要按顺序发送。遇到待审批或待执行的工具时,先处理并回复中断,再发送下一条用户输入。重试同一条消息时沿用原 msg_id;发送新消息时使用新 msg_id。断线重连只恢复接收事件,不要自动再发一次原消息。
重连后,你可能再次收到已经处理过的工具请求。执行写入前,先查中断 ID 和业务操作编号是否已有处理记录。服务端对重复消息的短期去重,不能代替你的应用在重启或多个进程同时处理时保存的记录。
响应中断
中断表示智能体需要外部决定或结果才能继续。收到 pending_phase: created 后:
- 保存中断 ID
interrupt_id(来自事件的d.pending.id)、所属会话和原输入的mid,把中断加入待处理列表。 - 按中断 ID 和业务幂等键检查是否已经处理,避免回放时再次执行业务操作。
- 根据中断类型展示审批,或执行业务工具;操作前检查用户权限和工具参数。
- 调用 HTTP
RespondInterrupt回传决定或结果,具体字段见请求示例。 - 收到对应的
resolved事件后移除待处理项,继续等待主智能体终态。HTTP 接收成功时先显示“已提交处理结果”,不要提前宣告整个任务完成。
处理确认型中断
pending.type = hitl 时,向有权决策的用户展示工具名称和参数。批准使用 APPROVE,拒绝使用 REJECT,可在 response_data 提供拒绝原因。不要默认批准未知工具,不要仅靠模型判断替代业务权限。
处理输入和用户工具结果
pending.type = respond 时,按工具契约提供回复。用户工具包需要你的应用校验 name 和字符串 arguments、执行业务代码,再用 RESPOND 返回序列化结果;执行失败使用 ERROR 返回安全错误信息。
APPROVE 不能替代实际工具结果。固定示例见工单助手实战。
取消和恢复运行
用户选择取消时,按以下顺序处理:
- 暂停该会话中新输入的发送,避免取消请求与下一条任务交错。
- 用原业务上下文调用
CancelRun,界面显示“正在取消”。 - 继续观察原运行的终态,再显示已取消、已完成或失败。取消请求被接收时,原运行可能已经完成。
取消不会撤销已完成的外部写入。需要重新尝试任务时,先核对业务操作和待处理中断,再发送新输入。
处理重启、断线和超时
恢复时先找回已保存的请求关联和处理记录,再继续消费事件;保持已完成的业务写入和下一步登记记录,避免回放推进同一步骤多次。
- 持久保存每个会话已处理的外层
seq,断线后退避重连并重新订阅;尚未处理的事件不能提前记为已完成。 - 如果收到
reset,用ListMessages和ListPendingInterrupts重建状态;查询失败时明确报告恢复失败。 - 对未确认结果的工具调用,先查询业务系统的操作记录,不直接重试有副作用的工具。
- 应用超时只代表应用停止等待,不代表远端已取消。需要停止运行时单独提交取消,并核对结果。
协议细节参见心跳、重连与补偿。