.NET+AI | Agent | 会话保存与恢复(4)
目录一句话简介 为什么需要对话持久化典型场景智能客服转人工 核心 API完整工作流程 实现方式1. 序列化对话状态2. 反序列化恢复对话 企业级应用场景场景 1无状态 Web 服务场景 2智能客服转人工⚠️ 最佳实践1. 数据安全2. 异常处理3. 存储选择 总结上一篇一句话简介MAF 提供的对话持久化能力让 Agent 能够序列化保存对话状态并在任意时间恢复解决了企业级应用中跨会话、跨设备、无状态服务的对话连续性问题。 为什么需要对话持久化在企业级 Agent 应用中对话持久化是必不可少的能力场景核心痛点持久化的价值在线客服用户关闭浏览器后对话丢失重新打开时恢复完整历史审批流程审批跨越几天甚至几周任何时间点都能恢复上下文无状态服务多实例部署请求路由不同服务器任何实例都能加载对话状态多渠道接入用户从 Web 切换到移动 App跨设备、跨平台恢复同一对话典型场景智能客服转人工核心价值人工客服接入后无需让用户重复描述问题直接基于完整对话历史快速解决问题。 核心 APIMAF 提供两个核心方法实现对话持久化API作用返回类型thread.Serialize()序列化对话状态为 JSONJsonElementagent.DeserializeThread(json)从 JSON 恢复对话AgentThread完整工作流程 实现方式1. 序列化对话状态当需要保存对话时如转人工、会话暂停// 创建 Agent 并开始对话 var agent chatClient.CreateAIAgent(options); var thread agent.GetNewThread(); // 用户与 AI 进行多轮对话 await agent.RunAsync(问题1, thread); await agent.RunAsync(问题2, thread); // ⭐ 序列化 Thread保存完整对话历史 JsonElement serializedThread thread.Serialize(); // 转换为字符串并保存到存储 string jsonString JsonSerializer.Serialize(serializedThread); await File.WriteAllTextAsync(filePath, jsonString);核心要点Serialize()返回JsonElement包含完整对话历史 可保存到任何存储介质文件、数据库、Redis JSON 数据不包含 API Key可安全存储2. 反序列化恢复对话当需要恢复对话时如人工接入、用户返回// 从存储加载 JSON 数据 string jsonString await File.ReadAllTextAsync(filePath); // 解析为 JsonElement JsonElement reloadedJson JsonSerializer.DeserializeJsonElement(jsonString); // ⭐ 使用 Agent 反序列化恢复 Thread AgentThread resumedThread agent.DeserializeThread(reloadedJson); // 基于恢复的 Thread 继续对话 var response await agent.RunAsync(继续处理问题, resumedThread);核心要点✅ 使用相同配置的 Agent 进行反序列化✅ 恢复的 Thread 包含所有历史消息和上下文✅ 可以立即基于完整历史继续对话 企业级应用场景场景 1无状态 Web 服务在云原生架构中服务通常是无状态的对话持久化至关重要实现要点 每次对话后立即保存到共享存储 每次请求前从存储加载对话状态 支持水平扩展和高可用部署// ✅ 推荐每次对话后立即保存 var response await agent.RunAsync(message, thread); await SaveToRedis(sessionId, thread.Serialize()); return response.Text; // ✅ 恢复时做好异常处理 try { var json await LoadFromRedis(sessionId); thread agent.DeserializeThread(json); } catch { thread agent.GetNewThread(); // 失败时创建新会话 }场景 2智能客服转人工完整的客服系统实现流程第一阶段AI 客服处理// AI 客服判断需要转人工 if (needHumanSupport) { // 保存完整对话历史到工单系统 var serialized thread.Serialize(); await ticketSystem.SaveConversation(ticketId, serialized); await NotifyHumanAgent(ticketId); }第二阶段人工客服接入// 人工客服打开工单 var ticket await ticketSystem.GetTicket(ticketId); // 恢复完整对话历史 var json ticket.ConversationData; var resumedThread agent.DeserializeThread(json); // 人工客服基于完整历史处理问题 var response await agent.RunAsync(humanReply, resumedThread);核心价值✅ 人工客服看到完整对话无需用户重复描述✅ 快速定位问题提升客户满意度✅ 节省沟通时间提高服务效率⚠️ 最佳实践1. 数据安全// ⚠️ JSON 可能包含用户敏感信息生产环境需加密 var serialized thread.Serialize(); var encrypted EncryptionHelper.Encrypt(serialized); await storage.SaveAsync(sessionId, encrypted);2. 异常处理// ✅ 做好容错处理避免反序列化失败影响用户体验 AgentThread GetOrCreateThread(string sessionId) { try { var json storage.Load(sessionId); return agent.DeserializeThread(json); } catch (Exception ex) { logger.LogWarning(ex, Failed to deserialize thread); return agent.GetNewThread(); // 降级处理 } }3. 存储选择存储类型适用场景优势Redis高并发、短期会话读写快支持过期SQL Server需要审计、长期存储事务支持复杂查询Azure Cosmos DB全球分布式应用低延迟自动扩展文件系统开发测试、低并发实现简单无依赖 总结✅核心 APIthread.Serialize()序列化agent.DeserializeThread()恢复✅工作流程Thread → JsonElement → 存储 → JsonElement → Thread✅业务价值避免用户重复描述提升服务效率和满意度✅企业场景在线客服、审批流程、无状态服务、多渠道接入✅最佳实践每次对话后立即保存做好异常处理和数据加密 关键提示对话持久化是企业级 Agent 的必备能力特别是在需要跨会话、跨设备、多实例部署的场景中至关重要。引入地址