У веб-версии DeepSeek нет API: ни ключа, ни эндпойнта, только вкладка
в браузере. Этот сервис держит такую вкладку и отдаёт наружу протокол
Ollama, поэтому любая программа, которая уже умеет ходить в Ollama,
подключается к DeepSeek сменой одного адреса.
GET /api/tags три "модели" по числу режимов чата;
503, пока браузер с чатом не поднят
GET /api/version
POST /api/chat images в сообщении уводят в чат со зрением
POST /api/generate
POST /api/embeddings 501: веб-чат векторов не отдаёт
Внутри — ollama_orchestro/ask.mjs дочерним процессом: он ничего не
экспортирует и выполняется при импорте, это программа командной строки.
Браузер поднимается напрямую из Node, а не через browser-launch.ps1 из
DeepShim: тот рассчитан на человека за консолью и на занятом профиле
спрашивает Read-Host, а у сервиса некому отвечать. Флаги окна оттуда
перенесены: у неактивного окна DeepSeek не дорисовывает блоки кода.
Чего нет: настоящего потока (формат соблюдается, но ответ приходит
целиком), temperature и num_predict, эмбеддингов, параллельных запросов —
вкладка одна, запросы идут очередью по одному.
Сервис слушает все адреса и ходит в DeepSeek под вашим логином. Только
доверенная сеть; сузить до этого компьютера — host в config.json.
Проверка перевода формата без браузера: node test.mjs
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
26 KiB
deepseek-api
DeepSeek, притворяющийся Ollama.
У веб-версии DeepSeek нет API: ни ключа, ни эндпойнта — только вкладка в браузере, куда человек руками пишет вопросы. Эта программа открывает такую вкладку, пишет в неё за вас и отдаёт наружу обычный HTTP — тот самый протокол, на котором говорит Ollama.
Смысл: любая программа, которая уже умеет работать с Ollama, начинает работать с DeepSeek после смены одного адреса. Ни строчки кода в ней менять не нужно.
ваша программа ──HTTP──> deepseek-api ──> браузер ──> chat.deepseek.com
(думает, что │
говорит с Ollama) <──────────── ответ ───────────────┘
Платить не нужно — используется ваш обычный аккаунт DeepSeek. Взамен всё медленно (секунды, а не миллисекунды) и работает только пока открыт браузер.
Оглавление
- Что понадобится
- Установка по шагам
- Проверка, что всё работает
- Как подключить свою программу
- Что умеет и чего не умеет
- Настройка
- Если не работает
- Безопасность
- Как это устроено внутри
Что понадобится
| Что | Зачем | Как проверить, что есть |
|---|---|---|
| Windows | скрипты запуска написаны под неё | — |
| Node.js 22 или новее | на нём написана программа | node --version → должно быть v22.… и выше |
| Браузер на движке Chromium | Яндекс.Браузер, Chrome, Edge — любой | — |
| Аккаунт DeepSeek | бесплатный, регистрация на chat.deepseek.com | — |
| Проект DeepShim | в нём живёт код, который умеет управлять вкладкой | ставится на шаге 1 |
Node.js, если его нет, ставится с nodejs.org — берите
версию LTS, кнопка слева. После установки закройте и откройте заново
командную строку, иначе node в ней не найдётся.
Установка по шагам
Всего шагов семь. Делайте по порядку, каждый заканчивается проверкой — не переходите к следующему, пока предыдущий не дал ожидаемого результата.
Шаг 1. Скачать обе программы
Нужны две: эта и DeepShim, в котором лежит код управления браузером. Положите их рядом, в одну папку:
C:\#Projects\
deepseek-api\ <- эта программа
ollama_orchestro\ <- DeepShim
cd C:\#Projects
git clone https://git.08h.ru/alex/deepseek-api.git
git clone https://git.08h.ru/alex/deepshim.git ollama_orchestro
Папка DeepShim должна называться именно ollama_orchestro — так она указана
в настройках по умолчанию. Хотите иначе — поправите путь на шаге 6.
Без git можно просто скачать ZIP с тех же страниц и распаковать.
Проверка: в
C:\#Projects\deepseek-api\лежитserver.mjs, вC:\#Projects\ollama_orchestro\—ask.mjs.
Шаг 2. Завести отдельный профиль браузера
Браузером будет управлять программа, поэтому работать в нём вам не нужно — и не стоит: он будет самопроизвольно открываться и переключать вкладки. Заведите под него отдельный профиль — это просто пустая папка, браузер сам её заполнит:
mkdir C:\Browsers\deepseek
Имя любое, запомните путь — понадобится на следующем шаге.
Шаг 3. Настроить DeepShim
В папке ollama_orchestro создайте файл config.json:
{
"profileDir": "C:\\Browsers\\deepseek",
"browserExe": "C:\\Program Files\\Yandex\\YandexBrowser\\Application\\browser.exe",
"port": 9333
}
Три значения:
-
profileDir— папка из шага 2. -
browserExe— путь к браузеру. Типичные:Браузер Путь Яндекс.Браузер C:\Program Files\Yandex\YandexBrowser\Application\browser.exeGoogle Chrome C:\Program Files\Google\Chrome\Application\chrome.exeMicrosoft Edge C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe -
port— порт, по которому программа управляет браузером.9333подходит, меняйте только если он у вас занят.
Обратные слэши в JSON удваиваются — C:\\Browsers\\deepseek, а не
C:\Browsers\deepseek. С одинарными файл не прочитается.
Проверка: откройте
config.jsonв браузере (перетащите файл в окно). Если показалась структура — JSON верный. Если ошибка — ищите пропущенную запятую или одинарный слэш.
Шаг 4. Запустить браузер и войти в DeepSeek
cd C:\#Projects\ollama_orchestro
start-browser.cmd
Откроется браузер с чистым профилем на странице DeepSeek. Войдите в аккаунт. Логин сохранится в профиле — больше делать это не придётся.
Проверка: в окне командной строки написано
READY. … is listening on port 9333.Если написаноPort 9333 did not answer— см. Если не работает.
Окно браузера не сворачивайте и не закрывайте. Свёрнутое окно Windows не отрисовывает, и программа не сможет прочитать ответ. Достаточно перевести его на другой рабочий стол или просто оставить позади других окон.
Шаг 5. Создать три рабочих чата
DeepSeek выбирает режим (обычный / с поиском в интернете / со зрением) в момент создания чата, и потом переключить его нельзя — тумблеры исчезают после первого сообщения. Поэтому под каждый режим нужен свой чат.
Создадутся они сами:
cd C:\#Projects\ollama_orchestro
node ask.mjs init
Команда откроет три новых чата, задаст в каждом по вопросу и запишет их
номера в chats.json. Займёт минуту-две, окно браузера в это время будет
само щёлкать — так и надо, не мешайте.
Проверка: в конце напечатается что-то вроде
Сохранено в chats.json: think expert af016e20-… search default+… 8021bbc1-… vision vision 14663b36-…
Шаг 6. Настроить deepseek-api
Файл config.json в папке deepseek-api уже готов:
{
"port": 11500,
"host": "0.0.0.0",
"bridge": "C:/#Projects/ollama_orchestro/ask.mjs",
"chatUrl": "https://chat.deepseek.com/",
"defaultRole": "think",
"timeout": 300
}
Если вы разложили папки как в шаге 1 — менять здесь нечего, переходите
к шагу 7. Если DeepShim лежит в другом месте, поправьте bridge. Здесь
слэши обычные, прямые (C:/…), а не обратные.
Шаг 7. Запустить
cd C:\#Projects\deepseek-api
start.cmd
Проверка: в окне появилось
DeepSeek прикидывается Ollama: http://localhost:11500 Модели: deepseek:think, deepseek:search, deepseek:vision
Это окно должно оставаться открытым — пока оно живо, работает и сервис.
Останов — Ctrl+C или просто закрыть окно.
Готово. Дальше — проверка.
Проверка, что всё работает
Откройте вторую командную строку (первая занята сервисом) и спросите что-нибудь:
curl http://localhost:11500/api/tags
Ожидается список из трёх «моделей»:
{"models":[{"name":"deepseek:think",…},{"name":"deepseek:search",…},{"name":"deepseek:vision",…}]}
Теперь настоящий вопрос:
curl http://localhost:11500/api/chat -d "{\"model\":\"deepseek:think\",\"stream\":false,\"messages\":[{\"role\":\"user\",\"content\":\"Ответь одним словом: столица Японии?\"}]}"
Через несколько секунд:
{"model":"deepseek:think","created_at":"…","message":{"role":"assistant","content":"Токио"},"done":true,"done_reason":"stop"}
Если пришло — всё работает. В окне сервиса при этом видно, сколько заняло:
[think] 37 симв.
[think] ответ 5 симв. за 8 с
Как подключить свою программу
Везде, где программа спрашивает адрес Ollama, укажите:
http://localhost:11500
Моделью выберите deepseek:think.
Если программа работает на другом компьютере в вашей сети — вместо
localhost укажите адрес этого компьютера, например http://192.168.0.10:11500.
Сервис слушает все адреса, ничего дополнительно настраивать не нужно.
Три «модели» — это три режима
| Модель | Что это | Когда брать |
|---|---|---|
deepseek:think |
обычный режим (expert) | почти всегда |
deepseek:search |
с поиском в интернете | нужны свежие данные |
deepseek:vision |
со зрением | разбор картинок |
Картинку можно просто приложить к запросу, как это делает Ollama —
в поле images массивом base64. Тогда режим vision включится сам,
независимо от того, какую модель вы указали.
Незнакомое имя модели — не ошибка. Если программа настойчиво шлёт свою
llama3 или qwen3:8b, запрос уйдёт в обычный чат. Это сделано нарочно:
чужую программу можно переключить на DeepSeek, не разыскивая в её настройках
поле с моделью.
Пример: помощник hlamingo
В hlamingo на вкладке ⚙ есть выбор «Кто думает» — переключите на «DeepSeek», укажите адрес, сохраните.
Что умеет и чего не умеет
Эндпойнты
| Адрес | Что делает |
|---|---|
GET /api/tags |
список «моделей». Отвечает 503, пока браузер не поднят — по этому клиенты понимают, что сервис не готов |
GET /api/version |
опознавательная строка |
POST /api/chat |
сообщения → ответ |
POST /api/generate |
то же, но вопрос одной строкой |
POST /api/embeddings |
501 — веб-чат векторов не отдаёт |
Чего нет и не будет
- Настоящего потока. Ollama печатает ответ по словам; здесь он приходит
целиком. Формат потока при этом соблюдается (клиент получит две строки JSON
вместо многих), поэтому программы, которые ждут поток, не ломаются —
просто ответ появляется разом. Хотите один объект вместо потока — присылайте
"stream": false. temperature,num_predictи прочих настроек генерации. Веб-чат их не принимает. Присланные — молча игнорируются.- Эмбеддингов (векторов для поиска по смыслу). Веб-чат их не считает. Вместо пустого вектора возвращается честная ошибка 501: молчаливая подделка испортила бы поиск так, что вы бы этого не заметили. Если вашей программе нужен и чат, и поиск по смыслу — оставьте поиск на настоящей Ollama.
- Параллельных запросов. Вкладка одна, и два запроса разом затрут друг другу поле ввода. Запросы встают в очередь и идут по одному.
Сколько ждать
Порядок величин, замерено на разборе фразы и генерации тегов:
| Ollama (qwen3:8b, локально) | DeepSeek (веб) | |
|---|---|---|
| короткий вопрос | 2–3 с | 8–12 с |
| первый запрос после запуска браузера | — | +15 с на подъём окна |
Если ваша программа считает, что модель обязана ответить за пару секунд, — увеличьте в ней таймаут.
Настройка
config.json
| Ключ | По умолчанию | Смысл |
|---|---|---|
port |
11500 |
порт, на котором сервис слушает |
host |
0.0.0.0 |
какие адреса слушать; 127.0.0.1 — только этот компьютер |
bridge |
C:/#Projects/ollama_orchestro/ask.mjs |
путь к DeepShim |
chatUrl |
https://chat.deepseek.com/ |
что открывать во вкладке |
defaultRole |
think |
режим для незнакомых имён моделей |
timeout |
300 |
сколько секунд ждать бездействия страницы |
Про timeout: это не «сколько ждать ответа». Пока DeepSeek печатает, ждём
сколько угодно; срок отсчитывается от последнего признака жизни страницы.
Переменные окружения
Перебивают файл, удобны для разовых запусков:
set DEEPSEEK_API_PORT=11501
set DEEPSEEK_CDP_PORT=9444
start.cmd
Профиль браузера, путь к нему и порт управления берутся из
ollama_orchestro/config.json — там уже выполнен вход в DeepSeek, и второй
экземпляр этих настроек однажды разошёлся бы с первым.
Если не работает
Сначала посмотрите в окно сервиса — там пишется, что происходит.
| Что видно | В чём дело | Что делать |
|---|---|---|
Браузер с отладочным портом 9333 не отвечает в ответе на /api/tags |
браузер закрыт | Ничего: он поднимется сам при первом запросе к /api/chat. Если не поднялся — следующая строка |
Браузер так и не открыл отладочный порт |
этот профиль уже открыт без порта управления: новый процесс отдаёт ссылку старому окну и молча завершается | Закройте все окна браузера с этим профилем и повторите. Проверить, что не осталось: диспетчер задач, процессы браузера |
в config.json не задан profileDir или browserExe |
шаг 3 пропущен или файл лежит не в той папке | ollama_orchestro\config.json, оба ключа заполнены |
мост вышел с кодом 1. Вкладка chat.deepseek.com не открыта |
вкладку закрыли руками | Откройте chat.deepseek.com в том же окне браузера, или перезапустите его через start-browser.cmd |
| Ответ приходит обрезанным, без кода | окно браузера свёрнуто — Windows перестаёт его отрисовывать, а DeepSeek дорисовывает блоки кода лениво | Разверните окно. Не сворачивайте: уводите на другой рабочий стол или за другие окна |
| Ответ приходит чужой, не на ваш вопрос | вкладка не успела обновиться | Повторите запрос. Если повторяется — перезапустите браузер |
В окне мелькнуло правки в этом чате кончились, завожу новый |
исчерпан лимит в шесть правок одного сообщения | Ничего. Это штатная смена чата, см. Чаты изнашиваются |
EADDRINUSE: address already in use |
сервис уже запущен в другом окне | Закройте то окно либо возьмите другой порт (DEEPSEEK_API_PORT) |
node не является внутренней или внешней командой |
Node не установлен или командная строка открыта до его установки | Поставьте Node, закройте и откройте заново командную строку |
| Просит войти в DeepSeek при каждом запуске | профиль браузера каждый раз новый | Проверьте, что profileDir указывает на одну и ту же существующую папку |
Отдельная диагностика самого моста — из папки DeepShim:
node ask.mjs probe
Она скажет, видна ли вкладка, найдено ли поле ввода и не просит ли сайт залогиниться.
Проверить перевод формата, не поднимая браузер:
cd C:\#Projects\deepseek-api
node test.mjs
Безопасность
Прочтите, это важнее, чем кажется.
- Сервис слушает все сетевые адреса (
0.0.0.0), а не только этот компьютер. Так задумано: подключаться должны и соседние машины, ровно как к самой Ollama. Аутентификации нет. - Он ходит в DeepSeek под вашим логином. Любой, кто достучится до порта 11500, задаёт вопросы от вашего имени и расходует ваши лимиты.
- Поэтому: только домашняя или доверенная сеть. Не пробрасывайте порт наружу и не открывайте его на публичном Wi-Fi.
- Всё, что вы отправляете, уходит на серверы DeepSeek — как если бы вы написали это в чат руками. Для приватных данных берите локальную Ollama.
Если сервис нужен только на этом компьютере, впишите в config.json:
"host": "127.0.0.1"
Тогда снаружи к нему не подключиться вовсе.
Как это устроено внутри
POST /api/chat
│
├─ склеить system + user в один текст (у веб-чата нет ролей)
├─ выбрать чат по имени модели (think / search / vision)
├─ встать в очередь (вкладка одна)
│
├─> написать вопрос во временный файл
├─> node ask.mjs ask --file … --out … (дочерний процесс)
│ └─> Chrome DevTools Protocol
│ └─> правка ПЕРВОГО сообщения чата
│ └─> дождаться, пока DeepSeek допечатает
├─< прочитать ответ из файла
│
└─ отдать в формате Ollama
Почему правка первого сообщения, а не новое: DeepSeek отбрасывает всё, что было после отредактированного сообщения, и чат остаётся из одного обмена. Контекст не растёт, мусор между запросами не копится, каждый вопрос — с чистого листа.
Почему дочерний процесс, а не импорт: ask.mjs — программа командной строки,
она ничего не экспортирует и выполняется сразу при подключении. Переделывать
чужой проект ради этого не стали.
Почему браузер поднимается напрямую, а не через browser-launch.ps1
из DeepShim: тот скрипт рассчитан на человека за консолью — на занятом профиле
он задаёт вопрос и ждёт ответа, а у сервиса некому отвечать.
Чаты изнашиваются и меняются сами
Одно сообщение DeepSeek разрешает править ровно шесть раз. После шестой правки кнопка перестаёт открывать поле ввода — и чат становится непригоден.
Ничего делать не нужно, это уже предусмотрено. На седьмом вопросе DeepShim
заводит новый чат того же режима, задаёт вопрос сразу в нём, записывает новый
номер в chats.json и удаляет отработавший чат. Снаружи не видно ничего:
тот же запрос, тот же ответ, разве что на несколько секунд дольше.
Отсюда два следствия:
chats.json— не настройка, а переменная. Номера в нём меняются сами по мере работы. Не правьте его руками и не удивляйтесь, если git покажет в нём изменения.- В сайдбаре DeepSeek не копится мусор. Старые чаты удаляются, плюс перед каждым вопросом сайдбар подчищается от посторонних служебных чатов.
Если вы удалите рабочий чат вручную — тоже ничего страшного: следующий запрос заметит пропажу и создаст новый.
Файлы:
| Файл | Что в нём |
|---|---|
server.mjs |
всё: HTTP, очередь, запуск браузера, вызов моста |
config.json |
настройки этой машины |
start.cmd |
запуск |
test.mjs |
проверка перевода формата, браузер не нужен |
Зависимостей нет — только то, что есть в Node 22.
Лицензия
MIT.