Три вещи, которых не хватало по сравнению с пультом 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>
deepwork
DeepSeek, который сам читает вашу папку с кодом.
Обычный веб-чат видит только то, что вы вставили в вопрос. Спросишь «почему падает вот эта функция» — и в ответ получишь три догадки, потому что остального кода он не видел.
Здесь у него появляется обратное направление. DeepSeek отвечает не текстом,
а запросом: «пришлите мне файл server.js», «покажите, где встречается
waitForAnswer». Программа исполняет запрос, досылает данные, и так по кругу,
пока он не соберёт всё нужное и не ответит по существу.
вы: "почему падает загрузка?"
│
▼
DeepSeek ──► "=== NEED: upload.js ==="
│ │
│ программа читает файл и досылает
│ │
▼ ▼
DeepSeek ──► "=== FIND: parseBody ==="
│ │
▼ ▼
DeepSeek ──► ответ по существу + исправленный файл
Читает он только вашу папку и только на чтение. Правки возвращает файлами, которые вы записываете нажатием кнопки — или не записываете.
Оглавление
- Что понадобится
- Установка по шагам
- Как пользоваться
- Что он умеет запрашивать
- Правки файлов
- Настройка
- Если не работает
- Безопасность
- Как это устроено внутри
- Что проверено вживую
Что понадобится
| Что | Зачем | Как проверить |
|---|---|---|
| Windows | скрипт запуска написан под неё | — |
| Node.js 22 или новее | на нём написана программа | node --version → v22.… и выше |
Сервис 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 КБ первого сообщения.
Что уезжает в первом сообщении
- Приставка из
agent-prompt.md— кто он и какие блоки может вернуть. - Дерево рабочей папки. Без него первый живой прогон ушёл на угадывание имён файлов, см. замеры ниже.
- Файлы, отмеченные галочками (или переданные через
--files). - Напоминание про инструменты — вплотную к вопросу. Не в начале: между приставкой и вопросом ложатся килобайты файлов, и инструкция теряется.
- Сам вопрос.
Файлы
| Файл | Что в нём |
|---|---|
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.