现在位置: 首页 > DeepSeek Harness > 正文

DeepSeek Harness Python SDK 调用

Web UI 适合人盯着看,但你要在程序里调用 dsh 时,需要的是 SDK。

本章节介绍 Python SDK:怎么装、怎么跑仓库内置示例、怎么在自己的程序里调用。


Python SDK 解决什么问题

SDK 把 dsh 变成你程序里的一行调用,而不是浏览器里的一个页面。

DeepSeekHarness 是 Python SDK 的核心类,用上下文管理器管理运行时的生命周期。

进入 with 块时延迟启动内置运行时,退出时自动释放,中间可反复调用 run。

适合的场景:批处理任务、把 dsh 集成进自己的产品、在测试里驱动 Agent。

SDK 装好之后,运行时不需要系统提供 Node.js,Python 进程自己带着一份。


前置要求

SDK 对系统有明确要求,先对照确认。

依赖要求
Python3.10 或更高版本
Git已安装
操作系统Linux x64、Linux arm64、macOS 14+(Apple 芯片)、Windows x64
API 端点DeepSeek 兼容的 API 端点与凭据
工作区agent 可以修改的隔离 workspace 与隔离的 dsh home

安装 SDK

克隆仓库拿到可运行示例,建虚拟环境,再安装 SDK 与同版本内置运行时。

$ git clone https://github.com/deepseek-ai/deepseek-harness.git
$ cd deepseek-harness
$ python -m venv .venv
$ . .venv/bin/activate
$ python -m pip install deepseek-harness-sdk

Windows PowerShell 使用 py -3.10 -m venv .venv 创建环境,再用 .venv\Scripts\Activate.ps1 激活。

虚拟环境让 SDK 与系统其它 Python 包隔离,是官方推荐的姿势。

安装后的运行时不需要系统提供 Node.js。

示例与 SDK 绝不会静默读取 ~/.dsh,必须显式传入 home 路径。


运行仓库内置示例

仓库里带了一个 minimal.py 示例,位于 python/sdk/examples/ 目录,跑通它等于验证整条 SDK 链路。

先在环境中设置凭据。

$ export DEEPSEEK_API_KEY=sk-your-key-here
# export DEEPSEEK_BASE_URL=http://127.0.0.1:8000/v1
# export DSH_MODEL=deepseek-v4-flash
# export DSH_SYSTEM_PROMPT='You are a helpful software engineer assistant.'

如果模型不是由默认 DeepSeek 端点提供,而是通过 OpenAI 兼容代理提供,还需要设置 DEEPSEEK_BASE_URL。

随后针对隔离的 workspace 和 dsh home 运行一个任务。

$ python python/sdk/examples/minimal.py \
  --workspace /absolute/path/to/disposable-workspace \
  --dsh-home /absolute/path/to/example-dsh-home \
  --session-id example-001 \
  "Inspect the repository and fix the failing tests."

脚本会打印 assistant 的最终回复。

指定的 home 下会保存生成的 sdk-minimal profile、已安装插件,以及 sessions/ 目录下的未压缩 JSONL 会话日志。


在自己的程序中使用 SDK

仓库内置示例其实是下面这段 SDK 调用的轻量包装,核心只有两步。

实例

# 文件路径:python/sdk/examples/minimal.py 的等价写法
from pathlib import Path

from deepseek_harness import DeepSeekHarness

# agent 可访问的 workspace,必须是绝对路径
workspace = Path("/absolute/path/to/disposable-workspace").resolve()

# 隔离的 dsh home:保存 profile、插件与会话日志,必须是绝对路径
dsh_home = Path("/absolute/path/to/example-dsh-home").resolve()

# 上下文管理器:进入时延迟启动内置运行时,退出时自动释放
with DeepSeekHarness(
    provider="deepseek-official",   # 使用 DeepSeek 官方提供方
    model="deepseek-v4-flash",      # 模型名,SDK 默认也是它
    max_tokens=49_152,              # 单次回复的最大 token 数
    cwd=str(workspace),             # 把 workspace 设为 agent 的工作目录
    dsh_home=str(dsh_home),         # 隔离的 dsh home
    profile="sdk-minimal",          # 随附的极简 profile
) as harness:
    # 发送一个任务;session_id 用于标识这段持久化对话
    result = harness.run(
        "Inspect the repository and fix the failing tests.",
        session_id="example-001",
    )

# 打印 assistant 的最终回复
print(result.final_response)

DeepSeekHarness 会延迟启动内置的 dsh --profile sdk-minimal 进程,并持续复用,直至退出上下文管理器。

同一个 harness 可以在 with 块里多次调用 run,运行时就启动一次。

profile、它的持久 patch、home patch 与传入的 patches 参数共同组成应用配置;要换自定义 profile,配置里必须包含一个 JSON-RPC server 插件(如 @deepseek-ai/dsh-sdk-app),否则启动会失败。


复用 session id:保留 Bash 进程

这是 SDK 最容易被忽略、也最有用的一条规则。

复用同一个 harness 与 session id,会保留该会话拥有的 Bash 进程。

包括它的工作目录、已导出的变量与 shell 函数,全都延续到下一次调用。

实例

# 第一次调用:在 runoob-workspace 里导出一个变量
result = harness.run(
    "Run `cd /repo && export RUNOOB_MODE=dev` and confirm.",
    session_id="runoob-session",
)
print(result.final_response)

# 第二次调用:复用同一个 session id,那个导出的变量还在
result = harness.run(
    "Print the value of RUNOOB_MODE.",
    session_id="runoob-session",
)
print(result.final_response)

独立任务应使用新的 session id;只有下一次调用需要延续同一段持久化对话时,才复用原有 id。


示例组合一览

minimal.py 背后的 sdk-minimal 组合是一份刻意精简的配置,逐项看清它做了什么。

属性值
系统提示词DSH_SYSTEM_PROMPT;未设置时使用 You are a helpful software engineer assistant.
minimal.py 使用的模型--model,其次为 DSH_MODEL,最后为 deepseek-v4-flash
面向模型的工具持久 bash(Windows 为 pwsh)、read_image 与 working_directory
Bash 超时300 秒
上下文压缩自动执行:达到阈值时通过额外模型请求生成较早历史的摘要
持久化检查点已启用:模型请求前等待历史刷盘,保证崩溃后恢复一致
会话持久化<dsh_home>/sessions 下未压缩的 JSONL
权限固定 danger-full-access,只能在可丢弃环境中运行

该组合的唯一组合包在空根之上插入完整配置树,不包含 dsh-base,因此基础 profile 以后新增的工具不会隐式出现。

它省略了 harness 身份、workspace 提示词文本、skill、任务工具、subagent、Web 工具与本地指令发现等插件。

整体调用流程如下。

Python SDK 调用流程图


显式启用 str_replace_editor

随附运行时包含 str_replace_editor,但 sdk-minimal 的默认配置树不挂载它。

需要文件编辑工具时,把下面的配置存成 editor.patch.yml:

实例

# 文件路径:editor.patch.yml
# insert 会添加编辑器工具,并复用已有的文件系统后端
- insert
:
    - id
: tool-str-replace-editor
      name
: '@deepseek-ai/dsh-tool-str-replace-editor'

构造 DeepSeekHarness 时传入 patches 参数即可单次生效:

实例

with DeepSeekHarness(
    profile="sdk-minimal",
    patches=("/absolute/path/to/editor.patch.yml",),  # 单次启动追加的 patch
    # ...其余参数同上
) as harness:
    ...

想持久生效,就把这段 patch 写进 $DSH_HOME/profiles/sdk-minimal/cordis.patch.yml。这个 patch 也适用于标准 sdk profile。

插件管理用 dsh plugin 命令:先设置 DSH_HOME 并执行一次 dsh --profile sdk-minimal --dump-default-config 初始化 profile,再用 dsh plugin --profile sdk-minimal add file:/path/to/my-plugin-bundle 安装——只有管理命令需要 pnpm,启动 SDK 本身不需要。


会话日志上传与关闭

sdk-minimal 默认带一个会话日志贡献器:每次 DeepSeek 请求会随请求上传未落定的事件,每次最多 maxBytes(默认 8 MiB)。

它用于平台侧诊断,不在 messages、系统提示词或工具 schema 之内,不增加模型输入 token。它仍涉及会话数据发送,使用前应按自己的数据要求决定是否关闭。

不希望上传时,在 profile patch 中关闭:

实例

# 文件路径:$DSH_HOME/profiles/sdk-minimal/cordis.patch.yml
# 按 id 覆盖该行配置,关闭会话日志上传
- id
: session-log-deepseek
  config
:
    enabled
: false

danger-full-access 的边界

这个示例组合固定使用 danger-full-access 权限预设,必须清楚它的边界。

danger-full-access 只能在可丢弃的 checkout 或容器内运行。

Bash 与文件访问可以修改运行时进程有权访问的任何路径,没有沙箱兜底。

Windows 上持久 shell 使用 pwsh,同样没有任何路径限制。

换句话说,拿它跑真实项目之前,先确认这个环境弄坏了也不心疼。


小结自测

一句话总结:Python SDK 用 DeepSeekHarness 上下文管理器包住运行时,用 run(prompt, session_id) 发任务。

用三个小问题检验理解。

  1. 复用同一个 session id 会保留什么?
  2. 什么情况下应该使用新的 session id?
  3. sdk-minimal 默认给模型开放了哪些工具?

参考答案:会保留该会话的 Bash 进程,包括工作目录、已导出变量与 shell 函数。

独立任务用新 id;只有需要延续同一段持久化对话时才复用。

持久 bash(Windows 为 pwsh)、read_image 与 working_directory;str_replace_editor 需要显式 patch 启用。