Session 管理:会话创建、持久化与恢复
详解 ADK Go 中 Session 的概念、创建、持久化和恢复机制,理解如何在多轮对话中保持 Agent 的上下文。
Session 管理:会话创建、持久化与恢复
Agent 和用户的对话不是一个一个独立请求的——多轮对话需要"会话"的概念,把上下文串起来。Session 就是这个会话的抽象。
什么是 Session
Session(会话)是 Agent 和用户之间的一次完整对话过程。在 Session 里,Agent 记得之前说过什么、用户问过什么,保持上下文连贯。
用户: 你好 Session 1
Agent: 你好,有什么可以帮你?
用户: 上海天气怎么样? Session 1(继续)
Agent: 上海今天晴天,22度
用户: 那北京呢? Session 1(上下文保持)
Agent: 北京今天多云,18度
如果没有 Session,每次请求都是独立的,Agent 就不知道"那北京呢"是在问什么。
Session 的生命周期
创建 Session → 交互(N 轮)→ 结束 Session
创建 Session
session, err := sessions.NewSession(ctx,
sessions.WithUserID("user-123"),
sessions.WithAgentID("my-agent"),
)
创建时指定:
UserID:用户标识AgentID:Agent 标识
交互
response, err := session.Run(ctx, "上海天气怎么样")
// response = "上海今天晴天,22度"
response, err := session.Run(ctx, "那北京呢")
// response = "北京今天多云,18度"(记得上文)
结束 Session
session.End(ctx)
Session 持久化:会话不丢
默认情况下 Session 数据存在内存里,进程重启就丢了。持久化让 Session 跨进程、跨服务保持。
使用 Redis 持久化
import "github.com/go-redis/redis/v8"
redisClient := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
store := sessions.NewRedisStore(redisClient, "sessions:", time.Hour*24)
session, err := sessions.NewSession(ctx,
sessions.WithUserID("user-123"),
sessions.WithAgentID("my-agent"),
sessions.WithStore(store), // 持久化存储
)
恢复 Session
用户重新访问时,从存储里恢复:
session, err := store.LoadSession(ctx, "session-id-xxx")
if err != nil {
// Session 不存在,创建新的
session, _ = sessions.NewSession(ctx, ...)
}
多用户 Session 管理
生产环境里,一个 Agent 服务多个用户。需要为每个用户维护独立的 Session:
type SessionManager struct {
store sessions.Store
mu sync.Map // userID -> session
}
func (m *SessionManager) GetSession(ctx context.Context, userID string) (*Session, error) {
if s, ok := m.mu.Load(userID); ok {
return s.(*Session), nil
}
// 不存在则创建新的
s, err := sessions.NewSession(ctx,
sessions.WithUserID(userID),
sessions.WithAgentID("my-agent"),
sessions.WithStore(m.store),
)
if err != nil {
return nil, err
}
m.mu.Store(userID, s)
return s, nil
}
这样每个用户有独立的会话上下文,互不干扰。
Session 配置参数
| 参数 | 说明 | 默认值 |
|---|---|---|
SessionTTL | Session 过期时间 | 24 小时 |
MaxTurns | 最大对话轮数 | 无限制 |
IdleTimeout | 空闲超时 | 30 分钟 |
session, err := sessions.NewSession(ctx,
sessions.WithUserID("user-123"),
sessions.WithAgentID("my-agent"),
sessions.WithTTL(time.Hour*48), // 48 小时过期
sessions.WithMaxTurns(100), // 最多 100 轮
)
常见问题
Q:Session 存 Redis 太大了
A:Session 数据含历史上下文,定期压缩或清理。可以用 session.Compress() 压缩历史消息。
Q:用户换设备了,Session 能恢复吗 A:只要 Session ID 不变,从存储加载即可。Session ID 可以存在 Cookie 或本地存储里。
Q:Session 太多了,占用内存 A:用带过期时间的 Redis Session,Redis 会自动清理长期不活跃的 Session。
下一步
Session 管理了对话历史,接下来看 State——如何读写 Agent 内部的状态,在多轮对话中保持自定义数据。
← Tool Confirmation 与安全认证 | State 读写 →
想跟着学更多 Go ADK 实战?关注「全栈之巅-梦兽编程」公众号,每周更新 Go / AI 编程实战干货。
