多轮对话与上下文管理 - AgentSession 核心总结
🎯 课程目标
掌握 AgentSession(对话会话)的使用,实现带记忆的连续对话。
理解
AgentSession的作用和生命周期创建和管理对话会话,实现多轮对话上下文传递
掌握流式多轮对话与会话隔离机制
💡 为什么需要 AgentSession?
问题回顾
每次调用 RunAsync() 时,如果不传入 session 参数,Agent会创建一个临时会话,调用结束后立即丢弃,导致无法记住之前的对话内容。
解决方案
显式创建并复用 AgentSession:
显式创建
AgentSession在所有相关调用中复用同一个
SessionSession会自动管理消息历史,实现对话记忆
🔑 AgentSession 核心特性
🚀 快速上手:创建多轮对话
1. 创建 Agent 和 Session
csharp
// 创建 Agent
AIAgent agent = chatClient.AsAIAgent(instructions: "...");
// 创建 Session
AgentSession session = await agent.CreateSessionAsync();2. 进行多轮对话
在所有调用中复用同一个 session 对象。
csharp
// 第一轮
await agent.RunAsync("我叫李明", session);
// 第二轮:Agent 记住了姓名
await agent.RunAsync("我叫什么名字?", session);3. 流式多轮对话
使用 RunStreamingAsync 方法,同样需要传入 session。
csharp
await foreach (var chunk in agent.RunStreamingAsync("讲个故事", session))
{
Console.Write(chunk);
}🔒 会话隔离机制
不同的 Session 之间完全独立,互不干扰。这对于多用户场景至关重要。
csharp
// 为两个用户创建独立的会话
AgentSession sessionUserA = await agent.CreateSessionAsync();
AgentSession sessionUserB = await agent.CreateSessionAsync();
// 两个会话的对话历史完全隔离
await agent.RunAsync("用户A的消息", sessionUserA);
await agent.RunAsync("用户B的消息", sessionUserB);📜 访问 Session 历史消息
可以通过 ChatHistoryProvider 获取会话的历史消息,用于统计、调试或导出。
csharp
// 通用方式:适用于所有 ChatHistoryProvider 实现
var historyProvider = agent.GetService<ChatHistoryProvider>();
var history = await historyProvider.InvokingAsync(new (agent, session, []));
// 简便方式:仅适用于默认的 InMemoryChatHistoryProvider
var inMemoryProvider = agent.GetService<InMemoryChatHistoryProvider>();
var messages = inMemoryProvider.GetMessages(session);⚠️ 注意:历史消息应作为只读数据使用。随着对话轮数增加,需注意 Token 限制和内存占用。
🎯 AgentSession 关键 API
✅ 最佳实践与常见错误
推荐做法
为每个用户/会话创建独立的
Session在整个对话过程中复用同一个 Session
流式场景优先使用带
Session的重载利用
StateBag携带用户ID等自定义状态
常见错误
❌ 忘记传入 Session 参数:导致每次都是新对话
❌ 为每次调用创建新的 Session:破坏了上下文连续性
❌ 多个用户共用同一个 Session:导致对话历史混乱
❌ 跨 Agent 复用 Session:Session 是 Agent 特定的,不能混用