token-wise-agent
Кастомный агент для написания кода, построенный на OpenHands SDK.
Цель дипломной работы — исследовать, как кастомные инструменты сокращают количество API-вызовов и расход токенов при работе на бенчмарке SWE-bench.
Архитектура
agent/cli.py ← CLI entry point (twa)
└── LocalConversation (OpenHands SDK)
├── Agent + system_prompt.j2 ← кастомный системный промпт
│ └── LLM (litellm → Anthropic / OpenAI / любой провайдер)
├── BashTool ← кастомный: stateless subprocess
├── GlobTool ← кастомный: поиск файлов по glob-паттерну
├── GrepTool ← кастомный: regex-поиск с контекстом
├── SmartReaderTool ← кастомный: чтение файла с диапазоном строк и контекстом
├── SmartEditorTool ← кастомный: редактирование файлов (replace/insert/create/delete/undo)
├── SubmitTool ← кастомный: сигнал завершения задачи (SWE-bench режим)
└── ThinkTool ← SDK built-in: внутренние размышления
token-wise-agent/
├── agent/
│ ├── cli.py # CLI entry point
│ ├── config.py # Загрузка конфига (.env + YAML + CLI)
│ ├── agent_tracker.py # Трекинг метрик агента (токены, стоимость, вызовы)
│ ├── trajectory.py # Сохранение траектории в .traj.json
│ ├── configs/
│ │ ├── agent_config.yaml # SWE-bench режим: промпты, tools, step_limit
│ │ ├── agent_config_user.yaml# Интерактивный режим
│ │ └── pricing.yaml # Стоимость токенов по моделям
│ ├── prompts/
│ │ ├── system_prompt.j2 # Промпт для SWE-bench режима
│ │ └── system_prompt_user.j2 # Промпт для интерактивного режима
│ └── tools/
│ ├── bash.py
│ ├── bash_session.py
│ ├── glob.py
│ ├── grep.py
│ ├── smart_reader.py
│ ├── smart_editor.py
│ ├── submit.py
│ └── tree.py # Авто-инъекция структуры репозитория
├── benchmarks/
│ ├── run_benchmark.py # SWE-Bench-style раннер
│ └── tasks/ # 10 задач с багами и тестами
├── tests/
│ └── test_tools.py
├── Dockerfile # Образ для запуска агента в изоляции
└── .env.example
Установка
Через pip (рекомендуется)
pip install token-wise-agent
twa edit # настройка API ключа
twa # запуск
Для разработки
Требуется uv.
git clone <repo-url>
cd token-wise-agent
uv sync
cp .env.example .env
# Вставьте API ключ в .env
Использование
Интерактивный режим
twa # запустить интерактивный чат
twa -i --working-dir /path/to/project # другая рабочая директория
В интерактивном режиме доступны команды:
| Команда | Действие |
|---|---|
/confirm |
Переключиться в режим подтверждений (агент спрашивает перед каждым tool call) |
/auto |
Вернуться в автоматический режим |
exit / Ctrl+C |
Выйти |
В режиме подтверждений: Enter — одобрить действие, любой текст — отклонить и передать агенту как причину.
Одноразовый режим (SWE-bench)
twa "Fix the failing tests in tests/" # запустить агента на задаче
twa --quiet "задача" # без вывода агента
twa --model anthropic/claude-opus-4.7 "задача"
twa --working-dir /path/to/project "задача"
twa --list-tools # список инструментов из конфига
Редактирование конфигурации
twa edit # редактировать .env (API ключ, модель)
twa edit config # редактировать agent_config_user.yaml
Конфигурация
Три источника конфигурации с чётким разделением:
~/.config/token-wise-agent/.env — секреты и подключение
| Переменная | Описание |
|---|---|
AGENT_API_KEY |
API ключ |
AGENT_BASE_URL |
Кастомный API endpoint (для OpenAI-совместимых сервисов) |
AGENT_MODEL |
litellm model ID (например anthropic/claude-sonnet-4-6) |
~/.config/token-wise-agent/agent_config_user.yaml — поведение агента
agent:
system_template: "system_prompt_user.j2"
llm_params:
temperature: 0.5
step_limit: 50
tools:
- think
- bash
- glob
- grep
- smart_reader
- smart_editor
Редактируется через twa edit config. Два готовых конфига в пакете:
agent_config.yaml— SWE-bench режим (step_limit: 30,temperature: 0.0, включёнsubmit)agent_config_user.yaml— интерактивный режим (step_limit: 50,temperature: 0.5)
agent/configs/pricing.yaml — стоимость токенов
# Цена за миллион токенов (USD)
anthropic/claude-sonnet-4-6:
input: 1.90
output: 9.54
anthropic/claude-opus-4.7:
input: 6.10
output: 30.49
Используется для подсчёта стоимости и передаётся в LiteLLM. Добавьте новую модель — стоимость подхватится автоматически.
CLI аргументы
| Аргумент | Описание |
|---|---|
-i / --interactive |
Запустить интерактивный режим |
--model |
Переопределить модель из .env |
--max-steps |
Переопределить step_limit из YAML |
--working-dir |
Рабочая директория (по умолчанию .) |
--quiet |
Подавить вывод агента |
--agent-config |
Путь к альтернативному YAML конфигу |
Инструменты
| Имя | Источник | Описание |
|---|---|---|
bash |
Кастомный | Stateless subprocess — каждый вызов независим |
bash_session |
Обёртка над TerminalTool | Персистентная bash-сессия (состояние между вызовами) |
glob |
Кастомный | Поиск файлов по glob-паттерну (сортировка по mtime) |
grep |
Кастомный | Regex-поиск по файлам с N строками контекста |
smart_reader |
Кастомный | Чтение файла: диапазон строк, контекст вокруг строки, авто-truncation |
smart_editor |
Кастомный | Редактирование файлов: replace, insert, create, delete, undo |
submit |
Кастомный | Сигнал завершения — останавливает агента (SWE-bench режим) |
think |
SDK built-in | Внутренние размышления перед действием |
Алиасы инструментов. Если модель вызывает
read_file,read_files,view_fileилиview— они прозрачно перенаправляются наsmart_readerбез лишних ошибок и потери шагов.
Бенчмарк
10 SWE-Bench-style задач. Структура каждой задачи:
task_XXX/
├── issue.md — описание бага
├── src/ — код с багом
├── tests/ — тесты (видны агенту)
└── gold_tests/ — золотые тесты (скрыты, запускаются после submit)
Локальный запуск
uv run python benchmarks/run_benchmark.py # все задачи
uv run python benchmarks/run_benchmark.py task_001 # одна задача
uv run python benchmarks/run_benchmark.py --quiet task_001
uv run python benchmarks/run_benchmark.py --model anthropic/claude-opus-4.7 task_001
uv run python benchmarks/run_benchmark.py --save results.json
Docker-режим (изолированное окружение)
uv run python benchmarks/run_benchmark.py --docker --docker-build task_001
uv run python benchmarks/run_benchmark.py --docker task_001 task_003
uv run python benchmarks/run_benchmark.py --docker --docker-image myrepo/agent:v1
В Docker-режиме код задачи монтируется в /testbed, агентский код живёт в /app образа.
API-ключи пробрасываются через --env-file ~/.config/token-wise-agent/.env.
Качество кода
Проект использует ruff для линтинга и форматирования.
uv run ruff check . # линтинг
uv run ruff format . # форматирование
uv run pytest tests/ -v # тесты
Pre-commit хуки (опционально):
uv run pre-commit install
CI запускается автоматически на каждый push в master и на Pull Request.
Трекинг метрик
После каждого запуска (одноразовый режим) выводится таблица и сохраняется METRICS.json в рабочей директории:
Agent Summary
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ Metric ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩
│ Model │ anthropic/… │
│ Latency │ 90.0s │
│ LLM calls │ 7 │
│ Total tool calls │ 14 │
│ Tool errors │ 0 │
│ │ │
│ Input tokens │ 120,000 │
│ Output tokens │ 3,200 │
│ │ │
│ Total cost │ $0.0414 │
└────────────────────┴─────────────┘
Полная траектория каждого запуска сохраняется в ~/.config/token-wise-agent/:
~/.config/token-wise-agent/
├── last_twa_run.traj.json # последний одноразовый запуск
└── run_YYYY-MM-DD_HH-MM-SS/
├── task_001.traj.json
└── task_002.traj.json
Добавление нового инструмента
- Создай файл в
agent/tools/(шаблон —smart_reader.py) - Добавь импорт в
agent/tools/__init__.py - Добавь имя тула в
tools:в нужномagent_config.yaml
Metadata
Release files for token-wise-agent 1.0.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| token_wise_agent-1.0.5.tar.gz | 462.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| token_wise_agent-1.0.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 499.4 kB
Release files / token_wise_agent-1.0.5.tar.gz
| Download URL | token_wise_agent-1.0.5.tar.gz |
|---|---|
| Size | 462.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7f5b1506a05ed806ea78dac6b3c28c9fdcffebd0682f1d65129ed76a4efc88ca
|
|
BLAKE2b-256 checksum How to use checksums |
cdb2e29ac1c4911826c815e775b59be54be44a202fd31b2130c779adc170640b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 May 8, 2026.
Transparency logRelease files / token_wise_agent-1.0.5-py3-none-any.whl
| Download URL | token_wise_agent-1.0.5-py3-none-any.whl |
|---|---|
| Size | 36.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
792a96a25c90470ec6bb91700c914dde72482ce6588ba0f4b775b69365b46c6e
|
|
BLAKE2b-256 checksum How to use checksums |
9465bf9ba66af7b55a64d0dacca7b902300888208eb073e2f8e67cf4620dc750
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 May 8, 2026.
Transparency log