Files
deepwork/README.md
T
Alex CubeandClaude Opus 5 263ad14810 Пульт: выключатель инструментов, помощь с git, память прошлого ответа
Три вещи, которых не хватало по сравнению с пультом DeepShim, — теперь
здесь, и DeepShim можно закрывать.

1. Выключатель инструментов. Снят — приставка, дерево папки и напоминание
   про NEED/LIST/FIND не едут вовсе, круг ровно один: обычное "спросил
   по этим файлам, получил ответ". Замер на одной задаче: 229 символов
   вопроса против 1886. В консоли это флаг --no-tools.

2. Помощь с git: ряд всплывает, только если в папке нет репозитория или
   в .gitignore не хватает строк. Главная - backup/, куда ложатся прежние
   версии файлов перед записью. Перенесено из пульта DeepShim.

3. "Помнить прошлый ответ": галочка, по которой прошлый ответ уезжает
   вместе со следующим вопросом. Разговор из нескольких вопросов, которого
   раньше не было: стенограмма велась внутри одного вопроса и на этом всё.

Попутно два дефекта, оба найдены при проверке:

- Разбор флагов съедал аргумент после булева флага: "deepwork --apply вопрос"
  превращался в apply="вопрос", а вопрос пропадал. Молчало, пока булев флаг
  стоял последним. Та же грабля уже ловилась в ask.mjs; добавлен BOOL_FLAGS.

- Блок-запрос вплотную к прозе не распознавался. DeepSeek регулярно пишет
  "Запрашиваю поиск константы.=== FIND: MAGIC ===" одной строкой, разбор
  требовал начала строки, и круг уходил впустую. Якорь начала снят, якорь
  конца оставлен: упоминание формата посреди фразы запросом не считается.
  От запросов внутри === FILE: === бережёт вырезание этих блоков, а не якорь.

Проверено вживую: без инструментов - 229 символов, один круг, верный ответ;
с инструментами - FIND распознан, два круга, верный ответ; git - repo:false
и пять недостающих строк, после кнопки repo:true и missing пуст; память -
"удвой это число" вернуло 80834 против бессмыслицы без галочки.
--selftest дополнен двумя случаями на разбор запросов.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 14:13:57 +03:00

26 KiB
Raw Blame History

deepwork

DeepSeek, который сам читает вашу папку с кодом.

Обычный веб-чат видит только то, что вы вставили в вопрос. Спросишь «почему падает вот эта функция» — и в ответ получишь три догадки, потому что остального кода он не видел.

Здесь у него появляется обратное направление. DeepSeek отвечает не текстом, а запросом: «пришлите мне файл server.js», «покажите, где встречается waitForAnswer». Программа исполняет запрос, досылает данные, и так по кругу, пока он не соберёт всё нужное и не ответит по существу.

вы: "почему падает загрузка?"
        │
        ▼
   DeepSeek ──► "=== NEED: upload.js ==="
        │              │
        │       программа читает файл и досылает
        │              │
        ▼              ▼
   DeepSeek ──► "=== FIND: parseBody ==="
        │              │
        ▼              ▼
   DeepSeek ──► ответ по существу + исправленный файл

Читает он только вашу папку и только на чтение. Правки возвращает файлами, которые вы записываете нажатием кнопки — или не записываете.


Оглавление

  1. Что понадобится
  2. Установка по шагам
  3. Как пользоваться
  4. Что он умеет запрашивать
  5. Правки файлов
  6. Настройка
  7. Если не работает
  8. Безопасность
  9. Как это устроено внутри
  10. Что проверено вживую

Что понадобится

Что Зачем Как проверить
Windows скрипт запуска написан под неё
Node.js 22 или новее на нём написана программа node --versionv22.… и выше
Сервис deepseek-api через него идёт разговор с DeepSeek см. шаг 1

Node.js, если его нет, ставится с nodejs.org — берите версию LTS. После установки закройте и откройте заново командную строку, иначе node в ней не найдётся.


Установка по шагам

Шаг 1. Поднять deepseek-api

У веб-версии DeepSeek нет API — только вкладка в браузере. Разговором с ней занимается отдельная программа deepseek-api: она держит вкладку и отдаёт наружу обычный HTTP.

Поставьте и запустите её по инструкции в её README — это отдельные пять шагов, включая вход в аккаунт DeepSeek. Возвращайтесь сюда, когда заработает.

Проверка:

curl http://localhost:11500/api/tags

должен вернуть список из трёх «моделей». Окно deepseek-api при этом остаётся открытым — пока оно живо, работает и сервис.

Шаг 2. Скачать deepwork

cd C:\#Projects
git clone https://git.08h.ru/alex/deepwork.git

Без git — скачайте ZIP с той же страницы и распакуйте. Папка может лежать где угодно; рядом с чем-то конкретным её класть не нужно.

Проверка:

cd C:\#Projects\deepwork
node deepwork.mjs --selftest

Ответ самопроверка пройдена. Ничего никуда не отправляется.

Шаг 3. Проверить связку

node deepwork.mjs --check

Три возможных ответа:

Что видно Что это значит
готов: браузер поднят, вкладка DeepSeek открыта всё на месте, можно работать
не готов (HTTP 503) сервис жив, но браузер ещё не поднят — встанет сам на первом вопросе
не отвечает: … deepseek-api не запущен, вернитесь к шагу 1

Готово. Настраивать больше нечего: адрес http://localhost:11500 вшит как значение по умолчанию.


Как пользоваться

Способ 1: пульт (обычный путь)

Перетащите папку своего проекта мышкой на файл start-deepwork.cmd.

Откроется страница в браузере:

  • слева файлы папки — отметьте галочками те, что точно нужны (можно ни одного);
  • поле вопроса;
  • ход работы построчно: видно, что DeepSeek запросил и сколько это заняло;
  • у каждого пришедшего файла кнопка «Записать».

Три переключателя рядом с кнопкой «Спросить»:

Что делает
инструменты разрешить модели самой запрашивать файлы. Снимите — получится обычный «спросил по этим файлам, получил ответ»: один круг, без беготни по папке. См. когда выключать
шагов сколько кругов позволить. Без инструментов не нужен и гаснет
помнить прошлый ответ прошлый ответ уедет вместе со следующим вопросом. Так можно вести разговор: «а теперь перепиши это на async»

Внизу слева иногда всплывает ряд про git — он появляется, только если в папке нет репозитория или в .gitignore не хватает строк. Главная из них — backup/: туда ложатся прежние версии файлов перед записью, и однажды они уедут в коммит.

Пульт открывается в браузере по умолчанию, а не в том, которым управляет deepseek-api: иначе он занял бы там вкладку, и вкладка с чатом потерялась бы. Порт 8787.

Остановить — Ctrl+C в чёрном окне.

Способ 2: командная строка

Работает в текущей папке: её читает, в неё же пишет правки.

cd C:\мой\проект
node C:\#Projects\deepwork\deepwork.mjs "почему падает загрузка файла?"

Полезные флаги:

Флаг Что делает
--files a.js,b.js положить эти файлы в вопрос сразу
--steps 6 сколько кругов позволить (по умолчанию 4)
--apply записать пришедшие файлы на диск (без него только покажет)
--no-tools не давать модели инструменты: один круг, только отмеченные файлы
--chat search режим с поиском в интернете вместо обычного
--check проверить связку и выйти
--selftest внутренние проверки, ничего не отправляя

Когда выключать инструменты

Инструменты хороши, когда непонятно, что читать: «почему падает загрузка» в чужом проекте. Модель сама найдёт нужное.

Выключать стоит, когда вы точно знаете нужные файлы. Тогда:

  • ответ приходит за один круг вместо двух-трёх;
  • вопрос выходит вчетверо короче — приставка, дерево папки и напоминание не едут вовсе (замер: 229 символов против 1886 на той же задаче);
  • модель не ходит по папке без нужды, и наружу не уезжает лишний код.

Чего ожидать по времени

Один круг — 7–15 секунд. Обычная задача укладывается в два-три круга, то есть полминуты. Если DeepSeek запросил много файлов, вопрос на следующем круге вырастает до десятков килобайт — это нормально.


Что он умеет запрашивать

Только чтение и только внутри текущей папки:

Блок в ответе Что делает
=== NEED: путь, путь === прислать файлы целиком
=== LIST: **/*.mjs === список файлов по маске
=== FIND: текст === где встречается текст, с номерами строк

Запуска команд (RUN) нет, и не будет. Исполнять строки, пришедшие из интернета, без белого списка и подтверждения нельзя — а белого списка, который был бы и полезен, и безопасен, придумать не вышло.

Лимиты на один круг: NEED — 200 000 символов суммарно, FIND — 100 попаданий, LIST — 300 путей. Обрезанное помечается прямо в тексте, чтобы DeepSeek видел, что данные неполные.

Цикл останавливается, когда запросов в ответе больше нет, когда кончились круги или когда пришёл тот же самый запрос второй раз подряд — это петля, данные ему уже присылали.


Правки файлов

Исправленный код DeepSeek возвращает блоками:

=== FILE: src/upload.js ===

...содержимое целиком...

=== END FILE ===

Записываются они только по вашей команде — кнопкой «Записать» в пульте или флагом --apply в консоли. Без этого программа просто перечислит, что пришло.

Прежняя версия не пропадает: перед записью она уезжает в папку backup/ внутри проекта. Файлы вне рабочей папки не пишутся вовсе — путь проверяется.


Настройка

Нужна редко. config.json рядом с программой (в репозиторий не попадает, образец — config.example.json):

{
  "deepseekHost": "http://localhost:11500",
  "deepseekModel": "deepseek:think",
  "steps": 4,
  "timeout": 240
}
Ключ По умолчанию Смысл
deepseekHost http://localhost:11500 адрес сервиса deepseek-api
deepseekModel deepseek:think режим чата: think, search или vision
steps 4 сколько кругов позволить
timeout 240 секунд на один круг (сверх этого сервису дают ещё две минуты на очередь)
uiPort 8787 порт пульта

Без файла всё работает на значениях по умолчанию. А вот битый config.json не молчит: программа скажет об ошибке, а не откатится тихо к умолчаниям — иначе правка в настройках не действует, и понять почему невозможно.


Если не работает

Что видно В чём дело Что делать
deepseek-api не отвечает по адресу … сервис не запущен Запустите start.cmd в папке deepseek-api
--check говорит не готов (HTTP 503) сервис жив, браузера ещё нет Ничего: браузер встанет на первом же вопросе
deepseek-api ответил 500 что-то со вкладкой curl http://localhost:11500/api/probe покажет, что там видно
Ответ пришёл обрезанным, код оборван на середине окно браузера свёрнуто Разверните его. Свёрнутое окно Windows не отрисовывает, а DeepSeek рисует блоки кода лениво — см. ниже
шаг 1: запросов нет, готово, а ответ — догадки DeepSeek поленился спросить и придумал Спросите конкретнее либо дайте файл сразу через --files. Так бывает; напоминание в конце вопроса помогает, но не всегда
тот же запрос повторно — петля, выхожу он не принял присланные данные Обычно значит, что запрошенного файла нет или он пуст. Посмотрите журнал шагов
шаги кончились, а запросы ещё идут задача крупнее четырёх кругов --steps 6, но сначала подумайте, не проще ли разбить вопрос
DeepSeek занят: «Server is busy» лимиты на стороне DeepSeek Подождите минуту
node не является внутренней или внешней командой Node не установлен или консоль открыта до установки Поставьте Node, закройте и откройте заново консоль
Чаты в DeepSeek пропадают сами тот же профиль браузера использует другая программа Дайте deepseek-api отдельный профиль

Безопасность

  • Ваш код уходит на серверы DeepSeek. Не только присланные файлы: он сам запрашивает то, что считает нужным, из всей рабочей папки. Для закрытых проектов это не годится.
  • Ключей и паролей в папке быть не должно. .env, config.json с токенами, приватные ключи — всё это он может запросить, и это уедет наружу. Убирайте такое из рабочей папки заранее.
  • Правки не применяются сами. Только кнопкой или флагом --apply, и прежняя версия всегда сохраняется в backup/.
  • За пределы рабочей папки программа не пишет и не читает: путь проверяется, .. не проходит.
  • Пульт слушает только этот компьютер (127.0.0.1), из сети к нему не подключиться.

Как это устроено внутри

Разговор помним мы, а не DeepSeek

Сервис deepseek-api без памяти: каждый запрос он кладёт в чат целиком, затирая прошлый. Поэтому стенограмму ведёт deepwork — функция growTranscript подклеивает к отправленному тексту прошлый ответ модели (между метками === ТВОЙ ПРЕДЫДУЩИЙ ОТВЕТ === и === END ===) и результаты запросов, и следующим кругом уезжает всё сразу.

Раньше память держал сам чат DeepSeek. Своя стенограмма надёжнее: видно в одном месте, что именно уедет модели, а чужая программа, вклинившаяся между нашими кругами, ничего не портит — мы всё приносим заново. Плата — вопрос растёт на длину прошлого ответа; при четырёх кругах это единицы килобайт против 22 КБ первого сообщения.

Что уезжает в первом сообщении

  1. Приставка из agent-prompt.md — кто он и какие блоки может вернуть.
  2. Дерево рабочей папки. Без него первый живой прогон ушёл на угадывание имён файлов, см. замеры ниже.
  3. Файлы, отмеченные галочками (или переданные через --files).
  4. Напоминание про инструменты — вплотную к вопросу. Не в начале: между приставкой и вопросом ложатся килобайты файлов, и инструкция теряется.
  5. Сам вопрос.

Файлы

Файл Что в нём
deepwork.mjs всё: цикл, инструменты, разбор ответов, пульт
agent-prompt.md приставка к первому сообщению
ui.html страница пульта
config.json настройки (не в репозитории)
start-deepwork.cmd запуск пульта перетаскиванием папки

Зависимостей нет — только то, что есть в Node 22.


Что проверено вживую

Внутренние проверки (--selftest)

Разбор запросов, отказ пути за пределы папки, маски * и **, снятие тройных кавычек и подписи языка. Строка вида === NEED: … === внутри блока === FILE: === за запрос не принимается — иначе правка файла с описанием формата запускала бы запрос сама. Пропавший файл в NEED возвращает «файла нет» и цикл не роняет. --steps 1 отдаёт ответ с пометкой «шаги кончились», а не зависает.

Из чего выросли два правила, 11.08.2026

Задача одна и та же: спросить, где решается, что ответ дописан до конца, дав в вопросе заведомо не тот файл. Правильный ответ достижим только через инструменты.

Прогон Кругов Что вышло
1. приставка только в начале сообщения 1 запросов нет. «Точный код в серверном файле» и три догадки
2. + напоминание вплотную к вопросу 4 нашёл, но два круга ушли на угадывание имён файлов
3. + дерево папки в первом сообщении 2 запросил нужный файл сразу, ответил по существу
  • Инструкция в начале сообщения не работает. Между приставкой и вопросом легли 22 КБ файла, и DeepSeek инструменты просто не заметил.
  • Дерево папки надо давать сразу. Без него он угадывал имена (server.js, bridge.js — таких в проекте нет), потом просил LIST *.js (проект на .mjs, пусто), потом LIST **/*. Дерево — 600 символов против двух кругов по минуте.

Пульт, 11.08.2026

Вопрос без единого приложенного файла — «какая функция решает, что ответ дописан?». 36 секунд, три круга: пять блоков FIND сразу, затем NEED на найденный файл, и точный ответ с номером строки. Журнал кругов обновлялся на странице по ходу.

Обрезанные ответы: причина найдена

Один из прогонов оборвался посреди блока кода на // Бы. Это не «конец определён раньше времени» и не кнопка Continue.

Браузер работал в фоне. У неактивного окна страница не отрисовывается, а DeepSeek рисует блоки кода лениво: пока блок не нарисован, в DOM от него лежат первые две строки, а остального нет вовсе — его не достать ни innerText, ни textContent. Прокрутка не помогает.

Помогает единственное — заставить браузер отрисовать страницу. Замеры на живых ответах:

до отрисовки после
ответ про TaskQueue 2068 24 362
ответ про EventBus 3136 30 817
ответ про Router 258 32 045

Вторая причина обрезания — кнопка Continue: DeepSeek режет длинный ответ по своему лимиту и предлагает дописать, а генерация при этом честно завершается. Сквозная проверка после починки — ответ на 47 414 символов с целыми кодом и тестами.

Обе поломки лечатся в deepseek-api, а не здесь: отрисовка и кнопка Continue живут в его browser.mjs. Отсюда остаётся одно требование — не сворачивать окно браузера.

Блок-запрос вплотную к прозе, 26.08.2026

DeepSeek регулярно дописывает запрос в конец фразы, без перевода строки:

Мне нужны данные для ответа. Запрашиваю поиск константы MAGIC.=== FIND: MAGIC ===

Разбор требовал, чтобы блок начинал строку, и такой запрос не видел: цикл решал, что запросов нет, и заканчивал работу догадкой. Круг впустую.

Якорь начала строки снят, якорь конца оставлен: упоминание формата посреди фразы («верни === NEED: файл === и я пришлю») запросом по-прежнему не считается. От запросов внутри блоков === FILE: === бережёт не якорь, а вырезание этих блоков перед разбором — так было и раньше.

Проверено на живой задаче: до правки — один круг и «запросов нет»; после — FIND: MAGIC, второй круг, верный ответ.

Переезд на deepseek-api, 26.08.2026

Раньше deepwork вызывал мост ask.mjs из проекта DeepShim дочерним процессом и гонял текст через временные файлы. Теперь это POST /api/chat, а память кругов переехала из чата в стенограмму (см. выше).

Проверено живым прогоном: круг 1 — 2094 символа, ответ NEED: deepwork.mjs; круг 2 — 28 447 символов стенограммы, ответ дословно верный и по вопросу из первого сообщения. Два круга за 17 с.


Лицензия

MIT.