| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Локальный OpenAI-compatible API proxy для DeepSeek Web Chat
Быстрый старт • Возможности • Примеры • Модели • Endpoints • Open WebUI
FreeDeepseekAPI поднимает локальный API-сервер для DeepSeek Web Chat (chat.deepseek.com) и позволяет подключать DeepSeek Web к Open WebUI, LiteLLM, Hermes, Claude Code, OpenAI SDK-style клиентам и другим OpenAI-compatible инструментам.
Проект работает через ваш обычный залогиненный аккаунт DeepSeek в отдельном Chrome-профиле. Локальный сервер принимает API-запросы, а дальше сам ходит в DeepSeek Web через сохранённую browser-сессию.
⚠️ Это экспериментальный web-chat proxy. DeepSeek может менять внутренний Web API без предупреждения. Для production-кейсов надёжнее официальный платный API DeepSeek.
ForgetMeAI: https://t.me/forgetmeai
git clone https://github.com/ForgetMeAI/FreeDeepseekAPI.git
cd FreeDeepseekAPI
npm run auth
npm startnpm run auth открывает меню авторизации:
npm run auth использует встроенный в Node.js WebSocket, поэтому ему нужен Node.js 22+. Сам proxy работает на Node.js 18+; на старом Node импортируйте готовый deepseek-auth.json через npm run auth:import.
npm start показывает меню запуска:
Настройки можно положить в .env (шаблон — .env.example): npm start, npm run auth и npm run doctor читают его сами. Переменные окружения важнее значений из .env.
Для headless/CI-запуска без меню:
NON_INTERACTIVE=1 npm start
# или
SKIP_ACCOUNT_MENU=1 npm startПо умолчанию сервер слушает:
http://localhost:9655
По умолчанию proxy доступен только с этого компьютера. Для доступа из сети явно задайте адрес и отдельный ключ proxy:
HOST=0.0.0.0 PROXY_API_KEY='replace-with-a-long-random-value' npm startПосле этого передавайте ключ как Authorization: Bearer <key> или x-api-key: <key> (так его отправляют Anthropic SDK). Без PROXY_API_KEY non-health endpoints остаются без авторизации, поэтому не публикуйте такой экземпляр в сеть.
Browser-запросы разрешены с loopback-origin. Если UI открыт на другом адресе, добавьте его точный origin через запятую, например PROXY_CORS_ORIGINS=https://ui.example.com,http://192.168.1.20:3000.
git clone https://github.com/ForgetMeAI/FreeDeepseekAPI.git
cd FreeDeepseekAPI
npm run auth
npm startЕсли Chrome установлен нестандартно, явно укажите путь:
$env:CHROME_PATH="C:\Program Files\Google\Chrome\Application\chrome.exe"
npm run authЕсли Chrome не найден, npm run auth теперь печатает готовые инструкции для Windows/macOS/Linux вместо загадочного stack trace.
git clone https://github.com/ForgetMeAI/FreeDeepseekAPI.git
cd FreeDeepseekAPI
CHROME_PATH=$(which chromium) npm run auth
npm startЕсли Chromium называется иначе:
CHROME_PATH=$(which chromium-browser) npm run auth
# или
CHROME_PATH=$(which google-chrome) npm run authСамый надёжный flow без Chrome на сервере:
npm run authscp deepseek-auth.json user@your-vps:/opt/FreeDeepseekAPI/deepseek-auth.jsoncd /opt/FreeDeepseekAPI
npm run auth:import -- --input ./deepseek-auth.json
npm run doctor -- --offlineNON_INTERACTIVE=1 npm startМожно импортировать не только готовый deepseek-auth.json, но и browser cookie export:
DEEPSEEK_TOKEN="<token>" npm run auth:import -- --input ./cookies.jsonВажно: deepseek-auth.json — это доступ к вашему DeepSeek Web login. Не коммитьте, не публикуйте, храните с правами 0600.
Контейнер предназначен только для non-interactive запуска proxy. Авторизацию через браузер выполните на хосте командой npm run auth: auth-скрипты и deepseek-auth.json в образ не копируются.
Запускайте Podman обычным пользователем, без sudo.
podman build --format docker --tag localhost/free-deepseek-api:local --file Containerfile .podman secret create --replace free-deepseek-auth ./deepseek-auth.json
printf 'Proxy API key: '
IFS= read -r -s PROXY_API_KEY
printf '\n'
printf '%s' "$PROXY_API_KEY" |
podman secret create --replace free-deepseek-proxy-key -Используйте длинный случайный ключ. Значение останется в переменной PROXY_API_KEY текущего shell, чтобы проверить API; оно не попадает в образ или командную строку Podman.
podman run --detach \
--name free-deepseek-api \
--publish 127.0.0.1:9655:9655 \
--secret free-deepseek-auth,target=deepseek-auth.json,uid=1000,gid=1000,mode=0400 \
--secret free-deepseek-proxy-key,target=proxy-api-key,uid=1000,gid=1000,mode=0400 \
--read-only \
--cap-drop=ALL \
--security-opt=no-new-privileges \
localhost/free-deepseek-api:localВнутри контейнера заранее выставлены NON_INTERACTIVE=1, HOST=0.0.0.0 и пути к обоим secrets. REQUIRE_PROXY_API_KEY=1 не даст контейнеру запуститься, если secret с ключом отсутствует или пуст. На хосте порт публикуется только на 127.0.0.1; не убирайте этот адрес без отдельного сетевого firewall/access policy.
podman healthcheck run free-deepseek-api
curl --fail http://127.0.0.1:9655/readyz
curl --fail \
-H "Authorization: Bearer $PROXY_API_KEY" \
http://127.0.0.1:9655/v1/modelsВстроенный healthcheck проверяет локальный /health (жив ли процесс). --format docker при сборке обязателен: в формате OCI (по умолчанию у Podman) инструкция HEALTHCHECK молча отбрасывается. /readyz дополнительно вернёт 503, если ни один DeepSeek auth-аккаунт сейчас не готов обслуживать запросы. Диагностика контейнера:
podman logs free-deepseek-api
podman inspect --format '{{.State.Health.Status}}' free-deepseek-apiОстановка и удаление контейнера вместе с сохранёнными Podman secrets:
podman stop free-deepseek-api
podman rm free-deepseek-api
podman secret rm free-deepseek-auth free-deepseek-proxy-key
unset PROXY_API_KEYПри ротации auth или proxy key замените соответствующий secret и пересоздайте контейнер, чтобы поведение не зависело от версии Podman.
npm run doctor
# без сетевых запросов к DeepSeek:
npm run doctor -- --offlinedoctor проверяет:
Если видите data.biz_data is null, fetch failed, 401/403/429 или Hermes/OpenCode не видит модели — первым делом запускайте npm run doctor.
FreeDeepseekAPI не создаёт новый DeepSeek чат на каждый HTTP-запрос без причины. Логика такая:
Явно задать agent/session:
curl -X POST http://localhost:9655/v1/chat/completions \
-H "Content-Type: application/json" \
-H "x-agent-session: my-agent" \
-d '{"model":"deepseek-chat","messages":[{"role":"user","content":"Привет"}]}'Посмотреть активные sessions:
curl http://localhost:9655/v1/sessionsСбросить одну session:
curl -X POST "http://localhost:9655/reset-session?agent=my-agent"Сбросить все sessions:
curl -X POST "http://localhost:9655/reset-session?agent=all"Почему чаты всё равно появляются в DeepSeek Web: proxy работает через внутренний Web Chat API, а DeepSeek хранит реальные chat sessions у себя. Это нормально для web-proxy. Задача session reuse — не плодить новые чаты без необходимости и аккуратно сбрасываться только когда chain протух/сломался.
Можно подключить несколько auth-файлов. Правильная модель: sticky account per agent/session — proxy не переключает аккаунт внутри живой DeepSeek-сессии. Если аккаунт получил 401/403/429 и ушёл в cooldown, session безопасно сбрасывается и новый запрос может перейти на другой доступный аккаунт.
Вариант 1 — директория с auth-файлами:
mkdir -p accounts
cp deepseek-auth-main.json accounts/main.json
cp deepseek-auth-backup.json accounts/backup.json
chmod 600 accounts/*.json
DEEPSEEK_AUTH_DIR=./accounts NON_INTERACTIVE=1 npm startВариант 2 — список файлов:
DEEPSEEK_AUTH_PATH="./accounts/main.json,./accounts/backup.json" NON_INTERACTIVE=1 npm startКак работает pool:
Настроить cooldown:
DEEPSEEK_ACCOUNT_COOLDOWN_MS=600000 npm startПарольный flow из PR #3 можно делать, но безопаснее не хранить пароль и не делать это дефолтом. Нормальная реализация:
Минимальный безопасный MVP: console auth только интерактивный, без env-пароля. Допустимый automation-вариант: DEEPSEEK_EMAIL=... npm run auth:console, но пароль всё равно вводится hidden prompt.
curl http://localhost:9655/
curl http://localhost:9655/v1/models
curl http://localhost:9655/v1/model-capabilitiesЕсли всё ок, /health вернёт статус сервера, список поддерживаемых aliases и config_ready: true.
curl -X POST http://localhost:9655/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "Привет! Ответь одной фразой."}],
"stream": false
}'curl -X POST http://localhost:9655/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-reasoner",
"messages": [{"role": "user", "content": "Реши коротко: почему небо голубое?"}],
"stream": false
}'При stream: true обычный ответ (запрос без tools) отдаётся клиенту по мере того, как DeepSeek его пишет: сначала размышление, потом текст. Если в запросе есть tools, ответ может оказаться вызовом инструмента, поэтому proxy дожидается конца и отдаёт его целиком, а пока ждёт — раз в DEEPSEEK_STREAM_KEEPALIVE_MS (10 с) шлёт SSE-комментарий : keep-alive, чтобы клиент не оборвал соединение по таймауту. Ошибка, случившаяся уже после начала потока, приходит событием error внутри стрима (SDK OpenAI и Anthropic превращают его в исключение); до начала потока — обычным HTTP-статусом.
Для reasoning-моделей API отдаёт цепочку размышления отдельно от финального ответа:
reasoning_tokens — приблизительная оценка по извлечённому DeepSeek Web THINK-тексту, потому что web stream не отдаёт официальный token usage по reasoning отдельно.
curl -X POST http://localhost:9655/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-chat-search",
"messages": [{"role": "user", "content": "Найди свежий факт про DeepSeek и ответь кратко."}],
"stream": false
}'curl -N -X POST http://localhost:9655/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "Напиши короткую шутку."}],
"stream": true
}'curl -X POST http://localhost:9655/v1/messages \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-chat",
"max_tokens": 512,
"messages": [{"role": "user", "content": "Ответь ровно OK"}],
"stream": false
}'Для Claude Code можно указывать backend напрямую:
export ANTHROPIC_BASE_URL="http://127.0.0.1:9655"
export ANTHROPIC_AUTH_TOKEN="dummy-key"
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1
claude --model deepseek-chatcurl -X POST http://localhost:9655/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-chat",
"input": "Ответь ровно OK",
"stream": false
}'FreeDeepseekAPI принимает:
Прокси просит DeepSeek вернуть строгий JSON tool call, но также умеет парсить fallback-форматы:
Типичные ошибки модели исправляются при разборе: неэкранированные обратные слеши в Windows-путях ("C:\git\src\index.ts") и настоящие переводы строк внутри строковых аргументов. Блоки кода с другим языком (```csharp, ```python) никогда не считаются tool call.
GET /v1/models возвращает только aliases, которые сейчас проверены и работают через этот proxy.
10 сентября 2026 DeepSeek объединил в веб-чате режимы «Быстрый», «Эксперт» и «Распознавание» в один умный режим на модели DeepSeek-V4.1-Flash, а 14 сентября отключил V4 Pro. Переключателя моделей больше нет, остались только «Глубокое мышление» (thinking_enabled) и «Поиск» (search_enabled) (#31).
Поэтому все aliases теперь отправляют в Web API один и тот же model_type: "default" и отличаются только этими двумя флагами. Старые имена (deepseek-expert, deepseek-v4-pro, …) оставлены, чтобы не ломать конфиги клиентов, и помечены в /v1/model-capabilities как deprecated. Если DeepSeek снова поменяет значение model_type, его можно переопределить через DEEPSEEK_MODEL_TYPE (пустое значение — не отправлять поле).
| Alias | Глубокое мышление | Web search | Комментарий |
|---|---|---|---|
| deepseek-chat | нет | нет | базовый chat |
| deepseek-default | нет | нет | совместимый alias |
| deepseek-v4-flash | нет | нет | имя официального API |
| deepseek-v4.1-flash | нет | нет | актуальная модель веб-чата |
| deepseek-v3 | нет | нет | устаревший alias |
| deepseek-reasoner | да | нет | thinking_enabled=true |
| deepseek-r1 | да | нет | R1-compatible alias |
| deepseek-chat-search | нет | да | web search |
| deepseek-default-search | нет | да | web search alias |
| deepseek-reasoner-search | да | да | reasoning + search |
| deepseek-r1-search | да | да | R1-compatible + search |
| deepseek-expert | да | нет | устаревший: «Эксперт» влит в единый режим |
| deepseek-v4-pro | да | нет | устаревший: V4 Pro отключён, отвечает V4.1-Flash |
| deepseek-expert-search | да | да | устаревший alias, теперь работает |
deepseek-vision по-прежнему недоступен: веб-чат понимает картинки в едином режиме, но proxy пока не загружает изображения в DeepSeek. Картинки из запросов заменяются коротким маркером [Image attached; not visible through this proxy] вместо вставки base64 в промпт.
Полный маппинг:
curl http://localhost:9655/v1/model-capabilities| Method | Path | Назначение |
|---|---|---|
| GET | / или /health | статус proxy |
| GET | /v1/models | список рабочих OpenAI-compatible aliases |
| GET | /v1/model-capabilities | полный маппинг aliases, real model, capabilities |
| POST | /v1/chat/completions | OpenAI-compatible Chat Completions |
| POST | /v1/messages | Anthropic Messages API shim |
| POST | /v1/responses | OpenAI Responses API shim |
| GET | /v1/sessions | активные локальные agent sessions |
| POST | /reset-session?agent=<id> | сбросить одну session |
| POST | /reset-session?agent=all | сбросить все sessions |
Base URL для Open WebUI в Docker:
http://host.docker.internal:9655/v1
Для локального запуска без Docker:
http://localhost:9655/v1
Если PROXY_API_KEY не задан, API key можно указать любой. Если ключ задан, клиент должен передавать именно его — proxy проверяет bearer token перед доступом к моделям, сессиям и completions.
npm run auth
npm startЕсли DeepSeek начал отвечать 401, 403 или просит новый PoW/session — повторите npm run auth и обновите сохранённую browser-сессию.
Локальные файлы авторизации не должны попадать в GitHub:
Они уже добавлены в .gitignore.
Синтаксическая проверка, unit-тесты и end-to-end тесты против локального mock-сервера DeepSeek (сеть и аккаунт не нужны; для node --test нужен Node.js 18.13+):
npm testLive smoke-тесты против запущенного локального proxy (если задан PROXY_API_KEY, он берётся из окружения):
BASE_URL=http://127.0.0.1:9655 MODEL=deepseek-chat npm run test:liveFreeDeepseekAPI — экспериментальный web-chat proxy для локального использования и интеграций. Он зависит от текущего контракта DeepSeek Web Chat, поэтому при изменениях на стороне DeepSeek может потребоваться обновление auth/session logic или model mapping.
Если что-то перестало работать:
ForgetMeAI · Telegram
| Back | FazBrowse Home | New Git URL |