用 Python SDK 程序化驱动 DeepSeek Harness:从 Web UI 到生产 Agent
前三篇我们理解了 Harness 是什么、架构怎么搭、和同类比好在哪。这一篇终于落到代码:官方除了 Web UI,还提供了 Python SDK,让你能在自己的 Python 程序里启动会话、发送任务、接收结果,把 Harness 从「交互式玩具」变成「可编程的生产组件」。本文带你从安装到跑通一个真实任务,并讲清楚生命周期、会话复用和运行时选择这几个最容易踩坑的点。

一、Python SDK 能做什么
先说清楚 Python SDK 的定位:它不是让你在 Python 里重新实现一个 Agent,而是让你远程驱动 Harness 内核。
具体能力:
- 启动会话:在 Python 里创建一个 Harness 会话;
- 发送任务:把一段自然语言任务交给 Agent;
- 接收结果:拿到 Agent 完成后的输出;
- 接收通知:订阅 Agent 运行过程中的事件通知;
- 复用会话:保留同一会话的 Bash 进程、工作目录、环境变量。
这意味着:你可以把 Harness 嵌进一个 Flask/FastAPI 服务、一个数据流水线、一个自动化脚本,让它成为一个「可调用的智能体」。
二、安装:一个 pip 命令
官方已经发布了 Python SDK 包,安装很简单:
pip install deepseek-harness-sdk
如果是从源码仓库安装,也可以:
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
python -m venv .venv
source .venv/bin/activate # Windows 用 .venv\Scripts\activate
python -m pip install deepseek-harness-sdk
安装完成后,核心入口是 deepseek_harness 模块下的 DeepSeekHarness 类。
三、最小示例:跑通第一个任务
先看一个最小可运行的例子,直接感受它的 API 形态:
from pathlib import Path
from deepseek_harness import DeepSeekHarness
workspace = Path("./my-project")
sessions = Path("./.sessions")
with DeepSeekHarness(
provider="deepseek-official",
model="deepseek-v4-flash",
max_tokens=49_152,
cwd=str(workspace),
session_root=str(sessions),
cordis=str(config), # 你的 cordis 配置文件路径
) as harness:
result = harness.run(
"Inspect the repository and fix the failing tests.",
session_id="example-001",
)
print(result)
几个关键参数说明:
| 参数 | 含义 |
|---|---|
provider | 模型提供方,这里用 DeepSeek 官方 |
model | 模型名,deepseek-v4-flash 是速度最快的选项 |
max_tokens | 最大输出 Token(49_152 是 Flash 的常见配置) |
cwd | Agent 可访问的工作目录(workspace) |
session_root | 会话日志和状态的落盘目录 |
cordis | Cordis 配置文件路径 |
四、生命周期:延迟启动 + 上下文复用
DeepSeekHarness 有两个容易误解、但非常重要的行为:
1. 延迟启动
DeepSeekHarness 会延迟启动内置运行时,并持续复用,直到退出 with 上下文管理器。也就是说,在进入 with 块之前,它不会真正拉起 Agent 运行时;只有第一次调用 harness.run(...) 时才会启动。这能省下不必要的启动开销。
2. 会话复用 = 保留 Bash 状态
这是最关键的一点,很多人会在这里踩坑:
复用同一个 harness 与 session_id,会保留该会话拥有的 Bash 进程,包括它的工作目录、已导出的环境变量与 shell 函数。
这意味着:
- 独立任务 → 用新的 session_id;
- 延续同一段对话/持久 shell 状态 → 复用原有 id。
举个例子。假设你想让 Agent 先装依赖、再跑测试、再改代码,这三个步骤如果各自用新 session_id,那第二步就看不到第一步 pip install 的结果(环境变量、venv 激活状态都没了)。正确做法是复用同一个 session_id,让它们在同一段持久 shell 里继续:
with DeepSeekHarness(
provider="deepseek-official",
model="deepseek-v4-flash",
cwd=str(workspace),
session_root=str(sessions),
) as harness:
# 第一步:安装依赖
harness.run("Set up the project and install dependencies.", session_id="task-001")
# 第二步:复用同一 session_id,延续同一个 shell
harness.run("Now run the test suite and report failures.", session_id="task-001")
# 第三步:继续复用,修复失败
harness.run("Fix the failing tests you just ran.", session_id="task-001")
这三步共享同一个 Bash 进程,第二步能「看见」第一步装好的依赖,第三步能「看见」第二步的测试输出。
五、默认组合:极简到只有两个工具
官方 Python SDK 的默认组合(preset)非常克制,值得你心里有数:
| 项 | 默认值 |
|---|---|
| 系统提示词 | DSH_SYSTEM_PROMPT 环境变量;未设置则用 You are a helpful software engineer |
| 模型 | model 参数,回退 DSH_MODEL,默认 deepseek-v4-flash |
| 暴露给模型的工具 | 仅 bash 与 str_replace_editor(字符串替换编辑器) |
| Bash 超时 | 300 秒 |
| 编辑器输出上限 | 16,000 |
| 上下文压缩 | 已启用 |
这个组合省略了 harness 身份、workspace 提示词文本、skill(技能)、一次性 Bash、任务工具、上下文压缩以外的其他面向模型的插件。沙箱策略被事实记录为运行时用户上下文,而不会追加到系统提示词中。
也就是说:Python SDK 默认给你的是一个极简模式的 Agent——只有 shell 和文件编辑两个工具。这正是官方用来跑模型基准测试的那个组合。如果你需要更多能力(子智能体、网页访问、技能等),需要自己在 cordis 配置里组装。
六、沙箱与安全:默认是「危险全访问」
这里有一个必须严肃对待的安全提醒。
Python SDK 的默认组合使用 danger-full-access 级别的沙箱:Bash 和编辑器可以修改运行时进程有权访问的任何路径。
官方对此的明确警告是:
只能在可丢弃的 checkout 或容器内运行。
也就是说,不要在一个包含你重要数据的真实项目目录里,用默认配置跑一个不受控的 Agent。正确姿势:
- 用一个可丢弃的 git checkout(克隆一份干净的副本);
- 或者跑在 Docker 容器 / 虚拟机里;
- 给 Agent 一个隔离的 workspace(
cwd指向一个空目录或副本目录)。
这也呼应了第 1 篇提到的:Harness 的沙箱主要约束文件操作,网络访问和进程可见性不在其约束范围内。生产环境务必额外加固。
七、一个更贴近生产的封装示例
把上面的知识串起来,写一个「可复用任务执行器」的骨架:
from pathlib import Path
from deepseek_harness import DeepSeekHarness
class HarnessWorker:
def __init__(self, workspace: str, model: str = "deepseek-v4-flash"):
self.workspace = Path(workspace)
self.sessions = self.workspace / ".sessions"
self.sessions.mkdir(parents=True, exist_ok=True)
self.model = model
def run(self, prompt: str, session_id: str):
"""独立任务用新 session_id;延续任务复用同一 id"""
with DeepSeekHarness(
provider="deepseek-official",
model=self.model,
max_tokens=49_152,
cwd=str(self.workspace),
session_root=str(self.sessions),
) as harness:
return harness.run(prompt, session_id=session_id)
if __name__ == "__main__":
worker = HarnessWorker("./sandbox-repo")
# 独立任务
print(worker.run("List all TODO comments in the codebase.", "job-001"))
# 连续任务(复用 session)
worker.run("Create a new branch and add a README.", "job-002")
result = worker.run("Now commit the changes with a clear message.", "job-002")
print(result)
八、运行时选择与配置进阶
Python SDK 参考文档还介绍了几个进阶点,这里给出要点:
- 运行时选择:你可以在配置层切换底层的运行时实现(例如用不同的会话持久化后端、不同的沙箱后端),而不改业务代码;
- 配置(cordis):通过
cordis参数传入配置文件,决定 Agent 装载哪些插件(工具、技能、子智能体、工作流等); - 通知(Notifications):SDK 支持订阅 Agent 运行过程中的事件通知,适合做进度展示、日志采集、异步任务回调;
- Cordis primer:官方文档有「Cordis primer」章节,介绍组合语法,值得在需要自定义组装时精读。
如果只想快速验证,官方还提供了 jsonrpc-agent 示例,用 JSON-RPC 在极简模式下复现基准测试,仓库的 BENCHMARK.md 有详细指引。
九、小结
Python SDK 把 DeepSeek Harness 从「交互式 Web UI」变成「可编程 Agent 组件」,核心就三句话:
DeepSeekHarness上下文管理器承载生命周期,延迟启动、退出即释放;session_id决定状态边界——独立任务用新 id,延续任务复用 id(保留 Bash 进程与环境);- 默认是极简 + 危险全访问——生产环境务必隔离 workspace、加固沙箱。
下一篇,我们更进一步:手写一个 Harness 插件,把它挂到 dsh-plugin 生态上,看看「一切皆插件」在开发者侧到底意味着什么。
十、补充:SDK 常用 API 速查表
最后把 Python SDK 中最常接触的几组 API 汇总成表,方便你在写 HarnessWorker、FastAPI 服务或自动化脚本时快速查阅。以下示例均以 DeepSeekHarness 的实例 harness 为入口。
| API | 方法签名 | 关键参数 | 返回值 | 典型用途 |
|---|---|---|---|---|
run | run(prompt: str, session_id: str \| None = None) -> RunResult | prompt:任务文本;session_id:会话标识,缺省时自动分配 | 任务执行结果对象,含输出文本与元信息 | 一次性提交自然语言任务并获取结果,是最常用的入口 |
runSession | runSession(prompt: str, session_id: str) -> SessionResult | 同上,但强制传入会话 ID | 会话维度结果,含该会话状态与输出 | 多步骤任务中显式绑定会话,保留 Bash 进程与环境 |
select | select(session_id: str) -> Session | session_id:要选择的既有会话 | 可复用的会话句柄 | 在长流程中定位并恢复历史会话,读取其状态后再继续 |
agent | agent(session_id: str) -> AgentHandle | session_id:要操作的 Agent 会话 | Agent 句柄,可进一步发送指令或订阅事件 | 需要细粒度控制时获取底层 Agent,便于做通知订阅与调试 |
使用提醒:上表是概念性签名,实际应以你安装版本的 SDK 参考文档为准。脚本中优先使用 run,需要严格管理状态时再用 runSession 或 select,agent 一般只在需要底层控制时使用。核心原则仍是:独立任务换新 session_id,延续任务复用同一 session_id。
标签:#DeepSeek #Python #AI Agent #Harness #编程实战

49

被折叠的 条评论
为什么被折叠?



