AI Security School SDK
Python-клиент для учебных агентских лабораторий. Скрипт атаки работает на вашей машине, а SDK вызывает явно доступные действия студента в персональном прогоне на платформе. Внутренние инструменты атакуемого агента через SDK не публикуются.
Требуется Python 3.12+. Исходники и релизы доступны в публичном репозитории.
Установка и токен
Установите SDK из PyPI:
python -m pip install ai-security-school-sdk
Чтобы зафиксировать версию для воспроизводимых экспериментов:
python -m pip install ai-security-school-sdk==0.1.1
На странице операции выберите «Подключить Python SDK» и получите токен. Он
ограничен одной операцией и имеет срок действия. Передайте его через переменную
окружения AI_SECURITY_SCHOOL_TOKEN; не сохраняйте токен в коде или репозитории.
Необязательная AI_SECURITY_SCHOOL_BASE_URL по умолчанию равна
https://plgn.aisecschool.ru. Для удалённых серверов необходим HTTPS.
Первый вызов
from ai_security_school_sdk import Client
with Client.from_env() as client:
for available in client.labs.list():
print(available.lab_id, available.title)
lab = client.labs.get("YOUR_LAB_ID")
run = lab.runs.create()
print("Сохраните run_id для продолжения:", run.run_id)
for action in run.actions.list():
print(action.name, action.description)
print(action.input_schema)
print(action.examples)
# Имя и аргументы выбираются из manifest текущей CTF.
result = run.actions.call("send_message", {"message": "Проверь новый документ"})
print(result.data)
print(run.observation().state)
send_message здесь — пример имени, а не встроенный метод SDK. Конкретные CTF
могут предоставлять разные действия: добавление документа, сообщение агенту,
загрузку вложения и другие операции. SDK получает их имена и JSON Schema от
сервера. Новый набор действий не требует новой версии Python-пакета.
Вызов проверяет аргументы локально и передаёт expected_task_id. Сервер повторно
проверяет действие, права и аргументы. SDK не загружает внешние ссылки JSON Schema
и не исполняет код из manifest. Если этап изменился через другой клиент, вызов
возвращает ConflictError; явно выполните run.refresh() и изучите новый набор.
Внешние поверхности атаки, например реестр пакетов или MCP-сервис, не перечисляются автоматически. Если они входят в сценарий, взаимодействуйте с ними через их собственные интерфейсы; SDK управляет только действиями, опубликованными CTF.
Прогоны, этапы и ветвление
with Client.from_env() as client:
run = client.runs.get("SAVED_RUN_ID")
checkpoint = run.checkpoint()
branch = checkpoint.fork()
print(branch.run_id, branch.task_id)
# Здесь выполняются доступные действия атаки.
verdict = branch.submit()
print(verdict.passed, verdict.success_rate)
if verdict.passed:
branch.advance() # Явный переход, если есть следующий этап.
print(branch.actions.list())
Этапы одной ветки разделяют состояние. Разные прогоны и forks независимы. Внутри одного прогона одновременно исполняется одно задание; для параллельного поиска создавайте отдельные прогоны. Новый прогон не обновляет общий бюджет пользователя. Checkpoint доступен для свободного прогона; fork сохраняет его состояние и этап.
submit() сдаёт записанный сервером результат вашей атаки. Проверка может
повторять действия на скрытых сценариях. Загружать Python-программу для исполнения
на сервере не требуется. Успешный обычный вызов действия сам по себе не даёт зачёт.
run.close() закрывает серверный прогон явно. Выход из with Client(...) закрывает
только HTTP-соединения и сохраняет прогон для продолжения.
Долгие задания, повторы и ошибки
from ai_security_school_sdk import Client, JobTimeoutError
with Client.from_env() as client:
run = client.runs.get("SAVED_RUN_ID")
job = run.actions.start_call("send_message", {"message": "Обработай заявку"})
print("Сохраните job_id:", job.job_id)
try:
result = job.wait(timeout=120, poll_interval=0.5)
except JobTimeoutError as error:
# Истечение времени ожидания не отменяет серверное задание.
resumed = client.jobs.get(error.job_id)
result = resumed.wait(timeout=120)
print(result)
run.actions.call()иrun.submit()запускают задание и ждут результат.start_call()иstart_submission()сразу возвращают handle задания.client.jobs.get(id),job.refresh(),job.cancel()иjob.result()позволяют управлять уже созданным заданием. Отмена не возвращает стоимость LLM-запросов, которые уже отправлены.- Все изменения имеют
Idempotency-Key. Сетевые повторы используют тот же ключ и тело; SDK никогда не создаёт новый ключ внутри повторного запроса. - Для восстановления после завершения процесса передайте сохранённый
idempotency_key=.TransportError.idempotency_keyсодержит ключ запроса с неопределённым результатом. С тем же ключом повторяйте только то же действие, аргументы и текущую CTF; не создавайте новую попытку вслепую. - По умолчанию доступны два повтора при сетевой ошибке и HTTP 429/502/503/504.
Параметры клиента:
timeout=30,max_retries=2,retry_backoff=0.25. Серверные HTTP-ошибки и ошибки самого задания после polling не запускают новую задачу. JobTimeoutErrorсодержитjob_id.JobInterruptedErrorозначает, что безопасное автоматическое продолжение исполнения невозможно; изучите историю.AuthenticationError,PermissionDeniedError,ConflictError,StageLockedError,LimitExceededErrorнаследуютAPIErrorс полямиcode,message,details,status_code,job_id.ActionValidationErrorописывает локальное несоответствие схеме, аProtocolError— некорректный ответ или неподдерживаемую ссылку схемы.
Async и наблюдения
import asyncio
from ai_security_school_sdk import AsyncClient
async def main():
async with AsyncClient.from_env() as client:
lab = await client.labs.get("YOUR_LAB_ID")
run = await lab.runs.create()
actions = await run.actions.list()
print(actions)
observation = await run.observation()
page = await run.events(after=0)
print(observation.state, observation.usage)
for event in page.events:
print(event.sequence, event.kind, event.data)
# Следующая порция: await run.events(after=page.next_cursor)
asyncio.run(main())
Все методы с сетевым вводом-выводом у AsyncClient вызываются через await.
Конструкторы, from_env(), поля объектов и job.result() синхронные. Asyncio
отмена локальной coroutine не отменяет серверное задание; сохраняйте job_id.
Примеры: первый эксперимент,
параллельный поиск,
этапы и fork.
Объекты содержат типизированный снимок в .info. Методы refresh() обновляют его;
для актуального состояния сервера не полагайтесь на старый снимок. Аргументы и
результаты конкретных действий — обычные JSON-объекты. Новые дополнительные поля
общих серверных моделей допускаются для совместимости.
Разработка
uv sync --python 3.12
uv run pytest
uv run ruff check .
uv run mypy src
uv build
Пакет не импортирует backend платформы. Тесты используют HTTPX MockTransport и
проверяют общий HTTP-контракт sync/async клиентов без LLM-вызовов. API имеет базу
/api/learner/v1; его версия не зависит от номера выпуска SDK.
Публикация новых версий в PyPI описана в PUBLISHING.md.
Release files for ai-security-school-sdk 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ai_security_school_sdk-0.1.1.tar.gz | 13.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ai_security_school_sdk-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.6 kB
Release files / ai_security_school_sdk-0.1.1.tar.gz
| Download URL | ai_security_school_sdk-0.1.1.tar.gz |
|---|---|
| Size | 13.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4cf2d41f4527189a1ba27d29fc93686fe76c777bc4e4caa3c994d720afb5e668
|
|
BLAKE2b-256 checksum How to use checksums |
3e6520915451d0855f1d1c29bae7baff0cc3c4120c184f3aad7efba010b45f57
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.
Transparency logRelease files / ai_security_school_sdk-0.1.1-py3-none-any.whl
| Download URL | ai_security_school_sdk-0.1.1-py3-none-any.whl |
|---|---|
| Size | 19.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9d4172d1f207200c548a35ee30dd817ce5730f3193671a99f199b6107b97a70d
|
|
BLAKE2b-256 checksum How to use checksums |
a3ae46ee354b034052ec1a0586881c3c87732841abeb1e3c9c694b484127c9b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 8, 2026.
Transparency log