Session

AgentSession — это контейнер состояния беседы, используемый в разных запусках агента.

Что AgentSession содержит

Поле Purpose
StateBag Произвольный контейнер состояния для этого сеанса

C# AgentSession является абстрактным базовым классом. Конкретные реализации (созданные с помощью CreateSessionAsync()) могут добавлять дополнительное состояние, например идентификатор для удаленного хранилища журнала чата, когда используется управляемый службой журнал.

Поле Purpose
session_id Локальный уникальный идентификатор для этого сеанса
service_session_id Идентификатор сеанса удалённого сервиса, например идентификатор беседы или ответа, при использовании истории, управляемой сервисом
state Изменяемый словарь, общий с поставщиками контекста и истории
Поле Purpose
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")

Область действия идентификатора сеанса службы

При использовании управляемого службой журнала сеанс может содержать идентификатор сеанса, выданный службой. Например, OpenAI Responses может использовать resp_* в качестве идентификатора ответа, например previous_response_id, а API OpenAI Conversations может использовать conv_* в качестве идентификатора беседы как самой беседы.

По умолчанию OpenAI ограничивает область действия этих идентификаторов связанным API-ключом или проектом. Обычно это достаточно, если этот ключ или проект уже соответствует границе приложения, например однопользовательское приложение или отдельный ключ или проект для каждого клиента. Рискованный подход заключается в использовании одного базового ключа или проекта для нескольких конечных пользователей, передаче клиентам исходных идентификаторов со стороны сервиса и приёме этих идентификаторов обратно без проверки прав владения. В хостируемых или многопользовательских приложениях, которые повторно используют один базовый ключ или проект, не рассматривайте service_session_id, previous_response_id или conversation/conversation_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()

Использование сеансов с агентом Use

Агент использования использует тот же AgentSession жизненный цикл, который описан выше. Повторное использование одного сеанса между поворотами, чтобы журнал чата и функции использования сеансов, такие как todos, операционный режим, память файлов, утверждения инструментов и состояние фоновой задачи, остаются подключенными. Сериализуйте сеанс, когда это состояние должно выжить после перезапуска процесса.

HarnessAgent по умолчанию использует InMemoryChatHistoryProvider. Замените его с помощью HarnessAgentOptions.ChatHistoryProvider журнала, если журнал должен использовать другое хранилище. AsHarnessAgent(options) является коротким для создания 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);

Ремень сохраняет журнал локального чата после каждого вызова модели внутри цикла вызова инструментов, а не только после запуска внешнего агента. Продолжайте передавать тот же сеанс, чтобы сохранить журнал в цикле и состояние поставщиков контекста по умолчанию.

create_harness_agent значение history_providerInMemoryHistoryProvider()по умолчанию . Передайте пользовательскую HistoryProvider версию, history_provider= когда журнал должен использовать другое хранилище.

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)

Для использования требуется сохраняемость журнала вызовов для каждого службы, поэтому настроенный поставщик журнала сохраняет каждый вызов модели внутри цикла инструментов. Сеанс также требуется по промежуточному по промежуточному слоям по утверждению инструментов по умолчанию; повторно и восстановите его, чтобы сохранить состояние утверждения и контекста поставщика.

Агент использования в настоящее время недоступен в пакете SDK go. Используйте шаблон регулярного сеанса, показанный выше.

Создание сеанса по существующему идентификатору сессии службы

Создание нового сеанса из существующего идентификатора беседы зависит от типа агента. Ниже приведены некоторые примеры.

При использовании 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> из хранилища, принадлежащее приложению, после проверки текущего пользователя или клиента. Не принимайте от клиента необработанные идентификаторы сервиса, если сначала не проверите, что вызывающая сторона является владельцем беседы.

Сериализация и восстановление

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

См. пример сохранённого диалога, чтобы увидеть полный пример.

Important

Сеансы относятся к конкретному агенту или службе. Повторное использование сеанса с другой конфигурацией агента или поставщиком может привести к недопустимому контексту. Если сериализованный сеанс содержит идентификатор сеанса на стороне службы, восстановите его только для пользователя приложения или клиента, которому принадлежит этот идентификатор.

Дальнейшие действия