- BrainTools - https://www.braintools.ru -
В первых текстах про Personal Task Assistant я писал про базовую идею:
не человек должен каждый раз думать, что можно поручить AI. Система задач должна сама показывать, какая работа уже готова для агента.
С тех пор проект сильно изменился.
Изначально это была доска задач с человеческой и агентской очередью. Сейчас это уже более практичный контур:
задачи можно безопасно забирать через атомарный claim;
повторный импорт из почты, Telegram или другого источника не создает дубли;
агент может работать через MCP, а не через скрейпинг UI;
MCP-инструменты проверяются отдельным eval-процессом;
для будущих Codex/Claude-сессий появились playbooks в AGENTS.md и .claude/skills/;
после явной установки launchd-расписания ежедневный ритуал в 15:00 пишет digest, а при явном включении дает Claude ограниченный набор инструментов, чтобы он сам двигал Codex-задачи до waiting_review.
То есть проект ушел от “вот список задач для AI” к более важному вопросу:
как сделать так, чтобы агент мог приходить в очередь каждый день, брать работу и не ломать операционный контроль человека.
Первая версия решала маршрутизацию:
это должен сделать человек;
это может взять агент;
это ждет ревью;
это заблокировано;
это еще не разобрано.
Но когда начинаешь реально жить с такой системой, быстро появляются следующие проблемы.
Первая: агенту нельзя просто дать весь список задач. Ему нужен конкретный контракт: что читать, что брать, как зафиксировать результат и когда остановиться.
Вторая: нельзя доверять только промпту. Если в промпте написано “не закрывай задачи”, это полезно, но недостаточно. Ограничение должно быть в коде.
Третья: интеграции будут переигрывать одни и те же события. Telegram polling, webhooks, будущие Gmail/Slack/Jira-адаптеры и scheduled jobs почти всегда когда-нибудь повторят один и тот же источник. Значит, ingest должен быть идемпотентным.
Четвертая: если MCP-инструменты плохо описаны, агент начинает ошибаться не потому, что модель плохая, а потому что контракт неочевидный. Это нужно проверять отдельно.
Главное изменение в 0.4.0: появился POST /api/agent/claim.
Агент больше не должен делать так:
прочитать список;
выбрать первую задачу;
надеяться, что никто другой ее не взял.
Теперь он вызывает claim endpoint, а сервер сам выбирает верхнюю Codex-owned задачу в backlog, условно переводит ее в in_progress и возвращает агенту.
Это важно даже для личного проекта. Как только появляются расписания, параллельные агенты или ручные запуски из разных окон, состояние “оба взяли одну задачу” становится реальным багом.
В SQLite это сделано условным UPDATE, в Firestore – транзакцией. Если другой процесс успел забрать задачу раньше, текущий runner просто получает следующую или 404, когда брать нечего.
Вторая практичная доработка – external_id.
У задачи может быть стабильный внешний идентификатор, например:
telegram:<chat_id>:<message_id>:<line>
jira:PROJ-42
gmail:<thread_id>:<message_id>:<n>
Если адаптер отправит тот же batch второй раз, система не создаст копии. В context ingest такие задачи вернутся в duplicates, а прямое создание одной задачи с тем же external_id даст conflict.
Для трекера это скучная, но критичная вещь. Без нее любая автоматизация из почты или чатов быстро превращается в генератор дублей.
Следующий шаг был в 0.5.0: MCP server.
До этого агент мог пользоваться JSON API напрямую. Это работает, но для Claude Code, Claude Desktop и других MCP-клиентов естественнее дать набор инструментов.
Сейчас MCP server в adapters/task_assistant_mcp.py оборачивает API в девять инструментов:
task_assistant_get_queue;
task_assistant_queue_summary;
task_assistant_claim_task;
task_assistant_finish_task;
task_assistant_create_task;
task_assistant_update_task;
task_assistant_list_tasks;
task_assistant_ingest_context;
task_assistant_due_reminders.
Нормальный цикл стал таким:
get_queue / queue_summary
-> claim_task
-> выполнить работу
-> finish_task
-> waiting_review
Ключевое здесь – последняя строка. Агент не должен по умолчанию закрывать задачу в done. Если он подготовил draft, внес изменения, собрал выводы или нашел блокер, это результат для review. Человек остается владельцем принятия.
После MCP появилась новая проблема: как понять, что агент действительно сможет пользоваться этими инструментами?
Для этого в 0.5.1 появился evals/.
Там есть:
deterministic eval board из 16 задач;
10 read-only вопросов с однозначными ответами;
бесплатная проверка verify_answers.py, которая решает вопросы через MCP без LLM;
опциональный LLM harness, который дает Claude только MCP server и смотрит, как он справляется;
write-loop check, который прогоняет claim -> in_progress -> finish -> waiting_review.
Это важный сдвиг в мышлении [1]. Я не проверяю абстрактно “умная ли модель”. Я проверяю, достаточно ли понятен и надежен мой tool surface.
Если eval падает, чаще всего проблема не в интеллекте [2] модели, а в том, что:
инструмент плохо назван;
описание недостаточно конкретное;
markdown output неудобен для агента;
ошибка [3] не объясняет следующий шаг;
API допускает неоднозначное состояние.
Еще одна вещь, которая появилась после нескольких итераций с Codex и Claude, – это AGENTS.md и .claude/skills/.
Это не просто документация для человека. Это операционный контракт для будущих агентов.
Например, если агент собирается:
работать с доской как worker;
менять daily automation;
трогать MCP tools;
менять схему БД;
shipping/release flow,
он сначала должен открыть соответствующий SKILL.md.
Это решает очень практичную проблему: без таких playbooks каждый новый агент заново открывает одни и те же ловушки. С ними знание о том, как безопасно работать с проектом, лежит рядом с кодом.
Для меня это стало отдельным выводом: если проект должен развивать не один человек, а человек плюс несколько AI-агентов, то repo docs должны быть написаны не только для людей. Они должны быть executable memory для агентов.
Самое заметное изменение в 0.6.0 – automation/. Расписание не включается само после обновления: его нужно осознанно установить через automation/install.sh.
Там два слоя.
Первый слой всегда deterministic:
daily_ritual.py
Он читает доску, классифицирует задачи и пишет digest:
overdue;
waiting for review;
blocked;
unassigned;
due soon;
agent-ready queue.
Этот слой ничего не меняет в трекере. Он просто каждый день дает картину:
что сейчас требует внимания [4].
Второй слой opt-in:
work_loop.py
Если включить DAILY_RITUAL_WORK=1 и передать ANTHROPIC_API_KEY, то Claude получает только task_assistant_* MCP tools и worker-инструкции.
Важно, что ограничения здесь не только в prompt:
у модели нет shell;
нет доступа к repo;
нет web;
только MCP tools трекера;
попытка поставить status=done отклоняется в коде;
--max-tasks ограничивает, сколько задач можно claim-нуть за один запуск.
То есть daily worker может прийти, взять несколько Codex-задач, сделать то, что реально можно сделать только через task tools, и вернуть результат в waiting_review. Но он не может сам закрыть работу за человека.
Есть соблазн сделать “полного автономного агента”, который сам ходит в shell, браузер, почту, GitHub, Slack и закрывает задачи.
Но для личного операционного трекера мне важнее другая модель:
core tracker = источник правды
MCP tools = ограниченный контракт
daily ritual = расписание и digest
human review = финальное принятие
Такой агент менее эффектен в демо, зато его проще оставить без присмотра.
Он не делает вид, что у него есть доступы, которых нет. Он не закрывает задачу сам. Если ему не хватает данных, он должен оставить блокер или вопрос.
Параллельно с продуктовой логикой [5] проект стал заметно взрослее:
SQLite schema теперь идет через Alembic migrations, а не create_all;
есть pytest suite;
есть Ruff;
CI гоняет lint и tests;
Local Mode стал безопаснее: loopback-only auto-login;
Docker image запускается non-root user;
Firestore reads оптимизированы, чтобы не читать done/cancelled backlog при polling;
Google Sheets history writes вынесены из request path в background tasks.
Это не самые громкие изменения, но именно они превращают toy project в штуку, которую можно запускать каждый день.
Первая версия отвечала на вопрос:
какие задачи можно отдать AI?
Текущая версия отвечает на более операционный вопрос:
как дать агенту регулярный, ограниченный и проверяемый способ двигать задачи, не забирая контроль у человека?
Мой текущий ответ:
статусы и next-action owner в модели задачи;
атомарный claim;
waiting_review как стандартный финал агентской работы;
идемпотентный ingest;
MCP как native tool layer;
evals для проверки tool surface;
playbooks как память [6] проекта для будущих агентов;
deterministic digest отдельно от opt-in agent work loop.
На версии 0.6.0 работа не остановилась. Следующие изменения я опишу отдельно, чтобы не смешивать несколько релизов в одной статье.
Следующие интересные направления:
user-built адаптеры для Gmail, Slack, Linear/Jira и более production-ready Telegram pattern;
более явное объяснение, почему задача считается agent-ready;
отчеты агента как отдельные first-class поля, а не только описание;
более удобный hosted setup;
шаблоны для разных рабочих ритмов: solo founder, PM, coding-agent workflow.
Исходники: https://github.com/J3d1-fm/Personal-Task-Assistant [7]
Если вы уже используете Codex, Claude Code или других агентов не разово, а как часть рабочего процесса, мне особенно интересно: где у вас сейчас граница между “агент может взять сам” и “человеку нужно принять решение”?
Автор: J3d1fm
Источник [8]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/33278
URLs in this post:
[1] мышлении: http://www.braintools.ru/thinking
[2] интеллекте: http://www.braintools.ru/article/7605
[3] ошибка: http://www.braintools.ru/article/4192
[4] внимания: http://www.braintools.ru/article/7595
[5] логикой: http://www.braintools.ru/article/7640
[6] память: http://www.braintools.ru/article/4140
[7] https://github.com/J3d1-fm/Personal-Task-Assistant: https://github.com/J3d1-fm/Personal-Task-Assistant
[8] Источник: https://habr.com/ru/articles/1060926/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1060926
Нажмите здесь для печати.