Session

AgentSession 是跨代理运行使用的会话状态容器。

AgentSession的内容包含

字段 目的
StateBag 此会话的任意状态容器

C# AgentSession 是一个抽象基类。 具体实现(通过 CreateSessionAsync() 创建)在使用服务管理的历史记录时,可能会添加其他状态,例如用于远程聊天历史记录存储的 ID。

字段 目的
session_id 此会话的本地唯一标识符
service_session_id 使用服务管理的历史记录时的远程服务会话标识符,例如对话或响应的 ID
state 与上下文/历史记录提供程序共享的可变字典
字段 目的
agent.Session 绑定到会话的键值状态容器

会话提供类型化的键值存储:

type UserPrefs struct {
    Theme    string `json:"theme"`
    Language string `json:"language"`
}

session.Set("user_prefs", UserPrefs{Theme: "dark", Language: "en"})

var prefs UserPrefs
session.Get("user_prefs", &prefs)

session.Delete("user_prefs")

服务会话 ID 的作用域

使用服务管理的历史记录时,会话可以包含服务颁发的会话标识符。 例如,OpenAI 响应可以使用 resp_* 响应 ID 作为 previous_response_id,OpenAI 对话 API 可能使用 conv_* 会话 ID 作为对话。

默认情况下,OpenAI 将这些 ID 限定为支持 API 密钥或项目。 当该密钥或项目已与应用程序边界匹配(例如单用户应用或每个租户单独的密钥/项目)时,这通常就足够了。 存在风险的托管模式是指:多个最终用户共用同一个后端密钥或项目,将原始的服务端 ID 回显给客户端,并在不检查所有权的情况下接收客户端回传的这些 ID。 在重复使用一个支持密钥或项目的托管或多用户应用中,请勿将service_session_idprevious_response_idconversation/conversation_id作为最终用户授权边界处理。 将服务端 ID 存储在受信任的应用程序存储中,将客户端可见的会话 ID 映射到这些服务端 ID,并在恢复会话之前验证经过身份验证的用户或租户。

内置使用模式

AgentSession session = await agent.CreateSessionAsync();

var first = await agent.RunAsync("My name is Alice.", session);
var second = await agent.RunAsync("What is my name?", session);
session = agent.create_session()

first = await agent.run("My name is Alice.", session=session)
second = await agent.run("What is my name?", session=session)
session, err := a.CreateSession(ctx)
if err != nil {
    panic(err)
}

resp, _ := a.RunText(ctx, "Hello!", agent.WithSession(session)).Collect()
resp, _ = a.RunText(ctx, "Follow-up question.", agent.WithSession(session)).Collect()

从现有服务会话 ID 创建会话

从现有会话 ID 创建新会话因代理类型而异。 下面是一些示例。

当使用 ChatClientAgent

AgentSession session = await chatClientAgent.CreateSessionAsync(conversationId);

使用 A2AAgent

AgentSession session = await a2aAgent.CreateSessionAsync(contextId, taskId);

当支持服务已具有会话状态时,请使用此功能。

session = agent.get_session(service_session_id="<service-conversation-id>")
response = await agent.run("Continue this conversation.", session=session)

在托管应用中,检查当前用户或租户后,从应用程序自有存储中解析 <service-conversation-id>。 除非首先验证调用方是否拥有会话,否则请避免接受来自客户端的原始服务端 ID。

序列化和还原

var serialized = agent.SerializeSession(session);
AgentSession resumed = await agent.DeserializeSessionAsync(serialized);
serialized = session.to_dict()
resumed = AgentSession.from_dict(serialized)
data, err := json.Marshal(session)
if err != nil {
    panic(err)
}

// Save to disk, database, etc.
if err := os.WriteFile("session.json", data, 0o644); err != nil {
    panic(err)
}

// Later, restore the session.
loaded, err := os.ReadFile("session.json")
if err != nil {
    panic(err)
}

var resumedSession agent.Session
if err := json.Unmarshal(loaded, &resumedSession); err != nil {
    panic(err)
}

resp, _ := a.RunText(ctx, "Continue from where we left off.", agent.WithSession(&resumedSession)).Collect()

Tip

有关完整示例,请参阅 持久化会话示例

重要

会话专用于特定的代理或服务。 使用其他代理配置或提供程序重用会话可能会导致上下文无效。 如果序列化会话包含服务端会话 ID,则仅针对拥有该 ID 的应用程序用户或租户还原它。

后续步骤