Sessão

AgentSession é o contêiner de estado de conversa usado em rodadas de execução do agente.

O que AgentSession contém

Campo Purpose
StateBag Contêiner de estado arbitrário para esta sessão

O C# AgentSession é uma classe base abstrata. Implementações concretas (criadas via CreateSessionAsync()) podem adicionar um estado adicional, por exemplo, uma ID para armazenamento de histórico de chat remoto, quando o histórico gerenciado pelo serviço é usado.

Campo Purpose
session_id Identificador exclusivo local para esta sessão
service_session_id Identificador de sessão de serviço remoto, como uma ID de conversa ou resposta, quando o histórico gerenciado pelo serviço é usado
state Dicionário mutável compartilhado com provedores de contexto/histórico
Campo Purpose
agent.Session Contêiner de estado chave-valor vinculado a uma conversa

As sessões fornecem armazenamento de chave-valor tipado:

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")

Escopo do ID da sessão do serviço

Quando o histórico gerenciado pelo serviço é usado, uma sessão pode conter um identificador de sessão emitido pelo serviço. Por exemplo, o OpenAI Responses pode usar um ID de resposta resp_* como previous_response_id, e a API OpenAI Conversations pode usar um ID de conversa conv_* como a conversa.

Por padrão, a OpenAI restringe esses IDs à chave de API ou ao projeto associado. Isso geralmente é suficiente quando essa chave ou projeto já corresponde ao limite do aplicativo, como um aplicativo de usuário único ou uma chave/projeto separado por locatário. O padrão de hospedagem arriscado consiste em usar uma chave ou projeto de suporte para vários usuários finais, ecoando IDs brutos do lado do serviço para os clientes e aceitando esses IDs de volta sem verificar a propriedade. Em aplicativos hospedados ou multiusuários que reutilizam uma chave de backup ou projeto, não tratam service_session_id, previous_response_idou conversation/conversation_id como limites de autorização do usuário final. Armazene IDs do lado do serviço no armazenamento confiável do aplicativo, mapeie IDs de sessão visíveis para o cliente para esses IDs do lado do serviço e verifique o usuário ou locatário autenticado antes de retomar uma conversa.

Padrão de uso interno

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()

Usar sessões com o Harness Agent

O Harness Agent usa o mesmo AgentSession ciclo de vida descrito acima. Reutilize uma sessão ao longo das interações para que o histórico do chat e os recursos do agente com suporte de sessão, como tarefas, modo operacional, memória de arquivos, aprovações de ferramentas e estado de tarefas em segundo plano, permaneçam conectados. Serialize a sessão quando esse estado deve sobreviver a uma reinicialização do processo.

HarnessAgent usa como padrão InMemoryChatHistoryProvider. Substitua-o por HarnessAgentOptions.ChatHistoryProvider quando o histórico precisar usar outro repositório. AsHarnessAgent(options) é a abreviação de construir new HarnessAgent(chatClient, options).

HarnessAgent agent = chatClient.AsHarnessAgent();
AgentSession session = await agent.CreateSessionAsync();

await agent.RunAsync("Plan the migration.", session);
await agent.RunAsync("Continue with the next step.", session);

var serialized = await agent.SerializeSessionAsync(session);
AgentSession resumed = await agent.DeserializeSessionAsync(serialized);

O agente persiste o histórico local de chat após cada chamada ao modelo dentro de um loop de chamadas de ferramenta, não apenas após a execução mais externa do agente. Continue passando a mesma sessão para preservar esse histórico em loop e o estado dos provedores de contexto padrão.

create_harness_agent define history_provider como InMemoryHistoryProvider(). Passe um HistoryProvider personalizado por meio de history_provider= quando o histórico precisar usar outro repositório.

agent = create_harness_agent(client)
session = agent.create_session()

await agent.run("Plan the migration.", session=session)
await agent.run("Continue with the next step.", session=session)

serialized = session.to_dict()
resumed = AgentSession.from_dict(serialized)

O agente requer persistência do histórico por chamada de serviço, portanto o provedor de histórico configurado salva cada chamada ao modelo dentro de um loop de ferramentas. Uma sessão também é necessária para o middleware padrão de aprovação de ferramentas. Reutilize-a e restaure-a para preservar o estado de aprovação e o estado do provedor de contexto.

No momento, o Harness Agent não está disponível no SDK do Go. Use o padrão de sessão regular mostrado acima.

Criando uma sessão a partir de uma ID de conversa de serviço existente

Criar uma nova sessão de uma ID de conversa existente varia de acordo com o tipo de agente. Aqui estão alguns exemplos.

Ao usar ChatClientAgent

AgentSession session = await chatClientAgent.CreateSessionAsync(conversationId);

Ao usar um A2AAgent

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

Use isso quando o serviço de suporte já tiver o estado da conversa.

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

Em aplicativos hospedados, resolva <service-conversation-id> do armazenamento pertencente ao aplicativo após verificar o usuário ou locatário atual. Evite aceitar IDs brutos do lado do serviço de um cliente, a menos que você primeiro verifique se o chamador é o proprietário da conversa.

Serialização e restauração

var serialized = agent.SerializeSession(session);
AgentSession resumed = await agent.DeserializeSessionAsync(serialized);

Em um aplicativo auto-hospedado, um AgentSessionStore pode carregar e salvar sessões usando um ID de continuação como parte do processamento da solicitação. Isso é diferente de persistir manualmente uma sessão e de configurar um provedor de histórico. Consulte aplicativos auto-hospedados do Agent Framework.

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()

Dica

Consulte o exemplo de conversa persistente para obter um exemplo completo.

Importante

As sessões são específicas para o agente/serviço. Reutilização de uma sessão com uma configuração ou provedor de agente diferente pode levar a um contexto inválido. Se a sessão serializada contiver uma ID de sessão do lado do serviço, restaure-a apenas para o usuário ou locatário do aplicativo que possui essa ID.

Próximas Etapas