Настройка dsh: API ключи, модели и локальные эндпоинты
Узнайте, где dsh хранит конфигурацию в Linux и как настроить API ключи DeepSeek или локальный Ollama. Разбираем структуру каталогов и детали передачи данных в каждом режиме работы.
Где dsh хранит конфигурацию
dsh (DeepSeek Harness) хранит конфигурацию в одном каталоге: $DSH_HOME, который по умолчанию находится в ~/.dsh. Все настройки, заданные через веб-интерфейс, записываются туда в виде обычных файлов. Скопируйте этот каталог на другой сервер, и новая машина будет вести себя так же, как старая.
Все важные данные распределены по четырем путям.
~/.dsh/settings.yamlсодержит настройки, созданные вручную или через интерфейс, включая маршруты к провайдерам и моделям.~/.dsh/.credentials.yamlхранит секретные данные. В настройках содержится только ссылка на учетные данные, поэтому само значение ключа находится в отдельном файле.~/.dsh/profiles/содержит именованные профили, а~/.dsh/storages/— сохраненные сессии.~/.dsh/cordis.patch.yml— это ваш собственный уровень патчей. Он применяется поверх встроенной конфигурации для каждого профиля.
DeepSeek анонсировала harness как developer preview с лицензией MIT 17 августа 2026 года, и в README указано, что возможны изменения, нарушающие обратную совместимость. Имена полей и пути в этом руководстве соответствуют документации репозитория по состоянию на август 2026 года. Сверяйте их с документацией для вашей версии перед копированием конфигурации из любых руководств, включая это, так как в предварительных версиях названия могут меняться от релиза к релизу.
Минимально необходимые действия для первого запуска
Для работы dsh требуется Node.js версии 22.19 или новее в рамках ветки 22, либо версия 24 и выше. Node 23 в этот диапазон не входит. Сначала проверьте версию, так как несоответствие версий приводит к сбою при запуске, а сообщение об ошибке может выглядеть как повреждение пакета.
node -v
npx @deepseek-ai/dsh webnpx загружает пакет из реестра npm и запускает веб-интерфейс на http://127.0.0.1:3080. Он привязывается к адресу loopback, поэтому порт недоступен с других машин, даже если это разрешено настройками брандмауэра. На VPS используйте проброс портов через SSH вместо открытия порта 3080 для доступа из интернета. Если выведенный URL вызывает вопросы, в почему dsh запускается на этом адресе объясняется, что именно защищает привязка к loopback и чего она не делает.
ssh -N -L 3080:127.0.0.1:3080 you@your-serverОткройте http://127.0.0.1:3080 на своем ноутбуке, затем перейдите в Settings и Models. В карточке DeepSeek есть поле для API key. Вставьте ключ с сайта platform.deepseek.com и сохраните изменения. Маршрут модели станет доступен немедленно, перезапуск не требуется, так как запущенный сервер сохраняет учетные данные и применяет их «на лету». В доступе к веб-интерфейсу dsh на удаленном сервере описаны варианты с туннелем и reverse proxy, а в установке DeepSeek Harness на VPS — подготовка сервера, которая предполагается в данном руководстве.
После сохранения проверьте, что создало приложение.
ls -la ~/.dsh
stat -c '%a %n' ~/.dsh/.credentials.yamlВы должны увидеть settings.yaml, .credentials.yaml и profiles/. Если stat показывает режим, отличный от 600, выполните chmod 600 ~/.dsh/.credentials.yaml. Файл с учетными данными, доступный для чтения группе или всем пользователям, делает ваш ключ доступным для любой другой учетной записи на сервере.
Для первого запуска без браузера достаточно одной команды.
npx @deepseek-ai/dsh --profile headless "summarise the files in this directory"Профиль headless выполняет одну сессию и выводит итоговый ответ.
Переменные окружения или файл конфигурации
Существует два способа передать ключ для dsh, и они не являются взаимозаменяемыми.
Провайдер из каталога (DeepSeek, Anthropic, OpenAI и остальные из встроенного списка) получает свой ключ через страницу Models. Значение записывается в ~/.dsh/.credentials.yaml, а ваши настройки хранят только ссылку на него. Веб-интерфейс больше не отображает ключ после того, как вы его сохранили.
Пользовательский провайдер может вместо этого использовать имя переменной окружения с помощью apiKeyEnv. Именно такой формат документация предлагает для ~/.dsh/settings.yaml.
llm-pi-ai:
providers:
my-gateway:
apiKeyEnv: GATEWAY_API_KEY
api: openai-completions
baseURL: https://gateway.example/v1
models:
- id: legacy-chat
- id: vision-preview
input: [text, image]Сначала добавьте одного провайдера через веб-интерфейс, затем откройте ~/.dsh/settings.yaml и скопируйте структуру, которую он создал. Во время предварительного просмотра для разработчиков (developer preview) структура вложенности может измениться, поэтому файл, который приложение только что записало, всегда является актуальным.
apiKeyEnv считывается из окружения процесса dsh, а не из вашей оболочки входа. Ключ, экспортированный в интерактивном сеансе, невидим для юнита systemd, поэтому та же конфигурация, которая работает при ручном запуске dsh web, возвращает MISSING_CREDENTIAL при работе в качестве службы. Создайте для юнита отдельный файл.
[Service]
EnvironmentFile=/etc/dsh/dsh.envУстановите для этого файла права доступа 600 и владельцем укажите пользователя, от имени которого работает служба.
Выбор моделей и идентификатор, который нельзя переименовать
Каждый настроенный провайдер отображается в меню выбора моделей. Выбор модели также делает её используемой по умолчанию для новых сессий. В уже существующих сессиях сохраняется привязка к той модели, которая была выбрана изначально, поэтому переключение не изменяет историю старых диалогов.
Идентификатор провайдера (Provider ID) является постоянным. Запросы, сохранённые сессии, настройки моделей по умолчанию и ссылки на учётные данные — всё это привязано к нему, поэтому кнопки переименования не существует. Изменение идентификатора требует создания нового провайдера и удаления старого. Выбирайте имя, которое вас устроит: local-ollama вместо test2.
Модели работают только с текстом, если не указано иное. Добавьте input: [text, image] в запись модели, чтобы объявить поддержку изображений, или установите defaultInput на уровне маршрута в качестве резервного значения для моделей, которые не описаны в каталоге. Маршрут chat-completions от DeepSeek поддерживает только текст и не может быть настроен иначе, поэтому изображение, прикреплённое к такому маршруту, будет отклонено до отправки запроса.
Настройка dsh на локальную конечную точку для работы кода внутри сервера
Ollama предоставляет API, совместимый с OpenAI, на http://127.0.0.1:11434/v1. dsh взаимодействует с любым базовым URL, совместимым с OpenAI, через пользовательский провайдер, поэтому они соединяются напрямую. Сначала настройте сервер моделей: в самостоятельном размещении LLM с помощью Ollama на VPS описаны установка и загрузка модели.
Убедитесь, что конечная точка отвечает, прежде чем переходить к dsh.
ollama list
curl -s http://127.0.0.1:11434/v1/modelsollama list выводит точный тег каждой загруженной вами модели. Скопируйте эту строку. curl возвращает список тех же моделей в формате JSON. Пустой список означает, что Ollama запущена, но модели не загружены. Connection refused означает, что Ollama не запущена или не ожидает подключений на порту 11434.
Теперь добавьте провайдера. Ollama требует наличия поля API key, но игнорирует его значение, поэтому подойдет любая непустая строка.
llm-pi-ai:
providers:
local-ollama:
apiKeyEnv: OLLAMA_API_KEY
api: openai-completions
baseURL: http://127.0.0.1:11434/v1
models:
- id: <the exact tag printed by ollama list>Экспортируйте переменную так, чтобы процесс dsh мог её увидеть.
sudo install -d -m 700 /etc/dsh
printf 'OLLAMA_API_KEY=ollama\n' | sudo tee /etc/dsh/dsh.env
sudo chmod 600 /etc/dsh/dsh.envТри типа ошибок охватывают почти все попытки настройки. MISSING_CREDENTIAL означает, что dsh не смог прочитать переменную, указанную в apiKeyEnv, поэтому проверьте окружение процесса, а не окружение вашего терминала. UNKNOWN_MODEL означает, что id не соответствует настроенной модели, поэтому сравните их с ollama list символ за символом, включая тег после двоеточия. Ошибка 401 при получении списка доступных моделей возникает при обнаружении модели, которое вызывает GET /models по вашему базовому URL; если конечные точки не обслуживают этот путь, модели нужно вводить вручную.
Еще одна ловушка — базовый URL. Если не указать /v1, запросы будут направляться по путям, которые Ollama не обслуживает, поэтому вызов вернет 404, и модель не запустится. Этот суффикс является частью интерфейса, совместимого с OpenAI, а не просто дополнением.
Если Ollama запущена на другой машине, адрес этой машины становится базовым URL, и ваши промпты будут передаваться по сети в открытом виде через обычный HTTP. Держите её на том же хосте или защитите с помощью TLS (transport layer security) и аутентификации: ограничение доступа к открытой конечной точке Ollama.
Какие данные покидают машину в каждом режиме
При использовании ключа DeepSeek каждый запрос отправляется к API DeepSeek. Этот запрос содержит ваш промпт, содержимое файлов, которые агент прочитал для подготовки ответа, вывод выполненных команд и результаты работы инструментов, которые он решил включить. Ваш исходный код попадает в этот пакет данных каждый раз, когда агент открывает файл. Так работают облачные модели, и именно поэтому важно учитывать, из какой директории вы запускаете агента.
При использовании другого провайдера из каталога или корпоративного шлюза те же данные отправляются соответствующему поставщику. Базовый URL (base URL) точно указывает, куда именно.
При использовании локальной конечной точки запрос к модели направляется на 127.0.0.1:11434 и остаётся внутри системы. Никакая часть вашего кода не передаётся поставщику модели. Тем не менее, три типа данных всё равно передаются по сети. npx загружает пакеты из реестра npm. Любой инструмент, который запускает агент, может самостоятельно обращаться к интернету, включая серверы MCP (model context protocol), к которым вы подключились; подробнее об этом написано в запуске MCP-серверов на VPS. Плагины относятся к той же категории: установка плагина запускает код стороннего автора с правами вашего агента, поэтому стоит проверить доступ плагина перед его установкой. Также учитывается телеметрия, если вы её включили.
Телеметрия отключена, пока вы не дадите согласие. DSH_TELEMETRY_MODE — это переключатель согласия; если значение не задано, пусто или не распознано, оно интерпретируется как DISABLED. В этом состоянии dsh не инициализирует провайдер, процессор или экспортер OpenTelemetry (OTel), поэтому при использовании нового профиля сетевые запросы телеметрии не выполняются. FEEDBACK_ONLY включает отправку логов сессии, инициированную обратной связью. FULL также разрешает отправку отчётов о запуске. Лента сессии может экспортировать содержимое сессии, данные инструментов, промпты и пути к рабочим пространствам, поэтому рассматривайте FULL как отправку вашей работы в DeepSeek.
Для гарантированной остановки, не зависящей от правильности указания строки режима, установите DSH_TELEMETRY_DISABLED=1. Любое непустое значение является принудительным отказом от участия, и оно считывается до начала работы, поэтому код проекта не сможет включить телеметрию обратно во время сессии. Адрес коллектора по умолчанию — harness-telemetry.deepseeksvc.com; это полезное имя, которое стоит знать при анализе логов вашего межсетевого экрана.
Проверяйте настройки, а не полагайтесь на них. Во время выполнения задачи выведите список исходящих соединений, которые удерживает процесс.
sudo ss -tnp | grep -i nodeВ режиме локальной модели вы должны видеть только loopback-соединение с 11434 и отсутствие соединений с публичными адресами. Любое другое соединение стоит идентифицировать, прежде чем продолжать работу. В статье Что кодинг-агент отправляет на сервер приведена аналогичная проверка для других инструментов и объясняется, как интерпретировать результат.
Где не следует хранить секреты
- История командной оболочки.
export DEEPSEEK_API_KEY=sk-...записывается в~/.bash_historyв открытом виде и остается там долгое время после ротации ключа. Добавляйте пробел перед командой, если установлена переменнаяHISTCONTROL=ignorespace, или используйте прямой вывод значения в файл с правами 600, минуя оболочку. - Файлы конфигурации в репозиториях. Ключ в
~/.bashrcили~/.zshrcможет оказаться в публичном доступе через одинgit add, если вы храните dotfiles в git. Запускайтеgit grep -I -n 'sk-'в репозитории перед отправкой изменений. settings.yaml. ИспользуйтеapiKeyEnvдля пользовательских провайдеров, чтобы в файле хранилось имя переменной, а не сам секрет. Файлы конфигурации часто копируют в отчеты об ошибках и чаты поддержки. Файлы с учетными данными — никогда.- Вывод
envи скриншоты терминала. Любая команда, выводящая все переменные окружения, отображает и ключ. - Резервные копии.
~/.dshнеобходимо копировать, но.credentials.yamlвнутри него — это активный секрет. Исключайте этот файл из архива или шифруйте сам архив.
Эти правила не ограничиваются dsh, а защита секретов в файлах окружения Compose описывает ту же проблему применительно к контейнерам на том же сервере.
Работа с developer preview
Зафиксируйте версию, которую вы протестировали, так как в preview-версиях ключ конфигурации может измениться в патч-релизе, из-за чего провайдер перестанет загружаться. Если зафиксированная установка отказывается запускаться или npx продолжает выдавать сборку, которую вы не запрашивали, в разделе ошибки установки и версий, возникающие в preview описаны работа с кэшем npx и npm, поставляемым с вашим Node. Храните settings.yaml и cordis.patch.yml в системе контроля версий, исключив файл с учетными данными, чтобы видеть изменения после обновления.
Два флага помогают, если профиль работает некорректно. --dump-default-config выводит составную конфигурацию по умолчанию без запуска, а --dump-config аналогичным образом выводит составную конфигурацию для вашего профиля. Сравнение этих двух выводов показывает, что именно изменил ваш слой патча, что быстрее, чем вручную просматривать слои.
dsh --profile web --dump-configЕсли после обновления что-то перестало работать, запустите эту команду в первую очередь. Ключ, перемещенный между релизами, будет виден как отсутствующая ветка в дампе, и исправление сведется к редактированию одной строки, а не к переустановке.
FAQ
Где dsh хранит мой API-ключ DeepSeek?
В $DSH_HOME/.credentials.yaml, путь к которому соответствует ~/.dsh/.credentials.yaml, если вы не задали DSH_HOME самостоятельно. Страница моделей записывает ключ в этот файл, а ваши настройки содержат только ссылку на него, поэтому секрет хранится в одном месте. Проверьте права доступа с помощью stat -c '%a %n' ~/.dsh/.credentials.yaml и установите их на 600, если они менее строгие. Пользовательский провайдер позволяет полностью избежать использования файла, если указать переменную окружения через apiKeyEnv.
Как заставить dsh использовать локальную модель вместо API DeepSeek?
Добавьте пользовательского провайдера, базовый URL которого указывает на ваш локальный OpenAI-совместимый эндпоинт. Для Ollama это http://127.0.0.1:11434/v1, с api: openai-completions и именем модели id, скопированным в точности из ollama list. Ollama требует наличия API-ключа, но игнорирует его значение, поэтому подойдет любая непустая строка. Убедитесь, что эндпоинт отвечает на запросы с помощью curl -s http://127.0.0.1:11434/v1/models, прежде чем редактировать конфигурацию dsh, так как неработающий эндпоинт и неверная конфигурация вызывают схожие ошибки.
Отправляет ли dsh мой код куда-либо по умолчанию?
При использовании облачной модели — да. Ваш промпт и содержимое файлов, прочитанных агентом, передаются в API-запросе к этому поставщику. При использовании локального эндпоинта запрос уходит на loopback-интерфейс и остается на машине. Телеметрия — это отдельный поток данных, и по умолчанию она отключена: DSH_TELEMETRY_MODE принимает значение DISABLED, если переменная не задана, и в этом состоянии экспортер не создается. Установите DSH_TELEMETRY_DISABLED=1 для отказа от участия, который считывается до начала работы.
Почему dsh сообщает MISSING_CREDENTIAL, хотя моя переменная задана?
Потому что dsh считывает переменную, указанную в apiKeyEnv, из окружения собственного процесса. Переменная, экспортированная в вашей оболочке, не передается в systemd-юнит, сессию другого пользователя или процесс, запущенный до того, как вы выполнили экспорт. Поместите значение в EnvironmentFile с правами 600 для юнита или экспортируйте его в той же оболочке, из которой запускаете dsh. Проверьте, какие переменные фактически видит запущенный процесс, с помощью sudo tr '\0' '\n' < /proc/$(pgrep -f dsh | head -1)/environ.
Какая версия Node.js требуется для dsh?
Node.js 22.19 или новее в ветке 22, либо 24 и выше. Node 23 не входит в список поддерживаемых версий. Запустите node -v перед любыми другими действиями, так как сбой при запуске из-за неподдерживаемой среды выполнения выглядит как поврежденная установка и заставляет пользователей переустанавливать пакет вместо обновления среды выполнения.