Skip to content

About

Educational ReAct agent in Python: direct DeepSeek API, read_file/bash/edit tools, sandbox and offline tests

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ReAct-агент на Python

Учебный агент без агентных фреймворков: прямой DeepSeek API, история сообщений и три инструмента - read_file, bash, edit. Модель выбирает действие, агент выполняет его и передает результат в следующем запросе. Пример показывает этот обмен, а не оценивает надежность модели.

Задача - найти причину падающего теста доставки, изменить реализацию и проверить ее тестами. По настройкам доставка бесплатна от 2000 рублей, но заказ на 2500 рублей получает стоимость 300 вместо 0. Причина намеренно заложена в загрузку настроек по относительному пути. Исходный кейс остается с ошибкой; каждый запуск агента работает со своей копией.

Требования и быстрый старт

  • Linux, Python 3.10+ и стандартная библиотека; проверено на Python 3.12.3.
  • Системный Python в /usr/bin:/bin, /usr/bin/bash и Bubblewrap (bwrap).
  • Обычные Unix-утилиты: ls, cat, grep, rm, sleep, setsid.
  • Работающие namespaces: одного установленного bwrap недостаточно. При недоступной песочнице команды на хосте не выполняются.

Сторонние Python-пакеты для запуска не нужны. В Debian/Ubuntu системные зависимости можно установить командой:

sudo apt install python3 bash bubblewrap coreutils grep util-linux git
git clone https://github.com/stemirkhan/react-agent-demo.git
cd react-agent-demo
python3 -m unittest discover -s tests -v
python3 -m react_demo case

Все дальнейшие команды выполняются из корня репозитория. pyproject.toml содержит только настройки необязательных Black и mypy; pip install . не требуется. Windows и macOS для запуска этого демо не поддерживаются.

Устройство

Начните с Agent.run(): история сообщений -> ответ модели -> инструмент -> результат в историю -> новое обращение к модели. Непустой ответ без вызовов инструментов завершает цикл.

react_demo/
  agent.py              один Agent, история - обычный список
  client.py             DeepSeekClient: запрос к модели
  main.py               Lesson: запуск, локальная проверка и replay
  prompts.py            общие правила и отдельное задание
  tools/
    read_file.py        ReadFileTool: прочитать разрешенный файл
    bash.py             BashTool: выполнить команду в песочнице
    edit.py             EditTool: точечно заменить фрагмент кода
    __init__.py         список трех доступных файлов
  recording.py          журнал и показ сохраненного запуска
  __main__.py           вход: python -m react_demo
case_project/
  shop/delivery.py      намеренный дефект загрузки настроек
  shop/settings.json   бесплатная доставка от 2000 рублей
  tests/test_delivery.py
tests/                  проверки демо без сети и модели
runs/                   журналы и рабочие копии, не входят в Git

В каждом файле инструмента находятся его описание для модели и выполнение. Общий системный промпт не привязан к доставке; условия кейса остаются в задании пользователя. Причина ошибки в запрос не передается. Описания инструментов передаются отдельным полем tools.

Проверка без API

python3 -m react_demo case
python3 -m unittest discover -s tests -v

Команда case запускает тесты доставки через Bash в изолированной временной копии. Для нее тоже требуется работающий Bubblewrap. Один тест намеренно падает: доставка для заказа на 2500 рублей стоит 300 вместо 0. Для команды case это ожидаемый результат и код завершения 0; настоящий код тестов 1 остается в журнале. Тесты самого демо должны проходить. Офлайн-проверка исправления выполняется только в копии; исходный кейс остается с ошибкой.

Ответы модели в проверках - явно обозначенные заглушки. Тесты протокола не требуют настоящей песочницы; проверки самой изоляции пропускаются, если среда ее не поддерживает. Это не настоящий маршрут модели. Если установлены инструменты разработки, дополнительно можно выполнить mypy и black --check react_demo tests case_project.

Настоящий запуск

Ключ задается в DEEPSEEK_API_KEY вне репозитория; программа не читает .env. Не вставляйте секрет в код или команды, сохраняемые в истории. Например, в Bash можно ввести ключ скрыто:

read -r -s -p 'DeepSeek API key: ' DEEPSEEK_API_KEY
export DEEPSEEK_API_KEY

Перед запуском проверьте доступную модель и тариф в своем аккаунте. Запросы могут быть платными. Ограничения числа шагов и токенов ниже не являются лимитом расходов в долларах.

После этого:

python3 -m react_demo run --model deepseek-flash --live

deepseek-flash использован в запуске, разобранном в статье. Модель указывается явно. Без --live или ключа обращение к API не выполняется. До первого запроса программа проверяет, что Bubblewrap действительно может создать песочницу: одного наличия исполняемого файла bwrap недостаточно.

Каждый запуск создает отдельную рабочую копию рядом с журналом: runs/ИМЯ-ЖУРНАЛА.project/. В песочнице она доступна как /project; это рабочая папка Bash. По заданию исправлять нужно только shop/delivery.py. Для точечной правки есть edit(path, old_text, new_text); для запуска тестов - bash с командой python3 -m unittest discover -s tests -v. Настройки и тесты недоступны для edit и смонтированы в песочнице только для чтения. Фрагмент old_text должен встретиться ровно один раз; иначе файл не меняется. Bash может выполнять обычные команды, включая пайпы, ls и grep; изменения доступных для записи файлов сохраняются между вызовами. Исходный case_project/ сохраняет намеренную ошибку и не подключается к песочнице живого запуска.

Клиент использует Chat Completions API DeepSeek в режиме thinking: disabled, с tool_choice: auto и без streaming. Формат вызовов сверяется с официальным примером tool calling. В примере показываем выбор инструментов и результаты, а не скрытые рассуждения. Полученный reasoning_content, если он есть в ответе, сохраняется вместе с сообщением; обычный показ журнала его не выводит.

По умолчанию: до 8 обращений к модели, 16 вызовов инструментов, 800 выходных токенов на ответ; сетевой таймаут 30 секунд. Значения меняются через --max-steps, --max-tool-calls, --max-tokens, --timeout и записываются в журнал. Это технические ограничения, не потолок расходов в долларах.

Автоматических повторов нет. Ошибка API, обрезанный ответ или исчерпание лимита завершает попытку с записью ошибки. Ответ модели не считается правильным автоматически; его проверяем по файлам и выводу тестов.

Сохраненный запуск

Каждая попытка получает новый JSONL-файл в runs/: параметры, хеши учебных файлов, запросы, сырые ответы с usage, вызовы инструментов, результаты, diff правок через edit и финал либо ошибка. Команды Bash и их вывод тоже журналируются, но отдельный diff каждой Bash-правки не формируется. Событие сохраняется до показа в терминале. Рабочая копия остается после успеха или ошибки. Существующий журнал и рабочая копия не перезаписываются, в том числе при --output.

python3 -m react_demo replay runs/ИМЯ-ЖУРНАЛА.jsonl
python3 -m react_demo replay runs/ИМЯ-ЖУРНАЛА.jsonl --json

Replay только читает журнал: не обращается к API и не выполняет инструменты заново. Журналы прежних запусков, рабочие копии и учетные данные в репозиторий не включены. Для replay нужно сначала создать свой журнал командой case или run.

Ограничения

  • read_file читает только три файла кейса; произвольные пути, символические ссылки и лишние аргументы отклоняются. Через Bash можно читать и другие доступные внутри песочницы файлы.
  • edit меняет существующий файл реализации в рабочей копии; создание файлов и правка настроек или тестов не разрешены.
  • bash выполняет переданную команду через /usr/bin/bash в Bubblewrap. Таймаут по умолчанию - 10 секунд; необязательный аргумент timeout может уменьшить его, но не увеличить. Вывод считывается с ограниченным буфером, чтобы большой stdout/stderr не накапливался целиком в памяти.
  • Песочница получает рабочую копию с возможностью записи, системный Python и команды Bash. Настройки и каталог тестов доступны только для чтения. Домашняя папка хоста, API-ключи, пользовательское окружение и сеть не передаются. При сбое изоляции команды на хосте не запускаются.
  • Команда case тоже выполняется через песочницу, в одноразовой копии. Одна только рабочая папка не считается изоляцией.
  • Изоляция не задает отдельные лимиты памяти и CPU. Это ограниченное учебное демо, не сервис для выполнения произвольного чужого кода.
  • Заголовок авторизации не журналируется; используемый ключ маскируется в событиях, включая возможное эхо ответа. На Unix файл создается с правами 0600. Перед публикацией или записью экрана журнал все равно нужно проверить на персональные данные.

Проверка версии

Перед публикацией на Linux с Python 3.12.3 и Bubblewrap 0.9.0 прошли 96 тестов демо, без пропусков. В исходном case_project один из трех тестов намеренно падает. Ответы DeepSeek в офлайн-тестах подменены; это проверка реализации, а не новый платный запуск модели.

About

Educational ReAct agent in Python: direct DeepSeek API, read_file/bash/edit tools, sandbox and offline tests

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages