Гайд · TNWS AI

Как ограничить историю через SessionSettings в OpenAI Agents SDK

5 мин

Задаём SessionSettings(limit=N) на один run, проверяем последние элементы и не изменяем содержимое underlying session.

Задача и критерий готовности

Задача — ограничить число последних session items, загружаемых перед конкретным run, не удаляя старую историю из хранилища. Результат считается готовым только при машинной проверке состояния session, RunState, interruption или event stream. Красивый ответ агента не заменяет доказательство.

Методы и поведение сверены 12 сентября 2026 года по официальной документации OpenAI Agents SDK. В статье нет выдуманных цен, квот и метрик.

Подтверждённый контракт

  • SessionSettings(limit=None) по умолчанию получает всю доступную историю.
  • SessionSettings(limit=N) получает последние N items.
  • Per-run настройка передаётся через RunConfig.session_settings.
  • Непустые значения per-run переопределяют default session settings.
  • Limit влияет на retrieval, а не физически удаляет старые items.

Каждый пункт проверяется отдельно. Не объединяйте доступность backend, корректность истории и качество ответа в один флаг success: это независимые слои.

Что подготовить

  • отдельную тестовую базу, Redis database или временный файл;
  • уникальный session_id, не совпадающий с ID реального пользователя;
  • fake tool и provider stub для контроля вызовов;
  • переменные окружения для ключей и строк подключения;
  • журнал безопасных агрегатов и версий без содержимого переписки.

Прежде чем запускать код, определите владельца соединения и cleanup. Для hosted storage проверьте, где фактически лежат данные. Для durable state считайте payload чувствительным: он включает app context и runtime metadata.

Пошаговая настройка

  1. Наполните тестовую session нумерованными items.
  2. Задайте небольшой limit через RunConfig только для одного run.
  3. Перехватите model input и проверьте, что пришёл хвост истории.
  4. После run вызовите get_items без limit и подтвердите сохранность старых записей.

После каждого шага записывайте наблюдаемый признак: число items, конкретный exception, наличие interruption, счётчик tool или факт завершения async iterator. Комментарий в коде не является проверкой.

Копируемый пример

import asyncio
from agents import Agent, RunConfig, Runner, SessionSettings, SQLiteSession

async def main():
    session=SQLiteSession("ticket-781","history.db")
    await session.add_items([{"role":"user","content":f"item-{i}"} for i in range(60)])
    agent=Agent(name="assistant",instructions="Используй только доступную историю.")
    await Runner.run(agent,"Перечисли последние элементы",session=session,run_config=RunConfig(session_settings=SessionSettings(limit=50)))
    all_items=await session.get_items()
    assert len(all_items)>=60

asyncio.run(main())

Запускайте пример в отдельном virtualenv. Все ключи и URL берите из окружения; тестовые localhost-адреса не превращайте в production-конфигурацию автоматически. Заполнители paused, original_agent и fake counters должны быть определены вашим воспроизводимым fixture.

Реалистичный вход

В session 60 нумерованных items, для run задан limit=50.

Ожидаемый результат

Model input содержит последние 50 старых items плюс новый ввод по правилам объединения; хранилище по-прежнему содержит исходные записи.

Перенесите ожидание в assert. Для недетерминированного текста проверяйте сохранённый факт через model stub либо напрямую session items. Для approval проверяйте и interruptions, и execution counter.

Негативный тест

Проверьте, что item-0 не попал в model input, но остался в session storage.

Негативная проверка меняет одно условие. Ошибка подключения не равна пустой истории, новый run не равен resume, другой session_id не является потерей данных, а отсутствие второй паузы допустимо только при подтверждённом sticky decision.

Готовый prompt для ревью

Проверь конфигурацию сценария «Как ограничить историю через SessionSettings в OpenAI Agents SDK». Для каждого факта найди исполняемое доказательство. Проверь ownership соединений, cleanup, секреты, session_id, число model/tool вызовов и негативный тест. Верни таблицу PASS/FAIL; если доказательства нет, ставь FAIL.

Prompt используйте после приложения кода и очищенного лога. Он не заменяет исполнение: языковая модель может назвать комментарий гарантией или пропустить неверный cleanup.

Независимая проверка

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

Считайте отдельно model calls, tool executions, session writes и approval interruptions. Один счётчик не описывает весь run. Для async cleanup добавьте fixture, который проверяет закрытие даже после исключения.

В CI сохраняйте версии пакета, exit code и агрегаты. Не сохраняйте encryption key, DATABASE_URL, Redis URL с паролем, сериализованный RunState или полный dialog в открытых artifacts.

Частые ошибки

Неправильное владение ресурсом

from_url может создать клиент или engine, который нужно закрыть. Если ресурс передан извне, его жизненный цикл может принадлежать приложению. Зафиксируйте это в одном месте.

Пустое значение считают успехом

Пустая история может означать новый ID, истёкший TTL, ошибку ключа или отсутствие записи. Тест должен различать причины и не возвращать универсальное «готово».

Approval смешивают с авторизацией

Решение оператора разрешает конкретный workflow SDK, но backend всё равно обязан проверить права пользователя и допустимость операции.

Cleanup выполняется только при успехе

Соединения закрывают в finally или lifecycle hook. Отдельно моделируйте исключение Runner и убеждайтесь, что dispose/close всё равно выполнен.

Чек-лист финальной проверки

  • Уникальный session_id не содержит PII.
  • Версия SDK зафиксирована.
  • Названия методов сверены 12 сентября 2026 года.
  • Секреты приходят только из окружения.
  • Есть штатный и негативный assert.
  • Model calls и tool executions считаются отдельно.
  • Cleanup работает после исключения.
  • Resume использует RunState, а не новый prompt.
  • Serialized state защищён как чувствительные данные.
  • Старые items не удаляются случайно retrieval-limitом.

Ограничения

Гайд проверяет технический контракт, но не соответствие нормативным требованиям, стоимость backend, качество модели и производительность. TTL, limit и схема retention выбираются по политике проекта; нельзя объявлять пример универсальным.

Шифрование session не отменяет управление ключами. Redis не даёт durable backup автоматически. SQLite branching не заменяет production database. Sticky approval действует в границах run и не должен превращаться в бессрочное разрешение.

FAQ

Нужно ли логировать всю историю?

Нет. Сохраняйте безопасные агрегаты и идентификаторы. Полная история и RunState требуют отдельного защищённого хранилища.

Почему недостаточно финального ответа?

Он не показывает, откуда взялась память, сколько раз выполнился tool и был ли run действительно возобновлён.

Что проверять после обновления SDK?

Импорты, constructor arguments, lifecycle close/dispose, сериализацию state и порядок approval.

Можно ли использовать реальные операции в тесте?

Нет. Approval, retry и cancellation сначала проверяются fake tool с измеримым счётчиком.

Первоисточник

Материал написан самостоятельно; тестовые идентификаторы не относятся к реальным пользователям.

Читайте также

Комментарии

Пока тихо. Скажите первое слово