Настройка 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 для доступа из Интернета.
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 на удаленном сервере описана настройка туннеля и обратного прокси-сервера, а в Установка 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-ключа, но игнорирует его значение, поэтому подойдет любая непустая строка.
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 точно указывает, куда именно.
При использовании локальной конечной точки запрос к модели направляется на 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-'в этом репозитории перед выполнением push. settings.yaml. ИспользуйтеapiKeyEnvдля пользовательских провайдеров, чтобы в файле хранилось имя переменной, а не сам секрет. Файлы конфигурации часто копируют в отчеты об ошибках и чаты поддержки. Файлы с учетными данными — нет.- Вывод
envи скриншоты терминала. Любая команда, выводящая все переменные окружения, выводит и ключ вместе с ними. - Резервные копии.
~/.dshнеобходимо копировать, но.credentials.yamlвнутри него — это активный секрет. Исключайте этот файл из архива или шифруйте архив целиком.
Эти правила не ограничиваются dsh, а защита секретов в файлах окружения Compose описывает ту же проблему применительно к контейнерам на том же сервере.
Работа с developer preview
Зафиксируйте версию, которую вы протестировали, так как в preview-версиях ключ конфигурации может измениться в патч-релизе, из-за чего провайдер перестанет загружаться. Храните 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 самостоятельно. Страница Models записывает ключ в этот файл, а ваши настройки содержат только ссылку на него, поэтому секретные данные хранятся в одном месте. Проверьте права доступа с помощью 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 перед любыми другими действиями, так как сбой при запуске из-за неподдерживаемой среды выполнения выглядит как поврежденная установка, из-за чего пользователи переустанавливают пакет вместо среды выполнения.