微软Agent Session

decade
1
2026-03-21

多轮对话与上下文管理 - AgentSession 核心总结

🎯 课程目标

掌握 AgentSession(对话会话)的使用,实现带记忆的连续对话。

  • 理解 AgentSession 的作用和生命周期

  • 创建和管理对话会话,实现多轮对话上下文传递

  • 掌握流式多轮对话与会话隔离机制

💡 为什么需要 AgentSession?

问题回顾

每次调用 RunAsync() 时,如果不传入 session 参数,Agent会创建一个临时会话,调用结束后立即丢弃,导致无法记住之前的对话内容。

解决方案

显式创建并复用 AgentSession

  1. 显式创建 AgentSession

  2. 在所有相关调用中复用同一个 Session

  3. Session 会自动管理消息历史,实现对话记忆


🔑 AgentSession 核心特性

特性

说明

会话隔离

每个 Session 维护独立的对话历史,互不干扰

自动管理

Session 自动存储所有消息(用户消息 + Agent 响应)

可复用

同一个 Session 可以在多次调用中复用

可序列化

Session 可以序列化保存,实现持久化

状态容器

每个 Session 有 StateBag 用于携带任意状态


🚀 快速上手:创建多轮对话

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

API

功能

使用场景

await agent.CreateSessionAsync()

创建新会话

用户会话开始时

agent.RunAsync(msg, session)

同步调用(带会话)

多轮对话

agent.RunStreamingAsync(msg, session)

流式调用(带会话)

多轮流式对话

historyProvider.InvokingAsync(...)

读取历史消息

历史查询、统计与调试

agent.SerializeSession(session)

序列化会话

持久化保存

agent.DeserializeSessionAsync(json)

反序列化会话

恢复会话


✅ 最佳实践与常见错误

推荐做法

  • 为每个用户/会话创建独立的 Session

  • 在整个对话过程中复用同一个 Session

  • 流式场景优先使用带 Session 的重载

  • 利用 StateBag 携带用户ID等自定义状态

常见错误

  • 忘记传入 Session 参数:导致每次都是新对话

  • 为每次调用创建新的 Session:破坏了上下文连续性

  • 多个用户共用同一个 Session:导致对话历史混乱

  • 跨 Agent 复用 Session:Session 是 Agent 特定的,不能混用


📊 调用模式对比

调用方式

Session 参数

是否记忆

使用场景

RunAsync("消息")

❌ 不传

❌ 不记忆

单次独立查询

RunAsync("消息", session)

✅ 传入

✅ 记忆

多轮对话

RunStreamingAsync("消息")

❌ 不传

❌ 不记忆

单次流式查询

RunStreamingAsync("消息", session)

✅ 传入

✅ 记忆

多轮流式对话