Python SDK 与外部集成
本教程共 32 篇 · 第 26 篇 · 更新于 2026-08-15 · 约 8 分钟阅读
本节目标:学会用 Python SDK 在程序里驱动 dsh,并弄清 SDK、JSON-RPC、ACP、API 网关这几条程序化接入通道各自解决什么问题。
程序化接入的几条路
Web UI 适合人盯着看;程序里要调用 dsh,走的是另一套接口。官方提供了几条通道:
- Python SDK:
deepseek-harness-sdk,在 Python 进程里驱动一个运行时子进程; - TypeScript SDK:
@deepseek-ai/dsh-sdk-client,同协议的 TS 客户端; - ACP:面向自动化客户端的窄协议服务器;
- API 网关(Typert):类型化远程方法层,Web 宿主控制面 ApiProxy 就建在它上面。
先学 Python SDK,其余通道对照着理解。
安装与跑通官方示例
官方要求:Python 3.10+、Git、Linux x64 / Linux arm64,或 macOS 14+ 的 arm64。安装后的运行时不需要系统提供 Node.js——deepseek-harness-sdk 会带一个同版本的 deepseek-harness-runtime-bin 平台 wheel,Python 进程自己携带运行时。
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
Note克隆仓库是为了拿
examples/jsonrpc-agent/里的可运行示例。SDK 本体来自 PyPI,包名deepseek-harness-sdk,导入模块是deepseek_harness。
先设置凭据;模型走 OpenAI 兼容代理时,加 DEEPSEEK_BASE_URL:
export DEEPSEEK_API_KEY=***
# export DEEPSEEK_BASE_URL=http://127.0.0.1:8000/v1
# export DSH_MODEL=deepseek-v4-flash
再跑一个一次性任务:
python examples/jsonrpc-agent/minimal.py \
--workspace /absolute/path/to/workspace \
--session-root /absolute/path/to/sessions \
--session-id example-001 \
"Inspect the repository and fix the failing tests."
脚本打印 assistant 的最终回复;会话目录会收到 JSONL 日志,里面是组装后的模型请求与工具调用。
在自己的程序里调用
示例是下面这段调用的轻量包装:
from pathlib import Path
from deepseek_harness import DeepSeekHarness
config = Path("examples/jsonrpc-agent/minimal.cordis.yml").resolve()
workspace = Path("/absolute/path/to/workspace").resolve()
sessions = Path("/absolute/path/to/sessions").resolve()
with DeepSeekHarness(
provider="deepseek-official",
model="deepseek-v4-flash",
max_tokens=49_152,
cwd=str(workspace),
session_root=str(sessions),
cordis=str(config),
) as harness:
result = harness.run(
"Inspect the repository and fix the failing tests.",
session_id="example-001",
)
print(result.final_response)
DeepSeekHarness 是核心类:进入 with 块时延迟启动内置运行时,退出时自动释放,中间可以反复 run()。RunResult 带 final_response(活动区间内最后提交的 root assistant 文本)、finish_reason(completed / max-tokens / error 等)、events 与 notifications。
示例组合的边界
minimal 示例的默认组合刻意精简,逐项看明白:
| 属性 | 值 |
|---|---|
| 系统提示词 | DSH_SYSTEM_PROMPT,未设置时用默认文案 |
| 模型优先级 | --model → DSH_MODEL → deepseek-v4-flash |
| 面向模型的工具 | 仅持久 bash 与 str_replace_editor |
| Bash 超时 / 编辑器输出上限 | 300 秒 / 16,000 字符 |
| 上下文压缩 | 关闭 |
| 会话持久化 | DSH_SESSION_ROOT 下未压缩的 JSONL |
Warning官方示例组合用
danger-full-access:Bash 和编辑器能修改运行时进程可见的任何路径,没有沙箱兜底。只能在可丢弃的 checkout 或容器里跑;持久 PTY 需要 POSIX 终端,Windows 不支持。
生产环境用哪套组合,由你自己的 cordis.yml 决定。
连接运行中的 dsh:两种姿势
「程序化驱动 dsh」有两种完全不同的姿势,别混淆:
- SDK 自带运行时:Python / TS SDK 在自己的进程里 spawn 一个私有运行时子进程,通过 stdio 通信。它和本机已启动的
dsh web没有任何关系,开箱即用; - 协议服务器:在某个 harness 组合里挂上 JSON-RPC server 或 ACP 插件,让外部程序连到宿主进程。比如
dsh-subagent-acp就是通过 ACP 连接父 harness、派生子 agent 的现成客户端。
官方文档里的示例跑法(dsh web 起 Web、SDK 起子进程、组合里起协议服务器)三者可以并存,各管各的通道。
session id 复用的含义
复用同一个 harness 和 session id,会保留该会话拥有的 Bash 进程——工作目录、已导出的变量、shell 函数都延续到下一次调用。这是 SDK 最容易被忽略的一条规则。
独立任务用新 session id;只有要延续同一段持久化对话时,才复用旧 id。
背后的协议:JSON-RPC over stdio
SDK 不是魔法。它 spawn 一个运行时子进程,通过 stdin/stdout 上的换行分隔 JSON-RPC 通信。协议方法就几个:
initialize:握手,serverInfo.name固定为deepseek-harness-sdk-runtime;session/prompt:把提示词入队,立即返回{ messageId };session.event/session.status:服务端把持久事实和状态转换推给客户端;shutdown:先回响应,再 flush、释放根上下文、以退出码 0 结束。
Tip
prompt()成功只表示入队,不表示模型跑完。高层run()负责从回执收集到整个 agent 下一次 idle,返回这段时间里最后提交的 root assistant 文本。
两条容易踩的坑:
- stdout 是协议专线。组合里不能再挂 stdout logger,诊断写 stderr;
- 协议没有轮次中取消。放弃等待只能关闭运行时:
close()走 stdin EOF → SIGTERM → SIGKILL 的回收阶梯。
TypeScript SDK 与 Python SDK 是设计孪生:共享同一份 wire contract,各自在调用方进程里拥有子进程。区别在启动层——TS 端显式给 command / args,Python 端负责解析打包运行时。
ACP:面向自动化客户端的窄协议
**ACP(Agent Client Protocol)**是另一条 stdio JSON-RPC 通道,刻意只暴露窄能力:
session/new:只接受新会话,不提供历史会话接管;session/prompt:每个会话同时只允许一个进行中的请求,agent 完全停稳才报end_turn;session/request_permission:一次性允许/拒绝,客户端可以自动回答;session/update:只推已提交的 assistant 文本(agent_message_chunk),不推未提交的分片。
它不提供布局、设置页、transcript 回放——这是产品契约,不是实现遗漏。每个会话都有独立的提示词槽位、工作区和取消路径,bridge 在路由事件前还会校验 agent 身份,防止串线。连接关闭时,bridge 会逐个 cancel、settle 并 dispose 自己创建的所有 agent,不留孤儿进程。适合受信任的程序化客户端做自动化,比如让另一个 agent 通过 dsh-subagent-acp 派生子 agent。
API 网关:类型化远程方法
**API 网关(Typert)**是更通用的一层:业务服务用 @Remote / @RemoteScope 装饰器声明对客户端开放的一元(unary)方法,构建时生成 Host 与 Client 约定,运行时走 Connection 的 /api 路由——HTTP 载体是 POST /api/<namespace>/<method>。
网关每次调用都从注册表解析描述符和实时服务:先用 codec 校验参数,再解析对象、调用方法、校验返回值。Agent 这类复杂对象不直接跨线传输,由网关把 agentId 解析成运行时对象;需要协作式取消的方法,签名最后一个参数是 AbortSignal。Web 宿主控制面 ApiProxy(workspace / session / prompt / approval / settings 等 API)就建在这层之上。
NoteRemote 只处理「一个请求一个结果」。会话事件流、增量数据这类流协议复用同一个 Connection,但不用 Remote 描述符。
怎么选
| 场景 | 通道 |
|---|---|
| 人在终端或浏览器里交互 | dsh web / CLI |
| Python 程序批量任务、产品集成、测试驱动 | Python SDK |
| TypeScript 程序、仓库近旁消费方 | TS SDK |
| 自动化客户端、子 agent 编排 | ACP |
| 给自己的服务暴露类型化 RPC | API 网关(Typert) |
Warningrc 阶段一切以实测为准:装完跑
python -m pip show deepseek-harness-sdk看版本,协议方法以官方文档为准。
小结
- Python SDK 用
DeepSeekHarness上下文管理器包住运行时子进程,run(prompt, session_id)发任务;复用 session id 保留 Bash 状态。 - 底层是 stdio 上的 JSON-RPC:
prompt只入队,run才收结果,没有轮次中取消。 - ACP 是窄自动化协议,只认新会话和已提交文本;API 网关是类型化一元 RPC,Web 控制面建在其上。