ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

DeepSeek Harness(dsh)新手使用教程:从 CLI 到 Python SDK 的 TaoToken 配置骨架

DeepSeek Harness(dsh)新手使用教程:从 CLI 到 Python SDK 的 TaoToken 配置骨架 1. 为什么新手会被 dsh 的配置卡住DeepSeek Harness命令名 dsh是 DeepSeek AI 开源的 agent harness你可以把它理解成一个“能替你在电脑上干活的 AI 助手运行时”。它和普通聊天 AI 最大的区别在于你给它的不是一个聊天窗口里的提示词而是一个工作目录加一段任务描述它会真的去读文件、跑命令、改代码、查资料。对刚接触 dsh 的开发者来说最容易卡住的不是“它是什么”而是“怎么把模型通道配通”。dsh 本身不内置模型必须配置一个模型提供方才能开始对话。官方文档里给了 DeepSeek 官方、Anthropic、OpenAI 以及自定义提供方等多条路径但如果你手头有多个项目、多个工具每个都去单独填 Key、单独改 Base URL很快就会乱。这篇教程聚焦两条上手路径CLI 和 Python SDK并演示如何用 TaoToken 统一 Key 与 API 通道把 settings.json 和 config.toml 的骨架先搭起来再给出插件加载和一次可复现的调用验证动作。适合谁看刚装完 dsh、准备跑第一个任务的新手想把 dsh 接进自己 Python 程序的开发者以及需要给团队统一模型入口、不想每个人各自维护 Key 的人。下面所有步骤都可以跟着做遇到报错也有对应排查。2. TaoToken 前置把 Key 和通道先统一在动 dsh 的配置文件之前先把模型通道这件事理清楚。TaoToken 在这里扮演的角色是统一的 Key 与 API 通道你不需要在每个项目里散落不同的 Key而是拿一个 Key通过统一的 API 地址去访问模型。官网入口是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 这个不加 UTM。你需要先拿到一个可用的 API Key。进入控制台创建 Key 的路径是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 管理页面在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。创建好之后先复制保存后面 settings.json 和 config.toml 都要用到。这里有个概念要提前说清楚dsh 的模型配置里provider 需要 Base URL 和 API Key 两个核心字段。TaoToken 的 API 地址就是那个 Base URLKey 就是凭据。dsh 的凭据解析顺序是继承的环境变量、$DSH_HOME/.credentials.yaml、调用目录下的 .env、$DSH_HOME/.env。也就是说你可以把 Key 放在环境变量里也可以写进配置文件两种方式 dsh 都认。注意dsh 目前处于 developer preview 阶段配置项和命令可能随版本变化。如果你准备接进生产流程先关注官方 Release 说明再决定是否升级。如果你只是想先验证模型能不能通不想马上写代码可以先用模型对话页面确认 Key 有效https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。确认能正常返回之后再往下做 dsh 的配置会少很多“到底是 Key 错还是配置错”的纠结。3. 可复制配置settings.json 与 config.toml 骨架这一节是全文的核心。dsh 的配置分两层理解一层是模型提供方provider的凭据与端点另一层是 dsh 自己的 profile 与 patch 配置。我们分别用 settings.json 和 config.toml 来承载先把骨架搭好再往里填。3.1 settings.json模型提供方骨架settings.json 用来描述模型提供方。下面是一个最小可用骨架把 Base URL 指向 TaoToken 的 API 地址Key 用环境变量引用避免明文写死在文件里{ providers: { taotoken: { type: openai-compatible, baseUrl: https://taotoken.net/api, apiKeyEnv: TAOTOKEN_API_KEY, models: [ { id: deepseek-v4-flash, name: DeepSeek V4 Flash, input: [text] } ] } }, defaultModel: deepseek-v4-flash }几个字段说明一下。type用openai-compatible因为 TaoToken 的 API 走 OpenAI 兼容协议baseUrl就是 https://taotoken.net/api apiKeyEnv表示从环境变量TAOTOKEN_API_KEY读取 Key这样配置文件可以进版本库而不泄露凭据models里声明你打算用的模型input声明模态纯文本任务写[text]即可。然后把 Key 写进环境变量。Linux 或 macOS 下export TAOTOKEN_API_KEY你的KeyWindows PowerShell$env:TAOTOKEN_API_KEY你的Key如果你更习惯把 Key 放在 dsh 的凭据文件里也可以写进$DSH_HOME/.credentials.yaml默认路径是~/.dsh/.credentials.yamltaotoken: apiKey: 你的Key两种方式选一种就行不要同时写否则排查时容易搞混到底读的是哪个。3.2 config.tomldsh profile 与 patch 骨架config.toml 用来描述 dsh 的 profile 和 patch 层。dsh 的配置叠加顺序是空根、各 bundle 的 patch、profile 的 cordis.patch.yml、home 级$DSH_HOME/cordis.patch.yml、--patch覆盖层后应用的层优先。下面是一个骨架把默认模型和权限预设先定下来[profile.web] model deepseek-v4-flash provider taotoken permission_mode workspace-write [profile.headless] model deepseek-v4-flash provider taotoken permission_mode workspace-write [env] DSH_MODEL deepseek-v4-flash DSH_PERMISSION_MODE workspace-writepermission_mode用workspace-write意思是 bash 和文件修改被限制在会话工作区与平台临时目录内读取、网络访问不受限。这是新手比较安全的默认值agent 能改你工作区里的文件但不会随意碰工作区之外的路径。如果你给它一个空目录它就不会碰到别的东西。提示DSH_MODEL和DSH_PERMISSION_MODE这两个环境变量在 CLI 和 SDK 里都生效写进 config.toml 的[env]段可以省去每次手动 export。3.3 两条路径的配置差异CLI 和 Python SDK 共用同一套 provider 配置但入口不同。CLI 通过dsh web或dsh --profile headless启动读取的是 profile 配置Python SDK 通过DeepSeekHarness类传入cordis参数指向一个 cordis 配置文件。下面这张表对照一下配置项CLI 路径Python SDK 路径provider 定义settings.jsonsettings.json 或 cordis 配置默认模型config.toml 的 profile.modelDeepSeekHarness(model...)工作区调用目录或--workspacecwd参数会话持久化$DSH_HOME下 JSONLsession_root参数权限预设DSH_PERMISSION_MODEcordis 配置或环境变量先把 settings.json 和 config.toml 两个骨架建好后面 CLI 和 SDK 都从这里取配置不用重复填 Key。4. 验证请求一次可复现的调用配置写完必须验证否则你不知道是配置错了还是模型不通。这一节给 CLI 和 Python SDK 各一个可复现的验证动作。4.1 CLI 验证headless 一次性任务headless 模式执行完任务就打印答案并退出不启动 HTTP 服务、不监听端口最适合验证。先确认 dsh 能读到配置dsh --profile headless --dump-config这条命令会打印组合后的完整配置树不启动服务。你可以在输出里找taotoken和deepseek-v4-flash确认 provider 和模型都加载了。如果这里看不到说明 settings.json 路径不对或格式有误。然后跑一个真实任务dsh --profile headless 列出当前目录下的文件并说明这个项目是做什么的调用目录就是默认 workspace 根目录。执行完终端会打印最终的非空助手文本退出码在任务 completed 时为 0否则为 1。你可以用退出码判断是否成功echo $?如果输出 0说明模型通道通了agent 也正常执行了。如果输出 1往下看第 5 节的排查。4.2 Python SDK 验证最小调用Python SDK 需要 Python 3.10Linux x64、Linux arm64 或 macOS 14arm64。先装 SDKpython -m venv .venv . .venv/bin/activate python -m pip install deepseek-harness-sdkSDK 自带捆绑运行时不需要系统安装 Node.js。然后写一个最小调用脚本from pathlib import Path from deepseek_harness import DeepSeekHarness config Path(settings.json).resolve() workspace Path(/absolute/path/to/workspace).resolve() sessions Path(/absolute/path/to/sessions).resolve() with DeepSeekHarness( providertaotoken, modeldeepseek-v4-flash, max_tokens49_152, cwdstr(workspace), session_rootstr(sessions), cordisstr(config), ) as harness: result harness.run( Inspect the repository and summarize its main packages., session_idverify-001, ) print(result.final_response)几个要点。DeepSeekHarness懒启动捆绑运行时并在上下文管理器退出前复用复用同一个 harness 加同一个 session id 会保留该会话的 bash 进程包括工作目录、环境变量、shell 函数想开始独立任务就用新的 session id想延续同一段对话才复用 id。运行后脚本会打印最终的助手回复会话目录里会生成包含模型请求与工具调用的 JSONL 日志。注意官方 SDK 示例使用持久化 PTY 后端需要 POSIX 终端环境暂不支持 Windows agent。如果你在 Windows 上先用 CLI 路径验证。4.3 验证成功的标志CLI 路径--dump-config能看到 taotoken providerheadless 任务退出码为 0终端打印了合理的助手回复。SDK 路径脚本正常退出result.final_response有内容session 目录下生成了 JSONL 日志。两个都通过说明 Key、Base URL、模型名三件事都对上了。5. 本篇常见错排查配置和验证过程中下面这些报错出现频率最高逐个对照。MISSING_CREDENTIAL没有可用凭据。检查TAOTOKEN_API_KEY环境变量是否 export 成功或者$DSH_HOME/.credentials.yaml里是否写了 taotoken 的 apiKey。用echo $TAOTOKEN_API_KEY确认环境变量在当前 shell 里可见。UNKNOWN_MODEL模型未配置。检查 settings.json 的models数组里是否有deepseek-v4-flash以及defaultModel是否拼写一致。模型名大小写敏感别写成DeepSeek-V4-Flash。获取可用模型返回 401Key 不对。模型发现走 OpenAI 兼容的GET /models接口如果 Key 无效就会 401。回到 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 确认 Key 状态必要时重新创建一个。发送图片前被拒绝该模型没声明图片模态。纯文本模型在 settings.json 里只写input: [text]不要加image。如果你确实需要图片能力换一个声明了图片模态的模型并新开会话旧会话日志里还带着图。从源码启动报“缺少构建产物”没有先执行pnpm run build。从源码运行时pnpm dsh会直接以 TypeScript 方式启动入口必须先构建否则启动会因缺少产物而报错。想改监听端口dsh web --port 8080。端口参数属于 web app要放在启动器参数之后。dsh web --help看的是 web app 自己的参数帮助dsh --help才是启动器帮助别搞混。安装 git 托管的插件失败pnpm allowBuilds源码型插件安装时触发构建pnpm 默认拦截。按报错提示把allowBuilds键写入 profile 的pnpm-workspace.yaml后重试。headless 退出码为 1任务没 completed。先看终端打印的助手文本通常是模型返回了错误信息或工具执行失败。如果文本为空检查 provider 配置和网络连通性。6. 插件加载与后续路径dsh 的架构是“一切皆插件”一个插件就是一个导出apply(ctx)函数的 TypeScript 模块。下面是一个最小插件骨架import type { Context } from deepseek-ai/cordis export const name hello-plugin export function apply(ctx: Context) { console.log([hello-plugin] plugin loaded!) }挂载到 Web UI 时从仓库根目录创建scratch-plugin/cordis.yml路径必须用绝对路径- insert: - id: hello name: /absolute/path/to/deepseek-harness/scratch-plugin/src/my-plugin.ts启动pnpm dsh web --patch ./scratch-plugin/cordis.yml打开 http://127.0.0.1:3080 终端会在启动时打印[hello-plugin] plugin loaded!插件生效。如果你想注册一个工具用defineTool并在inject里声明依赖import type { Context } from deepseek-ai/cordis import { defineTool } from deepseek-ai/dsh-tools export const name greet-tool export const inject [tools] export function apply(ctx: Context) { ctx.tools.register(defineTool({ name: greet, description: Greet someone by name., parameters: { name: { type: string, required: true, description: The name to greet }, }, output: { schema: { type: string }, render: (_args, value) [{ type: text, text: value }], }, async execute(args) { return Hello, ${args.name}! }, })) }重启后在 Web UI 里问“Use the greet tool to greet Ada.”模型就能调用 greet 工具并收到Hello, Ada!。关键机制有三个通过 ctx 注册的一切在插件卸载时自动清理网络连接等显式资源用ctx.effect(() { ... return disposer })提供清理函数在inject中声明所需服务框架会等所有依赖就绪后才加载插件。如果你打算长期用 dsh 做编码或 Agent 任务建议把模型通道固定下来用 Coding Plan 统一管理https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 遇到配置细节可以对照查。Claude Code 与 Anthropic 相关接入参考 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-code-anthropicutm_campaignrewrite 。最后说一个我踩过的坑settings.json 里的baseUrl末尾不要多加斜杠https://taotoken.net/api就是完整地址写成https://taotoken.net/api/有些兼容层会拼出双斜杠导致 404。配置改完先用--dump-config看一眼比直接跑任务再猜错要快得多。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进